diff --git a/404.html b/404.html index 6aa04229..e7c3aa01 100644 --- a/404.html +++ b/404.html @@ -10,8 +10,8 @@ - - + +
@@ -20,7 +20,7 @@ ) .lsd-dropdown__trigger:hover .lsd-dropdown__option-label,.lsd-dropdown:not(.lsd-dropdown--disabled):not( .lsd-dropdown--error ) .lsd-dropdown__trigger:focus .lsd-dropdown__option-label{-webkit-text-decoration:underline;text-decoration:underline;}.lsd-dropdown__label{display:block;}.lsd-dropdown__button-container{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-box-pack:justify;-webkit-justify-content:space-between;justify-content:space-between;}.lsd-dropdown__trigger{width:100%;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:row;-ms-flex-direction:row;flex-direction:row;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:justify;-webkit-justify-content:space-between;justify-content:space-between;border:none;cursor:pointer;background:none;}.lsd-dropdown__trigger:focus{outline:none;}.lsd-dropdown__option-label{cursor:inherit;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;}.lsd-dropdown__icons{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:row;-ms-flex-direction:row;flex-direction:row;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:center;-ms-flex-pack:center;-webkit-justify-content:center;justify-content:center;gap:8px;}.lsd-dropdown__icon{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;}.lsd-dropdown__supporting-text{margin:6px 14px;}.lsd-dropdown--error .lsd-dropdown__option-label{-webkit-text-decoration:line-through;text-decoration:line-through;}.lsd-dropdown--disabled{opacity:0.34;cursor:initial;}.lsd-dropdown--large{width:208px;}.lsd-dropdown--large.lsd-dropdown--error{width:230px;}.lsd-dropdown--large .lsd-dropdown__label{margin:0 0 6px 18px;}.lsd-dropdown--large .lsd-dropdown__button-container{height:40px;}.lsd-dropdown--large .lsd-dropdown__trigger{padding:10px 0px 10px 18px;}.lsd-dropdown--large .lsd-dropdown__icons{padding:0px 14px;}.lsd-dropdown--medium{width:188px;}.lsd-dropdown--medium.lsd-dropdown--error{width:210px;}.lsd-dropdown--medium .lsd-dropdown__label{margin:0 0 6px 14px;}.lsd-dropdown--medium .lsd-dropdown__button-container{height:32px;}.lsd-dropdown--medium .lsd-dropdown__trigger{padding:6px 0px 6px 14px;}.lsd-dropdown--medium .lsd-dropdown__icons{padding:0px 12px;}.lsd-dropdown--small{width:164px;}.lsd-dropdown--small.lsd-dropdown--error{width:186px;}.lsd-dropdown--small .lsd-dropdown__label{margin:0 0 6px 12px;}.lsd-dropdown--small .lsd-dropdown__button-container{height:28px;}.lsd-dropdown--small .lsd-dropdown__trigger{padding:6px 0px 6px 12px;}.lsd-dropdown--small .lsd-dropdown__icons{padding:0px 10px;}.lsd-dropdown--outlined .lsd-dropdown__button-container{border:1px solid rgb(var(--lsd-border-primary));}.lsd-dropdown--underlined .lsd-dropdown__button-container{border:1px solid transparent;border-bottom:1px solid rgb(var(--lsd-border-primary));}
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/_og/84bf3d4f0b89c5927cae2d71b0af32e50b90e8d9.png b/_og/84bf3d4f0b89c5927cae2d71b0af32e50b90e8d9.png new file mode 100644 index 00000000..53719428 Binary files /dev/null and b/_og/84bf3d4f0b89c5927cae2d71b0af32e50b90e8d9.png differ diff --git a/assets/images/alloc11-5e8896fbfcf04b3abe1b53fd63b4a04d.png b/assets/images/alloc11-5e8896fbfcf04b3abe1b53fd63b4a04d.png new file mode 100644 index 00000000..3dd7008f Binary files /dev/null and b/assets/images/alloc11-5e8896fbfcf04b3abe1b53fd63b4a04d.png differ diff --git a/assets/images/alloc12-f0d03e2eb102436dd8d14827ffeee782.png b/assets/images/alloc12-f0d03e2eb102436dd8d14827ffeee782.png new file mode 100644 index 00000000..d33eb297 Binary files /dev/null and b/assets/images/alloc12-f0d03e2eb102436dd8d14827ffeee782.png differ diff --git a/assets/images/alloc21-f0c07620d2c2a6dcc1cb8dd53d8bf33e.png b/assets/images/alloc21-f0c07620d2c2a6dcc1cb8dd53d8bf33e.png new file mode 100644 index 00000000..a358adff Binary files /dev/null and b/assets/images/alloc21-f0c07620d2c2a6dcc1cb8dd53d8bf33e.png differ diff --git a/assets/images/alloc22-0f0788c13a8f29a95543b44ffc3f7e5c.png b/assets/images/alloc22-0f0788c13a8f29a95543b44ffc3f7e5c.png new file mode 100644 index 00000000..f0535595 Binary files /dev/null and b/assets/images/alloc22-0f0788c13a8f29a95543b44ffc3f7e5c.png differ diff --git a/assets/images/alloc31-b33243d1b3e859704fa649c3cca423ae.png b/assets/images/alloc31-b33243d1b3e859704fa649c3cca423ae.png new file mode 100644 index 00000000..3e0f4e2d Binary files /dev/null and b/assets/images/alloc31-b33243d1b3e859704fa649c3cca423ae.png differ diff --git a/assets/images/alloc32-b4511228d11e730b80e97dbfe14f1b32.png b/assets/images/alloc32-b4511228d11e730b80e97dbfe14f1b32.png new file mode 100644 index 00000000..9e6ad048 Binary files /dev/null and b/assets/images/alloc32-b4511228d11e730b80e97dbfe14f1b32.png differ diff --git a/assets/images/alloc41-7df1382edc6f2440f4becb9306679308.png b/assets/images/alloc41-7df1382edc6f2440f4becb9306679308.png new file mode 100644 index 00000000..986a619c Binary files /dev/null and b/assets/images/alloc41-7df1382edc6f2440f4becb9306679308.png differ diff --git a/assets/images/alloc42-29736c27a94ac18072ccad4ba523374d.png b/assets/images/alloc42-29736c27a94ac18072ccad4ba523374d.png new file mode 100644 index 00000000..0471a329 Binary files /dev/null and b/assets/images/alloc42-29736c27a94ac18072ccad4ba523374d.png differ diff --git a/assets/images/alloc51-987d88b8264639cb4c1edf757b48b8f4.png b/assets/images/alloc51-987d88b8264639cb4c1edf757b48b8f4.png new file mode 100644 index 00000000..ebe24560 Binary files /dev/null and b/assets/images/alloc51-987d88b8264639cb4c1edf757b48b8f4.png differ diff --git a/assets/images/alloc52-ebf1d882e709a00714dce2fd122428eb.png b/assets/images/alloc52-ebf1d882e709a00714dce2fd122428eb.png new file mode 100644 index 00000000..4ac1b951 Binary files /dev/null and b/assets/images/alloc52-ebf1d882e709a00714dce2fd122428eb.png differ diff --git a/assets/images/consumed11-9cb04fe0b2e8a8a6e24ae048041099d4.png b/assets/images/consumed11-9cb04fe0b2e8a8a6e24ae048041099d4.png new file mode 100644 index 00000000..fd07d240 Binary files /dev/null and b/assets/images/consumed11-9cb04fe0b2e8a8a6e24ae048041099d4.png differ diff --git a/assets/images/consumed12-afda980a23ad27bab9dfb32a95a97a3f.png b/assets/images/consumed12-afda980a23ad27bab9dfb32a95a97a3f.png new file mode 100644 index 00000000..efc76f3d Binary files /dev/null and b/assets/images/consumed12-afda980a23ad27bab9dfb32a95a97a3f.png differ diff --git a/assets/images/consumed21-c4091416c0c2cbd0effc9d0e349308ec.png b/assets/images/consumed21-c4091416c0c2cbd0effc9d0e349308ec.png new file mode 100644 index 00000000..f8f3241b Binary files /dev/null and b/assets/images/consumed21-c4091416c0c2cbd0effc9d0e349308ec.png differ diff --git a/assets/images/consumed22-f8b42af736f124afd52887d14e5df7d9.png b/assets/images/consumed22-f8b42af736f124afd52887d14e5df7d9.png new file mode 100644 index 00000000..455f1e4c Binary files /dev/null and b/assets/images/consumed22-f8b42af736f124afd52887d14e5df7d9.png differ diff --git a/assets/images/consumed31-d75cf19d4acef0f2cafe8eb19a3605c4.png b/assets/images/consumed31-d75cf19d4acef0f2cafe8eb19a3605c4.png new file mode 100644 index 00000000..2394f924 Binary files /dev/null and b/assets/images/consumed31-d75cf19d4acef0f2cafe8eb19a3605c4.png differ diff --git a/assets/images/consumed32-44dfd430560af8658b94a3ef9f7e6e6f.png b/assets/images/consumed32-44dfd430560af8658b94a3ef9f7e6e6f.png new file mode 100644 index 00000000..756dff57 Binary files /dev/null and b/assets/images/consumed32-44dfd430560af8658b94a3ef9f7e6e6f.png differ diff --git a/assets/images/consumed41-362c4850d936a407e75ccd58283d88d1.png b/assets/images/consumed41-362c4850d936a407e75ccd58283d88d1.png new file mode 100644 index 00000000..1ca4a8c7 Binary files /dev/null and b/assets/images/consumed41-362c4850d936a407e75ccd58283d88d1.png differ diff --git a/assets/images/consumed42-a28992ae3211a5afb2458cf153e160be.png b/assets/images/consumed42-a28992ae3211a5afb2458cf153e160be.png new file mode 100644 index 00000000..591368da Binary files /dev/null and b/assets/images/consumed42-a28992ae3211a5afb2458cf153e160be.png differ diff --git a/assets/images/consumed51-75711af15f7936d72c04975e332935a7.png b/assets/images/consumed51-75711af15f7936d72c04975e332935a7.png new file mode 100644 index 00000000..a43e073a Binary files /dev/null and b/assets/images/consumed51-75711af15f7936d72c04975e332935a7.png differ diff --git a/assets/images/consumed52-51cbe29ddaf2bed5d9fc9018b549a00c.png b/assets/images/consumed52-51cbe29ddaf2bed5d9fc9018b549a00c.png new file mode 100644 index 00000000..c0d94996 Binary files /dev/null and b/assets/images/consumed52-51cbe29ddaf2bed5d9fc9018b549a00c.png differ diff --git a/assets/images/general11-51932659ec4e58ad9f1b20013b3abdda.png b/assets/images/general11-51932659ec4e58ad9f1b20013b3abdda.png new file mode 100644 index 00000000..2ae5f575 Binary files /dev/null and b/assets/images/general11-51932659ec4e58ad9f1b20013b3abdda.png differ diff --git a/assets/images/general12-aa03eb35a9936b02b34ff2ae3dc2a764.png b/assets/images/general12-aa03eb35a9936b02b34ff2ae3dc2a764.png new file mode 100644 index 00000000..af9a9a50 Binary files /dev/null and b/assets/images/general12-aa03eb35a9936b02b34ff2ae3dc2a764.png differ diff --git a/assets/images/general21-06d52d151e217cbc9ebe65b1dee0fd76.png b/assets/images/general21-06d52d151e217cbc9ebe65b1dee0fd76.png new file mode 100644 index 00000000..3fbdcaa6 Binary files /dev/null and b/assets/images/general21-06d52d151e217cbc9ebe65b1dee0fd76.png differ diff --git a/assets/images/general22-4c59fa28bca8c2b2cbd3d5f787e48489.png b/assets/images/general22-4c59fa28bca8c2b2cbd3d5f787e48489.png new file mode 100644 index 00000000..ba135132 Binary files /dev/null and b/assets/images/general22-4c59fa28bca8c2b2cbd3d5f787e48489.png differ diff --git a/assets/images/general31-127358c1aa2715173141d55c78c79d70.png b/assets/images/general31-127358c1aa2715173141d55c78c79d70.png new file mode 100644 index 00000000..b7f59cc0 Binary files /dev/null and b/assets/images/general31-127358c1aa2715173141d55c78c79d70.png differ diff --git a/assets/images/general32-eb289f0be9cc090fc455d823c26bd310.png b/assets/images/general32-eb289f0be9cc090fc455d823c26bd310.png new file mode 100644 index 00000000..f9e7a1e2 Binary files /dev/null and b/assets/images/general32-eb289f0be9cc090fc455d823c26bd310.png differ diff --git a/assets/images/general41-949405deaef610fd9742055a23363f7e.png b/assets/images/general41-949405deaef610fd9742055a23363f7e.png new file mode 100644 index 00000000..99aab98b Binary files /dev/null and b/assets/images/general41-949405deaef610fd9742055a23363f7e.png differ diff --git a/assets/images/general42-39f202b1dfdcecc289d3582e20cde498.png b/assets/images/general42-39f202b1dfdcecc289d3582e20cde498.png new file mode 100644 index 00000000..cc8e6ae0 Binary files /dev/null and b/assets/images/general42-39f202b1dfdcecc289d3582e20cde498.png differ diff --git a/assets/images/general51-72f8449fb89dfdd31ab4eeef2bfa8ebf.png b/assets/images/general51-72f8449fb89dfdd31ab4eeef2bfa8ebf.png new file mode 100644 index 00000000..c436a627 Binary files /dev/null and b/assets/images/general51-72f8449fb89dfdd31ab4eeef2bfa8ebf.png differ diff --git a/assets/images/general52-3903edbdaf25478fbcabf8ec390ac257.png b/assets/images/general52-3903edbdaf25478fbcabf8ec390ac257.png new file mode 100644 index 00000000..584c8cb7 Binary files /dev/null and b/assets/images/general52-3903edbdaf25478fbcabf8ec390ac257.png differ diff --git a/assets/images/sizes11-6ed8118385ec2b2570e7aaeee1f6541e.png b/assets/images/sizes11-6ed8118385ec2b2570e7aaeee1f6541e.png new file mode 100644 index 00000000..cb5877d0 Binary files /dev/null and b/assets/images/sizes11-6ed8118385ec2b2570e7aaeee1f6541e.png differ diff --git a/assets/images/sizes12-a05d9e5b04bc487f75d5ec3322619645.png b/assets/images/sizes12-a05d9e5b04bc487f75d5ec3322619645.png new file mode 100644 index 00000000..a6d6ca32 Binary files /dev/null and b/assets/images/sizes12-a05d9e5b04bc487f75d5ec3322619645.png differ diff --git a/assets/images/sizes21-b404c76c47b45312f15afe077e97c5d8.png b/assets/images/sizes21-b404c76c47b45312f15afe077e97c5d8.png new file mode 100644 index 00000000..c254a4a4 Binary files /dev/null and b/assets/images/sizes21-b404c76c47b45312f15afe077e97c5d8.png differ diff --git a/assets/images/sizes22-e801d2de7a6ae71ed02556af421d17b4.png b/assets/images/sizes22-e801d2de7a6ae71ed02556af421d17b4.png new file mode 100644 index 00000000..8d78c54b Binary files /dev/null and b/assets/images/sizes22-e801d2de7a6ae71ed02556af421d17b4.png differ diff --git a/assets/images/sizes31-9af6876cd32a8486431c0859f5c15e7c.png b/assets/images/sizes31-9af6876cd32a8486431c0859f5c15e7c.png new file mode 100644 index 00000000..9caf4499 Binary files /dev/null and b/assets/images/sizes31-9af6876cd32a8486431c0859f5c15e7c.png differ diff --git a/assets/images/sizes32-3011b5545d0899d6c3bf6a3c7f0c1304.png b/assets/images/sizes32-3011b5545d0899d6c3bf6a3c7f0c1304.png new file mode 100644 index 00000000..d00d5178 Binary files /dev/null and b/assets/images/sizes32-3011b5545d0899d6c3bf6a3c7f0c1304.png differ diff --git a/assets/images/sizes41-2eca56b296b460aa98b34ff0e3642a67.png b/assets/images/sizes41-2eca56b296b460aa98b34ff0e3642a67.png new file mode 100644 index 00000000..7a61f8bb Binary files /dev/null and b/assets/images/sizes41-2eca56b296b460aa98b34ff0e3642a67.png differ diff --git a/assets/images/sizes42-5024bdc66d052e6b6636040cef38bd93.png b/assets/images/sizes42-5024bdc66d052e6b6636040cef38bd93.png new file mode 100644 index 00000000..1040a3ec Binary files /dev/null and b/assets/images/sizes42-5024bdc66d052e6b6636040cef38bd93.png differ diff --git a/assets/images/sizes51-129c42f705ff833ed745045e7803cb6f.png b/assets/images/sizes51-129c42f705ff833ed745045e7803cb6f.png new file mode 100644 index 00000000..9cf9f5d8 Binary files /dev/null and b/assets/images/sizes51-129c42f705ff833ed745045e7803cb6f.png differ diff --git a/assets/images/sizes52-505ad4d2e61ad6462a0e9d100fcf234b.png b/assets/images/sizes52-505ad4d2e61ad6462a0e9d100fcf234b.png new file mode 100644 index 00000000..7b405c8d Binary files /dev/null and b/assets/images/sizes52-505ad4d2e61ad6462a0e9d100fcf234b.png differ diff --git a/assets/images/tempalloc11-2ba6018b7760dfd150567d789283ffdf.png b/assets/images/tempalloc11-2ba6018b7760dfd150567d789283ffdf.png new file mode 100644 index 00000000..922773bf Binary files /dev/null and b/assets/images/tempalloc11-2ba6018b7760dfd150567d789283ffdf.png differ diff --git a/assets/images/tempalloc12-1e7c0754f86c80cf83b4d58183816de6.png b/assets/images/tempalloc12-1e7c0754f86c80cf83b4d58183816de6.png new file mode 100644 index 00000000..81f68417 Binary files /dev/null and b/assets/images/tempalloc12-1e7c0754f86c80cf83b4d58183816de6.png differ diff --git a/assets/images/tempalloc21-875ab00f360822c237156c64609b1367.png b/assets/images/tempalloc21-875ab00f360822c237156c64609b1367.png new file mode 100644 index 00000000..2e07c549 Binary files /dev/null and b/assets/images/tempalloc21-875ab00f360822c237156c64609b1367.png differ diff --git a/assets/images/tempalloc22-214f62229a8d204d44e83dfcf6a69c19.png b/assets/images/tempalloc22-214f62229a8d204d44e83dfcf6a69c19.png new file mode 100644 index 00000000..457e819e Binary files /dev/null and b/assets/images/tempalloc22-214f62229a8d204d44e83dfcf6a69c19.png differ diff --git a/assets/images/tempalloc31-7b52143b8f6199186fb0ae7c66486365.png b/assets/images/tempalloc31-7b52143b8f6199186fb0ae7c66486365.png new file mode 100644 index 00000000..1fe0d83b Binary files /dev/null and b/assets/images/tempalloc31-7b52143b8f6199186fb0ae7c66486365.png differ diff --git a/assets/images/tempalloc32-0a2c79a5578806df5da0f97b15eb1c56.png b/assets/images/tempalloc32-0a2c79a5578806df5da0f97b15eb1c56.png new file mode 100644 index 00000000..60c61440 Binary files /dev/null and b/assets/images/tempalloc32-0a2c79a5578806df5da0f97b15eb1c56.png differ diff --git a/assets/images/tempalloc41-3174820f91664038d6fdd966f07bd90d.png b/assets/images/tempalloc41-3174820f91664038d6fdd966f07bd90d.png new file mode 100644 index 00000000..8d37bf33 Binary files /dev/null and b/assets/images/tempalloc41-3174820f91664038d6fdd966f07bd90d.png differ diff --git a/assets/images/tempalloc42-6122a1bdf8c5db3a03fa4249ebb52e1f.png b/assets/images/tempalloc42-6122a1bdf8c5db3a03fa4249ebb52e1f.png new file mode 100644 index 00000000..fb96b2af Binary files /dev/null and b/assets/images/tempalloc42-6122a1bdf8c5db3a03fa4249ebb52e1f.png differ diff --git a/assets/images/tempalloc51-5b0868395d26e76dac7744b216e4949f.png b/assets/images/tempalloc51-5b0868395d26e76dac7744b216e4949f.png new file mode 100644 index 00000000..b9cfd264 Binary files /dev/null and b/assets/images/tempalloc51-5b0868395d26e76dac7744b216e4949f.png differ diff --git a/assets/images/tempalloc52-ceccc6d4166dbdedebcdb4370acb9650.png b/assets/images/tempalloc52-ceccc6d4166dbdedebcdb4370acb9650.png new file mode 100644 index 00000000..cf022f4e Binary files /dev/null and b/assets/images/tempalloc52-ceccc6d4166dbdedebcdb4370acb9650.png differ diff --git a/assets/js/124805df.efc495a4.js b/assets/js/124805df.b9daba0d.js similarity index 77% rename from assets/js/124805df.efc495a4.js rename to assets/js/124805df.b9daba0d.js index 9156937a..30544058 100644 --- a/assets/js/124805df.efc495a4.js +++ b/assets/js/124805df.b9daba0d.js @@ -1 +1 @@ -"use strict";(self.webpackChunkvac_dev=self.webpackChunkvac_dev||[]).push([[2206],{9935:e=>{e.exports=JSON.parse('{"permalink":"/rlog","page":1,"postsPerPage":10,"totalPages":4,"totalCount":34,"nextPage":"/rlog/page/2","blogDescription":"Blog","blogTitle":"Research Blog"}')}}]); \ No newline at end of file +"use strict";(self.webpackChunkvac_dev=self.webpackChunkvac_dev||[]).push([[2206],{9935:e=>{e.exports=JSON.parse('{"permalink":"/rlog","page":1,"postsPerPage":10,"totalPages":4,"totalCount":35,"nextPage":"/rlog/page/2","blogDescription":"Blog","blogTitle":"Research Blog"}')}}]); \ No newline at end of file diff --git a/assets/js/2e8c87b8.756e51d5.js b/assets/js/2e8c87b8.666a61ea.js similarity index 84% rename from assets/js/2e8c87b8.756e51d5.js rename to assets/js/2e8c87b8.666a61ea.js index cdfd4356..7f555e5c 100644 --- a/assets/js/2e8c87b8.756e51d5.js +++ b/assets/js/2e8c87b8.666a61ea.js @@ -1 +1 @@ -"use strict";(self.webpackChunkvac_dev=self.webpackChunkvac_dev||[]).push([[2585],{93605:(e,t,r)=>{r.r(t),r.d(t,{assets:()=>l,contentTitle:()=>i,default:()=>p,frontMatter:()=>o,metadata:()=>c,toc:()=>s});var n=r(87462),a=(r(67294),r(3905));const o={title:"Exploring zkVMs: Which Projects Truly Qualify as Zero-Knowledge Virtual Machines?",date:new Date("2024-08-27T12:00:00.000Z"),authors:"moudy",published:!0,slug:"zkVM-explorations",categories:"research",discuss:"https://forum.vac.dev/t/exploring-zkvms-which-projects-truly-qualify-as-zero-knowledge-virtual-machines/317",toc_min_heading_level:2,toc_max_heading_level:5},i=void 0,c={permalink:"/rlog/zkVM-explorations",source:"@site/rlog/2024-08-27-Zkvm.mdx",title:"Exploring zkVMs: Which Projects Truly Qualify as Zero-Knowledge Virtual Machines?",description:"The blockchain space is rapidly evolving, and with it, new technologies are emerging that promise enhanced privacy, scalability, and security.",date:"2024-08-27T12:00:00.000Z",formattedDate:"August 27, 2024",tags:[],readingTime:23.53,hasTruncateMarker:!0,authors:[{name:"Moudy",github:"moudyellaz",key:"moudy"}],frontMatter:{title:"Exploring zkVMs: Which Projects Truly Qualify as Zero-Knowledge Virtual Machines?",date:"2024-08-27T12:00:00.000Z",authors:"moudy",published:!0,slug:"zkVM-explorations",categories:"research",discuss:"https://forum.vac.dev/t/exploring-zkvms-which-projects-truly-qualify-as-zero-knowledge-virtual-machines/317",toc_min_heading_level:2,toc_max_heading_level:5},nextItem:{title:"Nescience: A User-Centric State-Separation Architecture",permalink:"/rlog/Nescience-state-separation-architecture"}},l={authorsImageUrls:[void 0]},s=[],u={toc:s};function p(e){let{components:t,...r}=e;return(0,a.kt)("wrapper",(0,n.Z)({},u,r,{components:t,mdxType:"MDXLayout"}))}p.isMDXComponent=!0},3905:(e,t,r)=>{r.d(t,{Zo:()=>u,kt:()=>m});var n=r(67294);function a(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function o(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||(a[r]=e[r]);return a}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(a[r]=e[r])}return a}var l=n.createContext({}),s=function(e){var t=n.useContext(l),r=t;return e&&(r="function"==typeof e?e(t):i(i({},t),e)),r},u=function(e){var t=s(e.components);return n.createElement(l.Provider,{value:t},e.children)},p={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,a=e.mdxType,o=e.originalType,l=e.parentName,u=c(e,["components","mdxType","originalType","parentName"]),d=s(r),m=a,y=d["".concat(l,".").concat(m)]||d[m]||p[m]||o;return r?n.createElement(y,i(i({ref:t},u),{},{components:r})):n.createElement(y,i({ref:t},u))}));function m(e,t){var r=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var o=r.length,i=new Array(o);i[0]=d;var c={};for(var l in t)hasOwnProperty.call(t,l)&&(c[l]=t[l]);c.originalType=e,c.mdxType="string"==typeof e?e:a,i[1]=c;for(var s=2;s{r.r(t),r.d(t,{assets:()=>l,contentTitle:()=>i,default:()=>p,frontMatter:()=>o,metadata:()=>c,toc:()=>s});var n=r(87462),a=(r(67294),r(3905));const o={title:"Exploring zkVMs: Which Projects Truly Qualify as Zero-Knowledge Virtual Machines?",date:new Date("2024-08-27T12:00:00.000Z"),authors:"moudy",published:!0,slug:"zkVM-explorations",categories:"research",discuss:"https://forum.vac.dev/t/exploring-zkvms-which-projects-truly-qualify-as-zero-knowledge-virtual-machines/317",toc_min_heading_level:2,toc_max_heading_level:5},i=void 0,c={permalink:"/rlog/zkVM-explorations",source:"@site/rlog/2024-08-27-Zkvm.mdx",title:"Exploring zkVMs: Which Projects Truly Qualify as Zero-Knowledge Virtual Machines?",description:"The blockchain space is rapidly evolving, and with it, new technologies are emerging that promise enhanced privacy, scalability, and security.",date:"2024-08-27T12:00:00.000Z",formattedDate:"August 27, 2024",tags:[],readingTime:23.53,hasTruncateMarker:!0,authors:[{name:"Moudy",github:"moudyellaz",key:"moudy"}],frontMatter:{title:"Exploring zkVMs: Which Projects Truly Qualify as Zero-Knowledge Virtual Machines?",date:"2024-08-27T12:00:00.000Z",authors:"moudy",published:!0,slug:"zkVM-explorations",categories:"research",discuss:"https://forum.vac.dev/t/exploring-zkvms-which-projects-truly-qualify-as-zero-knowledge-virtual-machines/317",toc_min_heading_level:2,toc_max_heading_level:5},prevItem:{title:"zkVM Testing Report: Evaluating Zero-Knowledge Virtual Machines for Nescience",permalink:"/rlog/zkVM-testing"},nextItem:{title:"Nescience: A User-Centric State-Separation Architecture",permalink:"/rlog/Nescience-state-separation-architecture"}},l={authorsImageUrls:[void 0]},s=[],u={toc:s};function p(e){let{components:t,...r}=e;return(0,a.kt)("wrapper",(0,n.Z)({},u,r,{components:t,mdxType:"MDXLayout"}))}p.isMDXComponent=!0},3905:(e,t,r)=>{r.d(t,{Zo:()=>u,kt:()=>d});var n=r(67294);function a(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function o(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||(a[r]=e[r]);return a}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(a[r]=e[r])}return a}var l=n.createContext({}),s=function(e){var t=n.useContext(l),r=t;return e&&(r="function"==typeof e?e(t):i(i({},t),e)),r},u=function(e){var t=s(e.components);return n.createElement(l.Provider,{value:t},e.children)},p={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},m=n.forwardRef((function(e,t){var r=e.components,a=e.mdxType,o=e.originalType,l=e.parentName,u=c(e,["components","mdxType","originalType","parentName"]),m=s(r),d=a,y=m["".concat(l,".").concat(d)]||m[d]||p[d]||o;return r?n.createElement(y,i(i({ref:t},u),{},{components:r})):n.createElement(y,i({ref:t},u))}));function d(e,t){var r=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var o=r.length,i=new Array(o);i[0]=m;var c={};for(var l in t)hasOwnProperty.call(t,l)&&(c[l]=t[l]);c.originalType=e,c.mdxType="string"==typeof e?e:a,i[1]=c;for(var s=2;s{e.exports=JSON.parse('{"permalink":"/rlog/page/4","page":4,"postsPerPage":10,"totalPages":4,"totalCount":34,"previousPage":"/rlog/page/3","blogDescription":"Blog","blogTitle":"Research Blog"}')}}]); \ No newline at end of file +"use strict";(self.webpackChunkvac_dev=self.webpackChunkvac_dev||[]).push([[7972],{54910:e=>{e.exports=JSON.parse('{"permalink":"/rlog/page/4","page":4,"postsPerPage":10,"totalPages":4,"totalCount":35,"previousPage":"/rlog/page/3","blogDescription":"Blog","blogTitle":"Research Blog"}')}}]); \ No newline at end of file diff --git a/assets/js/8c1443cc.f0369ef8.js b/assets/js/8c1443cc.db36718a.js similarity index 79% rename from assets/js/8c1443cc.f0369ef8.js rename to assets/js/8c1443cc.db36718a.js index 0817273d..966881c7 100644 --- a/assets/js/8c1443cc.f0369ef8.js +++ b/assets/js/8c1443cc.db36718a.js @@ -1 +1 @@ -"use strict";(self.webpackChunkvac_dev=self.webpackChunkvac_dev||[]).push([[5302],{47407:e=>{e.exports=JSON.parse('{"permalink":"/rlog/page/3","page":3,"postsPerPage":10,"totalPages":4,"totalCount":34,"previousPage":"/rlog/page/2","nextPage":"/rlog/page/4","blogDescription":"Blog","blogTitle":"Research Blog"}')}}]); \ No newline at end of file +"use strict";(self.webpackChunkvac_dev=self.webpackChunkvac_dev||[]).push([[5302],{47407:e=>{e.exports=JSON.parse('{"permalink":"/rlog/page/3","page":3,"postsPerPage":10,"totalPages":4,"totalCount":35,"previousPage":"/rlog/page/2","nextPage":"/rlog/page/4","blogDescription":"Blog","blogTitle":"Research Blog"}')}}]); \ No newline at end of file diff --git a/assets/js/93541fc5.91b83c51.js b/assets/js/93541fc5.91b83c51.js new file mode 100644 index 00000000..cc8e47da --- /dev/null +++ b/assets/js/93541fc5.91b83c51.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkvac_dev=self.webpackChunkvac_dev||[]).push([[1773],{76944:(e,t,a)=>{a.r(t),a.d(t,{assets:()=>o,contentTitle:()=>l,default:()=>c,frontMatter:()=>r,metadata:()=>s,toc:()=>p});var n=a(87462),i=(a(67294),a(3905));const r={title:"zkVM Testing Report: Evaluating Zero-Knowledge Virtual Machines for Nescience",date:new Date("2024-09-26T12:00:00.000Z"),authors:"moudy",published:!0,slug:"zkVM-testing",categories:"research",discuss:"https://forum.vac.dev/t/zkvm-testing-report-evaluating-zero-knowledge-virtual-machines-for-nescience/",toc_min_heading_level:2,toc_max_heading_level:5},l=void 0,s={permalink:"/rlog/zkVM-testing",source:"@site/rlog/2024-09-26-Zkvm-testing.mdx",title:"zkVM Testing Report: Evaluating Zero-Knowledge Virtual Machines for Nescience",description:"Following our initial exploration of zkVMs in our previous blog post [1],",date:"2024-09-26T12:00:00.000Z",formattedDate:"September 26, 2024",tags:[],readingTime:11.625,hasTruncateMarker:!0,authors:[{name:"Moudy",github:"moudyellaz",key:"moudy"}],frontMatter:{title:"zkVM Testing Report: Evaluating Zero-Knowledge Virtual Machines for Nescience",date:"2024-09-26T12:00:00.000Z",authors:"moudy",published:!0,slug:"zkVM-testing",categories:"research",discuss:"https://forum.vac.dev/t/zkvm-testing-report-evaluating-zero-knowledge-virtual-machines-for-nescience/",toc_min_heading_level:2,toc_max_heading_level:5},nextItem:{title:"Exploring zkVMs: Which Projects Truly Qualify as Zero-Knowledge Virtual Machines?",permalink:"/rlog/zkVM-explorations"}},o={authorsImageUrls:[void 0]},p=[{value:"1. SP1",id:"1-sp1",level:3},{value:"2. RISC0",id:"2-risc0",level:3},{value:"3. Nexus",id:"3-nexus",level:3},{value:"4. ZkMIPS",id:"4-zkmips",level:3},{value:"5. ZkWASM",id:"5-zkwasm",level:3},{value:"6. Valida",id:"6-valida",level:3},{value:"Summary table",id:"summary-table",level:2},{value:"Stage 1",id:"stage-1",level:3},{value:"Stage 2",id:"stage-2",level:3}],m={toc:p};function c(e){let{components:t,...r}=e;return(0,i.kt)("wrapper",(0,n.Z)({},m,r,{components:t,mdxType:"MDXLayout"}),(0,i.kt)("h1",{id:"introduction"},"Introduction"),(0,i.kt)("p",null,"Following our initial exploration of zkVMs in our previous blog post [",(0,i.kt)("a",{parentName:"p",href:"https://vac.dev/rlog/zkVM-explorations/"},"1"),"],\nwe have conducted a series of tests to identify the most suitable zkVM for the Nescience architecture [",(0,i.kt)("a",{parentName:"p",href:"https://vac.dev/rlog/Nescience-state-separation-architecture"},"2"),"]. This post outlines the testing process, results, and conclusions. Additionally,\nthe full test suite and scripts can be found on our GitHub page [",(0,i.kt)("a",{parentName:"p",href:"https://github.com/vacp2p/nescience-zkvm-testing"},"3"),"],\nallowing others to replicate the results or explore the candidates further. "),(0,i.kt)("p",null,"We've shortlisted the following zkVMs for testing:"),(0,i.kt)("ul",null,(0,i.kt)("li",{parentName:"ul"},"SP1 [",(0,i.kt)("a",{parentName:"li",href:"https://blog.succinct.xyz/introducing-sp1/"},"4"),"]"),(0,i.kt)("li",{parentName:"ul"},"RISC0 [",(0,i.kt)("a",{parentName:"li",href:"https://www.risczero.com/zkvm"},"5"),"]"),(0,i.kt)("li",{parentName:"ul"},"Nexus [",(0,i.kt)("a",{parentName:"li",href:"https://docs.nexus.xyz/"},"6"),"]"),(0,i.kt)("li",{parentName:"ul"},"ZkMIPS [",(0,i.kt)("a",{parentName:"li",href:"https://docs.zkm.io/zkm-architecture"},"7"),"]"),(0,i.kt)("li",{parentName:"ul"},"ZkWASM [",(0,i.kt)("a",{parentName:"li",href:"https://delphinuslab.com/zk-wasm/"},"8"),"]"),(0,i.kt)("li",{parentName:"ul"},"Valida [",(0,i.kt)("a",{parentName:"li",href:"https://delendum.xyz/writings/2023-05-10-zkvm-design.html"},"9"),"]")),(0,i.kt)("h1",{id:"why-these-candidates"},"Why these candidates?"),(0,i.kt)("p",null,"When narrowing down the zkVMs, we focused on key factors:"),(0,i.kt)("ul",null,(0,i.kt)("li",{parentName:"ul"},"True zero-knowledge functionality: The zkVMs had to demonstrate or be close to demonstrating the ability to generate and verify zero-knowledge proofs."),(0,i.kt)("li",{parentName:"ul"},"Performance baselines: We sought zkVMs with solid benchmarks in performance, particularly in speed and efficiency."),(0,i.kt)("li",{parentName:"ul"},"Specific functionalities: For Nescience, functionalities like lookup tables, precompiles, and recursive capabilities are critical. ")),(0,i.kt)("p",null,"We need a zkVM that supports these to enable robust project development."),(0,i.kt)("h1",{id:"preliminary-information-on-the-candidates"},"Preliminary information on the candidates"),(0,i.kt)("ol",null,(0,i.kt)("li",{parentName:"ol"},(0,i.kt)("p",{parentName:"li"},"SP1 is a performant, open-source zkVM that verifies the execution of arbitrary Rust (or any LLVM-compiled language) programs.\nSP1 utilizes Plonky3, enabling recursive proofs and supporting a wide range of cryptographic algorithms, including ECC-based ones like Groth16.\nWhile it supports aggregation, it appears not to support zero knowledge in a conventional manner.")),(0,i.kt)("li",{parentName:"ol"},(0,i.kt)("p",{parentName:"li"},"RISC0 zkVM allows one to prove the correct execution of arbitrary Rust code. Built on a RISC-V architecture, it is inherently adaptable\nfor implementing standard cryptographic hash functions such as SHA-256 and ECDSA. RISC0 employs STARKs, providing a security level of 98 bits.\nIt supports multiple programming languages, including C and Rust, thanks to its compatibility with LLVM and WASM.")),(0,i.kt)("li",{parentName:"ol"},(0,i.kt)("p",{parentName:"li"},"Nexus is a modular, extensible, open-source, highly parallelized, prover-optimized, and contributor-friendly zkVM written in Rust.\nIt focuses on performance and security, using the Nova folding scheme, which is particularly effective for recursive proofs.\nNexus also supports precompiles and targeted compilation, and besides Rust, it offers C++ support.")),(0,i.kt)("li",{parentName:"ol"},(0,i.kt)("p",{parentName:"li"},"ZkMIPS is a general verifiable computing infrastructure based on Plonky2 and the MIPS microarchitecture, aiming to empower Ethereum\nas a global settlement layer. It can run arbitrary Rust code as well. Notably, zkMIPS is the only zkVM in this list that utilizes the MIPS opcode set.")),(0,i.kt)("li",{parentName:"ol"},(0,i.kt)("p",{parentName:"li"},"ZkWASM adheres to and supports the unmodified standard WASM bytecode specification. Since Rust code can be compiled to WASM bytecode,\none could theoretically run any Rust code on a zkWASM machine, providing flexibility and broad language support.")),(0,i.kt)("li",{parentName:"ol"},(0,i.kt)("p",{parentName:"li"},"Valida is a STARK-based virtual machine aiming to improve upon the state of the art in several categories:"),(0,i.kt)("ul",{parentName:"li"},(0,i.kt)("li",{parentName:"ul"},"Code reuse: The VM has a RISC-inspired instruction set, simplifying the targeting of conventional programming languages.\nA backend compiler is being developed to compile LLVM IR to the Valida ISA, enabling the proving of programs written in Rust,\nGo, C++, and others with minimal to no changes in source code."),(0,i.kt)("li",{parentName:"ul"},"Prover performance: Engineered to maximize prover performance, Valida is compatible with a 31-bit field, restricted to degree 3 constraints,\nand features minimal instruction decoding. It operates directly on memory without general-purpose registers or a dedicated stack,\nutilizing newer lookup arguments to reduce trace overhead involved in cross-chip communication."),(0,i.kt)("li",{parentName:"ul"},"Extensibility: Designed to be customizable, Valida can easily be extended to include an arbitrary number of user-defined instructions.\nProcedural macros are used to construct the desired machine at compile time, avoiding any runtime penalties.")))),(0,i.kt)("p",null,"Valida appears to be in the early stages of development but already showcases respectable performance metrics."),(0,i.kt)("h1",{id:"testing-plan"},"Testing plan"),(0,i.kt)("p",null,"To thoroughly evaluate each zkVM, we devised a two-stage testing process:"),(0,i.kt)("ul",null,(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("p",{parentName:"li"},"Stage 1: Arithmetic operations"),(0,i.kt)("p",{parentName:"li"}," The first phase focused on evaluating the zkVMs\u2019 ability to handle basic arithmetic operations: addition, subtraction, multiplication,\ndivision, modulus division, and square root calculations. We designed the test around heptagonal numbers, which required zkVMs to process\nmultiple arithmetic operations simultaneously. By using this method, we could measure efficiency and speed in handling complex mathematical calculations \u2013\na crucial element for zkVM performance. ")),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("p",{parentName:"li"},"Stage 2: Memory consumption"),(0,i.kt)("p",{parentName:"li"}," For the second phase, we evaluated each zkVM\u2019s ability to manage memory under heavy loads. We tested several data structures, including lists,\nhash maps, deques, queues, BTreeMaps, hash sets, and binary heaps. Each zkVM underwent tests for the following operations:"),(0,i.kt)("ul",{parentName:"li"},(0,i.kt)("li",{parentName:"ul"},"Insert: How quickly can the zkVM add data to structures?"),(0,i.kt)("li",{parentName:"ul"},"Delete: Does the zkVM handle memory release effectively?"),(0,i.kt)("li",{parentName:"ul"},"Append: Can the zkVM efficiently grow data structures?"),(0,i.kt)("li",{parentName:"ul"},"Search: How fast and efficient is the zkVM when retrieving stored data?")))),(0,i.kt)("p",null,"The purpose of this stage was to identify any memory bottlenecks and to determine whether a zkVM could manage high-intensity tasks efficiently,\nsomething vital for the Nescience project\u2019s complex, data-heavy processes."),(0,i.kt)("h1",{id:"machine-specifications"},"Machine specifications"),(0,i.kt)("p",null,"The tests were conducted on the following hardware configuration:"),(0,i.kt)("ul",null,(0,i.kt)("li",{parentName:"ul"},'CPU: AMD EPYC 7713 "Milan" 64-core processor (128 threads total)'),(0,i.kt)("li",{parentName:"ul"},"RAM: 600GiB DDR4 3200MHz ECC RAM, distributed across 16 DIMMs"),(0,i.kt)("li",{parentName:"ul"},"Host OS: Proxmox 8.3"),(0,i.kt)("li",{parentName:"ul"},"Hypervisor: KVM"),(0,i.kt)("li",{parentName:"ul"},"Network layer: Open vSwitch"),(0,i.kt)("li",{parentName:"ul"},"Machine model: Supermicro AS-2024US-TRT")),(0,i.kt)("h1",{id:"results"},"Results"),(0,i.kt)("h3",{id:"1-sp1"},"1. SP1"),(0,i.kt)("p",null,"SP1 does not provide zero-knowledge capability in its proofs but delivers respectable performance, though slightly behind its main competitor.\nMemory leaks were minimal, staying below the 700 KB threshold. Interestingly, SP1 consumed more RAM during the basic arithmetic\ntest than in memory allocation tests, showcasing the team's effective handling of memory under load. In the basic test,\nallocations were primarily in the 9-16 B, 33-64 B, and 65-128 B ranges. For memory allocations, most fell into the 129-256 B range."),(0,i.kt)("ul",null,(0,i.kt)("li",{parentName:"ul"},"Stage 1: Hept 100 test",(0,i.kt)("ul",{parentName:"li"},(0,i.kt)("li",{parentName:"ul"},"Proof size: 3.108 MB"),(0,i.kt)("li",{parentName:"ul"},"Proof time: 16.95 seconds")))),(0,i.kt)("table",null,(0,i.kt)("thead",{parentName:"table"},(0,i.kt)("tr",{parentName:"thead"},(0,i.kt)("th",{parentName:"tr",align:null},(0,i.kt)("img",{alt:"Image 1",src:a(89203).Z,width:"1318",height:"778"})),(0,i.kt)("th",{parentName:"tr",align:null},(0,i.kt)("img",{alt:"Image 2",src:a(93795).Z,width:"1310",height:"797"})),(0,i.kt)("th",{parentName:"tr",align:null},(0,i.kt)("img",{alt:"Image 3",src:a(11611).Z,width:"1307",height:"796"})),(0,i.kt)("th",{parentName:"tr",align:null},(0,i.kt)("img",{alt:"Image 4",src:a(38337).Z,width:"1308",height:"796"})),(0,i.kt)("th",{parentName:"tr",align:null},(0,i.kt)("img",{alt:"Image 5",src:a(48805).Z,width:"1308",height:"798"}))))),(0,i.kt)("ul",null,(0,i.kt)("li",{parentName:"ul"},"Stage 2: Vec 10000 test",(0,i.kt)("ul",{parentName:"li"},(0,i.kt)("li",{parentName:"ul"},"Proof size: 3.17 MB"),(0,i.kt)("li",{parentName:"ul"},"Proof time: 20.85 seconds")))),(0,i.kt)("table",null,(0,i.kt)("thead",{parentName:"table"},(0,i.kt)("tr",{parentName:"thead"},(0,i.kt)("th",{parentName:"tr",align:null},(0,i.kt)("img",{alt:"Image 1",src:a(81581).Z,width:"1316",height:"777"})),(0,i.kt)("th",{parentName:"tr",align:null},(0,i.kt)("img",{alt:"Image 2",src:a(64082).Z,width:"1320",height:"794"})),(0,i.kt)("th",{parentName:"tr",align:null},(0,i.kt)("img",{alt:"Image 3",src:a(90460).Z,width:"1317",height:"799"})),(0,i.kt)("th",{parentName:"tr",align:null},(0,i.kt)("img",{alt:"Image 4",src:a(423).Z,width:"1319",height:"798"})),(0,i.kt)("th",{parentName:"tr",align:null},(0,i.kt)("img",{alt:"Image 5",src:a(24860).Z,width:"1324",height:"793"}))))),(0,i.kt)("hr",null),(0,i.kt)("h3",{id:"2-risc0"},"2. RISC0"),(0,i.kt)("p",null,"RISC0 stands out with exceptional performance in proof size and generation time, ranking among the best\n(with the exception of Valida and zkWASM's basic test). It also handles memory well, with minor leaks under 0.5 MB\nand controlled RAM consumption staying below 2.2 GB. RISC0's memory allocations were consistent, primarily in the 17-32 B and 33-64 B ranges."),(0,i.kt)("ul",null,(0,i.kt)("li",{parentName:"ul"},"Stage 1: Hept 100 test",(0,i.kt)("ul",{parentName:"li"},(0,i.kt)("li",{parentName:"ul"},"Proof size: 217.4 KB"),(0,i.kt)("li",{parentName:"ul"},"Proof time: 9.73 seconds")))),(0,i.kt)("table",null,(0,i.kt)("thead",{parentName:"table"},(0,i.kt)("tr",{parentName:"thead"},(0,i.kt)("th",{parentName:"tr",align:null},(0,i.kt)("img",{alt:"Image 1",src:a(1459).Z,width:"1324",height:"759"})),(0,i.kt)("th",{parentName:"tr",align:null},(0,i.kt)("img",{alt:"Image 2",src:a(59108).Z,width:"1314",height:"799"})),(0,i.kt)("th",{parentName:"tr",align:null},(0,i.kt)("img",{alt:"Image 3",src:a(64450).Z,width:"1315",height:"798"})),(0,i.kt)("th",{parentName:"tr",align:null},(0,i.kt)("img",{alt:"Image 4",src:a(17410).Z,width:"1315",height:"801"})),(0,i.kt)("th",{parentName:"tr",align:null},(0,i.kt)("img",{alt:"Image 5",src:a(85209).Z,width:"1322",height:"800"}))))),(0,i.kt)("ul",null,(0,i.kt)("li",{parentName:"ul"},"Stage 2: Vec 10000 test",(0,i.kt)("ul",{parentName:"li"},(0,i.kt)("li",{parentName:"ul"},"Proof size: 217.4 KB"),(0,i.kt)("li",{parentName:"ul"},"Proof time: 16.63 seconds")))),(0,i.kt)("table",null,(0,i.kt)("thead",{parentName:"table"},(0,i.kt)("tr",{parentName:"thead"},(0,i.kt)("th",{parentName:"tr",align:null},(0,i.kt)("img",{alt:"Image 1",src:a(84606).Z,width:"1322",height:"773"})),(0,i.kt)("th",{parentName:"tr",align:null},(0,i.kt)("img",{alt:"Image 2",src:a(38538).Z,width:"1317",height:"803"})),(0,i.kt)("th",{parentName:"tr",align:null},(0,i.kt)("img",{alt:"Image 3",src:a(80247).Z,width:"1318",height:"801"})),(0,i.kt)("th",{parentName:"tr",align:null},(0,i.kt)("img",{alt:"Image 4",src:a(26210).Z,width:"1319",height:"799"})),(0,i.kt)("th",{parentName:"tr",align:null},(0,i.kt)("img",{alt:"Image 5",src:a(76245).Z,width:"1316",height:"800"}))))),(0,i.kt)("p",null,"Based on these results, RISC0 is a solid candidate for Nescience."),(0,i.kt)("hr",null),(0,i.kt)("h3",{id:"3-nexus"},"3. Nexus"),(0,i.kt)("p",null,"Nexus' performance offers interesting insights into folding scheme-based zkVMs. Surprisingly, proof sizes remained consistent\nregardless of workload, with no significant memory leaks (under 700 KB). However, while RAM consumption increased slightly with higher\nworkloads (up to 1.2 GB), Nexus performed poorly during memory allocation tests, making it unsuitable for our use case."),(0,i.kt)("ul",null,(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("p",{parentName:"li"},"Allocation details:"),(0,i.kt)("ul",{parentName:"li"},(0,i.kt)("li",{parentName:"ul"},"Basic test: Most allocations concentrated in 65-128 B"),(0,i.kt)("li",{parentName:"ul"},"Memory-heavy test: Allocations in the 129-256 B range"))),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("p",{parentName:"li"},"Stage 1: Hept 100 test"),(0,i.kt)("ul",{parentName:"li"},(0,i.kt)("li",{parentName:"ul"},"Proof size: 46 MB"),(0,i.kt)("li",{parentName:"ul"},"Proof time: 12.06 seconds")))),(0,i.kt)("table",null,(0,i.kt)("thead",{parentName:"table"},(0,i.kt)("tr",{parentName:"thead"},(0,i.kt)("th",{parentName:"tr",align:null},(0,i.kt)("img",{alt:"Image 1",src:a(25693).Z,width:"1325",height:"776"})),(0,i.kt)("th",{parentName:"tr",align:null},(0,i.kt)("img",{alt:"Image 2",src:a(80370).Z,width:"1321",height:"807"})),(0,i.kt)("th",{parentName:"tr",align:null},(0,i.kt)("img",{alt:"Image 3",src:a(29530).Z,width:"1316",height:"800"})),(0,i.kt)("th",{parentName:"tr",align:null},(0,i.kt)("img",{alt:"Image 4",src:a(87538).Z,width:"1313",height:"801"})),(0,i.kt)("th",{parentName:"tr",align:null},(0,i.kt)("img",{alt:"Image 5",src:a(3240).Z,width:"1321",height:"793"}))))),(0,i.kt)("ul",null,(0,i.kt)("li",{parentName:"ul"},"Stage 2: Vec 10000 test",(0,i.kt)("ul",{parentName:"li"},(0,i.kt)("li",{parentName:"ul"},"Proof size: 46 MB"),(0,i.kt)("li",{parentName:"ul"},"Proof time: 56 minutes")))),(0,i.kt)("table",null,(0,i.kt)("thead",{parentName:"table"},(0,i.kt)("tr",{parentName:"thead"},(0,i.kt)("th",{parentName:"tr",align:null},(0,i.kt)("img",{alt:"Image 1",src:a(4327).Z,width:"1318",height:"776"})),(0,i.kt)("th",{parentName:"tr",align:null},(0,i.kt)("img",{alt:"Image 2",src:a(61544).Z,width:"1320",height:"804"})),(0,i.kt)("th",{parentName:"tr",align:null},(0,i.kt)("img",{alt:"Image 3",src:a(61258).Z,width:"1315",height:"798"})),(0,i.kt)("th",{parentName:"tr",align:null},(0,i.kt)("img",{alt:"Image 4",src:a(20297).Z,width:"1322",height:"795"})),(0,i.kt)("th",{parentName:"tr",align:null},(0,i.kt)("img",{alt:"Image 5",src:a(83519).Z,width:"1312",height:"804"}))))),(0,i.kt)("hr",null),(0,i.kt)("h3",{id:"4-zkmips"},"4. ZkMIPS"),(0,i.kt)("p",null,"ZkMIPS presents an intriguing case. While it shows good results in terms of proof size and generation time during the basic test,\nthese come at the cost of significant RAM usage and memory leaks. The memory allocation test revealed a concerning 6.7 GB memory leak,\nwith 0.5 GB leaked during the basic test. Despite this, RAM consumption (while high at 17+ GB) remains stable under higher workloads.\nAllocation sizes are spread across several ranges, with notable concentrations in the 17-32 B, 65-128 B, and 257-512 B slots."),(0,i.kt)("ul",null,(0,i.kt)("li",{parentName:"ul"},"Stage 1: Hept 100 test",(0,i.kt)("ul",{parentName:"li"},(0,i.kt)("li",{parentName:"ul"},"Proof size: 4.3 MB"),(0,i.kt)("li",{parentName:"ul"},"Proof time: 9.32 seconds")))),(0,i.kt)("table",null,(0,i.kt)("thead",{parentName:"table"},(0,i.kt)("tr",{parentName:"thead"},(0,i.kt)("th",{parentName:"tr",align:null},(0,i.kt)("img",{alt:"Image 1",src:a(42204).Z,width:"1323",height:"779"})),(0,i.kt)("th",{parentName:"tr",align:null},(0,i.kt)("img",{alt:"Image 2",src:a(85554).Z,width:"1321",height:"803"})),(0,i.kt)("th",{parentName:"tr",align:null},(0,i.kt)("img",{alt:"Image 3",src:a(85465).Z,width:"1316",height:"802"})),(0,i.kt)("th",{parentName:"tr",align:null},(0,i.kt)("img",{alt:"Image 4",src:a(8839).Z,width:"1317",height:"806"})),(0,i.kt)("th",{parentName:"tr",align:null},(0,i.kt)("img",{alt:"Image 5",src:a(64125).Z,width:"1307",height:"806"}))))),(0,i.kt)("ul",null,(0,i.kt)("li",{parentName:"ul"},"Stage 2: Vec 10000 test",(0,i.kt)("ul",{parentName:"li"},(0,i.kt)("li",{parentName:"ul"},"Proof size: 4.898 MB"),(0,i.kt)("li",{parentName:"ul"},"Proof time: 42.57 seconds")))),(0,i.kt)("table",null,(0,i.kt)("thead",{parentName:"table"},(0,i.kt)("tr",{parentName:"thead"},(0,i.kt)("th",{parentName:"tr",align:null},(0,i.kt)("img",{alt:"Image 1",src:a(62942).Z,width:"1324",height:"776"})),(0,i.kt)("th",{parentName:"tr",align:null},(0,i.kt)("img",{alt:"Image 2",src:a(74498).Z,width:"1312",height:"800"})),(0,i.kt)("th",{parentName:"tr",align:null},(0,i.kt)("img",{alt:"Image 3",src:a(1484).Z,width:"1314",height:"801"})),(0,i.kt)("th",{parentName:"tr",align:null},(0,i.kt)("img",{alt:"Image 4",src:a(72683).Z,width:"1310",height:"800"})),(0,i.kt)("th",{parentName:"tr",align:null},(0,i.kt)("img",{alt:"Image 5",src:a(13077).Z,width:"1305",height:"800"}))))),(0,i.kt)("p",null,"This zkVM provides mixed results with strong proof generation but concerning memory management issues."),(0,i.kt)("hr",null),(0,i.kt)("h3",{id:"5-zkwasm"},"5. ZkWASM"),(0,i.kt)("p",null,"ZkWASM, unfortunately, performed poorly in both stages regarding proof size and generation time. RAM consumption was particularly high,\nexceeding 7 GB in the basic test, and an astounding 57 GB during memory allocation tests. Despite its impressive memory usage,\nthe proof sizes were relatively large at 18 KB and 334 KB respectively. Allocation sizes were mainly concentrated in the 33-64 B range,\nwith neighboring slots contributing small but notable amounts."),(0,i.kt)("ul",null,(0,i.kt)("li",{parentName:"ul"},"Stage 1: Hept 100 test",(0,i.kt)("ul",{parentName:"li"},(0,i.kt)("li",{parentName:"ul"},"Proof size: 18 KB"),(0,i.kt)("li",{parentName:"ul"},"Proof time: 42.7 seconds")))),(0,i.kt)("table",null,(0,i.kt)("thead",{parentName:"table"},(0,i.kt)("tr",{parentName:"thead"},(0,i.kt)("th",{parentName:"tr",align:null},(0,i.kt)("img",{alt:"Image 1",src:a(81969).Z,width:"1321",height:"778"})),(0,i.kt)("th",{parentName:"tr",align:null},(0,i.kt)("img",{alt:"Image 2",src:a(68593).Z,width:"1314",height:"802"})),(0,i.kt)("th",{parentName:"tr",align:null},(0,i.kt)("img",{alt:"Image 3",src:a(73312).Z,width:"1314",height:"803"})),(0,i.kt)("th",{parentName:"tr",align:null},(0,i.kt)("img",{alt:"Image 4",src:a(49155).Z,width:"1313",height:"808"})),(0,i.kt)("th",{parentName:"tr",align:null},(0,i.kt)("img",{alt:"Image 5",src:a(19895).Z,width:"1304",height:"803"}))))),(0,i.kt)("ul",null,(0,i.kt)("li",{parentName:"ul"},"Stage 2: Vec 10000 test",(0,i.kt)("ul",{parentName:"li"},(0,i.kt)("li",{parentName:"ul"},"Proof size: 334 KB"),(0,i.kt)("li",{parentName:"ul"},"Proof time: 323 seconds")))),(0,i.kt)("table",null,(0,i.kt)("thead",{parentName:"table"},(0,i.kt)("tr",{parentName:"thead"},(0,i.kt)("th",{parentName:"tr",align:null},(0,i.kt)("img",{alt:"Image 1",src:a(92076).Z,width:"1322",height:"773"})),(0,i.kt)("th",{parentName:"tr",align:null},(0,i.kt)("img",{alt:"Image 2",src:a(34403).Z,width:"1324",height:"791"})),(0,i.kt)("th",{parentName:"tr",align:null},(0,i.kt)("img",{alt:"Image 3",src:a(54443).Z,width:"1315",height:"799"})),(0,i.kt)("th",{parentName:"tr",align:null},(0,i.kt)("img",{alt:"Image 4",src:a(4229).Z,width:"1324",height:"803"})),(0,i.kt)("th",{parentName:"tr",align:null},(0,i.kt)("img",{alt:"Image 5",src:a(72106).Z,width:"1322",height:"803"}))))),(0,i.kt)("hr",null),(0,i.kt)("h3",{id:"6-valida"},"6. Valida"),(0,i.kt)("p",null,"Valida delivered impressive results in proof generation speed and size, with a proof size of 280 KB and a proof time of < 1 second.\nHowever, profiling was not possible due to Valida's limited Rust support. Valida currently compiles Rust using the LLVM backend,\ntranspiling LLVM IR to leverage its C/C++ implementation, which leads to errors when handling Rust-specific data structures or dependencies.\nAs a result, complex memory interactions couldn't be tested, and using Valida with Rust code is currently not advisable.\nA GitHub issue has been opened to address this."),(0,i.kt)("hr",null),(0,i.kt)("h2",{id:"summary-table"},"Summary table"),(0,i.kt)("h3",{id:"stage-1"},"Stage 1"),(0,i.kt)("table",null,(0,i.kt)("thead",{parentName:"table"},(0,i.kt)("tr",{parentName:"thead"},(0,i.kt)("th",{parentName:"tr",align:null},"zkVM"),(0,i.kt)("th",{parentName:"tr",align:null},"Proof time"),(0,i.kt)("th",{parentName:"tr",align:null},"Proof size"),(0,i.kt)("th",{parentName:"tr",align:null},"Peak RAM consumption"),(0,i.kt)("th",{parentName:"tr",align:null},"Memory leaked"))),(0,i.kt)("tbody",{parentName:"table"},(0,i.kt)("tr",{parentName:"tbody"},(0,i.kt)("td",{parentName:"tr",align:null},"SP1"),(0,i.kt)("td",{parentName:"tr",align:null},"16.95 s"),(0,i.kt)("td",{parentName:"tr",align:null},"3.108 MB"),(0,i.kt)("td",{parentName:"tr",align:null},"2.1 GB"),(0,i.kt)("td",{parentName:"tr",align:null},"656.8 KB")),(0,i.kt)("tr",{parentName:"tbody"},(0,i.kt)("td",{parentName:"tr",align:null},"RISC0"),(0,i.kt)("td",{parentName:"tr",align:null},"9.73 s"),(0,i.kt)("td",{parentName:"tr",align:null},"217.4 KB"),(0,i.kt)("td",{parentName:"tr",align:null},"1.9 GB"),(0,i.kt)("td",{parentName:"tr",align:null},"470.5 KB")),(0,i.kt)("tr",{parentName:"tbody"},(0,i.kt)("td",{parentName:"tr",align:null},"Nexus"),(0,i.kt)("td",{parentName:"tr",align:null},"12.06 s"),(0,i.kt)("td",{parentName:"tr",align:null},"46 MB"),(0,i.kt)("td",{parentName:"tr",align:null},"9.7 MB"),(0,i.kt)("td",{parentName:"tr",align:null},"646.5 KB")),(0,i.kt)("tr",{parentName:"tbody"},(0,i.kt)("td",{parentName:"tr",align:null},"ZkMIPS"),(0,i.kt)("td",{parentName:"tr",align:null},"9.32 s"),(0,i.kt)("td",{parentName:"tr",align:null},"4.3 MB"),(0,i.kt)("td",{parentName:"tr",align:null},"17.3 GB"),(0,i.kt)("td",{parentName:"tr",align:null},"453.8 MB")),(0,i.kt)("tr",{parentName:"tbody"},(0,i.kt)("td",{parentName:"tr",align:null},"ZkWASM"),(0,i.kt)("td",{parentName:"tr",align:null},"42.7 s"),(0,i.kt)("td",{parentName:"tr",align:null},"18 KB"),(0,i.kt)("td",{parentName:"tr",align:null},"8.2 GB"),(0,i.kt)("td",{parentName:"tr",align:null},"259.4 KB")),(0,i.kt)("tr",{parentName:"tbody"},(0,i.kt)("td",{parentName:"tr",align:null},"Valida"),(0,i.kt)("td",{parentName:"tr",align:null},"< 1 s"),(0,i.kt)("td",{parentName:"tr",align:null},"280 KB"),(0,i.kt)("td",{parentName:"tr",align:null},"N/A"),(0,i.kt)("td",{parentName:"tr",align:null},"N/A")))),(0,i.kt)("hr",null),(0,i.kt)("h3",{id:"stage-2"},"Stage 2"),(0,i.kt)("table",null,(0,i.kt)("thead",{parentName:"table"},(0,i.kt)("tr",{parentName:"thead"},(0,i.kt)("th",{parentName:"tr",align:null},"zkVM"),(0,i.kt)("th",{parentName:"tr",align:null},"Proof time"),(0,i.kt)("th",{parentName:"tr",align:null},"Proof size"),(0,i.kt)("th",{parentName:"tr",align:null},"Peak RAM consumption"),(0,i.kt)("th",{parentName:"tr",align:null},"Memory leaked"))),(0,i.kt)("tbody",{parentName:"table"},(0,i.kt)("tr",{parentName:"tbody"},(0,i.kt)("td",{parentName:"tr",align:null},"SP1"),(0,i.kt)("td",{parentName:"tr",align:null},"20.85 s"),(0,i.kt)("td",{parentName:"tr",align:null},"3.17 MB"),(0,i.kt)("td",{parentName:"tr",align:null},"1.9 GB"),(0,i.kt)("td",{parentName:"tr",align:null},"616 KB")),(0,i.kt)("tr",{parentName:"tbody"},(0,i.kt)("td",{parentName:"tr",align:null},"RISC0"),(0,i.kt)("td",{parentName:"tr",align:null},"16.63 s"),(0,i.kt)("td",{parentName:"tr",align:null},"217.4 KB"),(0,i.kt)("td",{parentName:"tr",align:null},"2.3 GB"),(0,i.kt)("td",{parentName:"tr",align:null},"485.3 KB")),(0,i.kt)("tr",{parentName:"tbody"},(0,i.kt)("td",{parentName:"tr",align:null},"Nexus"),(0,i.kt)("td",{parentName:"tr",align:null},"56 m"),(0,i.kt)("td",{parentName:"tr",align:null},"46 MB"),(0,i.kt)("td",{parentName:"tr",align:null},"1.9 GB"),(0,i.kt)("td",{parentName:"tr",align:null},"616 KB")),(0,i.kt)("tr",{parentName:"tbody"},(0,i.kt)("td",{parentName:"tr",align:null},"ZkMIPS"),(0,i.kt)("td",{parentName:"tr",align:null},"42.57 s"),(0,i.kt)("td",{parentName:"tr",align:null},"4.898 MB"),(0,i.kt)("td",{parentName:"tr",align:null},"18.9 GB"),(0,i.kt)("td",{parentName:"tr",align:null},"6.9 GB")),(0,i.kt)("tr",{parentName:"tbody"},(0,i.kt)("td",{parentName:"tr",align:null},"ZkWASM"),(0,i.kt)("td",{parentName:"tr",align:null},"323 s"),(0,i.kt)("td",{parentName:"tr",align:null},"334 KB"),(0,i.kt)("td",{parentName:"tr",align:null},"58.8 GB"),(0,i.kt)("td",{parentName:"tr",align:null},"259.4 KB")),(0,i.kt)("tr",{parentName:"tbody"},(0,i.kt)("td",{parentName:"tr",align:null},"Valida"),(0,i.kt)("td",{parentName:"tr",align:null},"N/A"),(0,i.kt)("td",{parentName:"tr",align:null},"N/A"),(0,i.kt)("td",{parentName:"tr",align:null},"N/A"),(0,i.kt)("td",{parentName:"tr",align:null},"N/A")))),(0,i.kt)("hr",null),(0,i.kt)("h1",{id:"summary"},"Summary"),(0,i.kt)("p",null,"After an extensive evaluation of six zkVM candidates for the Nescience project, RISC0 emerged as the top choice.\nIt excels in both proof generation time and size while maintaining a reasonable memory footprint. With strong zero-knowledge\nproof capabilities and support for multiple programming languages, it aligns well with our project's needs for privacy,\nperformance, and flexibility. Its overall balance between performance and efficiency makes it the most viable zkVM at this stage."),(0,i.kt)("p",null,"Valida, while promising with its potential for high prover performance, is still in early development and suffers from Rust integration issues.\nThe current LLVM IR transpilation limitations mean it cannot handle complex memory interactions, disqualifying it for now.\nHowever, once its development matures, Valida could become a strong alternative, and we plan to revisit it as it evolves."),(0,i.kt)("p",null,"SP1, though initially interesting, failed to meet the zero-knowledge proof requirement. Its performance in arithmetic operations was\nrespectable but insufficient to justify further consideration given its lack of ZK functionality \u2013 critical for our privacy-first objectives."),(0,i.kt)("p",null,"Nexus demonstrated consistent proof sizes and manageable memory usage, but its lackluster performance during memory-intensive tasks and\nits proof size (especially for larger workloads) disqualified it from being a top contender. While zkMIPS delivered solid proof times,\nthe memory issues were too significant to ignore, making it unsuitable."),(0,i.kt)("p",null,"Finally, zkWASM exhibited the poorest results, struggling both in proof size and generation time. Despite its potential for WASM bytecode support,\nthe excessive RAM consumption (up to 57 GB in the memory test) rendered it impractical for Nescience\u2019s use case."),(0,i.kt)("p",null,"In conclusion, RISC0 is the best fit for Nescience at this stage, but Valida remains a future candidate as its development progresses."),(0,i.kt)("p",null,"We\u2019d love to hear your thoughts on our zkVM testing process and results! Do you agree with our conclusions, or do you think we missed a promising zkVM?\nWe\u2019re always open to feedback, insights, and suggestions from the community. "),(0,i.kt)("p",null,"Join the discussion and share your perspectives on\n",(0,i.kt)("a",{parentName:"p",href:"https://forum.vac.dev/t/zkvm-testing-report-evaluating-zero-knowledge-virtual-machines-for-nescience/"},"our forum")," or try out the\ntests yourself through our ","[GitHub page]","(",(0,i.kt)("a",{parentName:"p",href:"https://github.com/vacp2p/nescience-zkvm-testing"},"https://github.com/vacp2p/nescience-zkvm-testing"),"!"),(0,i.kt)("h1",{id:"references"},"References"),(0,i.kt)("p",null,"[1]"," Exploring zkVMs: Which Projects Truly Qualify as Zero-Knowledge Virtual Machines? Retrieved from ",(0,i.kt)("a",{parentName:"p",href:"https://vac.dev/rlog/zkVM-explorations/"},"https://vac.dev/rlog/zkVM-explorations/")),(0,i.kt)("p",null,"[2]"," Nescience: A User-Centric State-Separation Architecture. Retrieved from ",(0,i.kt)("a",{parentName:"p",href:"https://vac.dev/rlog/Nescience-state-separation-architecture"},"https://vac.dev/rlog/Nescience-state-separation-architecture")),(0,i.kt)("p",null,"[3]"," Our GitHub Page for zkVM Testing. Retrieved from ",(0,i.kt)("a",{parentName:"p",href:"https://github.com/vacp2p/nescience-zkvm-testing"},"https://github.com/vacp2p/nescience-zkvm-testing")),(0,i.kt)("p",null,"[4]"," Introducing SP1: A performant, 100% open-source, contributor-friendly zkVM. Retrieved from ",(0,i.kt)("a",{parentName:"p",href:"https://blog.succinct.xyz/introducing-sp1/"},"https://blog.succinct.xyz/introducing-sp1/")),(0,i.kt)("p",null,"[5]"," The first general purpose zkVM. Retrieved from ",(0,i.kt)("a",{parentName:"p",href:"https://www.risczero.com/zkvm"},"https://www.risczero.com/zkvm")),(0,i.kt)("p",null,"[6]"," The Nexus 2.0 zkVM. Retrieved from ",(0,i.kt)("a",{parentName:"p",href:"https://docs.nexus.xyz/"},"https://docs.nexus.xyz/")),(0,i.kt)("p",null,"[7]"," ZKM Architecture. Retrieved from ",(0,i.kt)("a",{parentName:"p",href:"https://docs.zkm.io/zkm-architecture"},"https://docs.zkm.io/zkm-architecture")),(0,i.kt)("p",null,"[8]"," ZK-WASM. Retrieved from ",(0,i.kt)("a",{parentName:"p",href:"https://delphinuslab.com/zk-wasm/"},"https://delphinuslab.com/zk-wasm/")),(0,i.kt)("p",null,"[9]"," Valida zkVM Design. Retrieved from ",(0,i.kt)("a",{parentName:"p",href:"https://delendum.xyz/writings/2023-05-10-zkvm-design.html"},"https://delendum.xyz/writings/2023-05-10-zkvm-design.html")))}c.isMDXComponent=!0},3905:(e,t,a)=>{a.d(t,{Zo:()=>m,kt:()=>u});var n=a(67294);function i(e,t,a){return t in e?Object.defineProperty(e,t,{value:a,enumerable:!0,configurable:!0,writable:!0}):e[t]=a,e}function r(e,t){var a=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),a.push.apply(a,n)}return a}function l(e){for(var t=1;t=0||(i[a]=e[a]);return i}(e,t);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,a)&&(i[a]=e[a])}return i}var o=n.createContext({}),p=function(e){var t=n.useContext(o),a=t;return e&&(a="function"==typeof e?e(t):l(l({},t),e)),a},m=function(e){var t=p(e.components);return n.createElement(o.Provider,{value:t},e.children)},c={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},d=n.forwardRef((function(e,t){var a=e.components,i=e.mdxType,r=e.originalType,o=e.parentName,m=s(e,["components","mdxType","originalType","parentName"]),d=p(a),u=i,g=d["".concat(o,".").concat(u)]||d[u]||c[u]||r;return a?n.createElement(g,l(l({ref:t},m),{},{components:a})):n.createElement(g,l({ref:t},m))}));function u(e,t){var a=arguments,i=t&&t.mdxType;if("string"==typeof e||i){var r=a.length,l=new Array(r);l[0]=d;var s={};for(var o in t)hasOwnProperty.call(t,o)&&(s[o]=t[o]);s.originalType=e,s.mdxType="string"==typeof e?e:i,l[1]=s;for(var p=2;p{a.d(t,{Z:()=>n});const n=a.p+"assets/images/alloc11-5e8896fbfcf04b3abe1b53fd63b4a04d.png"},64082:(e,t,a)=>{a.d(t,{Z:()=>n});const n=a.p+"assets/images/alloc12-f0d03e2eb102436dd8d14827ffeee782.png"},59108:(e,t,a)=>{a.d(t,{Z:()=>n});const n=a.p+"assets/images/alloc21-f0c07620d2c2a6dcc1cb8dd53d8bf33e.png"},38538:(e,t,a)=>{a.d(t,{Z:()=>n});const n=a.p+"assets/images/alloc22-0f0788c13a8f29a95543b44ffc3f7e5c.png"},80370:(e,t,a)=>{a.d(t,{Z:()=>n});const n=a.p+"assets/images/alloc31-b33243d1b3e859704fa649c3cca423ae.png"},61544:(e,t,a)=>{a.d(t,{Z:()=>n});const n=a.p+"assets/images/alloc32-b4511228d11e730b80e97dbfe14f1b32.png"},85554:(e,t,a)=>{a.d(t,{Z:()=>n});const n=a.p+"assets/images/alloc41-7df1382edc6f2440f4becb9306679308.png"},74498:(e,t,a)=>{a.d(t,{Z:()=>n});const n=a.p+"assets/images/alloc42-29736c27a94ac18072ccad4ba523374d.png"},68593:(e,t,a)=>{a.d(t,{Z:()=>n});const n=a.p+"assets/images/alloc51-987d88b8264639cb4c1edf757b48b8f4.png"},34403:(e,t,a)=>{a.d(t,{Z:()=>n});const n=a.p+"assets/images/alloc52-ebf1d882e709a00714dce2fd122428eb.png"},38337:(e,t,a)=>{a.d(t,{Z:()=>n});const n=a.p+"assets/images/consumed11-9cb04fe0b2e8a8a6e24ae048041099d4.png"},423:(e,t,a)=>{a.d(t,{Z:()=>n});const n=a.p+"assets/images/consumed12-afda980a23ad27bab9dfb32a95a97a3f.png"},17410:(e,t,a)=>{a.d(t,{Z:()=>n});const n=a.p+"assets/images/consumed21-c4091416c0c2cbd0effc9d0e349308ec.png"},26210:(e,t,a)=>{a.d(t,{Z:()=>n});const n=a.p+"assets/images/consumed22-f8b42af736f124afd52887d14e5df7d9.png"},87538:(e,t,a)=>{a.d(t,{Z:()=>n});const n=a.p+"assets/images/consumed31-d75cf19d4acef0f2cafe8eb19a3605c4.png"},20297:(e,t,a)=>{a.d(t,{Z:()=>n});const n=a.p+"assets/images/consumed32-44dfd430560af8658b94a3ef9f7e6e6f.png"},8839:(e,t,a)=>{a.d(t,{Z:()=>n});const n=a.p+"assets/images/consumed41-362c4850d936a407e75ccd58283d88d1.png"},72683:(e,t,a)=>{a.d(t,{Z:()=>n});const n=a.p+"assets/images/consumed42-a28992ae3211a5afb2458cf153e160be.png"},49155:(e,t,a)=>{a.d(t,{Z:()=>n});const n=a.p+"assets/images/consumed51-75711af15f7936d72c04975e332935a7.png"},4229:(e,t,a)=>{a.d(t,{Z:()=>n});const n=a.p+"assets/images/consumed52-51cbe29ddaf2bed5d9fc9018b549a00c.png"},89203:(e,t,a)=>{a.d(t,{Z:()=>n});const n=a.p+"assets/images/general11-51932659ec4e58ad9f1b20013b3abdda.png"},81581:(e,t,a)=>{a.d(t,{Z:()=>n});const n=a.p+"assets/images/general12-aa03eb35a9936b02b34ff2ae3dc2a764.png"},1459:(e,t,a)=>{a.d(t,{Z:()=>n});const n=a.p+"assets/images/general21-06d52d151e217cbc9ebe65b1dee0fd76.png"},84606:(e,t,a)=>{a.d(t,{Z:()=>n});const n=a.p+"assets/images/general22-4c59fa28bca8c2b2cbd3d5f787e48489.png"},25693:(e,t,a)=>{a.d(t,{Z:()=>n});const n=a.p+"assets/images/general31-127358c1aa2715173141d55c78c79d70.png"},4327:(e,t,a)=>{a.d(t,{Z:()=>n});const n=a.p+"assets/images/general32-eb289f0be9cc090fc455d823c26bd310.png"},42204:(e,t,a)=>{a.d(t,{Z:()=>n});const n=a.p+"assets/images/general41-949405deaef610fd9742055a23363f7e.png"},62942:(e,t,a)=>{a.d(t,{Z:()=>n});const n=a.p+"assets/images/general42-39f202b1dfdcecc289d3582e20cde498.png"},81969:(e,t,a)=>{a.d(t,{Z:()=>n});const n=a.p+"assets/images/general51-72f8449fb89dfdd31ab4eeef2bfa8ebf.png"},92076:(e,t,a)=>{a.d(t,{Z:()=>n});const n=a.p+"assets/images/general52-3903edbdaf25478fbcabf8ec390ac257.png"},48805:(e,t,a)=>{a.d(t,{Z:()=>n});const n=a.p+"assets/images/sizes11-6ed8118385ec2b2570e7aaeee1f6541e.png"},24860:(e,t,a)=>{a.d(t,{Z:()=>n});const n=a.p+"assets/images/sizes12-a05d9e5b04bc487f75d5ec3322619645.png"},85209:(e,t,a)=>{a.d(t,{Z:()=>n});const n=a.p+"assets/images/sizes21-b404c76c47b45312f15afe077e97c5d8.png"},76245:(e,t,a)=>{a.d(t,{Z:()=>n});const n=a.p+"assets/images/sizes22-e801d2de7a6ae71ed02556af421d17b4.png"},3240:(e,t,a)=>{a.d(t,{Z:()=>n});const n=a.p+"assets/images/sizes31-9af6876cd32a8486431c0859f5c15e7c.png"},83519:(e,t,a)=>{a.d(t,{Z:()=>n});const n=a.p+"assets/images/sizes32-3011b5545d0899d6c3bf6a3c7f0c1304.png"},64125:(e,t,a)=>{a.d(t,{Z:()=>n});const n=a.p+"assets/images/sizes41-2eca56b296b460aa98b34ff0e3642a67.png"},13077:(e,t,a)=>{a.d(t,{Z:()=>n});const n=a.p+"assets/images/sizes42-5024bdc66d052e6b6636040cef38bd93.png"},19895:(e,t,a)=>{a.d(t,{Z:()=>n});const n=a.p+"assets/images/sizes51-129c42f705ff833ed745045e7803cb6f.png"},72106:(e,t,a)=>{a.d(t,{Z:()=>n});const n=a.p+"assets/images/sizes52-505ad4d2e61ad6462a0e9d100fcf234b.png"},11611:(e,t,a)=>{a.d(t,{Z:()=>n});const n=a.p+"assets/images/tempalloc11-2ba6018b7760dfd150567d789283ffdf.png"},90460:(e,t,a)=>{a.d(t,{Z:()=>n});const n=a.p+"assets/images/tempalloc12-1e7c0754f86c80cf83b4d58183816de6.png"},64450:(e,t,a)=>{a.d(t,{Z:()=>n});const n=a.p+"assets/images/tempalloc21-875ab00f360822c237156c64609b1367.png"},80247:(e,t,a)=>{a.d(t,{Z:()=>n});const n=a.p+"assets/images/tempalloc22-214f62229a8d204d44e83dfcf6a69c19.png"},29530:(e,t,a)=>{a.d(t,{Z:()=>n});const n=a.p+"assets/images/tempalloc31-7b52143b8f6199186fb0ae7c66486365.png"},61258:(e,t,a)=>{a.d(t,{Z:()=>n});const n=a.p+"assets/images/tempalloc32-0a2c79a5578806df5da0f97b15eb1c56.png"},85465:(e,t,a)=>{a.d(t,{Z:()=>n});const n=a.p+"assets/images/tempalloc41-3174820f91664038d6fdd966f07bd90d.png"},1484:(e,t,a)=>{a.d(t,{Z:()=>n});const n=a.p+"assets/images/tempalloc42-6122a1bdf8c5db3a03fa4249ebb52e1f.png"},73312:(e,t,a)=>{a.d(t,{Z:()=>n});const n=a.p+"assets/images/tempalloc51-5b0868395d26e76dac7744b216e4949f.png"},54443:(e,t,a)=>{a.d(t,{Z:()=>n});const n=a.p+"assets/images/tempalloc52-ceccc6d4166dbdedebcdb4370acb9650.png"}}]); \ No newline at end of file diff --git a/assets/js/99c49682.49525b7c.js b/assets/js/99c49682.49525b7c.js deleted file mode 100644 index d80ff266..00000000 --- a/assets/js/99c49682.49525b7c.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkvac_dev=self.webpackChunkvac_dev||[]).push([[6807],{10319:e=>{e.exports=JSON.parse('{"blogPosts":[{"id":"zkVM-explorations","metadata":{"permalink":"/rlog/zkVM-explorations","source":"@site/rlog/2024-08-27-Zkvm.mdx","title":"Exploring zkVMs: Which Projects Truly Qualify as Zero-Knowledge Virtual Machines?","description":"The blockchain space is rapidly evolving, and with it, new technologies are emerging that promise enhanced privacy, scalability, and security.","date":"2024-08-27T12:00:00.000Z","formattedDate":"August 27, 2024","tags":[],"readingTime":23.53,"hasTruncateMarker":true,"authors":[{"name":"Moudy","github":"moudyellaz","key":"moudy"}],"frontMatter":{"title":"Exploring zkVMs: Which Projects Truly Qualify as Zero-Knowledge Virtual Machines?","date":"2024-08-27T12:00:00.000Z","authors":"moudy","published":true,"slug":"zkVM-explorations","categories":"research","discuss":"https://forum.vac.dev/t/exploring-zkvms-which-projects-truly-qualify-as-zero-knowledge-virtual-machines/317","toc_min_heading_level":2,"toc_max_heading_level":5},"nextItem":{"title":"Nescience: A User-Centric State-Separation Architecture","permalink":"/rlog/Nescience-state-separation-architecture"}},"content":"\x3c!--truncate--\x3e\\n\\n\\n# Introduction\\n\\nThe blockchain space is rapidly evolving, and with it, new technologies are emerging that promise enhanced privacy, scalability, and security. \\nAs decentralized systems grow in complexity and usage, the need for secure and private computation has never been greater.\\nZero-knowledge virtual machines (zkVMs) are one such innovation, allowing for computations to be proven correct without revealing the underlying data. \\nZkVMs have enormous implications for privacy-preserving applications, decentralized finance (DeFi), and other blockchain-based use cases.\\nHowever, as the term \\"zkVM\\" becomes more widely adopted, it is critical to distinguish between projects that truly satisfy the stringent requirements of a zkVM and those that do not.\\n\\n\\n# What is a zkVM?\\nA zkVM is a virtual machine that combines the principles of cryptographic proof generation and privacy preservation with the computational model \\nof traditional virtual machines. Essentially, a zkVM enables the execution of arbitrary programs while generating cryptographic proofs\u2014specifically, zero-knowledge proofs (ZKPs)\u2014that \\ncan verify the correctness of these computations without revealing any sensitive information. This ensures that computations can be trusted while protecting the privacy of the data involved. \\nThe key characteristics of a zkVM include:\\n\\n- Proof generation: The ability to produce ZKPs that verify the correct execution of programs. There are several types of cryptographic techniques used in zkVMs to \\ngenerate these proofs, such as zk-SNARKs, zk-STARKs, and recursive proofs. A zkVM\u2019s ability to generate these proofs determines how effectively it can ensure the integrity of computations \\nin a privacy-preserving manner.\\n- Privacy preservation: The system must maintain privacy, ensuring that only the proof is revealed, not the underlying computation or data. Privacy-preserving zkVMs allow users to maintain \\nconfidentiality without compromising the security or verifiability of their operations. However, not all zkVMs achieve the same level of privacy. Some may focus more on proof generation \\nand scalability while deprioritizing privacy features, which can limit their use in certain privacy-sensitive applications.\\n- Scalability and performance: zkVMs should offer scalable and efficient computation, leveraging advanced cryptographic techniques like zk-SNARKs, zk-STARKs, or recursive proofs. \\nA zkVM\'s performance must also be measured in terms of latency (time to generate and verify a proof) and throughput (number of computations processed within a certain time frame).\\n- Verifiable computation: The zkVM should be able to prove the execution of arbitrary programs in a secure and verifiable manner. Verifiable computation ensures that zkVMs can be deployed \\nacross a wide range of applications, from DeFi to private data-sharing platforms and more.\\n\\n# Why zkVMs matter\\n\\nThe rise of zkVMs is a crucial development for the future of blockchain and decentralized technologies. As more systems require the ability to scale while maintaining privacy and trust, \\nzkVMs provide a powerful solution. They offer the potential to reshape the way decentralized applications (dapps) handle sensitive information, enabling them to be both efficient and private.\\n\\nIt is essential to distinguish between projects that fully realize the potential of zkVMs and those that do not. In the remainder of this post, we evaluate several zkVM projects, analyzing \\nwhether they satisfy the criteria for being classified as zkVMs based on our research.\\n\\n# Our methodology\\n\\nWe analyzed each project\u2019s documentation, source code, and available benchmarks to determine whether they meet the definition of a zkVM. \\nOur criteria focus on the key capabilities of zkVMs\u2014proof generation, privacy, scalability, and integration with existing systems.\\n\\n# ZkVM project analysis\\n\\n## 1. [SP1]\\n- Overview: SP1 [[1](https://blog.succinct.xyz/introducing-sp1/)] is a developer-friendly zkVM designed to enable ZKP execution for LLVM-based languages like C, C++, Rust, and others. It supports a RISC-V-like instruction set architecture (ISA), \\nwhich makes it compatible with various programming languages compiled through LLVM.\\n- Main focus: The main focus of SP1 is scalability, open-source contributions, and accessibility for developers. It prioritizes performance over privacy, \\nmaking it a good fit for environments where privacy isn\'t the primary concern.\\n- Privacy: Not explicitly mentioned, making it less suitable for privacy-preserving applications.\\n- Performance: SP1 has demonstrated up to 5.4x better performance than similar zkVMs like RISC0 for specific computations such as Fibonacci sequence generation.\\n- Integration: SP1 is highly adaptable for rollups, light client verifiers, oracles, and even web2 projects like verifying the originality of images.\\n- Conclusion: Yes, SP1 is a zkVM, but it does not prioritize zero-knowledge privacy, focusing more on scalability and performance.\\n\\n\\n## 2. [Nexus]\\n- Overview: Nexus [[2](https://docs.nexus.xyz/)] is a highly modular zkVM designed to process up to a trillion CPU cycles per second. It relies on RISC-V instructions for computation, making it extensible and scalable. \\nHowever, it currently lacks full ZKP capabilities due to its use of Spartan proofs.\\n- Main focus: Nexus focuses on high performance and scalability, aiming to create an efficient execution environment for computationally intensive tasks.\\n- Privacy: Although zero-knowledge privacy isn\'t the primary feature of Nexus, the project hints at potential privacy enhancements in the future.\\n- Performance: Nexus has a high theoretical throughput, but it has yet to demonstrate benchmarks on zero-knowledge privacy.\\n- Integration: Nexus is a good fit for high-performance environments that do not necessarily require full privacy.\\n- Conclusion: Yes, Nexus qualifies as a zkVM in terms of scalability and proof generation, but it does not yet achieve full zero-knowledge privacy.\\n\\n## 3. [RISC0]\\n- Overview: Risc0 [[3]( https://www.risczero.com/zkvm)] is a general-purpose zkVM with strong developer support. It allows for the execution of Rust and C code on a RISC-V virtual machine \\nand generates zk-SNARK and zk-STARK proofs for these computations.\\n- Main focus: Risc0 is focused on ease of use for developers by abstracting away the complexities of circuit generation, making it accessible for a wide range of use cases.\\n- Privacy: Full zero-knowledge privacy is supported via zk-SNARK and zk-STARK proofs, with Groth16 used for constant-size proof generation.\\n- Performance: Risc0 offers strong benchmarks across different hardware setups, making it one of the most versatile zkVMs in terms of performance and scalability.\\n- Integration: Risc0 integrates with several ecosystems, including Ethereum, and supports verifiable execution of Rust-based programs.\\n- Conclusion: Yes, Risc0 qualifies as a zkVM, offering a balance of developer usability, scalability, and privacy.\\n\\n## 4. [Powdr]\\n- Overview: Powdr [[4](https://docs.powdr.org/)] is a toolkit for creating custom zkVMs. It allows developers to select from various front-end and back-end components to create zkVMs tailored to specific needs.\\n- Main focus: Powdr is focused on providing a modular architecture for zkVM creation. It enables flexibility by allowing the combination of different ZK-proof backends like Halo2 or Valida.\\n- Privacy: Powdr itself does not generate ZKPs, but it facilitates the creation of zkVMs that do.\\n- Performance: The performance depends on the components chosen by the developer, as Powdr itself is more of a framework.\\n- Integration: Powdr is highly customizable and can integrate with existing zkVM frameworks to extend their capabilities.\\n- Conclusion: No, Powdr is not a zkVM itself, but it is a powerful tool for building customized zkVMs with different privacy and performance needs.\\n\\n## 5. [ZkMIPS]\\n- Overview: ZkMIPS [[5](https://docs.zkm.io/zkm-architecture)] uses zk-STARKs to ensure privacy during computation, ensuring that private inputs are preserved while still proving correctness.\\n- Performance: ZkMIPS is built for scalability, though explicit benchmarks are not widely published.\\n- Integration: ZkMIPS can be integrated into systems that rely on MIPS architecture, making it versatile for legacy codebases that require privacy.\\n- Conclusion: Yes, zkMIPS is a zkVM focused on scalability and privacy for MIPS-based architectures.\\n\\n## 6. [Valida]\\n- Overview: Valida [[6]( https://delendum.xyz/writings/2023-05-10-zkvm-design.html)] is a performance-oriented zkVM that generates proofs for programs using a custom ISA designed to optimize zkVM implementation. \\nIt uses Plonky3 for its proof system.\\n- Main focus: Valida is centered around optimizing prover performance and extensibility, making it a valuable tool for generating proofs efficiently.\\n- Privacy: While Valida is focused on performance, it does not prioritize zero-knowledge privacy as much as other zkVMs.\\n- Performance: Valida has benchmarks indicating its performance advantages in proving computations quickly, particularly through parallel processing.\\n- Integration: Valida is specialized and may not integrate as seamlessly into general-purpose systems, as it is optimized for performance over broad applicability.\\n- Conclusion: Yes, Valida qualifies as a zkVM based on proof generation, but its lack of focus on privacy makes it less suitable for privacy-first use cases.\\n\\n## 7. [Jolt]\\n- Overview: Jolt [[7](https://a16zcrypto.com/posts/article/building-jolt/)] is a zkVM built to optimize prover performance using a modified Hyrax polynomial commitment system. It relies on RISC-V instructions for computation \\nbut falls short of full zero-knowledge capabilities.\\n- Main focus: Jolt\'s main goal is to optimize the speed of proving program execution, making it suitable for high-performance applications where privacy isn\'t the primary concern.\\n- Privacy: Jolt does not fully achieve zero-knowledge privacy due to the choice of polynomial commitment schemes.\\n- Performance: Jolt offers strong performance, with benchmarks highlighting its ability to process proofs efficiently.\\n- Integration: Jolt can be integrated with systems that prioritize speed over privacy, particularly where rapid proof generation is essential.\\n- Conclusion: Yes, Jolt qualifies as a zkVM based on proof generation, though it does not provide full zero-knowledge privacy.\\n\\n## 8. [ZkWASM]\\n- Overview: ZkWASM [[8](https://delphinuslab.com/zk-wasm/)] is a zkVM designed to execute WebAssembly (WASM) code in a privacy-preserving and scalable manner. It uses zk-SNARKs to prove the correctness of WASM \\nprogram execution while ensuring privacy.\\n- Main focus: ZkWASM focuses on scalability and privacy for WebAssembly, making it ideal for dapps that require verifiable computation without compromising privacy.\\n- Privacy: Full zero-knowledge privacy is provided through zk-SNARKs, ensuring that the execution of WASM programs remains confidential.\\n- Performance: ZkWASM is optimized for running WASM programs efficiently, with offchain computation and onchain verification to enhance performance.\\n- Integration: ZkWASM is ideal for dapps, particularly those that use WebAssembly and require verifiable execution.\\n- Conclusion: Yes, zkWASM qualifies as a zkVM, providing strong privacy, scalability, and verifiable execution for WebAssembly code.\\n\\n## 9. [Aleo]\\n- Overview: Aleo\'s [[9](https://aleo.org/blog/)] snarkVM converts code into Aleo instructions, which are then compiled into bytecode executable on its zkVM. Aleo emphasizes building private, scalable dapps.\\n- Main focus: Aleo prioritizes privacy and scalability for dapps, providing a robust framework for developers building private dapps.\\n- Privacy: Aleo offers full privacy through zk-SNARK proofs, making it suitable for building fully private applications.\\n- Performance: Aleo focuses on scalability through efficient proof systems, though detailed performance benchmarks are not widely available.\\n- Integration: Aleo is built for privacy-first dapps and integrates with other zkVM-based systems.\\n- Conclusion: Yes, Aleo qualifies as a zkVM, offering a comprehensive solution for private and scalable dapps.\\n\\n## 10. [Ola]\\n- Overview: Ola [[10](https://github.com/Sin7Y/olavm-whitepaper-v2/tree/master)] is a ZK-friendly, high-performance layer-2 (L2) rollup platform that is still under development. It is designed to execute computations offchain while generating \\nvalidity proofs for these computations, ensuring that they are correctly executed without compromising security. \\n- Privacy: Ola does not specifically prioritize privacy in the same way that zkVMs do. While it leverages ZKPs for scalability, its focus is on proving the correctness of \\ntransactions and computations rather than ensuring that the data remains private.\\n- Performance: Ola is designed to achieve high performance, particularly in terms of transaction throughput.\\n- Integration: Ola is designed to be interoperable with various layer-1 blockchains. The platform supports a hybrid ZK-rollup architecture and is expected to include bridges for cross-chain \\ninteroperability, enabling assets and data to move seamlessly between the layer-1 blockchain and the Ola rollup.\\n- Conclusion: No, Ola is not a zkVM. While it leverages ZKPs (in the form of ZK-rollups) to ensure the validity of offchain computations, its primary focus is on scalability and performance \\nrather than privacy or verifiable execution of arbitrary programs. Ola is more accurately described as a ZK-rollup platform aimed at improving transaction throughput and reducing transaction costs on \\nlayer-1 blockchains. \\n\\n## 11. [Miden]\\n- Overview: Miden zkVM [[11](https://0xpolygonmiden.github.io/miden-vm/intro/main.html)] is a zk-STARK-based virtual machine that converts code into Miden VM instructions and proves the execution of these instructions with zero-knowledge privacy.\\n- Main focus: Miden focuses on scalability and privacy for ZK-rollups, offering efficient proof generation for dapps.\\n- Privacy: Miden ensures privacy for transactions and programs via zk-STARK proofs, making it suitable for private dapps.\\n- Performance: Miden is optimized for scalability, with benchmarks showing its ability to handle up to 1,000 transactions per second (TPS).\\n- Integration: Miden integrates well with ZK-rollup solutions, making it ideal for L2 scaling solutions on blockchains like Ethereum.\\n- Conclusion: Yes, Miden qualifies as a zkVM, providing strong privacy and scalability for dapps and ZK-rollups.\\n\\n## 12. [ZkOS]\\n- Overview: ZkOS [[12](https://osblog.stephenmarz.com/index.html)] is a verifiable operating system focused on running zkApps in a decentralized manner. It is built on the RISC-V architecture and aims to create \\na world computer where all untrusted executions can be verified.\\n- Main focus: ZkOS is primarily designed to offer a proof-of-concept operating system where all executions can be verified in a trustless manner. \\nHowever, its focus is more on the infrastructure for verifiable applications rather than being a traditional zkVM.\\n- Privacy: ZkOS does not focus on privacy guarantees such as those found in zkVMs that generate ZKPs.\\n- Performance: ZkOS focuses on the efficient execution of dapps, but performance benchmarks specific to ZKP generation are not provided.\\n- Integration: ZkOS supports the execution of zkApps, but it is more of a verifiable operating system rather than a zkVM, making it distinct in its functionality.\\n- Conclusion: No, zkOS is not a zkVM. It is a verifiable operating system focused on the infrastructure to support zkApps but does not directly generate ZKPs or focus on privacy preservation.\\n\\n## 13. [Triton]\\n- Overview: Triton [[13](https://triton-vm.org/spec/)] is a domain-specific language (DSL) and compiler designed primarily for high-performance GPU kernels, particularly those used in deep learning applications. \\n- Main focus: The primary goal of Triton is to optimize computation for machine learning and GPU workloads. It is focused on enhancing performance and efficiency in processing data \\nrather than on ZKPs or verifiable computation.\\n- Privacy: Triton does not provide ZKPs or privacy features typically associated with zkVMs. Its focus is on high-performance computation rather than cryptographic verifiability.\\n- Performance: Triton is highly optimized for GPU execution, offering significant improvements in performance for computationally intensive tasks such as those found in deep learning.\\n- Integration: Triton is integrated with GPU-based computation environments and is highly specialized for optimizing low-level operations on hardware rather \\nthan being a general-purpose virtual machine.\\n- Conclusion: No, Triton is not a zkVM. It is a specialized tool for optimizing GPU workloads, focusing on performance rather than privacy or ZKPs.\\n\\n## 14. [Cairo]\\n- Overview: Cairo zkVM [[14](https://github.com/lambdaclass/cairo-vm/blob/main/docs/python_vm/README.md)] uses a custom language that compiles to an optimized STARK-based proof system, ensuring verifiable computation. It is primarily used in systems like Starknet.\\n- Main focus: Cairo focuses on scalability and performance, using zk-STARK proofs to ensure the verifiable and secure execution of programs.\\n- Privacy: Cairo provides privacy through zk-STARKs, but it focuses more on scalability and performance than privacy-first use cases.\\n- Performance: Cairo is highly optimized for performance, making it well-suited for scalable applications on Starknet.\\n- Integration: Cairo integrates deeply with systems like Starknet, supporting verifiable computation in a highly scalable and efficient manner.\\n- Conclusion: Yes, Cairo qualifies as a zkVM, focusing on performance and verifiable execution while being ZK-friendly.\\n\\n## 15. [SnarkOS]\\n- Overview: SnarkOS [[15](https://aleo.org/post/aleo-completes-security-audits-of-snarkos-and-snarkvm/)] is a decentralized operating system designed to power Aleo\'s network, enabling secure and private dapps. \\nIt manages transactions and consensus, making it a critical infrastructure component for Aleo\'s zkVM-based ecosystem.\\n- Main focus: SnarkOS primarily focuses on securing Aleo\'s network through consensus mechanisms and privacy-preserving transactions rather than acting as a \\nzkVM that directly proves program execution.\\n- Privacy: SnarkOS supports zero-knowledge privacy through its integration with Aleo\'s zkVM, but the operating system itself does not generate ZKPs for arbitrary computations.\\n- Performance: SnarkOS is optimized for managing dapps on the Aleo network and handling private transactions, but its focus is more on infrastructure \\nand consensus than on proof generation.\\n- Integration: SnarkOS integrates seamlessly with Aleo\'s zkVM to support private dapps and transactions, but its primary role is as a consensus layer.\\n- Conclusion: No, SnarkOS is not a zkVM. It serves as an operating system for Aleo\'s decentralized network, focusing on privacy and consensus rather than on generating ZKPs for computations.\\n\\n## 16. [Lurk]\\n- Overview: Lurk [[16](https://github.com/lurk-lab)] is a Turing-complete programming language designed for recursive zk-SNARKs. It focuses on enabling developers to build complex, \\nrecursive ZKPs efficiently through a custom language tailored for verifiable computation.\\n- Main focus: Lurk is centered around recursive proof generation rather than serving as a traditional virtual machine. Its purpose is to facilitate the creation of complex zk-SNARK-based proofs, \\nmaking it a specialized tool for cryptographic proofs rather than general-purpose computation.\\n- Privacy: Lurk is built for generating zk-SNARKs, which inherently provide privacy. However, Lurk itself is a language and not a zkVM that executes arbitrary programs and generates ZKPs for them.\\n- Performance: Lurk is optimized for recursive zk-SNARK generation, but specific performance metrics are tied to its proof-generation capabilities rather than traditional execution environments.\\n- Integration: Lurk is specialized for zk-SNARKs and may not easily integrate with other general-purpose systems, as it focuses on specific cryptographic tasks.\\n- Conclusion: No, Lurk is not a zkVM. It is a programming language designed for recursive zk-SNARKs and focuses on proof generation rather than program execution in a virtual machine environment.\\n\\n## 17. [Piecrust]\\n- Overview: Piecrust [[17](https://docs.rs/piecrust/latest/piecrust/)] is a WASM-based zkVM designed to run on the Dusk Network. It supports concurrent execution and focuses on providing privacy and scalability for smart contracts.\\n- Main focus: Piecrust is designed to provide private and efficient execution of smart contracts through the use of ZKPs.\\n- Privacy: Piecrust supports ZK-friendly computations and enhances privacy through cryptographic primitives such as Merkle trees.\\n- Performance: Piecrust is designed to be scalable and concurrent, allowing multiple sessions to run simultaneously, which improves overall performance.\\n- Integration: Piecrust integrates with the Dusk Network and supports private smart contracts, making it ideal for dapps.\\n- Conclusion: Yes, Piecrust qualifies as a zkVM, offering scalability, privacy, and support for succinct proof generation.\\n\\n## 18. [Ceno]\\n- Overview: Ceno [[18](https://eprint.iacr.org/2024/387)] is a zkVM that provides a theoretical framework for reducing proving time by grouping common portions of code together. It uses recursive proofs to enhance prover efficiency.\\n- Main focus: Ceno aims to optimize prover performance through recursive proofs, making it a powerful tool for handling complex computations efficiently.\\n- Privacy: Ceno supports zero-knowledge privacy through recursive proofs and is designed to handle large-scale computations securely.\\n- Performance: Ceno\'s recursive proof framework ensures that it can efficiently prove the execution of programs, reducing the time required for proof generation.\\n- Integration: Ceno can be integrated into systems that require high efficiency and privacy, particularly those handling complex, repeated computations.\\n- Conclusion: Yes, Ceno qualifies as a zkVM, providing efficient and private computation through the use of recursive proofs.\\n\\n## 19. [Stellar]\\n- Overview: Stellar [[19](https://stellar.org/blog/developers/zkvm-a-new-design-for-fast-confidential-smart-contracts)] is a decentralized protocol designed to facilitate cross-border transactions between digital and fiat currencies.\\n- Main focus: Stellar\'s primary goal is to improve financial transactions by enabling decentralized, low-cost currency transfers. It does not aim to provide ZKPs or run verifiable computations \\nlike a zkVM.\\n- Privacy: Stellar focuses on confidentiality and security for financial transactions, but it does not employ ZKPs in the way zkVMs do for verifying computation without revealing data.\\n- Performance: Stellar prioritizes the performance of financial transactions, ensuring low latency and high throughput across its decentralized network. \\nHowever, this performance focus is specific to transactions rather than general-purpose program execution.\\n- Integration: Stellar is designed for integration with financial systems, enabling currency conversions and transfers, but it is not built for executing smart contracts or verifiable computations.\\n- Conclusion: No, Stellar is not a zkVM. It is a decentralized financial protocol focused on facilitating cross-border payments rather than verifiable or privacy-preserving computation.\\n\\n## 20. [NovaNet]\\n- Overview: NovaNet [[20](https://www.novanet.xyz/blog)] is an open peer-to-peer network that aims to build upon concepts of non-uniform incremental verifiable computation. \\n- Main focus: NovaNet\'s focus is on peer-to-peer networking and decentralized computing rather than on proving the execution of programs in a zero-knowledge manner.\\n- Privacy: NovaNet does not provide ZKPs or privacy features typically associated with zkVMs. Its focus is on decentralized networking and computation.\\n- Performance: NovaNet prioritizes efficient decentralized computation but does not focus on privacy or performance benchmarks related to ZKPs.\\n- Integration: NovaNet is built for decentralized networks but is not designed to integrate with systems requiring verifiable computation or ZKP generation.\\n- Conclusion: No, NovaNet is not a zkVM. It is a decentralized peer-to-peer network focused on distributed computing rather than zero-knowledge computation.\\n\\n\\n## 21. [ZkLLVM]\\n- Overview: ZkLLVM [[21](https://github.com/NilFoundation/zkLLVM)] is a compiler that transforms C++ or Rust code into circuits for use in zk-SNARK or zk-STARK systems. Its primary purpose is to bridge high-level programming \\nlanguages with ZKP systems by compiling code into arithmetic circuits that can be used to generate and verify proofs.\\n- Main focus: ZkLLVM focuses on making ZKPs accessible to developers by enabling them to write code in familiar languages (C++, Rust) and then compile that code into ZK circuits.\\n- Privacy: ZkLLVM enables the generation of ZKPs by compiling high-level code into ZK-compatible circuits. It plays a crucial role in privacy-preserving applications but does not act \\nas a zkVM itself.\\n- Performance: ZkLLVM allows for the performance of ZKPs to be closely tied to the complexity of the compiled circuits. The performance depends on the underlying \\nzk-SNARK or zk-STARK system used.\\n- Integration: ZkLLVM integrates with zk-SNARK and zk-STARK proof systems, making it useful for a variety of privacy-focused applications, but it does not serve as a zkVM \\nfor general-purpose computation.\\n- Conclusion: No, zkLLVM is not a zkVM. It is a compiler that transforms high-level code into ZK circuits, enabling ZKPs but not acting as a virtual machine for executing and proving programs.\\n\\n\\n## 22. [ZkMove]\\n- Overview: ZkMove [[22](https://www.zkmove.net/2023-06-20-zkMove-0.2.0-Achieving-Full-Bytecode-Compatibility-with-Move/)] is a zkVM designed to execute smart contracts written in the Move language. It utilizes ZKPs to ensure that the execution of these contracts remains verifiable and secure.\\n- Main focus: ZkMove focuses on privacy and verifiable execution for Move-based smart contracts, providing a framework for ZK-friendly computation.\\n- Privacy: ZkMove ensures that smart contract execution remains private through ZKPs, making it suitable for privacy-preserving applications.\\n- Performance: ZkMove is optimized for verifiable execution, ensuring that contracts can be proven correct while preserving privacy.\\n- Integration: ZkMove integrates well with systems that use the Move language, particularly in environments that require private smart contract execution.\\n- Conclusion: Yes, zkMove qualifies as a zkVM, offering ZK-friendly execution and privacy for smart contracts written in the Move language.\\n\\n## 23. [O1VM]\\n- Overview: O1VM [[23](https://github.com/o1-labs/proof-systems/tree/master/o1vm)] is a general-purpose zkVM developed by o1Labs. It is designed to prove the execution of MIPS programs efficiently through a combination of zk-SNARKs \\nand specialized techniques like folding schemes and RAMLookups.\\n- Main focus: O1VM focuses on scalability and verifiable computation for MIPS-based programs, making it a strong contender for executing and proving complex programs efficiently.\\n- Privacy: O1VM ensures privacy through zk-SNARK proofs, keeping the details of the computation private while proving its correctness.\\n- Performance: O1VM is optimized for handling long execution traces and complex computations, making it highly scalable.\\n- Integration: O1VM integrates well with MIPS-based architectures and systems that require privacy-preserving computation.\\n- Conclusion: Yes, o1VM qualifies as a zkVM, providing privacy, scalability, and strong proof generation for MIPS programs.\\n\\n\\n# Summary of findings \\n| Project name | ZkVM status | Zero knowledge | Reasoning/comments |\\n|--------------|-------------|----------------|-------------------|\\n| **SP1** | Yes | No | Proves execution of LLVM-based programs but lacks privacy features. |\\n| **Nexus** | Yes | No | Strong proof generation but lacks zero-knowledge privacy due to Spartan. |\\n| **Risc0** | Yes | Yes | Supports full ZKP generation for Rust programs. |\\n| **Powdr** | No | Yes | Toolkit for creating custom zkVMs, not a zkVM itself. |\\n| **ZkMIPS** | Yes | Yes | Supports MIPS-like architecture with full zero-knowledge and proof generation. |\\n| **Valida** | Yes | No | Performance-focused zkVM, lacks privacy guarantees. |\\n| **Jolt** | Yes | No | Performance-focused zkVM, does not achieve zero-knowledge privacy. |\\n| **ZkWASM** | Yes | Yes | Full zero-knowledge and verifiable execution of WebAssembly code. |\\n| **Aleo** | Yes | Yes | Fully private and scalable dapps. |\\n| **Ola** | No | No | Primarily a ZK-rollup platform, not a zkVM, focusing on scalability and performance rather than privacy. |\\n| **Miden** | Yes | Yes | Zk-STARK-based zkVM with strong privacy and scalability. |\\n| **ZkOS** | No | No | Verifiable operating system focused on zkApps, not a zkVM. |\\n| **Triton** | No | No | Optimizes GPU workloads but not designed for ZKPs. |\\n| **Cairo** | Yes | ZK-friendly | Custom Rust-based language with zk-STARK proof generation. |\\n| **SnarkOS** | No | Yes | Decentralized OS for Aleo\'s network, focuses on consensus rather than verifiable computation. |\\n| **Lurk** | No | No | Programming language for recursive zk-SNARKs, not a zkVM. |\\n| **Piecrust** | Yes | ZK-friendly | ZkVM with recursive SNARK capabilities, focused on succinct proof generation. |\\n| **Ceno** | Yes | Yes | Theoretical zkVM improving prover efficiency through recursive proofs. |\\n| **Stellar** | No | No | Focuses on cross-border transactions, not ZK-proof generation or verifiable computation. |\\n| **NovaNet** | No | No | Peer-to-peer network focused on distributed computing, not zero-knowledge computation. |\\n| **ZkLLVM** | No | Yes, in some cases | Compiler for generating ZK-circuits, not a zkVM. |\\n| **ZkMove** | Yes | ZK-friendly | ZkVM supporting Move language with ZKP execution. |\\n| **O1VM** | Yes | Yes | MIPS-based zkVM with strong privacy, scalability, and proof generation. |\\n\\n# Insights and conclusions\\n\\nOur analysis reveals that many of the projects labeled as zkVMs do meet the core criteria for zkVMs, offering verifiable computation and proof generation \\nas foundational features. However, a number of these projects fall short of delivering full zero-knowledge privacy. Projects like Risc0, Aleo, and Miden stand out as leading zkVM frameworks \\nthat balance proof generation, privacy, and scalability, offering strong platforms for developers seeking to build privacy-preserving applications.\\n\\nConversely, projects like SP1 and Nexus excel in generating verifiable proofs but currently lack comprehensive zero-knowledge privacy mechanisms. These platforms are excellent for \\nscenarios where proof generation and scalability are paramount, but privacy is not a primary concern.\\n\\nAs zkVM technology continues to evolve, we expect to see more projects integrating enhanced privacy-preserving mechanisms while simultaneously improving performance and scalability. \\nThis ongoing development will likely broaden the application of zkVMs across the blockchain ecosystem, particularly in privacy-sensitive sectors such as finance, data security, \\nand decentralized applications.\\n\\nWhat are your thoughts on our zkVM analysis? Do you agree with our findings, or do you know of other zkVM projects that should be on our radar? We would love to hear your insights, questions, \\nor suggestions! Feel free to join the [discussion](https://forum.vac.dev/t/exploring-zkvms-which-projects-truly-qualify-as-zero-knowledge-virtual-machines/317) on our forum.\\n\\n\\n# References\\n\\n[1] Introducing SP1: A performant, 100% open-source, contributor-friendly zkVM. Retrieved from https://blog.succinct.xyz/introducing-sp1/\\n\\n[2] The Nexus 2.0 zkVM. Retrieved from https://docs.nexus.xyz/\\n\\n[3] The first general purpose zkVM. Retrieved from https://www.risczero.com/zkvm\\n\\n[4] Powdr. Retrieved from https://docs.powdr.org/\\n\\n[5] ZKM Architecture. Retrieved from https://docs.zkm.io/zkm-architecture\\n\\n[6] Valida zkVM Design. Retrieved from https://delendum.xyz/writings/2023-05-10-zkvm-design.html\\n\\n[7] Building Jolt: A fast, easy-to-use zkVM. Retrieved from https://a16zcrypto.com/posts/article/building-jolt/\\n\\n[8] ZK-WASM. Retrieved from https://delphinuslab.com/zk-wasm/\\n\\n[9] Aleo. Retrieved from https://aleo.org/blog/\\n\\n[10] OlaVM Whitepaper V2. Retrieved from https://github.com/Sin7Y/olavm-whitepaper-v2/tree/master\\n\\n[11] Polygon Miden VM. Retrieved from https://0xpolygonmiden.github.io/miden-vm/intro/main.html\\n\\n[12] The Adventures of OS: Making a RISC-V Operating System using Rust. Retrieved from https://osblog.stephenmarz.com/index.html\\n\\n[13] Triton VM. Retrieved from https://triton-vm.org/spec/\\n\\n[14] How does the original Cairo VM work?. Retrieved from https://github.com/lambdaclass/cairo-vm/blob/main/docs/python_vm/README.md\\n\\n[15] Aleo completes security audits of snarkOS & snarkVM. Retrieved from https://aleo.org/post/aleo-completes-security-audits-of-snarkos-and-snarkvm/\\n\\n[16] Lurk zkVM. Retrieved from https://github.com/lurk-lab\\n\\n[17] Piecrust VM. Retrieved from https://docs.rs/piecrust/latest/piecrust/\\n\\n[18] Ceno: Non-uniform, Segment and Parallel Zero-knowledge Virtual Machine. Retrieved from https://eprint.iacr.org/2024/387\\n\\n[19] ZkVM: a new design for fast, confidential smart contracts. Retrieved from https://stellar.org/blog/developers/zkvm-a-new-design-for-fast-confidential-smart-contracts\\n\\n[20] Novanet. Retrieved from https://www.novanet.xyz/blog\\n\\n[21] ZKLLVM. Retrieved from https://github.com/NilFoundation/zkLLVM\\n\\n[22] zkMove 0.2.0 - Achieving Full Bytecode Compatibility with Move. Retrieved from https://www.zkmove.net/2023-06-20-zkMove-0.2.0-Achieving-Full-Bytecode-Compatibility-with-Move/\\n\\n[23] O1VM. Retrieved from https://github.com/o1-labs/proof-systems/tree/master/o1vm"},{"id":"Nescience-state-separation-architecture","metadata":{"permalink":"/rlog/Nescience-state-separation-architecture","source":"@site/rlog/2024-08-23-state-separation.mdx","title":"Nescience: A User-Centric State-Separation Architecture","description":"Nescience: A user-centric state-separation architecture.","date":"2024-08-23T12:00:00.000Z","formattedDate":"August 23, 2024","tags":[],"readingTime":86.535,"hasTruncateMarker":true,"authors":[{"name":"Moudy","github":"moudyellaz","key":"moudy"}],"frontMatter":{"title":"Nescience: A User-Centric State-Separation Architecture","date":"2024-08-23T12:00:00.000Z","authors":"moudy","published":true,"slug":"Nescience-state-separation-architecture","categories":"research","toc_min_heading_level":2,"toc_max_heading_level":5},"prevItem":{"title":"Exploring zkVMs: Which Projects Truly Qualify as Zero-Knowledge Virtual Machines?","permalink":"/rlog/zkVM-explorations"},"nextItem":{"title":"Membership with Bloom Filters and Cuckoo Filters","permalink":"/rlog/membership-with-bloom-filters-and-cuckoo-filters"}},"content":"Nescience: A user-centric state-separation architecture.\\n\\n\x3c!--truncate--\x3e\\n\\n_Disclaimer: This content is a work in progress. Some components may be updated, changed, or expanded as new research findings become available._\\n\\n# A. Introduction\\n\\nIn blockchain applications, privacy settings are typically predefined by developers, leaving users with limited control. This traditional, \\none-size-fits-all approach often leads to inefficiencies and potential privacy concerns as it fails to cater to the diverse needs of individual users. \\nThe Nescience state-separation architecture (NSSA) aims to address these issues by shifting privacy control from developers to users. NSSA introduces a flexible, \\nuser-centric approach that allows for customized privacy settings to better meet individual needs. This blog post will delve into the details of NSSA, \\nincluding its different execution types, cryptographic foundations, and unique challenges.\\n\\n## Introducing NSSA: A user-centric approach\\n\\nNSSA gives users control over their privacy settings by introducing _shielded_ (which creates a layer of privacy for the outputs, and only the necessary details are shared) \\nand _deshielded_ (which reveal private details, making them publicly visible) execution types in addition to the traditional public and private modes. This flexibility allows \\nusers to customize their privacy settings to match their unique needs, whether they require high levels of confidentiality or more transparency. In NSSA, the system is divided \\ninto two states: public and private. The public state uses an account-based model while the private state employs a UTXO-based (unspent transaction output) model. Private executions within NSSA utilize \\nUTXO exchanges, ensuring that transaction details remain confidential. The sequencer verifies these exchanges without accessing specific details, enhancing privacy by unlinking \\nsender and receiver identities. Zero-knowledge proofs (ZKPs) allow users to prove transaction validity without revealing data, maintaining the integrity and confidentiality of \\nprivate transactions. UTXOs contain assets such as balances, NFTs, or private storage data, and are stored in plaintext within Sparse Merkle trees (SMTs) in the private state and \\nas hashes in the public state. This dual-storage approach keeps UTXO details confidential while allowing public verification through hashes, achieving a balance between privacy and transparency.\\n\\n\\nImplementing NSSA introduces unique challenges, particularly in cryptographic implementation and maintaining the integrity of private executions. These challenges are addressed \\nthrough various solutions such as ZKPs, which ensure transaction validity without compromising privacy, and the dual-storage approach, which maintains confidentiality while enabling \\npublic verification. By allowing users to customize their privacy settings, NSSA enhances user experience and promotes wider adoption of private execution platforms. As we move towards \\na future where user-empowered privacy control is crucial, NSSA provides a flexible and user-centric solution that meets the diverse needs of blockchain users.\\n\\n## Why NSSA differs from other hybrid execution platforms\\n\\nIn many existing hybrid execution platforms, privacy settings are predefined by developers, often applying a one-size-fits-all approach that does not accommodate the \\ndiverse privacy needs of users. These platforms blend public and private states, but control over privacy remains with the application developers. \\nWhile this approach is straightforward for developers (who bear the responsibility for any potential privacy leaks), it leaves users with no control over their own privacy settings. \\nThis rigidity becomes problematic as user needs evolve over time, or as new regulations necessitate changes to privacy configurations. In such cases, \\nupdates to decentralized applications are required to adjust privacy settings, which can disrupt the user experience and create friction.\\n\\nNSSA addresses these limitations by introducing a groundbreaking concept: **selective privacy**. Unlike traditional platforms where privacy \\nis static and determined by developers, selective privacy empowers users to dynamically choose their own privacy levels based on their unique needs and sensitivity. \\nThis flexibility is critical in a decentralized ecosystem where the diversity of users and use cases demands a more adaptable privacy solution.\\n\\nIn the NSSA model, users have the autonomy to select how they interact with decentralized applications (dapps) by choosing from four types of transaction executions: **public**, \\n**private**, **shielded**, and **deshielded**. This model allows users to tailor their privacy settings on a per-transaction basis, selecting the most appropriate execution type for each \\nspecific interaction. For instance, a user concerned about data confidentiality might opt for a fully private transaction while another user, wary of privacy but seeking transparency, \\nmight choose a public execution.\\n\\nWhile selective privacy may appear complex, especially for users who are not technically inclined, Nescience mitigates this by allowing the community or developers to \\nestablish best practices and recommended approaches. These guidelines provide users with an informed starting point, and over time, users can adjust their privacy \\nsettings as their preferences and trust in the platform evolve. Importantly, selective privacy gives users the right to alter their privacy level at any point in the future, \\nensuring that their privacy settings remain aligned with their needs as they change.\\n\\nThis approach not only empowers users but also facilitates greater adoption of dapps. Users who are skeptical about privacy concerns can initially engage with transparent \\ntransactions and gradually shift towards more private executions as they gain confidence in the system and vice versa for users who start with privacy but later find transparency \\nbeneficial for certain transactions. In this way, selective privacy bridges the gap between privacy and transparency, allowing for an optimal balance to emerge from the community\u2019s \\ncollective preferences.\\n\\nTo liken this to open-source projects: in traditional systems, developers fix privacy rules much like immutable code\u2014users must comply with these fixed settings. \\nIn contrast, with selective privacy, the rules are malleable and shaped by the users\u2019 preferences, enabling the community to find the ideal balance between privacy and efficiency over time.\\n\\nNSSA is distinct from traditional zero-knowledge (ZK) rollups in several key ways. One of the unique features of NSSA is its **public execution type**, which does not \\nrequire ZKPs or a zero-knowledge virtual machine (zkVM). This provides a significant advantage in terms of scalability and efficiency as users can choose public executions for \\ntransactions that do not require enhanced privacy, avoiding the overhead associated with ZKP generation and verification.\\n\\nMoreover, NSSA introduces two additional execution types\u2014**shielded and deshielded**\u2014which further distinguish it from traditional privacy-preserving rollups. \\nThese execution types allow for more nuanced control over privacy, giving users the ability to shield certain aspects of a transaction while deshielding others. \\nThis flexibility sets NSSA apart as a more adaptable and user-centric platform, catering to a wide range of privacy needs without imposing a one-size-fits-all solution.\\n\\nBy combining selective privacy with a flexible execution model, NSSA offers a more robust and adaptable framework for decentralized applications, \\nensuring that users maintain control over their privacy while benefiting from the security and efficiency of blockchain technology.\\n\\n## How Nescience state-separation architecture can be used\\n\\nNSSA offers a flexible, privacy-preserving add-on that can be applied to existing dapps. \\nOne of the emerging trends in the blockchain space is that each dapp is expected to have its own rollup for efficiency, and it is estimated that Ethereum could see \\nthe deployment of different rollups in the near future. A key question arises: how many of these rollups will incorporate privacy? For dapp developers who want to offer flexible, \\nuser-centric privacy features, NSSA provides a solution through selective privacy.\\n\\n### Use case: Adding privacy to existing dapps\\n\\nConsider a dapp running on a transparent network that offers no inherent privacy to its users. Converting this dapp to a privacy-preserving architecture from scratch would \\nrequire significant effort, restructuring, and a deep understanding of cryptographic frameworks. However, with NSSA, the dapp does not need to undergo extensive changes. \\nInstead, the **Nescience state-separation model** can be deployed as an **add-on**, offering selective privacy as an option for the dapp\u2019s users.\\n\\nThis allows the dapp to retain its existing functionality while providing users with a choice between the traditional, transparent version and a new version with selective privacy features. \\nWith NSSA, the privacy settings are flexible, meaning users can tailor their level of privacy according to their individual needs while the dapp operates on its current infrastructure. \\nThis contrasts sharply with the typical approach, where dapps are either entirely transparent or fully private, with no flexibility for users to select their own privacy preferences.\\n\\n### Key advantage: Decoupling from the host chain\\n\\nA key feature of NSSA is that it operates independently of the privacy characteristics of the host blockchain. Whether the host chain is fully transparent or fully private, \\nthe Nescience state-separation architecture can be deployed on top of it, offering users the ability to choose their own privacy settings. \\nThis decoupling from the host chain\u2019s inherent privacy model is critical as it allows users to benefit from selective privacy even in environments that were not originally designed to offer it.\\n\\nIn **fully private chains**, NSSA allows users to selectively reveal transaction details when compliance with regulations or other requirements is necessary. \\nIn **fully transparent chains**, NSSA allows users to maintain privacy for specific transactions, offering flexibility that would not otherwise be possible.\\n\\n### Conclusion\\n\\nNSSA provides a powerful tool for dapp developers who want to offer **selective privacy** to their users without the need for a complete overhaul of their existing systems. \\nBy deploying NSSA as an add-on, dapps can give users the ability to choose their own privacy settings whether they are operating on \\ntransparent or private blockchains. This flexibility makes NSSA a valuable option for any dapp looking to provide enhanced privacy options while maintaining efficiency and ease of use.\\n\\n# B. Design\\nIn this section, we will delve into the core design components of the Nescience state-separation architecture, covering its key structural elements and the mechanisms \\nthat drive its functionality. We will explore the following topics:\\n\\n1. **Architecture\'s components**: An in-depth look at the foundational building blocks of NSSA, including the public and private states, UTXO structures, zkVM, and smart contracts. \\nThese components work together to facilitate secure, flexible, and scalable transactions within the architecture.\\n\\n2. **General execution overview**: We will outline the overall flow of transaction execution within NSSA, describing how users interact with the system and how the architecture \\nsupports various types of executions\u2014public, private, shielded, and deshielded\u2014while preserving privacy and efficiency.\\n\\n3. **Execution processes and UTXO management**: This section will focus on the lifecycle of UTXOs within the architecture, from their generation to consumption. \\nWe will also cover the processes involved in managing UTXOs, including proof generation, state transitions, and ensuring transaction validity.\\n\\nThese topics will provide a comprehensive understanding of how NSSA enables flexible and secure interactions within dapps.\\n\\n## 1. Architecture\'s components\\n---\\nNSSA introduces an advanced prototype execution framework designed to enhance privacy and security in blockchain applications. \\nThis framework integrates several essential components: the public state, private state, zkVM, various execution types, Nescience users, and smart contracts.\\n\\n### a) Public state\\n---\\nThe public state in the NSSA is a fundamental component designed to hold all publicly accessible information within \\nthe blockchain network. This state is organized as a single Merkle tree structure, a sophisticated data structure that ensures efficient and secure data verification. \\nThe public state includes critical information such as user balances and the public storage data of smart contracts.\\n\\nIn an account-based model, the public state operates by storing each account or smart contract\'s public data as individual leaf nodes within the Merkle tree. \\nWhen transactions occur, they directly modify the state by updating these leaf nodes. This direct modification ensures that the most current state of the network \\nis always reflected accurately.\\n\\nThe Merkle tree structure is essential for maintaining data integrity. Each leaf node contains a hash of a data block, and each non-leaf node contains the \\nhash of its child nodes. This hierarchical arrangement means that any change in the data will result in a change in the corresponding hash, making it easy to detect \\nany tampering. The root hash, or Merkle root, is stored on the blockchain, providing a cryptographic guarantee of the data\'s integrity. This root hash serves as a single, \\nconcise representation of the entire state, enabling quick and reliable verification by any network participant.\\n\\nTransparency is a key feature of the public state. All data stored within this state is openly accessible and verifiable by any participant in the network. \\nThis openness ensures that all transactions and state changes are visible and auditable, fostering trust and accountability. For example, user balances are\\npublicly viewable, which helps ensure transparency and trust in the system. Similarly, public smart contract storage can be accessed and verified by anyone, \\nmaking it suitable for applications that require public scrutiny and auditability, such as public record updates and some financial transactions.\\n\\nThe workflow of managing the public state involves several steps to ensure data integrity and transparency. When a user initiates a transaction involving public data, \\nthe relevant changes are proposed and applied to the public state tree. The transaction details, such as transferring funds between accounts or updating smart contract storage, \\nupdate the corresponding leaf nodes in the Merkle tree. Following this, the hashes of the affected nodes are recalculated up to the root, ensuring that the entire tree \\naccurately reflects the new state of the network. The updated Merkle root is then recorded on the blockchain, allowing all network participants to verify the integrity \\nof the public state. Any discrepancy in the data will result in a mismatched root hash, signaling potential tampering or errors.\\n\\nIn summary, the public state in NSSA leverages the robustness of the Merkle tree structure to provide a secure, transparent, and verifiable environment for publicly \\naccessible information. By operating on an account-based model and maintaining rigorous data integrity checks, the public state ensures that all transactions are \\ntransparent and trustworthy, laying a strong foundation for a reliable blockchain network.\\n\\n\\n### b) Private state\\n---\\nThe private state in the NSSA is a sophisticated system designed to maintain user privacy while ensuring transaction integrity. \\nEach user has their own individual Merkle tree, which holds their private information such as balances and storage data. This structure is distinct from the public state, \\nwhich uses an account-based model. Instead, the private state employs a UTXO-based model. In this model, each transaction output is a discrete \\nunit that can be independently spent in future transactions. This design provides users with granular control over their transaction outputs.\\n\\nA key aspect of maintaining privacy within the private state is the use of ZKPs. ZKPs allow transactions to be validated without revealing any \\nunderlying private data. This means that while the system can verify that a transaction is legitimate, the details of the transaction remain confidential. Only parties \\nwith the appropriate viewing key can access and reconstruct the user\u2019s list of UTXOs, ensuring that sensitive information is protected.\\n\\nThe private state also employs a dual-storage approach to balance privacy and transparency. UTXOs are stored in plaintext within SMTs in the private state, \\nproviding detailed and accessible records for the user. In contrast, the public state only holds hashes of these UTXOs. This method ensures that while the public can verify \\nthe existence and integrity of private transactions through these hashes, they cannot access the specific details.\\n\\nThe workflow for a transaction in the private state begins with the user initiating a transaction involving their private data, such as transferring a private balance or \\nupdating private smart contract storage. The transaction involves spending existing UTXOs, represented as leaves in the Merkle tree, and creating new UTXOs, \\nwhich are then appended to the user\u2019s private list. The zkVM generates a ZKP to validate the transaction without revealing \\nany private data, ensuring the transaction adheres to the system\'s rules.\\n\\nOnce the proof is generated, it is submitted to the sequencer, which verifies the transaction\u2019s validity. Upon successful verification, the nullifier is added to the nullifier set, \\npreventing double spending of the same UTXO. The use of ZKPs and nullifiers ensures that the private state maintains both security and privacy.\\n\\nIn summary, the private state in NSSA is meticulously designed to provide users with control over their private information while ensuring the security and integrity of transactions. \\nBy utilizing a UTXO-based model, individual Merkle trees, ZKPs, and a dual-storage system, NSSA achieves a balance between confidentiality and verifiability, \\nmaking it a robust solution for managing private blockchain transactions.\\n\\n### c) ZkVM (zero-knowledge virtual machine)\\n---\\nThe zkVM is a pivotal component in NSSA, designed to uphold the highest standards \\nof privacy and security in blockchain transactions. Its primary function is to generate and aggregate ZKPs, enabling users to validate the \\ncorrectness of their transactions without disclosing any underlying details. This capability is crucial for maintaining the confidentiality and integrity of sensitive \\ndata within the blockchain network.\\n\\nZKPs are sophisticated cryptographic protocols that allow one party, the prover, to convince another party, the verifier, that a certain statement is true, \\nwithout revealing any information beyond the validity of the statement itself. In the context of the zkVM, this means users can prove their transactions are valid without \\nexposing transaction specifics, such as amounts or parties involved. This process is essential for transactions within the private state, where maintaining confidentiality is paramount.\\n\\nThe generation of ZKPs involves intricate cryptographic computations. When a user initiates a transaction, the zkVM processes the transaction inputs and produces a proof \\nthat the transaction adheres to the protocol\'s rules. This proof must be robust enough to convince the verifier of the transaction\'s validity while preserving the privacy \\nof the transaction details.\\n\\nPerformance optimization is another critical function of the zkVM. In a typical blockchain scenario, verifying multiple individual proofs can be computationally intensive \\nand time consuming, potentially leading to network congestion and delays. To address this, the zkVM can aggregate multiple ZKPs into a single, consolidated proof. \\nThis aggregation significantly reduces the verification overhead as the verifier needs to check only one comprehensive proof rather than multiple individual ones. \\nThis efficiency is vital for maintaining high throughput and low latency in the blockchain network, ensuring that the system can handle a large volume of transactions swiftly and securely.\\n\\nFurthermore, the zkVM\'s role extends beyond mere proof generation and aggregation. It also ensures that all transactions meet the required privacy and security standards \\nbefore they are recorded on the blockchain. By interacting seamlessly with other components such as the public and private states, the zkVM ensures that any transaction, \\nwhether it involves public data, private data, or a mix of both, is thoroughly validated and secured.\\n\\nIn summary, the zkVM is essential for the NSSA, providing the cryptographic backbone necessary to support secure and private transactions. Its ability to generate and \\naggregate ZKPs not only preserves the confidentiality of user data but also enhances the overall efficiency and scalability of the blockchain network. \\nBy ensuring that all transactions are validated without revealing sensitive information, the zkVM upholds the integrity and trustworthiness of the Nescience blockchain system.\\n\\n\\n### d) Execution types in NSSA\\n---\\nNSSA incorporates multiple execution types to cater to varying levels of privacy and security requirements. \\nThese execution types\u2014public, private, shielded, and deshielded\u2014are designed to provide users with flexible options for managing their transactions based on their specific privacy needs.\\n\\n#### 1. Public executions\\n\\nPublic executions are straightforward transactions that involve reading from and writing to the public state. In this model, data is openly accessible and verifiable \\nby all participants in the network. Public executions do not require ZKPs since transparency is the primary goal. This execution type is ideal \\nfor non-sensitive transactions where public visibility is beneficial, such as updating public records, performing open financial transactions, or interacting with public smart contracts.\\n\\nThe workflow for a public execution starts with a user initiating a transaction that modifies public data. The transaction details are then used to update the relevant \\nleaf nodes in the Merkle tree. As changes are made, the hashes of affected nodes are recalculated up to the root, ensuring that the entire tree reflects the most recent state. \\nFinally, the updated Merkle root is recorded on the blockchain, making the new state publicly verifiable.\\n\\n#### 2. Private executions\\n\\nPrivate executions are designed for confidential transactions, reading from and writing to the private state. These transactions require ZKPs to ensure that while the \\ntransaction details are validated, the actual data remains private. This execution type is suitable for scenarios where privacy is crucial, such as private financial \\ntransactions or sensitive data management within smart contracts.\\n\\nIn a private execution, the user initiates a transaction involving private data. The transaction spends existing UTXOs and creates new ones, all of which are represented as \\nleaves in the Merkle tree. The zkVM generates a ZKP to validate the transaction without revealing private data. This proof is submitted to the sequencer, \\nwhich verifies the proof to ensure the transaction\'s validity. Upon successful verification, the nullifier is added to the nullifier set, and the private state is updated \\nwith the new Merkle root.\\n\\n#### 3. Shielded executions\\n\\nShielded executions create a layer of privacy for the outputs by allowing interactions between the public and private states. When a transaction occurs in a shielded execution, \\ndetails of the transaction are processed within the private state, ensuring that sensitive information remains confidential. Only the necessary details are shared with the public state, \\noften in a masked or encrypted form. This approach allows for the validation of the transaction without revealing critical data, thus preserving the privacy of the involved parties.\\n\\nThe workflow for shielded executions begins with the user initiating a transaction that reads from the public state and prepares to write to the private state. Public data is accessed, \\nand the private state is prepared to receive new data. The zkVM generates a ZKP to hide the receiver\u2019s identity. This proof is submitted to the sequencer, which verifies \\nthe proof to ensure the transaction\'s validity. If valid, the private state is updated with the new data while the public state reflects the change without revealing private details. \\nThis type of execution is particularly useful for scenarios where the receiver\u2019s identity needs to be hidden, such as in anonymous donation systems or confidential data storage.\\n\\n#### 4. Deshielded executions\\n\\nDeshielded executions operate in the opposite manner of shielded executions, where data is read from the private state and written to the public state. This execution type is useful \\nin situations where the sender\'s identity needs to be kept confidential while making the transaction results publicly visible.\\n\\nIn a deshielded execution, the user initiates a transaction that reads from the private state and prepares to write to the public state. Private data is accessed, \\nand the transaction details are prepared. The zkVM generates a ZKP to hide the sender\u2019s identity. This proof is then submitted to the sequencer, \\nwhich verifies the proof to ensure the transaction\'s validity. Once verified, the public state is updated with the new data, reflecting the change while keeping the sender\u2019s \\ndetails confidential. This can be useful when transparency is needed, such as when auditing or proving certain aspects of a transaction to a wider audience. \\nBy selectively deshielding certain transactions, users can control what information is shared publicly, thus maintaining a balance between privacy and transparency \\nas required by their specific use case.\\n\\n\\n#### Table of execution types\\n\\n| Type | Read from | Write to | ZKP required | Use case | Description |\\n|------------|--------------|-------------|--------------|------------------------------------------------------------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|\\n| Public | Public state | Public state| No | Non-sensitive transactions requiring transparency. | Ideal for transactions that do not require privacy, ensuring full transparency. |\\n| Private | Private state| Private state| Yes | Confidential transactions needing privacy. | Suitable for transactions that require confidentiality. Ensures that transaction details remain private through the use of ZKPs. |\\n| Shielded | Public state | Private state| Yes | Transactions where the receiver\u2019s identity needs to be hidden. | Hides the identity of the receiver while keeping the transaction details private. Suitable for anonymous donations or confidential data storage. |\\n| Deshielded | Private state| Public state| Yes | Transactions where the sender\u2019s identity needs to be hidden. | Ensures the sender\u2019s identity remains confidential while making the transaction results public. Suitable for confidential disbursements or anonymized data publication. |\\n---\\n\\n\\nBy supporting a range of execution types, NSSA provides a flexible and robust framework for managing privacy and security in blockchain transactions. \\nWhether the need is for complete transparency, total privacy, or a balanced approach, NSSA\'s execution types allow users to select the level of confidentiality \\nthat best fits their requirements. This flexibility enhances the overall utility of the blockchain, making it suitable for a wide array of applications and use cases.\\n\\n### e) Nescience users\\n---\\nNescience users are integral to the architecture, managing balances and assets within the blockchain network and invoking smart contracts with various privacy options. \\nThey can choose the appropriate execution type\u2014public, private, shielded, or deshielded\u2014based on their specific privacy and security needs.\\n\\nUsers handle both public and private balances. Public balances are visible to all network participants and suitable for non-sensitive transactions, \\nwhile private balances are confidential and used for transactions requiring privacy. Digital wallets provide a user-friendly interface for managing \\nthese balances, assets, and transactions, allowing users to select the desired execution type seamlessly.\\n\\nSecurity is ensured through the use of cryptographic keys, which authenticate and verify transactions. ZKPs maintain privacy \\nby validating transaction correctness without revealing underlying data, ensuring sensitive information remains confidential even during verification.\\n\\nThe workflow for users involves initiating a transaction, preparing inputs, interacting with smart contracts, generating proofs if needed, \\nand submitting the transaction to the sequencer for verification and state update. This flexible approach supports various use cases, \\nfrom financial transactions and decentralized applications to data privacy management, allowing users to maintain control over their privacy settings.\\n\\nBy offering this high degree of flexibility and security, Nescience enables users to tailor their privacy settings to their specific needs, \\nensuring sensitive transactions remain confidential while non-sensitive ones are transparent. This integration of cryptographic keys and ZKPs \\nprovides a robust framework for a wide range of blockchain applications, enhancing both utility and trust within the network.\\n\\n\\n### f) Smart contracts in NSSA\\n---\\nSmart contracts are a core feature of NSSA, providing a way to automate and execute predefined actions based on coded rules. \\nOnce deployed on the blockchain, these contracts become immutable, meaning their behavior cannot be altered. This ensures that they perform exactly as \\nintended without the risk of tampering. Because the state and data of the contract are stored permanently on the blockchain, all interactions are fully \\ntransparent and auditable, creating a reliable and trustworthy environment.\\n\\nOne of the key strengths of smart contracts is their ability to automate processes. They are designed to automatically execute when specific conditions are met, \\nreducing the need for manual oversight or intermediaries. For example, a smart contract might transfer funds when a certain deadline is reached or update a record \\nonce a task is completed. This self-executing nature makes them efficient and minimizes human error.\\n\\nSmart contracts operate deterministically, meaning they will always produce the same result given the same inputs. This predictability is crucial for ensuring reliability, \\nespecially in complex systems. Additionally, they run in isolated environments on the blockchain, which enhances security by preventing unintended interactions with other processes.\\n\\nSecurity is another critical feature of smart contracts. They leverage the underlying cryptographic protections of the blockchain, ensuring that every interaction \\nis secure and authenticated. Before deployment, the contract code can be audited and verified to ensure it functions correctly. Once on the blockchain, \\nthe immutable nature of the code prevents unauthorized modifications, further ensuring the integrity of the system.\\n\\nRunning smart contracts requires computational resources, which are compensated through gas fees. These fees vary depending on the complexity of the operations within the contract. \\nMore resource-intensive contracts incur higher fees, which helps manage the computational load on the blockchain network.\\n\\nThe workflow of a smart contract begins with its development, where developers code the contract using languages like Rust. Once the code is compiled and deployed to the blockchain, \\nit becomes a permanent part of the network. Users can then interact with the contract by sending transactions that invoke specific functions. The contract checks whether the \\nrequired conditions are met, and if so, it automatically executes the specified actions, such as transferring tokens or updating data on the blockchain.\\n\\nThe benefits of smart contracts are numerous. They eliminate the need for intermediaries by providing a system where trust is built into the code itself. \\nThis not only reduces costs but also increases efficiency by automating repetitive processes. The inherent security of smart contracts, combined with their \\ntransparency\u2014where every action is recorded and visible on the blockchain\u2014makes them a powerful tool for ensuring accountability and trust in decentralized systems. \\nThey can be ideal for managing decentralized autonomous organizations (DAOs), where governance decisions are automated through coded rules.\\n\\nBy integrating smart contracts, NSSA offers a highly versatile, secure, and transparent framework that can support a wide range of applications \\nacross various industries, from finance to governance, supply chains, and more.\\n\\n## 2. General execution overview\\n---\\nThis section explains the execution process within NSSA, providing an overview of how it works from start to finish. \\nIt outlines the steps involved in each execution type, guiding the reader through the entire process from user interaction to completion.\\n\\nThe process begins when a user initiates a transaction by invoking a smart contract. This invocation involves selecting at least one of \\nthe four execution types: public, private, shielded, or deshielded. The choice of execution type determines how data will be read from and written to the blockchain, \\naffecting the transaction\'s privacy and security levels. Each execution type caters to different privacy needs, allowing the user to tailor the transaction according \\nto their specific requirements, whether it be full transparency or complete confidentiality.\\n\\n![general](/img/general.png)\\n\\n\\n### User actions\\n---\\n**Step 1**: **Smart contract selection and input creation**\\n- **Smart contract selection**: The user selects a smart contract they wish to invoke.\\n- **Input creation**: The user creates a set of inputs required for the invocation by reading the necessary data from both the public and private states. This includes:\\n - Public data such as current account balances, public keys, and smart contract states.\\n - Private data such as private account balances and UTXOs.\\n\\n**Step 2**: **Choosing execution type**\\n- **Execution type selection**: The user selects the type of execution based on their privacy needs. The options include:\\n - **Public execution**: Suitable for transactions where transparency is desired.\\n - **Private execution**: Used when transaction details need to be confidential.\\n - **Shielded execution**: Hides the receiver\'s identity.\\n - **Deshielded execution**: Hides the sender\'s identity.\\n- **ZkVM requirement**: If the execution involves private, shielded, or deshielded types, the user must call the zkVM to handle these confidential transactions. \\nFor purely public executions, the zkVM is not needed, and the user can directly transmit the transaction code to the sequencer.\\n\\n**Step 3**: **Calling zkVM for proof generation**\\n- **ZkVM compilation**: The user calls the zkVM to compile the smart contract with both public and private inputs.\\n - **Kernel circuit proofs**: The zkVM generates individual proofs for each execution type through kernel circuits.\\n - **Proof aggregation**: The zkVM aggregates these individual proofs into a single comprehensive proof, combining both private and public inputs.\\n\\n**Step 4**: **Transmitting public inputs and retaining private inputs**\\n- **Retaining private inputs**: The user keeps the private inputs secure and does not transmit them.\\n- **Revealing public inputs**: The user transmits the following public inputs to the sequencer:\\n - Public inputs of the recursive proof\\n - Hashes of UTXOs\\n - Updates to the public state\\n - Transaction signature\\n - Nullifiers (to prevent double spending)\\n\\nAfter completing these steps, the user\'s part of the execution is done, and the sequencer takes over the process.\\n\\n### Sequencer actions\\n---\\n**Step 5**: **Proof verification**\\n- **Proof and data reception**: The sequencer receives the proof and public inputs from the user.\\n- **Verification process**:\\n - For private, shielded, and deshielded executions, the sequencer verifies the proof using the provided public data.\\n - For public executions, the sequencer reruns the smart contract code with the provided inputs to check the results.\\n- **Validation**: If both the zkVM proofs and public execution results are verified successfully, the sequencer collects the proof and public data to proceed. \\nIf verification fails, the process is aborted, and the transaction is rejected.\\n\\n**Step 6**: **Aggregating proofs and finalizing the block**\\n- **Proof aggregation**: The sequencer calls the zkVM again to aggregate all received proofs into one comprehensive proof to finalize the block.\\n- **Finalizing the block**:\\n - **Public state update**: The sequencer updates the public state with the new transaction data.\\n - **Nullifier tree update**: Updates the nullifier tree to reflect the new state and prevent double spending.\\n - **Synchronization mechanism**: Runs synchronization mechanisms to ensure fairness and consistency across the network.\\n - **UTXO validation**: Validates the exchanged UTXOs to complete the transaction process.\\n\\nThis comprehensive process ensures that transactions are executed securely, with the appropriate level of privacy and state updates synchronized across the network.\\n\\nBelow, we outline the execution process of the four different execution types within NSSA:\\n- **Public execution**:\\n\\n![public](/img/public.png)\\n\\n- **Private execution**:\\n\\n![private](/img/private.png)\\n\\n- **Shielded execution**:\\n\\n![shielded](/img/se.png)\\n\\n- **Deshielded execution**:\\n\\n![deshielded](/img/de.png)\\n\\n\\n## 3. Execution processes and UTXO management\\n---\\nIn Nescience state-separation architecture, UTXOs are key components for managing private data and assets. They serve as private entities that hold both storage and assets, \\nfacilitating secure and confidential transactions. UTXOs are utilized in three of the four execution types within NSSA: private, shielded, \\nand deshielded executions. This section explores the lifecycle of UTXOs, detailing their generation, transfer, encryption, and eventual consumption within the private execution framework.\\n\\n### a) Components of a Nescience UTXO\\n---\\nA Nescience UTXO is a critical and versatile component of the private state in the Nescience state-separation architecture. \\nIt carries essential information that ensures its proper functionality within private execution, such as the owner, value, private storage slot, non-fungibles, \\nand other cryptographic components. Below is a detailed breakdown of each component and its role in maintaining the integrity, security, and privacy of the system:\\n\\n* **Owner:**\\nThe owner component represents the public key of the entity that controls the UTXO. Only the owner can spend this UTXO, ensuring its security and privacy through public key cryptography. \\nThis means that the UTXO remains secure as only the rightful owner, using their private key, can generate valid signatures to authorize the transaction. For example, \\nif Alice owns a UTXO linked to her public key, she must sign any transaction to spend it using her private key. This cryptographic protection ensures that only Alice can authorize \\nspending the UTXO and transfer it to someone else, such as Bob.\\n\\n* **Value:**\\nThe value in a UTXO represents the balance or asset contained within it. This could be cryptocurrency, tokens, or other digital assets. The value ensures accurate accounting, \\npreventing double spending and maintaining the overall integrity of the system. For instance, if Alice\'s UTXO has a value of 10 tokens, this represents her ownership of that amount \\nwithin the network, and when spent, this value will be deducted from her UTXO and transferred accordingly.\\n\\n* **Private storage slot:**\\nThe private storage slot is an arbitrary and flexible storage space within the UTXO for Nescience applications. It allows users and smart contracts to store additional private data \\nthat is only accessible by the owner. This could be used to hold metadata, smart contract states, or user-specific information. For example, if a smart contract is holding private user data, \\nthis information is securely stored in the private storage slot and can only be accessed or modified by the owner, ensuring privacy and security.\\n\\n* **Non-fungibles:**\\nNon-fungibles within the UTXO represent unique assets, such as NFTs (Non-Fungible Tokens). Each non-fungible asset is assigned a unique serial number or identifier within the UTXO, \\nensuring its distinctiveness and traceability. For example, if Alice owns a digital artwork represented as an NFT, the non-fungible component of the UTXO will store the unique identifier \\nfor this NFT, preventing duplication or forgery of the digital asset.\\n\\n* **Random commitment key:**\\nThe random commitment key (RCK) is a randomly generated number used to create a cryptographic commitment to the contents of the UTXO. This commitment ensures the integrity of the data \\nwithout revealing any private information. By generating a random key for the commitment, the system ensures that even if someone observes the commitment, they cannot infer any details \\nabout the underlying UTXO. For example, RCK helps maintain confidentiality in the system while still allowing the verification of transactions.\\n\\n* **Nullifier key:**\\nThe Nullifier key is another randomly generated number, used to ensure that a UTXO is only spent once. When a UTXO is spent, its nullifier key is recorded in a nullifier set to prevent \\ndouble spending. This key guarantees that once a UTXO is spent, it cannot be reused in another transaction, effectively nullifying it from future use. This mechanism is crucial for \\nmaintaining the security and integrity of the system, as it ensures that no UTXO can be spent more than once.\\n\\n\\n### b) UTXO lifecycle: From generation to consumption\\n---\\nUTXOs in NSSA are created when a transaction outputs a specific value, asset, or data intended for future use. Once generated, these UTXOs become private entities \\nowned by specific users, containing sensitive information such as balances, private data, or unique assets like NFTs.\\n\\nTo maintain the required level of confidentiality, UTXOs are encrypted and transferred anonymously across the network. This encryption process ensures that the data within each UTXO \\nremains hidden from network participants, including the sequencer, while still allowing for verification and validation through ZKPs. These proofs enable the network \\nto ensure that UTXOs are valid, prevent double spending, and maintain security, all without revealing any sensitive information.\\n\\nWhen a user wishes to spend or transfer a UTXO, the lifecycle progresses towards its consumption. The user must prove ownership and validity of the UTXO through a ZKP, \\nwhich is then verified by the sequencer. This process occurs in private, shielded, and deshielded executions, where confidentiality is a priority. Once the proof is validated, \\nthe UTXO is consumed, meaning it is marked as spent and cannot be reused, ensuring the integrity of the transaction and preventing double spending. \\n\\nUTXOs are central to the private, shielded, and deshielded execution types in Nescience. In private executions, UTXOs are transferred securely between parties without revealing any \\ndetails to the public state. In shielded executions, UTXOs are used to receive assets from the public state while keeping the recipient\'s identity confidential. Finally, \\nin deshielded executions, UTXOs are used to send assets from the private state to the public state, while preserving the sender\'s anonymity.\\n\\nSince UTXOs are not exchanged in public executions, this lifecycle analysis is focused solely on private, shielded, and deshielded executions, where privacy and confidentiality are essential. \\nIn these contexts, the careful management and transfer of UTXOs ensure that the users\' private data and assets remain secure, while still allowing for seamless and confidential transactions \\nwithin the network.\\n\\nAt this point, it\'s crucial to introduce two key components that will play a significant role in the next section: the ephemeral key and the nillifier.\\n\\n* **Ephemeral key:** The ephemeral key is embedded in the transaction message and plays a crucial role in maintaining privacy. It is used by the sender, alongside the receiver\'s public key, \\nin a key agreement protocol to derive a shared secret. This shared secret is then employed to encrypt the transaction details, ensuring that only those with the receiver\'s viewing key can \\ndecrypt the transaction. By using the ephemeral key, the receiver can regenerate the shared secret, granting access to the transaction\'s contents. The sender generates the ephemeral key \\nusing their spending key and the UTXO\'s nullifier, reinforcing the security of the transaction. (more details in [key management and addresses section](#key))\\n\\n* **Nullifier:** A nullifier is a unique value tied to a specific UTXO, ensuring that it has not been spent before. Its uniqueness is essential, as a nullifier must never correspond to more \\nthan one UTXO\u2014otherwise, even if both UTXOs are valid, only one could be spent. This would undermine the integrity of the system. To spend a UTXO, a proof must be provided showing that \\nthe nullifier does not already exist in the Nullifier Tree. Once the transaction is confirmed and included in the blockchain, the nullifier is added to the Nullifier Tree, preventing any \\nfuture reuse of the same UTXO. A UTXO\'s nullifier is generated by combining the receiver\'s nullifier key with the transaction note\'s commitment, further ensuring its distinctiveness \\nand security. (More details in [nullifier tree section](#nul).)\\n\\n#### I) UTXOs in private executions\\n---\\nIn private executions within NSSA, transactions are handled ensuring maximum privacy by concealing all transaction details from the public state. \\nThis approach is particularly useful for confidential payments, where the identities of the sender and receiver, as well as the transaction amounts, must remain hidden. \\nThe process is powered by ZKPs, ensuring that only the involved parties have access to the transaction details while maintaining the integrity of the network.\\n\\n* **Stages of private execution**: Private executions operate in two key stages: UTXO consumption and UTXO creation. In the first stage, UTXOs from the private state are used \\nas inputs for the transaction. In the second stage, new UTXOs are generated as outputs and stored back in the private state. Throughout this process, the details of the \\ntransaction are kept confidential and only shared between the sender and receiver.\\n\\n* **Private transaction workflow (transaction initialization)**: The user initiates a private transaction by selecting the input UTXOs that will be spent and determining the \\noutput UTXOs to be created. This involves specifying the amounts to be transferred and the recipient\u2019s private address (a divestified address that hides the recipient\'s public \\naddress from the network). The nullifier key and random number for commitments (RCK) are also generated at this stage to define how these UTXOs can be spent or nullified in the \\nfuture by the receiver.\\n\\n* **Proof generation and verification**: Next, the zkVM generates a ZKP to validate the transaction. This proof includes both a membership proof for the input UTXOs, \\nconfirming their presence in the hashed UTXO tree, and a non-membership proof to ensure that the input UTXOs have not already been spent (i.e., they are not in the nullifier tree). \\nThe proof also confirms that the total input value matches the total output value, ensuring no discrepancies. The user then submits the proof, along with the necessary metadata, to the sequencer.\\n\\n* **Shared secret and encryption**: To maintain confidentiality, the sender uses the receiver\u2019s divestified address to generate an ephemeral public key. \\nThis allows the creation of a shared secret between the sender and receiver. Using a key derivation function, a symmetric encryption key is generated from the shared secret. \\nThe input and output UTXOs are then encrypted using this symmetric key, ensuring that only the intended recipient can decrypt the data.\\n\\n* **Broadcasting the transaction**: The user broadcasts the encrypted UTXOs to the network, along with a commitment to the output UTXOs using Pedersen hashes. \\nThese committed UTXOs are sent to the sequencer, which updates the hashed UTXO tree without knowing the transaction details.\\n\\n* **Decryption by the receiver**: After the broadcast, the receiver attempts to decrypt the broadcast UTXOs using their symmetric key, derived from the ephemeral public key. \\nIf the receiver successfully decrypts a UTXO, it confirms ownership of that UTXO. The receiver then computes the nullifier for the UTXO and verifies its presence in the hashed \\nUTXO tree and its absence from the nullifier tree, ensuring it has not been spent. Finally, the new UTXO is added to the receiver\u2019s locally stored UTXO tree for future transactions.\\n\\nThroughout the private execution process, the identities of both the sender and receiver, as well as all transaction details, remain hidden from the public. \\nThe use of ZKPs ensures that the integrity of the transaction is verified without revealing any sensitive information. At the end of the process, \\nthe network guarantees that no participant, aside from the sender and receiver, can deduce any details about the transaction or the involved parties.\\n\\n#### II) UTXOs in shielded executions\\n---\\nIn shielded executions, the interaction between public and private states provides a hybrid privacy model that balances transparency and confidentiality. \\nThis model is suitable for scenarios where the initial step, such as a public transaction, requires visibility, while subsequent actions, such as private asset management, \\nneed to remain confidential. One common use case is asset conversion\u2014where a public token is converted into a private token. The conversion is visible on the public ledger, \\nbut subsequent transactions remain private.\\n\\n##### a) How shielded executions work\\nShielded executions operate in two distinct stages: first, there is a modification of the public state, and then new UTXOs are created and stored in the private state. \\nImportantly, shielded executions do not consume UTXOs but instead mint them, as new UTXOs are created to reflect the changes in the private state. This structure demands \\nZKPs to ensure that the newly minted UTXOs are consistent with the modifications in the public state. Here\u2019s a step-by-step breakdown of how the shielded \\nexecution process unfolds:\\n\\n1. **Transaction initiation:** The user initiates a transaction that modifies the public state, such as converting a public token to a private token.\\n The transaction alters the public state (e.g., balances or smart contract storage) while simultaneously preparing to mint new UTXOs in the private state.\\n\\n2. **Generating UTXOs:** After modifying the public state, the system mints new UTXOs in the private state. These UTXOs must be securely created, ensuring their integrity \\nand consistency with the initial public state modification. A ZKP is generated by the user to prove that these new UTXOs align with the changes made in the public state.\\n\\n3. **Key setup for privacy**: The sender retrieves the receiver\'s address and uses it to create a shared secret through an ephemeral public key. This shared secret is then used \\nto derive a symmetric key, which encrypts the output UTXOs. This encryption ensures that only the intended receiver can decrypt and access the UTXOs.\\n\\n4. **Broadcasting and verifying UTXOs**: After encrypting the UTXOs, the sender broadcasts them to the network. The new hashed UTXOs are sent to the sequencer, \\nwhich verifies the validity of the UTXOs and attaches them to the hashed UTXO tree within the private state. The public inputs for the ZKP circuits consist of the \\nPedersen-hashed UTXOs and the modifications in the public state.\\n\\n5. **Receiver\'s role**: Once the UTXOs are broadcast, the receiver attempts to decrypt each UTXO using the symmetric key derived from the shared secret. If the decryption is successful, \\nthe UTXO belongs to the receiver. The receiver then verifies the UTXO\u2019s validity by checking its inclusion in the hashed UTXO tree and ensuring that its nullifier has not yet been used.\\n\\n6. **Nullifier check and integration**: To prevent double spending, the receiver computes the nullifier for the received UTXO and verifies that it is not already present in the nullifier tree. \\nOnce verified, the receiver adds the UTXO to their locally stored UTXO tree for future use in private transactions.\\n\\n\\nWhile shielded executions offer privacy, certain information is still exposed to the public state, such as the sender\'s identity. To further enhance privacy, \\nthe sender can create empty UTXOs\u2014UTXOs that don\u2019t belong to anyone but are included in the transaction to obfuscate the true details of the transaction. \\nThough this approach increases the size of the data, it adds a layer of privacy by complicating the identification of meaningful transactions.\\n\\n##### b) Summary of shielded execution flow\\n* **Stage 1 (public modification):** The user modifies public state data, such as converting tokens from public to private. This stage is visible to the public.\\n* **Stage 2 (UTXO minting and privacy):** New UTXOs are minted in the private state, encrypted, and broadcast to the network. The transaction remains private from this point forward, \\nsecured by ZKPs and cryptographic keys.\\n* **Receiver\u2019s role:** The receiver decrypts the UTXOs and verifies their validity, ensuring the UTXOs are not double spent and are ready for future transactions.\\n\\nIn summary, shielded executions enable a hybrid privacy model in Nescience, balancing public transparency and private confidentiality. They are well-suited for \\ntransactions requiring initial public visibility, such as asset conversions, while ensuring that subsequent actions remain secure and private within the network.\\n\\n#### III) UTXOs in deshielded executions\\n---\\nIn NSSA, deshielded executions offer a unique way to move data and assets from the private state to the public state, revealing previously private \\ninformation in a controlled and verifiable manner. This type of execution allows for selective disclosure, ensuring transparency when needed while still maintaining \\nthe security and privacy of critical details through cryptographic techniques like ZKPs. Deshielded executions are particularly valuable for use cases \\nsuch as regulatory compliance reporting, where specific transaction details must be revealed to meet legal requirements, while other sensitive transactions remain private.\\n\\n##### a) Stages of deshielded executions\\n\\n* **Stage 1 (UTXO consumption):** The process begins in the private state, where UTXOs are consumed as inputs for the transaction. This involves gathering all necessary \\nUTXOs that contain the assets or balances to be made public, as well as any associated private data stored in memory slots.\\n\\n* **Stage 2 (public state modification):** After the UTXOs are consumed, the transaction details are made public by modifying the public state. This update includes changes \\nto the public balances, storage data, and any necessary public records. While the public state is updated, the sender\u2019s identity and other sensitive information remain hidden, \\nthanks to the privacy-preserving properties of ZKPs.\\n\\nThis model ensures that private data can be selectively revealed when needed, offering both flexibility and transparency. It is particularly useful for scenarios requiring \\nauditing or compliance reporting, where specific details must be made publicly verifiable without exposing the entire history or contents of private transactions.\\n\\n##### b) How deshielded executions work\\nThe deshielded execution process starts when a user initiates a transaction using private UTXOs. The Nescience zkVM is called to generate a ZKP, \\nwhich validates the transaction without revealing sensitive details such as the sender\'s identity or the specifics of the Nescience application being executed.\\n\\nDuring the transaction, the UTXOs from the private state are consumed, meaning they are used up as inputs and will no longer be available for future transactions. \\nInstead of generating new UTXOs, the transaction modifies the public state, updating the necessary balances or memory slots related to the transaction. \\nHere\u2019s a step-by-step breakdown of how the deshielded execution process unfolds:\\n\\n1. **Get receiver\'s public address:** The sender first identifies the public address of the receiver, to which the information or assets will be made public.\\n\\n2. **Determine input UTXOs and public state modifications:** The sender gathers all the input UTXOs needed for the transaction and determines the public state modifications \\nnecessary for the Nescience applications and token transfers involved.\\n\\n3. **Calculate nullifiers:** Nullifiers are generated for each input UTXO, ensuring that these UTXOs cannot be reused or double spent. The nullifiers are derived from the\\n corresponding UTXO commitments.\\n\\n4. **Call zkVM with deshielded circuits:** The sender invokes the zkVM with deshielded kernel circuits, which generates the proof. The proof ensures that all input UTXOs \\nare valid by verifying their membership in the UTXO tree and their non-membership in the nullifier tree, ensuring they haven\u2019t been spent.\\n\\n5. **Generate and submit proof:** The zkVM generates a ZKP that verifies the correctness of the transaction without revealing private details. \\nThe proof includes the nullifiers and the planned modifications to the public state.\\n\\n6. **Send proof to sequencer:** The sender then sends the proof and any relevant public information to the sequencer. The sequencer is responsible for verifying the proof, \\nupdating the public state accordingly, and adding the nullifiers to the nullifier tree.\\n\\nOnce the proof and public information have been broadcast to the network, the receiver does not need to take any further action. \\nThe sequencer manages the public state updates and ensures that the transaction is properly executed. By the end of the deshielded execution, \\nspecific transaction details become publicly visible, such as the identity of the receiver and the outcome of the transaction. \\nThis allows participants in the public state to extract information about the transaction, including the receiver\'s identity and some details about the execution. \\nWhile the receiver\'s identity is revealed, the sender\'s identity and sensitive transaction details remain hidden, thanks to the use of ZKPs. \\nThis makes deshielded executions ideal for cases where transparency is needed, but complete privacy is still a priority for certain elements of the transaction.\\n\\n### Summary of UTXO consumption in NSSA\\n---\\nIn NSSA, consuming UTXOs is a critical step in maintaining the security and integrity of the blockchain by preventing double spending. \\nWhen a UTXO is consumed, it is used as an input in a transaction, effectively marking it as spent. This ensures that the UTXO cannot be reused, preserving the integrity of the blockchain.\\n\\n1. **The process of consuming UTXOs:** The process of consuming a UTXO begins when a user selects a UTXO from their private state. The user verifies the UTXO\u2019s existence and \\nownership using their viewing key, ensuring that they are the legitimate owner of the UTXO. Once verified, the user generates two key cryptographic proofs:\\n * **Membership proof:** This proof confirms that the UTXO exists within the hashed UTXO tree, ensuring its validity within the system.\\n * **Non-membership proof:** This proof ensures that the UTXO has not been previously consumed by checking its absence in the nullifier tree, which tracks spent UTXOs.\\n\\nTo mark the UTXO as spent, a **nullifier** is generated. This nullifier is a unique cryptographic hash derived from the UTXO, which is then added to the nullifier tree in the public state. \\nAdding the nullifier to the tree prevents the UTXO from being reused in future transactions, thus preventing double spending.\\n\\nAfter generating the membership and non-membership proofs, the user compiles the transaction using the zkVM. The zkVM is responsible for generating the necessary ZKPs,\\n which validate the transaction without revealing sensitive details. The compiled transaction, along with the proofs, is then submitted to the sequencer for verification.\\n\\n2. **The role of the sequencer:** Once the transaction is submitted, the sequencer verifies the ZKPs to confirm that the transaction is valid. If the proofs are verified \\nsuccessfully, the sequencer updates both the private and public states to reflect the transaction. This includes updating the nullifier tree with the newly generated nullifier, \\nensuring that the UTXO is marked as spent and cannot be reused.\\n\\n#### Example: Alice sending tokens to Bob\\n---\\nConsider an example where Alice wants to send 5 Nescience tokens to Bob using a private execution. Alice selects a UTXO from her private state that contains 5 Nescience tokens. \\nShe generates the necessary membership and non-membership proofs, ensuring that her UTXO exists in the system and has not been previously spent. Alice then creates a nullifier by \\nhashing the UTXO and compiles the transaction with the zkVM.\\n\\nOnce Alice submits the transaction, the sequencer verifies the proofs and updates the blockchain by adding the nullifier to the nullifier tree and recording the transaction details. \\nThis ensures that Alice\u2019s UTXO is marked as spent and cannot be used again, while Bob receives the 5 tokens.\\n\\n#### The importance of nullifiers\\n---\\nNullifiers are a key mechanism in preventing double spending. By marking consumed UTXOs as spent and tracking them in the nullifier tree, NSSA ensures that \\nonce a UTXO is used in a transaction, it cannot be reused in any future transactions. This process is fundamental to maintaining the integrity and security of the blockchain, \\nas it guarantees that assets are only spent once and prevents potential attacks on the system.\\n\\nIn conclusion, the process of consuming UTXOs in NSSA combines cryptographic proofs, nullifiers, and ZKPs to ensure that transactions \\nare secure, confidential, and free from the risks of double spending.\\n\\n\\n# C. Cryptographic primitives in NSSA\\n\\nIn the NSSA, cryptographic primitives are the foundational elements that ensure the security, privacy, and efficiency of the state separation model.\\n These cryptographic tools enable private transactions, secure data management, and robust verification processes across both public and private states. \\n The architecture leverages a wide range of cryptographic mechanisms, including advanced hash functions, key management systems, tree structures, and ZKPs, \\n to safeguard user data and maintain the integrity of transactions.\\n\\nCryptographic hash functions play a pivotal role in concealing UTXO details, generating nullifiers, and constructing sparse Merkle trees, which organize and verify \\ndata efficiently within the network. Key management and address generation further enhance the security of user assets and identity, ensuring that only authorized \\nusers can access and control their holdings.\\n\\nThe architecture also relies on specialized tree structures for organizing data, verifying the existence of UTXOs, and tracking nullifiers, which prevent double spending. \\nAdditionally, Nescience features a privacy-preserving zero-knowledge virtual machine (zk-zkVM), which allows users to prove the correctness of an execution without \\ndisclosing sensitive information. This enables private transactions and maintains confidentiality across the network.\\n\\nAs Nescience evolves, optional cryptographic mechanisms such as multi-party computation (MPC) may be integrated to enhance synchronization across privacy levels. \\nThis MPC-based synchronization mechanism is still under development and under review for potential inclusion in the system. Together, these cryptographic primitives \\nform the backbone of Nescience\u2019s security architecture, ensuring that users can transact and interact privately, securely, and efficiently.\\n\\nIn the following sections, we will explore each of these cryptographic components in detail, beginning with the role of hash functions.\\n\\n## a) Hash functions in Nescience\\n---\\nHash functions are a foundational element of Nescience\u2019s cryptographic framework, serving multiple critical roles that ensure the security, privacy, and efficiency of the system. \\nOne of the primary uses of hash functions in Nescience is to conceal sensitive details of UTXOs by converting them into fixed-size hashes. This process allows UTXO details \\nto remain private, ensuring that sensitive information is not directly exposed on the blockchain, while still enabling their existence and integrity to be verified. Hashing \\nthe UTXO details allows the actual data to remain confidential, with the hashes stored in a global tree structure for efficient management and retrieval.\\n\\nAdditionally, hash functions are essential for generating **nullifiers**, which play a crucial role in preventing double spending. Nullifiers are created by hashing UTXOs \\nand are used to mark them as spent, ensuring that they cannot be reused in subsequent transactions. These nullifiers are stored in a nullifier tree, and each transaction \\nmust prove that its UTXO\u2019s nullifier is not already present in the tree before it can be processed. This ensures that the UTXO has not been spent before, maintaining the \\nintegrity of the transaction process.\\n\\nHash functions are also vital in the construction of **sparse Merkle trees**, which provide an efficient and secure method for verifying data within the blockchain. \\nSparse Merkle trees enable quick and reliable proofs of membership and non-membership, making them essential for verifying both UTXOs and nullifiers. By using hash functions \\nto build these trees, Nescience can ensure the integrity of the data, as any tampering with the data would result in a change in the hash, making the manipulation detectable.\\n\\nAnother critical consideration in Nescience is the compatibility of hash functions with **ZKPs**. ZK-friendly hash functions are optimized for efficient \\ncomputation within the constraints of ZK circuits, ensuring that they do not become a bottleneck in the proof generation or verification process. These hash functions \\nmaintain strong cryptographic security properties while enabling efficient computations in ZKP systems, which is essential for maintaining privacy and \\nintegrity within the ZK framework.\\n\\nThe primary advantage of using hash functions in Nescience is their ability to ensure that transaction details remain private while still allowing for verification \\nof their validity. Furthermore, by integrating hash functions into Merkle trees, the blockchain data becomes tamper-proof, enabling quick and efficient verification \\nprocesses that uphold the system\u2019s security and privacy standards.\\n\\n### Use case: How to use the Pedersen hash to create the UTXO commitment\\n---\\nAs mentioned in the [UTXOs in private exections section](#pe), the user broadcasts the encrypted UTXOs to the network, along with a commitment to the output UTXOs \\nusing **Pedersen hashes**. The Pedersen hash is used to create the UTXO commitment. The Pedersen hash is a homomorphic commitment scheme that allows secure commitments\\nwhile maintaining privacy and enabling proofs of correctness in transactions. The commitment formula is as follows:\\n\\n$$Commitment = C(UTXO,RCK) =g^{UTXO}\u22c5h^{RCK}$$\\n\\n\\nIn this formula, $g$ and $h$ are two generators of a cryptographic group where no known relationship exists between them. This ensures that the commitment is secure \\nand computationally infeasible to reverse or manipulate without knowing the original UTXO components. The random number $RCK$ adds an additional layer of security \\nby blinding the UTXO\'s contents, ensuring that the commitment doesn\'t leak any information about the underlying data.\\n\\n**Importance of homomorphic commitments**\\n\\nIt is essential to use a homomorphic commitment like the Pedersen commitment for UTXOs because it allows for the verification of important properties in transactions, \\nsuch as ensuring that the total input value of a transaction equals the total output value. This balance is crucial for preventing the unauthorized creation of funds or d\\ndiscrepancies in transactions. A homomorphic commitment enables these proofs because of its additive properties. Specifically, the exponents in the commitment formula are additive, \\nmeaning that commitments can be combined and verified without revealing the individual components. For instance, if you have two UTXOs with commitments $C(UTXO_1,RCK_1)$ \\nand $C(UTXO_2,RCK_2)$, you can combine them and verify that the resulting commitment is valid without exposing the actual amounts.\\n\\nThis capability is leveraged through a modified version of the Schnorr protocol, which is used in conjunction with the Pedersen hash to verify the correctness of transactions. \\nThe Schnorr protocol allows users to prove, without revealing the actual values, that the sum of inputs equals the sum of outputs, ensuring that no funds are created or lost in the transaction.\\n\\n**Limitations of standard cryptographic hashes**\\n\\nStandard cryptographic hash functions, such as SHA-256, are not suitable for this purpose because they lack the algebraic structure needed for homomorphic properties. \\nIn particular, while SHA-256 provides strong security for general hashing purposes, it does not allow the additive properties that are required to perform the type of \\nZKPs used in Nescience for UTXO commitments. This is why the Pedersen hash is preferred, as it enables the secure and private execution of transactions\\nwhile allowing for balance verification and other critical proofs.\\n\\n**Conclusion**\\n\\nBy using homomorphic commitments like the Pedersen hash, NSSA ensures that UTXOs can be securely committed and validated without exposing sensitive information. \\nThe random component (RCK) adds an additional layer of security, and the additive properties of the Pedersen commitment enable powerful ZKPs that maintain the \\nintegrity of the system.\\n\\n\\n## b) Key management and addresses in Nescience\\n---\\nNSSA utilizes different cryptographic schemes, such as public key encryption and digital signatures, to ensure secure private executions through \\nthe exchange of UTXOs. These schemes rely on a structured set of cryptographic keys, each serving a specific purpose in maintaining privacy, security, and control over assets. \\nHere\'s a breakdown of the keys used in Nescience:\\n\\n### I. Spending key\\nThe spending key is the fundamental secret key in NSSA, acting as the primary control mechanism for a user\u2019s UTXOs and other digital assets. \\nIt plays a critical role in the cryptographic security of the system, ensuring that only the rightful owner can authorize and spend their assets.\\n\\n- **Role of the spending key**: The spending key is responsible for generating the user\u2019s private keys, which are used in various cryptographic operations such as \\nsigning transactions and creating commitments. This hierarchical relationship means that the spending key sits at the root of a user\u2019s key structure, safeguarding \\naccess to all associated private keys and, consequently, to the user\u2019s assets. In Nescience\u2019s privacy-focused model, the spending key is never exposed or shared outside \\nthe user\u2019s control. Unlike other keys, it does not interact with the public state, kernel circuits, or even the ZKP system. This isolation ensures that \\nthe spending key remains completely private and inaccessible to external entities. By keeping the spending key separate from the operational aspects of the network, \\nNescience minimizes the risk of key leakage or compromise.\\n\\n- **Generation and security of the spending key**: The spending key is generated randomly from the scalar field, a large mathematical space that ensures uniqueness \\nand cryptographic strength. This randomness is crucial because it prevents attackers from predicting or replicating the key, thereby safeguarding the user\u2019s assets \\nfrom unauthorized access: it is computationally infeasible for an attacker to guess or brute-force the key. Once the spending key is generated, it is securely stored \\nby the user, typically in a hardware wallet or another secure storage mechanism that prevents unauthorized access.\\n\\n- **Spending UTXOs with the spending key**: The spending key\u2019s primary function is to authorize the spending of UTXOs in private transactions. When a user initiates \\na transaction, the spending key is used to generate the necessary cryptographic proofs and signatures, ensuring that the transaction is valid and originates from \\nthe rightful owner. However, even though the spending key generates these proofs, it is never directly exposed during the transaction process. Instead, derived \\nprivate keys handle the operational aspects while the spending key remains secure in the background. For example, when Alice decides to spend a UTXO in a \\nprivate execution, her spending key generates the required private keys that will sign the transaction and ensure its validity. However, the spending key itself \\nnever appears in any public state or transaction data, preserving its confidentiality.\\n\\n- **Ensuring security through isolation**: One of the key security principles of the spending key is its isolation from the network. Since it never interacts with \\npublic-facing elements, such as the public state or kernel circuits, the risk of exposure is significantly reduced. This isolation ensures that even if other parts \\nof the cryptographic infrastructure are compromised, the spending key remains protected, preventing unauthorized spending of UTXOs.\\n\\nIn summary, the spending key in Nescience is a powerful and carefully guarded element of the cryptographic system. It is the root key from which other private keys\\nare derived, allowing users to spend their UTXOs securely and privately. Its isolation from the public state and its random generation from a secure scalar field ensures \\nthat the spending key remains protected, making it a cornerstone of security in NSSA.\\n\\n### II. Private keys\\nIn Nescience, the private key is an essential cryptographic element responsible for facilitating various secure operations, such as generating commitments and signing \\ntransactions. While the spending key plays a foundational role in safeguarding access to UTXOs and assets, the private keys handle the operational aspects of transactions \\nand cryptographic proofs. The private key consists of three critical components: ${private}_{key}.rsd$, ${private}_{key}.rcm$, and ${private}_{key}.sig$, each serving a \\ndistinct purpose within the Nescience cryptographic framework.\\n\\n1. **${private}_{key}.rsd$ (random seed)**: The random seed (${private}_{key}.rsd$) is the first and foundational component of the private key. It is a value randomly chosen from the scalar field, which ensures \\nits cryptographic security and unpredictability. This seed is generated using a random number generator, making it virtually impossible to predict or replicate. \\nThe random seed is essential because it is used to derive the other two components of the private key. By leveraging a secure random seed, Nescience ensures that \\nthe entire private key structure is rooted in randomness, preventing external entities from guessing or deriving the key through brute-force attacks. \\nThe strength of the random seed ensures the overall security of the private key and, consequently, the integrity of the user\'s transactions and commitments.\\n\\n2. **${private}_{key}.rcm$ (random commitment)**: The random commitment component (${private}_{key}.rcm$) is a crucial part of the private key used specifically in the commitment scheme. It acts as a blinding factor, \\nadding a layer of security to commitments made by the user. The ${private}_{key}.rcm$ value is also drawn from the scalar field and is used to ensure that the commitment \\nto any UTXO or other sensitive data remains confidential. The commitment scheme in Nescience requires the use of ${private}_{key}.rcm$ to create cryptographic commitments \\nthat bind the user to specific data (such as UTXO details) without revealing the actual data. The role of ${private}_{key}.rcm$ is to ensure that these commitments are \\nnon-malleable and secure, preventing anyone from modifying the committed data without detection. For instance, when Alice commits to a UTXO, ${private}_{key}.rcm$ is used \\nto generate a Pedersen commitment that ensures the UTXO details are hidden but can still be verified cryptographically. This means that even though the actual UTXO details \\nare concealed, their existence and integrity can be proven.\\n\\n3. **${private}_{key}.sig$ (signing key for transactions)**: The signing key (${private}_{key}.sig$) is the third and final component of the private key, used primarily for signing transactions. One possible approach is that \\nNescience employs Schnorr signatures, a cryptographic protocol known for its efficiency and security. In this case, the ${private}_{key}.sig$ component would generate \\nSchnorr signatures that are used to authenticate transactions, ensuring that only the rightful owner of the private key can authorize the spending of UTXOs. Schnorr \\nsignatures are important as they provide a secure and non-repudiable method of verifying that a transaction was initiated by the legitimate owner of the assets. \\nWhen Alice signs a transaction using her ${private}_{key}.sig$, the corresponding public key allows others to verify that the transaction was indeed signed by Alice, \\nwithout revealing her private key. This verification process ensures that all transactions are legitimate and prevents unauthorized entities from forging transactions \\nor spending assets they do not control. Even if an attacker gains access to the signed transaction, they cannot reverse engineer the ${private}_{key}.sig$, ensuring \\nthe security of Alice\'s future transactions.\\n\\n**Robustness of private keys in Nescience**\\n\\nDespite the critical role of the private key in the operation of NSSA, the system is designed to maintain security even in the event that the \\nprivate key is compromised. This resilience is achieved through the integrity of the spending key, which is never exposed in the process of signing or committing. \\nThe spending key acts as the ultimate safeguard, ensuring that even if a private key component is compromised, the attacker cannot access or spend the user\'s assets \\nwithout control over the spending key.\\n\\nThe architecture\u2019s design, where private keys handle operational tasks but rely on the spending key for ultimate control, ensures a layered approach to security. \\nThis way, the system can mitigate the damage of a compromised private key by maintaining the inviolability of the user\'s assets.\\n\\n**Conclusion**\\n\\nIn summary, the private key in Nescience consists of three interrelated components that together ensure secure transaction signing, commitment creation, and the \\nprotection of user data. The ${private}_{key}.rsd$ serves as the root from which the other key components are derived, ensuring randomness and security. \\nThe ${private}_{key}.rcm$ plays a crucial role in generating commitments, while ${private}_{key}.sig$ provides the signing capability needed for transaction authentication. \\nTogether, these components enable users to engage in private, secure transactions while preserving the integrity of their assets, even in the face of potential key compromise.\\n\\n### III. Public keys\\nPublic keys in Nescience serve as the user\'s interface with the network, allowing for secure interaction and verification without exposing the user\'s private keys. \\nDerived directly from the user\'s private keys, public keys play a crucial role in enabling cryptographic operations such as transaction verification, commitment schemes, \\nand deterministic computations. The public key components correspond to their private key counterparts and ensure that transactions and commitments are securely processed \\nand validated across the network.\\n\\n1. **${public}_{key}.sig$ (verifying Schnorr signatures)**:\\n\\nThe ${public}_{key}.sig$ is derived from the signing component of the private key (${private}_{key}.sig$) and is used for verifying **Schnorr signatures**. \\nSchnorr signatures are used to authenticate transactions, ensuring that they have been signed by the legitimate owner of the private key. This public key is \\nessentially a verification key, allowing others in the network to confirm that a specific transaction was indeed authorized by the user. When a transaction is \\nbroadcast to the network, ${public}_{key}.sig$ enables any participant to verify that the transaction\u2019s signature matches the user\u2019s private key without \\nneeding access to the private key itself. This mechanism prevents forgeries as only the legitimate owner with access to the private key can generate a valid Schnorr signature.\\nFor example, if Alice sends a transaction, she signs it with her private key (${private}_{key}.sig$). Bob, or any other network participant, can use Alice\u2019s ${public}_{key}.sig$ \\nto verify the signature. If the signature is valid, Bob can be confident that the transaction was authorized by Alice and not by an imposter.\\n\\n2. **${public}_{key}.rcm$ (commitment schemes)**\\n\\nThe ${public}_{key}.rcm$ is derived from the commitment component of the private key (${private}_{key}.rcm$). It is used in the **commitment schemes** \\nthat underpin Nescience\u2019s privacy-preserving architecture. Commitments are a crucial cryptographic technique that allows users to commit to a piece of data (such as a UTXO)\\n without revealing the actual data, while still enabling proof of its integrity and existence. In Nescience, the ${public}_{key}.rcm$ is used as part of the Pedersen commitment scheme, \\n where it functions as a public commitment to certain transaction details. Even though the actual values are hidden (thanks to the private key component), the commitment can \\n still be verified by other network participants using ${public}_{key}.rcm$. This enables secure and private transactions while maintaining the ability to verify that commitments \\n are consistent with the original data. For instance, when Alice commits to a UTXO, she uses her private key to generate the commitment, and the ${public}_{key}.rcm$ is available \\n to others to verify the commitment\u2019s validity without revealing the underlying details.\\n\\n3. **${public}_{key}.sk(prf)$ (pseudorandom function)**\\n\\nThe ${public}_{key}.sk(prf)$ is derived from a random field element within the private key and is used to generate the **pseudorandom function (PRF)** associated with the user\'s account. \\nThis PRF is essential for producing deterministic outputs based on the user\u2019s keys and transaction data while ensuring that these outputs are unique to the user and cannot be \\npredicted or replicated by others. The PRF is crucial in scenarios where the user needs to derive unique identifiers or values that are tied to their specific account, \\nensuring that these values remain consistent across different transactions or interactions without revealing sensitive information. For example, ${public}_{key}.sk(prf)$ may be \\nused in generating deterministic yet secure addresses or transaction references, which can be linked to the user\u2019s activity in a controlled manner. By using ${public}_{key}.sk(prf)$, \\nNescience ensures that certain operations, like generating addresses or computing deterministic transaction outcomes, remain both private and cryptographically secure. The public key\u2019s \\nrole in this process is to maintain consistency in these outputs while preventing unauthorized parties from reverse engineering the associated private keys or transaction data.\\n\\n**Summary**\\n\\nPublic keys in Nescience are essential for secure interactions within the network. \\"${public}_{key}.sig$\\" allows others to verify that transactions were signed by the legitimate owner, \\nensuring the authenticity of every operation. \\"${public}_{key}.rcm$\\" enables secure and private commitment schemes, allowing participants to commit to transaction details without \\nrevealing sensitive information. Finally, \\"${public}_{key}.sk(prf)$\\" powers deterministic outputs through a pseudorandom function, ensuring that user-specific data remains consistent \\nand secure throughout various transactions. Together, these public key components facilitate privacy, security, and trust within NSSA, enabling seamless interactions while safeguarding user data.\\n\\n### IV. Viewing key\\nThe **viewing key** in NSSA is a specialized cryptographic key that allows a user to decrypt both incoming and outgoing transactions associated with their account. \\nThis key is designed to offer a degree of transparency to the user, enabling them to view the details of their transactions without compromising the security of their assets or granting \\ncontrol over those assets.\\n\\n- **Role of the viewing key**: The primary function of the viewing key is to provide visibility into transaction details while maintaining the integrity of private, shielded, \\nor deshielded transactions. It enables the user to see the specifics of the transactions they are involved in\u2014such as amounts transferred, asset types, and metadata\u2014without \\nexposing the sensitive transaction data to the broader network. For instance, if Alice has executed a private transaction with Bob, her viewing key allows her to decrypt and \\nreview the details of the transaction, ensuring that everything was processed correctly. This ability to audit her own transactions helps Alice maintain confidence in the integrity \\nof her private interactions on the blockchain.\\n\\n- **Security considerations**: Despite its utility, the viewing key must be handled with care as its exposure could potentially compromise the user\u2019s privacy. \\nAlthough possessing the viewing key does **not** provide the ability to spend or sign transactions (that authority remains strictly with the spending key and private keys), \\nit does allow anyone with access to the viewing key to decrypt the details of the user\u2019s private transactions. This means that if the viewing key is leaked or stolen, \\nthe privacy guarantees of Nescience\u2019s private, shielded, and deshielded executions could be undermined. Specifically, the viewing key could be used to link various transactions, \\nbreaking the unlinkability of private transactions. For example, an attacker with access to the viewing key could decrypt past and future transactions, exposing the relationships \\nbetween different parties and transaction flows. To mitigate this risk, Nescience recommends that users treat their viewing key with the same level of protection as their private keys. \\nIt should be stored securely in encrypted hardware wallets or other secure storage solutions to prevent unauthorized access. \\n\\n- **Balancing privacy and transparency**: The viewing key provides an essential balance between privacy and transparency in NSSA. While it ensures that users \\ncan monitor their transaction history and verify the details of their private transactions, it does so without compromising the control of their funds. This allows users to maintain \\na transparent view of their interactions while keeping their assets secure. For example, if Alice is using shielded execution to transfer assets, her viewing key enables her to \\naudit the transaction without allowing anyone else, including Bob or external observers, to see the specific details unless they also have access to the viewing key. Moreover, \\nsince the viewing key does not grant signing or spending authority, even if it were exposed, an attacker would still not be able to manipulate the user\u2019s assets. However, \\nto maintain the unlinkability and confidentiality of private transactions, the viewing key must be kept secure at all times.\\n\\n- **Protecting transaction unlinkability**: In private transactions, unlinkability is one of the core privacy guarantees. This property ensures that individual \\ntransactions cannot be correlated with each other or linked to the same user unless that user chooses to reveal the connection. The viewing key must be carefully \\nprotected to preserve this unlinkability, as its compromise could allow someone to map out a user\u2019s private transaction history. For instance, in deshielded transactions, \\nthe viewing key allows the user to see which private UTXOs were consumed and how the public state was modified. If the viewing key is compromised, an attacker could potentially \\nlink private UTXOs across multiple transactions, unraveling the user\u2019s privacy.\\n\\n**Conclusion**\\n\\nThe viewing key in Nescience is a powerful tool for providing insight into both incoming and outgoing transactions without granting control over assets. It allows users \\nto decrypt and verify their transaction details, maintaining transparency in their interactions. However, due to its potential to compromise privacy if exposed, the viewing \\nkey must be handled with great care. Proper security measures are necessary to protect the viewing key, ensuring that the unlinkability of private, shielded, and deshielded \\ntransactions remains intact. In this way, the viewing key offers a crucial balance between privacy and transparency within the Nescience ecosystem.\\n\\n### V. Ephemeral key\\nThe ephemeral key is generated using a combination of the sender\u2019s spending key and the UTXO\'s nullifier, ensuring that the key is unique to each transaction. \\nThe process can be informally described as follows:\\n\\n1. **Ephemeral key generation** \\n Let $\\\\rho$ denote the nullifier of the UTXO being consumed in the transaction. The sender uses the receiver\u2019s public key component ${public}_{key}.sk(prf)$, \\n which is derived from the receiver\u2019s private key, to compute an **ephemeral secret key ($esk$)**. The computation is based on the nullifier $\\\\rho$ and a base value:\\n \\n $$esk = {public}_{key}.sk(prf((0,0,0,0) || \\\\rho)$$\\n This formula binds the secret key to the specific transaction, leveraging the receiver\u2019s cryptographic identity and the unique properties of the UTXO being spent.\\n\\n2. **Deriving the ephemeral public key** \\n After computing the ephemeral secret key ($esk$), the next step is to derive the corresponding **ephemeral public key (epk)**. This is done using the Key Agreement \\n Protocol\'s **DerivePublic algorithm**, which generates the public key associated with the shared secret key. The ephemeral public key is computed as:\\n \\n $$epk = KA.DerivePublic(esk, gd)$$\\n \\nHere, ($gd$) is the **diversifier address** associated with the receiver\u2019s account. The diversifier address is computed from the receiver\u2019s \\naccount using the **DiversifierHash** function:\\n \\n $$gd = receiver.DiversifierHash(d)$$\\n\\nThe diversifier ($d$) is a random value selected by the sender to add randomness to the process. This diversifier ensures that even if a single receiver is involved \\nin multiple transactions, the derived keys remain distinct for each transaction. The value ($d$) is included in the transaction note for transparency and reproducibility.\\n\\n3. **Establishing the shared secret** \\nThe shared secret, used to encrypt the transaction details, is derived from the key agreement between the sender\u2019s ephemeral key and the receiver\u2019s viewing key. \\nAny party possessing the receiver\u2019s viewing key can use it in conjunction with the ephemeral key to compute the shared secret, which is then used to decrypt the transaction. \\nThis ensures that only the intended recipient (or anyone with their viewing key) can access the transaction details.\\n\\n**Key components and protocol**\\n\\nThe formal protocol for generating ephemeral keys closely follows this informal description but involves additional intermediate steps for converting values to \\nbinary sequences to fit implementation requirements. These steps are essential for ensuring compatibility with cryptographic algorithms used in NSSA. \\nThe protocol uses the following key components:\\n- **Nullifier ($\\\\rho$):** Ensures that the ephemeral key is tied to the specific UTXO being consumed, preventing reuse of the key in future transactions.\\n- **Receiver\u2019s public key (${public}_{key}.sk(prf)$:** Establishes the receiver\'s identity in the key generation process, ensuring that the shared secret can \\nonly be derived by the intended party.\\n- **Diversifier ($d$):** Adds randomness to the transaction, ensuring that keys remain unique across different transactions involving the same receiver.\\n\\nThe end result is an ephemeral key system that provides strong cryptographic guarantees for transaction privacy, leveraging key agreement protocols and secure \\ncryptographic primitives to prevent unauthorized access to sensitive transaction data.\\n\\n**Conclusion**\\n\\nThe ephemeral key in Nescience is a critical element for maintaining transaction confidentiality. It facilitates a secure key agreement between the sender and the receiver, \\nallowing for the encryption of transaction details with a shared secret that can only be derived by the intended recipient. By incorporating the nullifier, receiver\'s public key, \\nand diversifier address, the ephemeral key ensures that transaction privacy is preserved while preventing unauthorized access to transaction information, even in a complex, \\nmulti-party blockchain environment.\\n\\n### VI. Nescience addresses\\nNescience\u2019s dual address system is a core component of its privacy-focused architecture, designed to balance transparency and confidentiality across different types of transactions. \\nThe architecture provides each user or smart contract with both public addresses and private addresses, allowing them to participate in both open and confidential activities on the blockchain.\\n\\n#### a) Public addresses\\nPublic addresses in Nescience are visible to all participants on the network and reside within the public state. These addresses are essential for engaging in \\ntransparent and verifiable interactions, such as sending tokens or invoking smart contracts that are meant to be publicly auditable. Public addresses serve as \\nthe interface for users who need to engage with the transparent elements of the system, including public transactions or smart contracts that require public access.\\n\\nThey are analogous to traditional blockchain addresses seen in systems like Ethereum or Bitcoin, where every participant can see the address and the transactions associated with it. \\nFor example, when Alice wants to receive tokens from Bob in a public transaction, she can provide her public address, allowing Bob to send the tokens transparently. \\nAnyone on the network can verify the transaction, providing accountability and trust in the public state.\\n\\nBecause public addresses are visible and auditable, they are typically used for interactions where privacy is not a concern or where transparency is desirable. \\nThis could include simple token transfers, public contract calls, or interactions with dapps that require public accountability, \\nsuch as voting or governance systems.\\n\\n#### b) Private addresses\\nIn contrast, private addresses are designed for confidentiality and are not visible onchain. These addresses are used exclusively for private transactions and executions, \\nensuring that sensitive details\u2014such as the sender, receiver, or amount transferred\u2014remain hidden from the public state. Private addresses are a key feature of \\nNescience\u2019s private, shielded, and deshielded execution models, where preserving the confidentiality of participants is crucial.\\n\\nUsers can generate an unlimited number of private addresses using their private keys. This flexibility allows users to compartmentalize their interactions, \\ngiving them the ability to provide different private addresses to different parties. For instance, Alice could create a unique private address for each entity \\nshe interacts with, thereby ensuring that her transactions remain isolated and difficult to trace. This feature enhances privacy by preventing any direct linkage \\nbetween different transactions or activities associated with a single user.\\n\\nPrivate addresses are not tied to the public state and are only accessible through the user\u2019s private key infrastructure. Transactions involving private addresses \\nare conducted within the confines of the private state and are only decrypted by the intended participants. For example, when Alice sends tokens to Bob using \\na private address, the details of that transaction remain confidential, accessible only to Alice and Bob, unless they choose to reveal it.\\n\\n**Role of the viewing key in private addresses**: A key feature of Nescience\u2019s private address system is the viewing key, which allows users to decrypt any transaction \\ninvolving their private addresses. This capability provides oversight and transparency into the user\u2019s private transactions, ensuring that they can monitor their own \\nactivity without exposing the details to the public. The viewing key does not compromise the security of the user\'s assets as it does not grant spending or signing authority. \\nHowever, it does allow the user to audit and verify the accuracy of their private transactions, ensuring that everything proceeds as expected. For instance, Alice can use her \\nviewing key to review the details of a private transaction she conducted with Bob, ensuring that the correct amount was transferred and that the transaction was properly processed. \\nThis functionality is critical for users who want to maintain control over their private interactions while still benefiting from transparency into their transaction history. \\nThe ability to generate multiple private addresses and decrypt them with the viewing key ensures that users can maintain compartmentalized privacy without sacrificing oversight.\\n\\n**Summary**\\n\\nNescience\u2019s dual address system\u2014comprising public and private addresses\u2014provides users with the flexibility to engage in both transparent and confidential transactions. \\nPublic addresses are visible onchain and are used for open, public interactions that require accountability and auditability. In contrast, private addresses are \\ninvisible onchain and are used for confidential transactions, enhancing privacy and security.\\n\\nBy allowing users to generate multiple private addresses, Nescience gives individuals control over the visibility of their transactions. Combined with the viewing \\nkey\u2019s ability to decrypt transactions involving private addresses, the system ensures that users can maintain transparency over their private transactions without \\nexposing sensitive information to the public state. This dual-address approach enables users to seamlessly switch between public and private interactions depending on their needs, \\nproviding a robust framework for both privacy and transparency in NSSA.\\n\\n### VII. Conclusion\\nKey management in NSSA is a carefully designed system that strikes an optimal balance between security, privacy, and flexibility. \\nThe architecture\u2019s hierarchical structure, with distinct roles for the spending key, private keys, and public keys, ensures that users retain full control \\nover their assets while maintaining the integrity of their transactions. The spending key, as the root of security, provides unassailable control over the \\nuser\'s UTXOs and assets, ensuring that only the rightful owner can authorize spending. Private keys, derived from the spending key, enable users to engage \\nin cryptographic operations such as signing transactions and generating commitments without exposing sensitive information to the network.\\n\\nThe viewing key adds another layer of transparency, allowing users to decrypt and review their transactions without compromising their authority over their assets. \\nWhile it provides a window into transaction history, the viewing key does not grant spending power, preserving the critical separation between visibility and control.\\n\\nThe dual system of public and private addresses gives users the flexibility to navigate between open, transparent transactions and confidential, privacy-protected activities. \\nPublic addresses allow users to engage in verifiable, public interactions while private addresses enable compartmentalized, secure transactions that remain hidden \\nfrom the public eye. This dual-address framework ensures that users can seamlessly adapt to different privacy requirements, whether they are participating in public \\ndapps or conducting sensitive financial operations.\\n\\nOverall, Nescience\u2019s cryptographic infrastructure is designed to empower users to engage confidently in both transparent and confidential activities. \\nBy providing flexible, secure key management and address systems, Nescience ensures that users can fully participate in the blockchain ecosystem without \\ncompromising their privacy or control. The architecture supports the nuanced needs of modern blockchain users, who require both the transparency of public \\ninteractions and the security of private transactions, all while maintaining the integrity and confidentiality of their assets.\\n\\n\\n## c) Trees in NSSA\\nTrees in NSSA serve as verifiable databases, essential for maintaining privacy and security. Different types of trees are used for various purposes:\\n\\n1. **Global state tree:** The global state tree is a single, public tree that holds all public assets and storage information. It acts as a central repository for all \\npublicly accessible data on the blockchain. By organizing this data in a Merkle tree structure, the Global State Tree allows for efficient and secure verification of public information.\\n\\n2. **Hashed UTXO tree:** The hashed UTXO tree is a public tree that contains hashes of all created UTXOs. When users wish to consume a UTXO, they provide a membership \\nproof to demonstrate that the UTXO exists within this tree. This process ensures that only valid and existing UTXOs can be spent, maintaining the integrity of transactions. \\nIn fact, users generate membership proofs that verify the presence of specific UTXOs in the tree without revealing their actual data. The benefit here is that the Merkle \\ntree structure allows for quick and efficient verification of UTXO existence.\\n\\n3. **UTXO trees (private states):** Each user or smart contract has its private state stored in UTXO trees. These trees are kept as plaintext on the client\u2019s \\nlocal system (off-chain), ensuring privacy as sensitive information remains confidential. The private state includes all UTXOs owned by the user or the smart contract, and these \\nare not directly exposed to the public blockchain. For instance, users have full control over their private state, which is not visible to other participants in the network.\\n\\nIn conclusion, the tree structures enable efficient verification of transaction validity without compromising privacy. By using Merkle trees, \\nNescience ensures that any tampering with the data can be easily detected. The efficient structure of these trees supports the scalability of the architecture, \\nallowing it to handle a large number of transactions and data entries. By leveraging different types of trees, Nescience ensures efficient and secure management \\nof both public and private states.\\n\\n## d) Nullifier tree in Nescience\\n\\nThe **nullifier tree** is a fundamental component of NSSA, designed to prevent double spending by securely tracking all consumed UTXOs. \\nThis tree acts as a public ledger of spent UTXOs, ensuring that once a UTXO is consumed in a transaction, it cannot be reused in future transactions. \\n\\nThe primary function of the nullifier Tree is to store the **nullifiers** of all consumed UTXOs. By recording the nullifiers in a public tree, \\nthe system ensures that each UTXO is spent only once, thereby safeguarding the integrity of the entire network.\\n\\n- **Ensuring non-membership and preventing double spending**\\nBefore a user can consume a UTXO in a transaction, they must provide a **non-membership proof**. This proof demonstrates that the UTXO\u2019s nullifier \\ndoes not already exist in the Nullifier Tree, proving that the UTXO has not been spent before. If the UTXO\u2019s nullifier is found in the tree, \\nthe system will reject the transaction, preventing double spending. The non-membership proof ensures that users cannot attempt to spend the \\nsame UTXO in multiple transactions. This mechanism is critical for maintaining the security and reliability of NSSA. \\nThe tree structure, which is typically built using a cryptographic tree like a Merkle tree, allows for efficient verification of nullifiers. \\nVerifiers can quickly check whether a nullifier is present or absent in the tree, ensuring that each UTXO is only spent once.\\n\\n- **Nullifier tree structure and operation**\\nThe nullifier tree is likely structured as a **Merkle tree**, which is a cryptographic binary tree where each node represents the hash of its child nodes. \\nThis structure allows for efficient storage and verification of large sets of nullifiers as only the root hash of the tree needs to be stored on the blockchain. \\nWhen a new nullifier is added to the tree, the tree is recalculated, and the root hash is updated. This process ensures that all consumed UTXOs are securely recorded. \\nEach time a transaction consumes a UTXO, the nullifier is added to the Nullifier Tree, and the tree is updated to reflect this new entry. To verify that a \\nUTXO has not been double spent, verifiers can use the tree\u2019s root hash and a proof of inclusion or exclusion (membership or non-membership proof) to check whether the \\nnullifier is present in the tree. For example, if Alice wants to spend a UTXO, she must prove that the nullifier associated with that UTXO is not already in the Nullifier Tree. \\nShe generates a non-membership proof that shows her nullifier is not recorded in the tree, and the transaction is allowed to proceed. Once the transaction is completed, \\nthe nullifier is added to the tree, ensuring that the UTXO cannot be used again.\\n\\n**Conclusion**\\nThe Nullifier Tree is a crucial element of Nescience\'s security. By recording all consumed UTXOs and ensuring that nullifiers are unique, the tree prevents double spending \\nand maintains the integrity of the blockchain. The non-membership proof mechanism guarantees that every transaction is validated against the tree. This structure supports \\nthe scalability and security of NSSA, providing a reliable method for verifying the validity of transactions while preventing malicious behavior.\\n\\n## e) Recursive-friendly privacy-preserving zk-zkVM\\nThe development of the zk-zkVM in Nescience is a work in progress, as the architecture continues to evolve to support privacy-preserving transactions \\nand efficient ZKP generation. The goal of the zk-zkVM is to seamlessly integrate with the Nescience state-separation architecture, \\nensuring that private transactions remain confidential while allowing the network to verify their validity without compromising privacy.\\n\\nCurrently, we are exploring and testing several existing zkVMs to identify the most suitable platform for our needs. Our focus is on finding a zkVM \\nthat not only supports the core features of Nescience, such as state separation and privacy, but also provides the efficiency and scalability required \\nfor a decentralized system. Once a suitable zkVM is chosen, we will begin implementing advanced privacy features on top of it, including support for \\nconfidential transactions, selective disclosure, and recursive proof aggregation.\\n\\nThe integration of these privacy-preserving features with an existing zkVM will enable Nescience to fully employ its state-separation architecture, \\nensuring that users can conduct private transactions with robust security and scalability. This approach will allow us to leverage the strengths of \\nproven zkVM technologies while enhancing them with the unique privacy and state-separation capabilities that Nescience requires.\\n\\n\\n- **Privacy-preserving features**: At its core, the zk-zkVM is designed with privacy in mind. One of the zk-zkVM\u2019s standout privacy features is **selective disclosure**, \\nwhich allows users to reveal only specific details of a transaction as needed. For example, a user could disclose the transaction amount while concealing the identities \\nof the participants. The zk-zkVM employs advanced encryption techniques to protect this sensitive data. All transaction data is encrypted before being stored on the blockchain, \\nso even if the data is intercepted, it cannot be deciphered without the appropriate decryption keys. Another of the crucial privacy-preserving features is the support \\nfor **confidential transactions**. Only the parties involved in the transaction can access the encrypted data. Furthermore, the zk-zkVM supports **verifiable encryption**, \\na powerful capability that allows encrypted data to be included in ZKPs without needing to decrypt it. This ensures that transaction details remain private \\nwhile their correctness can still be proven.\\n\\n\\n- **Lightweight design for accessibility**: The zk-zkVM is being designed to be lightweight and efficient, enabling it to run on standard consumer-grade hardware. \\nThis makes it accessible to a wide range of users without requiring specialized equipment or significant computational resources.\\n\\n- **Faster proving time**: To maintain a seamless user experience, especially during high transaction volumes, the zk-zkVM is being optimized for **fast proving times**. \\nFast proof generation is particularly important for ensuring that the system remains usable during periods of peak activity, preventing bottlenecks and maintaining the fluidity of the network.\\n\\n- **Recursive-friendly operations**: One of the most advanced features of the zk-zkVM will be its support for **recursive operations**. Recursion enables the aggregation \\nof multiple proofs into a single proof, improving efficiency on both the client and sequencer sides of the network.\\n\\n- **Client-side recursion (batch processing):** When a single transaction involves multiple executions, each requiring its own ZKP, these individual \\nproofs can be recursively aggregated before being sent to the sequencer. This reduces the overall data transmitted, enhancing the efficiency of the transaction process \\nby compressing multiple proofs into a single package.\\n \\n- **Sequencer-side recursion (reduced redundancy):** The sequencer, which is responsible for processing transactions and creating verifiable blocks, collects transactions \\ncontaining aggregated proofs. These proofs are further merged into a single comprehensive proof, ensuring that all transactions within a block are validated collectively. \\nThis process reduces redundancy and optimizes the blockchain\u2019s efficiency by minimizing the size and complexity of the proofs required for verification.\\n\\n- **Developer-friendly language**: To foster widespread adoption and innovation within the Nescience ecosystem, the zk-zkVM would include a **developer-friendly language**. \\nThis high-level language simplifies the process of building applications that leverage state separation and privacy-preserving transactions. The language should offer extensive \\nsupport for modular design, APIs, and SDKs, enabling developers to integrate their applications with the zk-zkVM more easily. By lowering the barrier to entry, Nescience encourages \\ninnovation and helps expand the range of privacy-preserving applications that can be built on its platform.\\n\\n**Conclusion**\\n\\nThe zk-zkVM in Nescience is a powerful and versatile virtual machine that embodies the principles of privacy, efficiency, and scalability. By supporting ZKPs \\nand integrating with advanced privacy technologies like homomorphic encryption. Its lightweight design allows it to run efficiently on standard hardware, promoting decentralization, \\nand its recursive operations further enhance the system\'s scalability. With its developer-friendly language and fast proving times, the zk-zkVM is positioned as a key component in \\nfostering the growth and adoption of privacy-preserving blockchain applications.\\n\\n## f) MPC-based synchronization mechanism (under review)\\n\\nNescience is developing an **MPC-based** synchronization mechanism to balance privacy and fairness between public and private execution types. \\nThis mechanism extracts common information from encrypted UTXOs without revealing private details, ensuring privacy and preventing UTXO linkage to users or specific transactions. \\nIt guarantees that public and private executions remain equitable, with the total input equaling the public output.\\n\\nThe mechanism employs **MPC protocols** to perform computations privately, **ZKPs** to verify correctness, and **cryptographic protocols** \\nto secure data during synchronization. This ensures a consistent and fair environment for all users, regardless of their chosen privacy level. Currently, \\nthis feature is under development and review for potential inclusion depending on the research output and compability.\\n\\n\\n\\n\\n\\n# D. Future plans for Nescience\\n\\nNescience is committed to continuously evolving its architecture to ensure scalability, privacy, and security in a growing blockchain landscape. \\nOne of the primary goals is to integrate the **zk-zkVM** and the **Nescience state-separation architecture** into a fully functioning node, \\nenabling efficient private transactions while maintaining network integrity.\\n\\n- **Addressing scalability challenges**: A key challenge facing Nescience is the increasing size of nullifier and hashed UTXO trees, which could impact \\nnetwork performance and scalability over time. To mitigate this, Nescience plans to adopt state-of-the-art scalable privacy techniques such as:\\n - **Mutator sets:** Dynamically adjusting data structures to manage the growth of the nullifier set efficiently.\\n - **SNARK-based accumulators:** Compressing data in a verifiable way to ensure that only relevant information is stored while maintaining cryptographic security.\\n - **Pruning techniques:** Periodically trimming unnecessary data from trees to maintain optimal size and performance, ensuring that the network scales logarithmically \\n rather than exponentially as more transactions occur.\\n\\nBy implementing these approaches, Nescience aims to keep the size of its data structures manageable, ensuring that scalability does not come at the cost of performance or privacy.\\n\\n- **Enhanced key management**: Another critical focus for Nescience is improving key management to streamline operations and enhance security. \\nThe plan is to integrate the different keys used for signatures, addresses, UTXO encryption, and SNARK verification into a unified system. \\nThis integration will simplify key management for users while reducing the risk of security breaches caused by complex, disparate key systems. \\nNescience also plans to implement **Hierarchical Deterministic (HD) keys**, which allow users to derive multiple keys from a single seed, \\nenhancing both security and usability. This approach reduces the complexity of managing multiple keys across various functions and provides an additional \\nlayer of protection for private transactions. Additionally, **multi-signature schemes** will be introduced, requiring multiple parties to authorize transactions. \\nThis feature increases security by reducing the likelihood of unauthorized access, ensuring that a single compromised key cannot lead to malicious transactions.\\n\\n- **Integrating advanced cryptographic techniques**: Nescience will integrate advanced cryptographic techniques, enhancing both privacy and scalability. Among these are:\\n - **Homomorphic encryption:** Allowing computations to be performed on encrypted data without the need to decrypt it, preserving privacy while enabling secure, complex data processing.\\n - **Zero-knowledge rollups:** Bundling multiple transactions into a single proof to reduce the amount of data processed and stored on the blockchain, \\n significantly improving scalability without sacrificing security.\\n\\nThese cryptographic enhancements will ensure that Nescience can support a growing network while continuing to protect user privacy and maintaining high transaction throughput.\\n\\n- **Long-term vision**\\n\\nThe ultimate goal for Nescience is to deploy a fully operational **node powered by zk-zkVM** and the **Nescience state-separation architecture**. \\nThis node will handle complex, private transactions at scale while integrating all of the advanced cryptographic techniques outlined in the roadmap. \\nNescience aims to provide users with an infrastructure that balances privacy, security, and efficiency, ensuring the network remains resilient and capable of handling future demands.\\n\\nBy pursuing these future plans, Nescience is poised to not only address current challenges around scalability and key management but also lead the way in \\napplying advanced cryptography to decentralized systems. This vision will help secure the long-term integrity and performance of the Nescience state-separation \\nmodel as the blockchain grows and evolves.\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n# References\\n\\n[1] Nakamoto, S. (2008). Bitcoin: A Peer-to-Peer Electronic Cash System. Retrieved from https://bitcoin.org/bitcoin.pdf\\n\\n[2] Sanchez, F. (2021). Cardano\u2019s Extended UTXO accounting model. Retrived from https://iohk.io/en/blog/posts/2021/03/11/cardanos-extended-utxo-accounting-model/\\n\\n[3] Morgan, D. (2020). HD Wallets Explained: From High Level to Nuts and Bolts. Retrieved from https://medium.com/mycrypto/the-journey-from-mnemonic-phrase-to-address-6c5e86e11e14\\n\\n[4] Wuille, P. (2012). Bitcoin Improvement Proposal (BIP) 32. Retrieved from https://github.com/bitcoin/bips/blob/master/bip-0032.mediawiki\\n\\n[5] Sin7y Tech Review (29): Design Principles of Private Transactions in Aleo & Zcash. Retrieved from https://hackmd.io/@sin7y/rkxFXLkgs\\n\\n[6] Sin7y Tech Review (33): Principles of private transactions and regulatory compliance issues. Retrieved from https://hackmd.io/@sin7y/S16RyFzZn\\n\\n[7] Zcash Protocol Specification. Retrieved from https://zips.z.cash/protocol/protocol.pdf\\n\\n[8] Anatomy of a Zcash Transaction. Retrieved from https://electriccoin.co/blog/anatomy-of-zcash\\n\\n[9] The Penumbra Protocol: Notes, Nullifiers, and Trees. Retrieved from https://protocol.penumbra.zone/main/concepts/notes_nullifiers_trees.html\\n\\n[10] Zero-knowledge Virtual Machine (ZKVM). Retrieved from https://medium.com/@abhilashkrish/zero-knowledge-virtual-machine-zkvm-95adc2082cfd\\n\\n[11] What\'s a Sparse Merkle tree?. Retrieved from https://medium.com/@kelvinfichter/whats-a-sparse-merkle-tree-acda70aeb837\\n\\n[12] Lecture 10: Accounts Model and Merkle Trees. Retrieved from https://web.stanford.edu/class/ee374/lec_notes/lec10.pdf\\n\\n[13] The UTXO vs Account Model. Retrieved from https://www.horizen.io/academy/utxo-vs-account-model/\\n\\n[14] Addresses and Value Pools in Zcash. Retrieved from https://zcash.readthedocs.io/en/latest/rtd_pages/addresses.html"},{"id":"membership-with-bloom-filters-and-cuckoo-filters","metadata":{"permalink":"/rlog/membership-with-bloom-filters-and-cuckoo-filters","source":"@site/rlog/2024-07-19-bloomfilter.mdx","title":"Membership with Bloom Filters and Cuckoo Filters","description":"We examine two data structures: Bloom filters and Cuckoo filters.","date":"2024-07-19T12:00:00.000Z","formattedDate":"July 19, 2024","tags":[],"readingTime":12.62,"hasTruncateMarker":true,"authors":[{"name":"Marvin","github":"jonesmarvin8","key":"marvin"}],"frontMatter":{"title":"Membership with Bloom Filters and Cuckoo Filters","date":"2024-07-19T12:00:00.000Z","authors":"marvin","published":false,"slug":"membership-with-bloom-filters-and-cuckoo-filters","categories":"research","toc_min_heading_level":2,"toc_max_heading_level":4},"prevItem":{"title":"Nescience: A User-Centric State-Separation Architecture","permalink":"/rlog/Nescience-state-separation-architecture"},"nextItem":{"title":"RLN-v3: Towards a Flexible and Cost-Efficient Implementation","permalink":"/rlog/rln-v3"}},"content":"We examine two data structures: Bloom filters and Cuckoo filters.\\n\\n\x3c!--truncate--\x3e\\n\\n## Membership with Bloom Filters and Cuckoo Filters\\n\\nThe ability to efficiently query the membership of an element in a given data set is crucial.\\nIn certain applications, it is more important to output a result quickly than to have a \'perfect\' result.\\nIn particular, false positives may be an acceptable tradeoff for speed.\\nIn this blog, we examine [Bloom](https://dl.acm.org/doi/10.1145/362686.362692) and [Cuckoo](https://www.cs.cmu.edu/~dga/papers/cuckoo-conext2014.pdf) data filters.\\nBoth of these filters are data structures that can be used for membership proofs.\\n\\nEveryone is familiar with the process of creating a new account for various websites, whether it is an e-mail account or a social media account.\\nConsider when you enter your desired username.\\nMany sites provide real-time feedback, as you type, on the availability of a given string.\\nIn this scenario, it is necessary that the result is seemingly instant, regardless of the number of existing accounts.\\nHowever, it is not important that the usernames that are flagged as unavailable are, in fact, in use.\\nThat is, it is sufficient to have a probabilistic check for membership.\\n\\n**Bloom filters** and **Cuckoo filters** are data structures that can be used to accumulate data with a fixed amount of space.\\nThe associated filter $F$ for a digest of data $D$ can be queried to determine whether an element is (possibly) a member of $D$:\\n\\n- **0:** The queried element is definitely not a member of digest $D$.\\n- **1:** The entry is possibly a member of the digest $D$.\\n\\nThe algorithms associated with Bloom filters and Cuckoo filters, which we will discuss shortly, are deterministic.\\nThe possibility of false positives arises from the query algorithm.\\n\\n\\n## Bloom filters\\nA **Bloom filter** is a data structure that can be used to accumulate an arbitrary amount of data with a fixed amount of space.\\nBloom filters have been a popular data structure for proof of non-membership due to their small storage size.\\nSpecifically, a Bloom filter consists of a binary string ${\\\\bf{v}} \\\\in \\\\{0,1\\\\}^n$ and $k$ hash functions $\\\\{h_i: \\\\{0,1\\\\}^* \\\\rightarrow \\\\{0,\\\\dots,n-1\\\\}\\\\}_{i=0}^{k-1}$.\\nWe note that each hash function $h_i$ is used to determine an index of our binary string ${\\\\bf{v}}$ to flip the associated bit to 1.\\nThe binary string ${\\\\bf{v}}$ is initialized with every entry as 0.\\nThe hash functions do not need to be cryptographic hash functions.\\n\\n\\n- **Append:** Suppose that we wish to add the element $x$ to the Bloom filter.\\n - Define the vector ${\\\\bf{b}} \\\\in \\\\{0,\\\\dots,n-1\\\\}^k$ so that ${\\\\bf{b}}[i] := h_i(x)$ for each $i \\\\in \\\\{0,\\\\dots,k-1\\\\}$.\\n - Update the binary string ${\\\\bf{v}}[{\\\\bf{b}}[i]] \\\\leftarrow 1$ for each $i \\\\in \\\\{0,\\\\dots,k-1\\\\}$.\\n \\n- **Query:** Suppose that we wish to query the Bloom filter for element $y$.\\n - Return 1 provided ${\\\\bf{v}}[h_i(y)] = 1$ for every $i \\\\in \\\\{0,\\\\dots,k-1\\\\}$. Otherwise, return 0.\\n \\nThe algorithm **Query** will output 1 for every element $y$ that has been added to the Bloom filter.\\nThis is a consequence of the **Append** algorithm.\\nHowever, due to potential collisions over a set of hash functions, it is possible for false positives to occur.\\nMoreover, the possibility of collisions makes it impossible to remove elements from the Bloom filter.\\n\\n### Complexity\\nThe storage of a Bloom filter requires constant space.\\nSpecifically, the Bloom filter uses $n$ bits regardless of the size of the digest.\\nSo, regardless of the number of elements that we append, the Bloom filter will use $n$ bits.\\nFurther, if we assume that each of the $k$ hash functions runs in constant time, then we can append/query an entry in $O(k)$.\\n\\n### Example\\nSuppose that $k = 3$ and $n = 10$. \\nOur Bloom filter is initialized as $\\\\bf{v} = \\\\begin{pmatrix}0&0&0&0&0&0&0&0&0&0\\\\end{pmatrix}.$\\nNow, we will append the words $add$, $sum$, and $equal$.\\nSuppose that\\n\\n$\\\\begin{matrix}\\nh_0(add) = 1 & h_1(add) = 4 & h_2(add) = 7\\\\\\\\\\nh_0(sum) = 9 & h_1(sum) = 2 & h_2(sum) = 1\\\\\\\\\\nh_0(equal) = 5 & h_1(equal) = 8 & h_2(equal) = 0.\\n\\\\end{matrix}$\\n\\nAfter appending these words, the Bloom filter is $\\\\bf{v} = \\\\begin{pmatrix}1&1&1&0&1&1&0&1&1&1\\\\end{pmatrix}.$\\n\\nNow, suppose that we query the words $subtract$ and $multiple$ so that\\n\\n$\\\\begin{matrix} h_0(subtract) = 3 & h_1(subtract) = 5 & h_2(subtract) = 1\\\\\\\\ h_0(multiple) = 7 & h_1(multiple) = 1 & h_2(multiple) = 4\\\\\\\\\\n\\\\end{matrix}$.\\n\\nThe query for $subtract$ returns 0 since ${\\\\bf{v}}[3]=0$.\\nOn the other hand, the query for $multiple$ returns 1 since ${\\\\bf{v}}[1]=1, {\\\\bf{v}}[4] = 1$, and ${\\\\bf{v}}[7]=1$.\\nEven though $multiple$ was not used to generate the Bloom filter ${\\\\bf{v}}$, our query returns the false positive.\\n\\n\\n### Probability of false positives\\nFor our analysis, we will assume that the probabilities that arise in our analysis are independent. \\nHowever, this assumption can be removed to gain the same approximation.\\n\\nWe note that for a single hash function, the probability that a specific bit is flipped to 1 is $1/n$.\\nSo, the probability that the specific bit is not flipped by the hash function is $1-1/n$.\\nApplying our assumption that the $k$ hash functions are \'independent,\'\\nthe probability that the specific bit is not flipped by any of the hash functions is\\n$(1-1/n)^k$.\\n\\nRecall the calculus fact $\\\\lim_{\\\\infty} (1-1/n)^n = e^{-1}$.\\nThat is, as we increase the number of bits that our Bloom filter uses, the approximate probability that a given bit is not flipped by any of the $k$ hash functions is $e^{-k/n}$.\\n\\nSuppose that $\\\\ell$ entries have been added to the Bloom filter.\\nThe probability that a specific bit is still 0 after the $\\\\ell$ entries have been added is approximately $e^{-\\\\ell k/n}$.\\nThe probability that a queried element is erroneously claimed as a member of the digest is approximately\\n$(1-e^{-\\\\ell k/n})^k$.\\n\\nThe following table provides concrete values for these approximations.\\n\\n| $n$ | $k$ | $\\\\ell$ | $(1-e^{-\\\\ell k/n})^k$|\\n| -------- | -------- | -------- | --- |\\n| 32 | 3 | 3 | 0.01474 |\\n| 32 | 3 | 7 | 0.11143 |\\n| 32 | 3 | 12 |0.30802 |\\n| 32 | 3 | 17 |0.50595 |\\n| 32 | 3 | 28 |0.79804 |\\n\\nNotice that the probability of false positives increases as the number of elements ($\\\\ell$) that have been added to the digest increases.\\n\\n### Sliding-Window Bloom filter\\nOur toy example and table illustrated an issue concerning Bloom filters.\\nThe number of entries that can be added to a Bloom filter is restricted by our choice of $k$ and $n$.\\nNot only does the probability that false positives will occur increase,\\nbut it is possible that our vector ${\\\\bf{v}}$ can be a string of all 1s.\\n[Szepieniec and V\xe6rge](https://eprint.iacr.org/2023/1208.pdf) proposed a modification to Bloom filters to handle this.\\n\\nInstead of having a fixed number of bits for our Bloom filter, we dynamically allot memory based on the number of entries that have been added to the filter.\\nGiven a predetermined threshold ($b$) for the number of entries, we shift our \'window\' of flipping bits by $s$ bits.\\nNote that this means that it is necessary to keep track of when a given entry is added to the digest.\\nThis means that querying the Sliding-Window Bloom filter will yield different results when different timestamps are used.\\n\\nThis can be done with $k$ hash functions as we used earlier.\\nAlternatively, Szepieniec and V\xe6rge proposed using the same hash function but to produce $k$ entries in the current window.\\nSpecifically, we obtain the bits we wish to flip to 1s by computing $h(X || i)$ for each $i \\\\in \\\\{0,\\\\dots, k-1\\\\}$ and $X$ as we will define next.\\nFor Sliding-Window Bloom filters, $X$ is more than just the element we wish to append to the filter.\\nInstead, $X$ consists of the element $x$ and a timestamp $t$. \\nThe timestamp $t$ is used to locate the correct window for bits, as we see below:\\n\\n- **Append:** Suppose that we wish to add the element $x$ with timestamp $t$ to the Sliding-Window Bloom filter.\\n - Define the vector ${\\\\bf{b}} \\\\in \\\\{0,\\\\dots,n-1\\\\}^k$ so that ${\\\\bf{b}}[i] := h(x||t||i)$ for each $i \\\\in \\\\{0,\\\\dots,k-1\\\\}$.\\n - Update the binary string ${\\\\bf{v}}[{\\\\bf{b}}[i]+\\\\lfloor t/b \\\\rfloor s] \\\\leftarrow 1$ for each $i \\\\in \\\\{0,\\\\dots,k-1\\\\}$.\\n \\n- **Query:** Suppose that we wish to query the Bloom filter for element $y$ with timestamp $t$.\\n - Return 1 provided ${\\\\bf{v}}[h(y||t||i) + \\\\lfloor t/b \\\\rfloor s] = 1$ for every $i \\\\in \\\\{0,\\\\dots,k-1\\\\}$. Otherwise, return 0.\\n \\n\\nBy incorporating a shifting window, we maintain efficient querying and appending at the cost of constant space.\\nHowever, by losing constant space, we gain \'infinite\' scalability.\\n\\n## Cuckoo filters\\nA Cuckoo filter is a data structure for probabilistic membership proofs based on Cuckoo hash tables.\\nThe specific design goal for Cuckoo filters is to address the inability to remove elements from a Bloom Filter.\\nThis is done by replacing a list of bits with a list of \'fingerprints.\'\\nA fingerprint can be thought of as the hash value for an entry in the digest.\\nA Cuckoo filter is a fixed-length list of \'fingerprints.\'\\nIf the maximum number of entries that a Cuckoo filter can hold is $n$ and a fingerprint occupies $f$ bits,\\nthen the Cuckoo filter occupies $nf$ bits.\\n\\nNow, we describe the algorithms associated with the Cuckoo filter $C$ with hash function $hash(X)$ and fingerprint function $fingerprint(X)$.\\n\\n- **Append:** Suppose that we wish to add the element $x$ to the Cuckoo filter.\\n - If either position $i_x := hash(x)$ or $j_x := i \\\\otimes hash(fingerprint(x))$ of $C$ is empty,\\n then $fingerprint(x)$ is inserted into an empty position.\\n - If both $i_x$ and $j_x$ are occupied with a fingerprint that is distinct from $fingerprint(x)$,\\n then we select either $i_x$ or $j_x$ to insert $fingerprint(x)$.\\n The fingerprint that had previously occupied this position cannot be discarried.\\n Instead, we insert this fingerprint into its alternate location.\\n This reshuffling process either ends with fingerprints all having their own bucket or one that cannot be inserted.\\n In the case that we have a fingerprint that cannot be inserted, then the Cuckoo filter is overfilled.\\n\\n- **Query:** Suppose that we wish to query the Cuckoo filter for element $y$.\\n - Return 1 provided $fingerprint(y)$ is either in position $i_y$ or $j_y$.\\n\\n- **Delete:** Suppose that we wish to delete the element $y$ from the Cuckoo filter.\\n - If $y$ has been added to the Cuckoo filter, then $fingerprint(y)$ is either in position $i_y$ or $j_y$.\\n We remove $fingerprint(y)$ from the appropriate position.\\n\\nWe note that false positives in Cuckoo filters only occur when an element shares a fingerprint and hash with a value that has already been added to the Cuckoo filter.\\n\\n### Example\\nIn this example, we will append the words $add$, $sum$, and $equal$ to a Cuckoo filter with 8 slots.\\n\\nFor each word $x$, we compute two indices:\\n$i_x := hash(x) \\\\text{ and } j_x := hash(x) \\\\otimes hash(fingerprint(x)).$\\nSuppose that we have the following values for\\nour words:\\n\\n| word | $i_x$ | $j_x$|\\n|---|---|---|\\n|$add$| $(0,1,0)$ | $(1,0,0)$ |\\n|$sum$| $(1,0,1)$ | $(1,1,0)$ |\\n|$equal$| $(0,1,0)$ | $(1,0,1)$ |\\n\\nFor clarity of the example, we append the words directly to the buckets instead of fingerprints of our data.\\n\\n| |0 | 1 | 2 | 3 | 4| 5| 6| 7|\\n|---|---|---|---|---|---|---|---|---|\\n|append $add$| ||$add$||||| |\\n|append $sum$| ||$add$|||$sum$|| |\\n\\nNotice that both of the buckets (2 and 5) that $equal$ can map to are occupied.\\nSo, we select one of these buckets (say 2) to insert $equal$ into.\\nThen, we have to insert $add$ to its possible bucket (1).\\nThis leaves us with the Cuckoo filter:\\n\\n|0 | 1 | 2 | 3 | 4| 5| 6| 7|\\n|---|---|---|---|---|---|---|---|\\n| |$add$|$equal$|||$sum$|| |\\n\\n### Complexity\\nNotice that deletions and queries to Cuckoo filters are done in constant time.\\nSpecifically, only two locations need to be checked for any data $x$.\\nAppends may require shuffling previously added elements to their alternate locations.\\nAs such, the append does not run in constant time.\\n\\n## Bloom filters vs Cuckoo filters\\nThe design of Bloom filters is focused on space efficiency and quick query time.\\nEven though they occupy constant space,\\nCuckoo filters require significantly more space for $n$ items than Bloom filters.\\nThe worst-case append in a Cuckoo filter is slower than the append in a Bloom filter.\\nHowever, an append that does not require any shuffling in a Cuckoo filter can be quicker than appends in Bloom filters.\\nCuckoo filters make up for these disadvantages with quicker query time and the ability to delete entries.\\nFurther, the probability of false positives in Cuckoo filters is lower than the probability of false positives in Bloom filters.\\n\\n\\n## Combining Filters with RLN\\nIn a series of posts ([1](https://vac.dev/rlog/rln-anonymous-dos-prevention),[2](https://vac.dev/rlog/rln-v3/),[3](https://vac.dev/rlog/rln-light-verifiers)),\\nvarious versons of rate limiting nullifiers (RLN) that are used by Waku has been discussed.\\nRLN uses a sparse Merkle tree for the membership set.\\nThe computational power required to construct the Merkle tree prevent light clients from participating in verifying membership proofs.\\nIn [Verifying RLN Proofs in Light Clients with Subtrees](https://vac.dev/rlog/rln-light-verifiers),\\nit was proposed to move the membership set on-chain so that it would not be necessary for a light client to construct the entire Merkle tree locally.\\nUnfortunately, the naive approach is not practical as the gas limit for a single call is too restrictive for an appropriately sized tree.\\nInstead, it was proposed to make utilize of subtrees.\\nIn this section, we provide a discussion of an alternate solution for light clients by using filters for the membership set.\\nThe two [parts of RLN](https://rate-limiting-nullifier.github.io/rln-docs/rln_in_details.html) that we will focus on are user registration and deletion.\\n\\nBoth Bloom and Cuckoo filters support user registration as this is can be done as an append.\\nThe fixed size of these filters would restrict the total number of users that can register.\\nThis can be migitated by using Sliding-Window Bloom filter as this supports system growth.\\nThe Sliding-Window can be adapted to Cuckoo filters as well.\\nIn the case of a Sliding-Window filter, an user would maintain the epoch of when they registered.\\nThe registration of new users to Bloom filters can be done in constant time which is a significant improvement over appending to subtrees.\\nUnfortunately, the complexity of registration to Cuckoo filters cannot be as easily computed.\\n\\nA user could be slashed from the RLN by sending too many messages in a given epoch.\\nUnfortunately, Bloom filters do not support the deletion of members.\\nLuckily, Cuckoo filters allow for deletions that can performed in constant time.\\n\\nCuckoo filter that use Sliding-Window could be used so that light clients are able to verify proofs of membership in the RLN.\\nThese proofs are not a substitute to the usual proofs that a heavy client can verify due to the allowance of false positives.\\nHowever, with the allowance of false positives, a light client can participate in verification RLN proofs in an efficient manner.\\n\\n\\n### References\\n- [Space/Time Trade-offs in Hash Coding with Allowable Errors](https://dl.acm.org/doi/10.1145/362686.362692)\\n- [David Wagner\'s Lecture Notes on Bloom filters](https://people.eecs.berkeley.edu/~daw/teaching/cs170-s03/Notes/lecture10.pdf)\\n- [Mutator Sets and their Application to Scalable Privacy](https://eprint.iacr.org/2023/1208)\\n- [Cuckoo Filter: Practically Better than Bloom](https://www.cs.cmu.edu/~dga/papers/cuckoo-conext2014.pdf)\\n- [Strengthening Anonymous DoS Prevention with Rate Limiting Nullifiers in Waku](https://vac.dev/rlog/rln-anonymous-dos-prevention)\\n- [RLN-v3: Towards a Flexible and Cost-Efficient Implementation](https://vac.dev/rlog/rln-v3/)\\n- [Verifying RLN Proofs in Light Clients with Subtrees](https://vac.dev/rlog/rln-light-verifiers)\\n- [RLN in details](https://rate-limiting-nullifier.github.io/rln-docs/rln_in_details.html)"},{"id":"rln-v3","metadata":{"permalink":"/rlog/rln-v3","source":"@site/rlog/2024-05-13-rln-v3.mdx","title":"RLN-v3: Towards a Flexible and Cost-Efficient Implementation","description":"Improving on the previous version of RLN by allowing dynamic epoch sizes.","date":"2024-05-13T12:00:00.000Z","formattedDate":"May 13, 2024","tags":[],"readingTime":6.31,"hasTruncateMarker":true,"authors":[{"name":"Aaryamann","twitter":"p1ge0nh8er","github":"rymnc","key":"p1ge0nh8er"}],"frontMatter":{"title":"RLN-v3: Towards a Flexible and Cost-Efficient Implementation","date":"2024-05-13T12:00:00.000Z","authors":"p1ge0nh8er","published":true,"slug":"rln-v3","categories":"research","toc_min_heading_level":2,"toc_max_heading_level":4},"prevItem":{"title":"Membership with Bloom Filters and Cuckoo Filters","permalink":"/rlog/membership-with-bloom-filters-and-cuckoo-filters"},"nextItem":{"title":"Verifying RLN Proofs in Light Clients with Subtrees","permalink":"/rlog/rln-light-verifiers"}},"content":"Improving on the previous version of RLN by allowing dynamic epoch sizes.\\n\\n\x3c!--truncate--\x3e\\n\\n## Introduction\\n\\nRecommended previous reading: [Strengthening Anonymous DoS Prevention with Rate Limiting Nullifiers in Waku](https://vac.dev/rlog/rln-anonymous-dos-prevention).\\n\\nThe premise of RLN-v3 is to have a variable message rate per variable epoch,\\nwhich can be explained in the following way:\\n\\n- **RLN-v1:** \u201cAlice can send 1 message per global epoch\u201d\\n\\n Practically, this is `1 msg/second`\\n\\n- **RLN-v2:** \u201cAlice can send `x` messages per global epoch\u201d\\n\\n Practically, this is `x msg/second`\\n\\n- **RLN-v3:** \u201cAlice can send `x` messages within a time interval `y` chosen by herself.\\n The funds she has to pay are affected by both the number of messages and the chosen time interval.\\n Other participants can choose different time intervals fitting their specific needs.\\n\\n Practically, this is `x msg/y seconds`\\n\\nRLN-v3 allows higher flexibility and ease of payment/stake for users who have more predictable usage patterns and therefore,\\nmore predictable bandwidth usage on a p2p network (Waku, etc.).\\n\\nFor example:\\n\\n- An AMM that broadcasts bids, asks, and fills over Waku may require a lot of throughput in the smallest epoch possible and hence may register an RLN-v3 membership of `10000 msg/1 second`.\\n They could do this with RLN-v2, too.\\n- Alice, a casual user of a messaging app built on Waku, who messages maybe 3-4 people infrequently during the day, may register an RLN-v3 membership of `100 msg/hour`,\\n which would not be possible in RLN-v2 considering the `global epoch` was set to `1 second`.\\n With RLN-v2, Alice would have to register with a membership of `1 msg/sec`,\\n which would translate to `3600 msg/hour`. This is much higher than her usage and would\\n result in her overpaying to stake into the membership set.\\n- A sync service built over Waku,\\n whose spec defines that it MUST broadcast a set of public keys every hour,\\n may register an RLN-v3 membership of `1 msg/hour`,\\n cutting down the costs to enter the membership set earlier.\\n\\n## Theory\\n\\n### Modification to leaves set in the membership Merkle tree\\n\\nTo ensure that a user\u2019s epoch size (`user_epoch_limit`) is included within their membership we must modify the user\u2019s commitment/leaf in the tree to contain it.\\nA user\u2019s commitment/leaf in the tree is referred to as a `rate_commitment`,\\nwhich was previously derived from their public key (`identity_commitment`)\\nand their variable message rate (`user_message_limit`).\\n\\nIn **RLN-v2:**\\n\\n$$\\nrate\\\\_commitment = poseidon([identity\\\\_commitment, user\\\\_message\\\\_limit])\\n$$\\n\\nIn **RLN-v3:**\\n\\n$$\\nrate\\\\_commitment = poseidon([identity\\\\_commitment, user\\\\_message\\\\_limit, user\\\\_epoch\\\\_limit])\\n$$\\n\\n### Modification to circuit inputs\\n\\nTo detect double signaling,\\nwe make use of a circuit output `nullifier`,\\nwhich remains the same if a user generates a proof with the same `message_id` and `external_nullifier`,\\nwhere the `external_nullifier` and `nullifier` are defined as:\\n\\n$$\\nexternal\\\\_nullifier = poseidon([epoch, rln\\\\_identifier]) \\\\\\\\\\nnullifier = poseidon([identity\\\\_secret, external\\\\_nullifier, message\\\\_id])\\n$$\\n\\nWhere:\\n\\n- `epoch` is defined as the Unix epoch timestamp with seconds precision.\\n- `rln_identifier` uniquely identifies an application for which a user submits a proof.\\n- `identity_secret` is the private key of the user.\\n- `message_id` is the sequence number of the user\u2019s message within `user_message_limit` in an epoch.\\n\\nIn RLN-v2, the global epoch was 1 second,\\nhence we did not need to perform any assertions to the epoch\u2019s value inside the circuit,\\nand the validation of the epoch was handled off-circuit (i.e., too old, too large, bad values, etc.).\\n\\nIn RLN-v3, we propose that the `epoch` that is passed into the circuit\\nmust be a valid multiple of `user_epoch_limit`\\nsince the user may pass in values of the `epoch` which do not directly correlate with the `user_epoch_limit`.\\n\\nFor example:\\n\\n- A user with `user_epoch_limit` of 120\\n passes in an epoch of `237`\\n generates `user_message_limit` proofs with it,\\n can increment the epoch by `1`,\\n and generate `user_message_limit` proofs with it,\\n thereby allowing them to bypass the message per epoch restriction.\\n\\nOne could say that we could perform this validation outside of the circuit,\\nbut we maintain the `user_epoch_limit` as a private input to the circuit so that the user is not deanonymized by the anonymity set connected to that `user_epoch_limit`.\\nSince `user_epoch_limit` is kept private,\\nthe verifier does not have access to that value and cannot perform validation on it.\\n\\nIf we ensure that the `epoch` is a multiple of `user_epoch_limit`,\\nwe have the following scenarios:\\n\\n- A user with `user_epoch_limit` of 120\\n passes in an epoch of `237`.\\n Proof generation fails since the epoch is not a multiple of `user_epoch_limit`.\\n- A user with `user_epoch_limit` of 120\\n passes in an epoch of `240` and\\n can generate `user_message_limit` proofs without being slashed.\\n\\nSince we perform operations on the `epoch`, we must include it as a circuit input (previously, it was removed from the circuit inputs to RLN-v2).\\n\\nTherefore, the new circuit inputs are as follows:\\n\\n```c\\n// unchanged\\nprivate identity_secret\\nprivate user_message_limit\\nprivate message_id\\nprivate pathElements[]\\nprivate pathIndices[]\\npublic x // messageHash\\n\\n// new/changed\\nprivate user_epoch_limit\\nprivate user_epoch_quotient // epoch/user_epoch_limit to assert within circuit\\npublic epoch\\npublic rln_identifier\\n```\\n\\nThe circuit outputs remain the same.\\n\\n### Additional circuit constraints\\n\\n1. Since we accept the `epoch`, `user_epoch_quotient`, and `user_epoch_limit`,\\n we must ensure that the relation between these 3 values is preserved. I.e.:\\n\\n $$\\n epoch == user\\\\_epoch\\\\_limit * user\\\\_epoch\\\\_quotient\\n $$\\n\\n2. To ensure no overflows/underflows occur in the above multiplication,\\n we must constrain the inputs of `epoch`, `user_epoch_quotient`, and `user_epoch_limit`.\\n We have assumed `3600` to be the maximum valid size of the `user_epoch_quotient`.\\n\\n$$\\nsize(epoch) \\\\leq 64\\\\ bits \\\\\\\\\\nsize(user\\\\_epoch\\\\_limit) \\\\leq 12\\\\ bits \\\\\\\\\\nuser\\\\_epoch\\\\_limit \\\\leq 3600 \\\\\\\\\\nuser\\\\_epoch\\\\_limit \\\\leq epoch \\\\\\\\\\nuser\\\\_epoch\\\\_quotient < user\\\\_epoch\\\\_limit\\n$$\\n\\n### Modifications to external epoch validation (Waku, etc.)\\n\\nFor receivers of an RLN-v3 proof\\nto detect if a message is too old, we must use the higher bound of the `user_epoch_limit`, which has been set to `3600`.\\nThe **trade-off** here is that we allow hour-old messages to propagate within the network.\\n\\n### Modifications to double signaling detection scheme (Waku, etc.)\\n\\nFor verifiers of RLN-v1/v2 proofs,\\na log of nullifiers seen in the last epoch is maintained,\\nand if there is a match with a pre-existing nullifier,\\ndouble signaling has been detected and the verifier MAY proceed to slash the spamming user.\\n\\nWith the RLN-v3 scheme,\\nwe need to increase the size of the nullifier log used,\\nwhich previously cleared itself every second to the higher bound of the `user_epoch_limit`, which is `3600`.\\nNow, the RLN proof verifier must clear the nullifier log every `3600` seconds to satisfactorily detect double signaling.\\n\\n## The implementation\\n\\nAn implementation of the RLN-v3 scheme in [gnark](https://docs.gnark.consensys.io/) can be found [here](https://github.com/vacp2p/gnark-rln/blob/9b05eddc89901a06d8f41b093ce8ce12fd0bb4e0/rln/rln.go).\\n\\n## Comments on performance\\n\\n- Hardware: Macbook Air M2, 16GB RAM\\n- Circuit: [RLN-v3](https://github.com/vacp2p/gnark-rln/blob/9b05eddc89901a06d8f41b093ce8ce12fd0bb4e0/rln/rln.go)\\n- Proving system: [`Groth16`](https://eprint.iacr.org/2016/260.pdf)\\n- Framework: [`gnark`](https://docs.gnark.consensys.io/)\\n- Elliptic curve: [`bn254`](https://eprint.iacr.org/2013/879.pdf) (aka bn128) (not to be confused with the 254-bit Weierstrass curve)\\n- Finite field: Prime-order subgroup of the group of points on the `bn254` curve\\n- Default Merkle tree height: `20`\\n- Hashing algorithm: [`Poseidon`](https://eprint.iacr.org/2019/458.pdf)\\n- Merkle tree: [`Sparse Indexed Merkle Tree`](https://github.com/rate-limiting-nullifier/pmtree)\\n\\n### Proving\\n\\nThe proving time for the RLN-v3 circuit is `90ms` for a single proof.\\n\\n### Verification\\n\\nThe verification time for the RLN-v3 circuit is `1.7ms` for a single proof.\\n\\n## Conclusion\\n\\nThe RLN-v3 scheme introduces a new epoch-based message rate-limiting scheme to the RLN protocol.\\nIt enhances the user\'s flexibility in setting their message limits and cost-optimizes their stake.\\n\\n## Future work\\n\\n- Implementing the RLN-v3 scheme in [Zerokit](https://github.com/vacp2p/zerokit)\\n- Implementing the RLN-v3 scheme in [Waku](https://github.com/waku-org/nwaku)\\n- Formal security analysis of the RLN-v3 scheme\\n\\n## References\\n\\n- [Strengthening Anonymous DoS Prevention with Rate Limiting Nullifiers in Waku](https://vac.dev/rlog/rln-anonymous-dos-prevention)\\n- [RLN Circuits](https://github.com/rate-limiting-nullifier/circom-rln)\\n- [Groth16](https://eprint.iacr.org/2016/260.pdf)\\n- [Gnark](https://docs.gnark.consensys.io/)\\n- [Poseidon Hash](https://eprint.iacr.org/2019/458.pdf)\\n- [Zerokit](https://github.com/vacp2p/zerokit)\\n- [RLN-v1 RFC](https://rfc.vac.dev/spec/32/)\\n- [RLN-v2 RFC](https://rfc.vac.dev/spec/58/)\\n- [Waku](https://waku.org)"},{"id":"rln-light-verifiers","metadata":{"permalink":"/rlog/rln-light-verifiers","source":"@site/rlog/2024-05-03-rln-light-verifiers.mdx","title":"Verifying RLN Proofs in Light Clients with Subtrees","description":"How resource-restricted devices can verify RLN proofs fast and efficiently.","date":"2024-05-03T12:00:00.000Z","formattedDate":"May 3, 2024","tags":[],"readingTime":4.81,"hasTruncateMarker":true,"authors":[{"name":"Aaryamann","twitter":"p1ge0nh8er","github":"rymnc","key":"p1ge0nh8er"}],"frontMatter":{"title":"Verifying RLN Proofs in Light Clients with Subtrees","date":"2024-05-03T12:00:00.000Z","authors":"p1ge0nh8er","published":true,"slug":"rln-light-verifiers","categories":"research","toc_min_heading_level":2,"toc_max_heading_level":4},"prevItem":{"title":"RLN-v3: Towards a Flexible and Cost-Efficient Implementation","permalink":"/rlog/rln-v3"},"nextItem":{"title":"Strengthening Anonymous DoS Prevention with Rate Limiting Nullifiers in Waku","permalink":"/rlog/rln-anonymous-dos-prevention"}},"content":"How resource-restricted devices can verify RLN proofs fast and efficiently.\\n\\n\x3c!--truncate--\x3e\\n\\n## Introduction\\n\\nRecommended previous reading: [Strengthening Anonymous DoS Prevention with Rate Limiting Nullifiers in Waku](https://vac.dev/rlog/rln-anonymous-dos-prevention).\\n\\nThis post expands upon ideas described in the previous post,\\nfocusing on how resource-restricted devices can verify RLN proofs fast and efficiently.\\n\\nPreviously, it was required to fetch all the memberships from the smart contract,\\nconstruct the merkle tree locally,\\nand derive the merkle root,\\nwhich is subsequently used to verify RLN proofs.\\n\\nThis process is not feasible for resource-restricted devices since it involves a lot of RPC calls, computation and fault tolerance.\\nOne cannot expect a mobile phone to fetch all the memberships from the smart contract and construct the merkle tree locally.\\n\\n## Constraints and requirements\\n\\nAn alternative solution to the one proposed in this post is to construct the merkle tree on-chain,\\nand have the root accessible with a single RPC call.\\nHowever, this approach increases gas costs for inserting new memberships and _may_ not be feasible until it is optimized further with batching mechanisms, etc.\\n\\nThe other methods have been explored in more depth [here](https://hackmd.io/@rymnc/rln-tree-storages).\\n\\nFollowing are the requirements and constraints for the solution proposed in this post:\\n\\n1. Cheap membership insertions.\\n2. As few RPC calls as possible to reduce startup time.\\n3. Merkle root of the tree is available on-chain.\\n4. No centralized services to sequence membership insertions.\\n5. Map inserted commitments to the block in which they were inserted.\\n\\n## Metrics on sync time for a tree with 2,653 leaves\\n\\nThe following metrics are based on the current implementation of RLN in the Waku gen0 network.\\n\\n### Test bench\\n\\n- Hardware: Macbook Air M2, 16GB RAM\\n- Network: 120 Megabits/sec\\n- Nwaku commit: [e61e4ff](https://github.com/waku-org/nwaku/tree/e61e4ff90a235657a7dc4248f5be41b6e031e98c)\\n- RLN membership set contract: [0xF471d71E9b1455bBF4b85d475afb9BB0954A29c4](https://sepolia.etherscan.io/address/0xF471d71E9b1455bBF4b85d475afb9BB0954A29c4#code)\\n- Deployed block number: 4,230,716\\n- RLN Membership set depth: 20\\n- Hash function: PoseidonT3 (which is a gas guzzler)\\n- Max size of the membership set: 2^20 = 1,048,576 leaves\\n\\n### Metrics\\n\\n- Time to sync the whole tree: 4 minutes\\n- RPC calls: 702\\n- Number of leaves: 2,653\\n\\nOne can argue that the time to sync the tree at the current state is not _that_ bad.\\nHowever, the number of RPC calls is a concern,\\nwhich scales linearly with the number of blocks since the contract was deployed\\nThis is because the implementation fetches all events from the contract,\\nchunking 2,000 blocks at a time.\\nThis is done to avoid hitting the block limit of 10,000 events per call,\\nwhich is a limitation of popular RPC providers.\\n\\n## Proposed solution\\n\\nFrom a theoretical perspective,\\none could construct the merkle tree on-chain,\\nin a view call, in-memory.\\nHowever, this is not feasible due to the gas costs associated with it.\\n\\nTo compute the root of a Merkle tree with $2^{20}$ leaves it costs approximately 2 billion gas.\\nWith Infura and Alchemy capping the gas limit to 350M and 550M gas respectively,\\nit is not possible to compute the root of the tree in a single call.\\n\\nAcknowledging that [Polygon Miden](https://polygon.technology/blog/polygon-miden-state-model) and [Penumbra](https://penumbra.zone/blog/tiered-commitment-tree/) both make use of a tiered commitment tree,\\nwe propose a similar approach for RLN.\\n\\nA tiered commitment tree is a tree which is sharded into multiple smaller subtrees,\\neach of which is a tree in itself.\\nThis allows scaling in terms of the number of leaves,\\nas well as reducing state bloat by just storing the root of a subtree when it is full instead of all its leaves.\\n\\nHere, the question arises:\\nWhat is the maximum number of leaves in a subtree with which the root can be computed in a single call?\\n\\nIt costs approximately 217M gas to compute the root of a Merkle tree with $2^{10}$ leaves.\\n\\nThis is a feasible number for a single call,\\nand hence we propose a tiered commitment tree with a maximum of $2^{10}$ leaves in a subtree and the number of subtrees is $2^{10}$.\\nTherefore, the maximum number of leaves in the tree is $2^{20}$ (the same as the current implementation).\\n\\n![img](/img/light-rln-verifiers.png)\\n\\n### Insertion\\n\\nWhen a commitment is inserted into the tree it is first inserted into the first subtree.\\nWhen the first subtree is full the next insertions go into the second subtree and so on.\\n\\n### Syncing\\n\\nWhen syncing the tree,\\none only needs to fetch the roots of the subtrees.\\nThe root of the full tree can be computed in-memory or on-chain.\\n\\nThis allows us to derive the following relation:\\n\\n$$\\nnumber\\\\_of\\\\_rpc\\\\_calls = number\\\\_of\\\\_filled\\\\_subtrees + 1\\n$$\\n\\nThis is a significant improvement over the current implementation,\\nwhich requires fetching all the memberships from the smart contract.\\n\\n### Gas costs\\n\\nThe gas costs for inserting a commitment into the tree are the same as the current implementation except it consists of an extra SSTORE operation to store the `shardIndex` of the commitment.\\n\\n### Events\\n\\nThe events emitted by the contract are the same as the current implementation,\\nappending the `shardIndex` of the commitment.\\n\\n### Proof of concept\\n\\nA proof of concept implementation of the tiered commitment tree is available [here](https://github.com/vacp2p/rln-contract/pull/37),\\nand is deployed on Sepolia at [0xE7987c70B54Ff32f0D5CBbAA8c8Fc1cAf632b9A5](https://sepolia.etherscan.io/address/0xE7987c70B54Ff32f0D5CBbAA8c8Fc1cAf632b9A5).\\n\\nIt is compatible with the current implementation of the RLN verifier.\\n\\n## Future work\\n\\n1. Optimize the gas costs of the tiered commitment tree.\\n2. Explore using different number of leaves under a given node in the tree (currently set to 2).\\n\\n## Conclusion\\n\\nThe tiered commitment tree is a promising approach to reduce the number of RPC calls required to sync the tree and reduce the gas costs associated with computing the root of the tree.\\nConsequently, it allows for a more scalable and efficient RLN verifier.\\n\\n## References\\n\\n- [RLN Circuits](https://github.com/rate-limiting-nullifier/circom-rln)\\n- [Zerokit](https://github.com/vacp2p/zerokit)\\n- [RLN-V1 RFC](https://rfc.vac.dev/spec/32/)\\n- [RLN-V2 RFC](https://rfc.vac.dev/spec/58/)\\n- [RLN Implementers guide](https://hackmd.io/7cBCMU5hS5OYv8PTaW2wAQ?view)\\n- [Strengthening Anonymous DoS Prevention with Rate Limiting Nullifiers in Waku](https://vac.dev/rlog/rln-anonymous-dos-prevention)"},{"id":"rln-anonymous-dos-prevention","metadata":{"permalink":"/rlog/rln-anonymous-dos-prevention","source":"@site/rlog/2023-11-07-rln-relay.mdx","title":"Strengthening Anonymous DoS Prevention with Rate Limiting Nullifiers in Waku","description":"Rate Limiting Nullifiers in practice, applied to an anonymous p2p network, like Waku.","date":"2023-11-07T12:00:00.000Z","formattedDate":"November 7, 2023","tags":[],"readingTime":6.77,"hasTruncateMarker":true,"authors":[{"name":"Aaryamann","twitter":"p1ge0nh8er","github":"rymnc","key":"p1ge0nh8er"}],"frontMatter":{"title":"Strengthening Anonymous DoS Prevention with Rate Limiting Nullifiers in Waku","date":"2023-11-07T12:00:00.000Z","authors":"p1ge0nh8er","published":true,"slug":"rln-anonymous-dos-prevention","categories":"research","toc_min_heading_level":2,"toc_max_heading_level":4},"prevItem":{"title":"Verifying RLN Proofs in Light Clients with Subtrees","permalink":"/rlog/rln-light-verifiers"},"nextItem":{"title":"GossipSub Improvements: Evolution of Overlay Design and Message Dissemination in Unstructured P2P Networks","permalink":"/rlog/GossipSub Improvements"}},"content":"Rate Limiting Nullifiers in practice, applied to an anonymous p2p network, like Waku.\\n\\n\x3c!--truncate--\x3e\\n\\n## Introduction\\n\\nRate Limiting Nullifier (RLN) is a zero-knowledge gadget that allows users to prove 2 pieces of information,\\n1. They belong to a permissioned membership set\\n2. Their rate of signaling abides by a fixed number that has been previously declared\\n\\nThe \\"membership set\\" introduced above, is in the form of a sparse, indexed merkle tree.\\nThis membership set can be maintained on-chain, off-chain or as a hybrid depending on the network\'s storage costs.\\nWaku makes use of a hybrid membership set, \\nwhere insertions are tracked in a smart contract.\\nIn addition, each Waku node maintains a local copy of the tree, \\nwhich is updated upon each insertion.\\n\\nUsers register themselves with a hash of a locally generated secret, \\nwhich is then inserted into the tree at the next available index.\\nAfter having registered, users can prove their membership by proving their knowledge of the pre-image of the respective leaf in the tree.\\nThe leaf hashes are also referred to as commitments of the respective users.\\nThe actual proof is done by a [Merkle Inclusion Proof](https://ethereum.org/en/developers/tutorials/merkle-proofs-for-offline-data-integrity/), which is a type of ZK proof.\\n\\nThe circuit ensures that the user\'s secret does indeed hash to a leaf in the tree,\\nand that the provided Merkle proof is valid.\\n\\nAfter a User generates this Merkle proof, \\nthey can transmit it to other users, \\nwho can verify the proof.\\nIncluding a message\'s hash within the proof generation, \\nadditionally guarantees integrity of that message.\\n\\nA malicious user could generate multiple proofs per epoch.\\nthey generate multiple proofs per epoch.\\nHowever, when multiple proofs are generated per epoch, \\nthe malicious user\'s secret is exposed, which strongly disincentivizes this attack.\\nThis mechanism is further described in [malicious User secret interpolation mechanism](#malicious-user-secret-interpolation-mechanism)\\n\\nNote: This blog post describes rln-v1, which excludes the range check in favor of a global rate limit for all users,\\nwhich is once per time window. This version is currently in use in waku-rln-relay.\\n\\n## RLN Protocol parameters\\n\\nGiven below is the set of cryptographic primitives, \\nand constants that are used in the RLN protocol. \\n\\n1. Proving System: [`groth16`](https://eprint.iacr.org/2016/260.pdf)\\n2. Elliptic Curve: [`bn254`](https://eprint.iacr.org/2013/879.pdf) (aka bn128) (not to be confused with the 254 bit Weierstrass curve)\\n3. Finite Field: Prime-order subgroup of the group of points on the `bn254` curve\\n4. Default Merkle Tree Height: `20`\\n5. Hashing algorithm: [`Poseidon`](https://eprint.iacr.org/2019/458.pdf)\\n6. Merkle Tree: [`Sparse Indexed Merkle Tree`](https://github.com/rate-limiting-nullifier/pmtree)\\n7. Messages per epoch: `1`\\n8. Epoch duration: `10 seconds`\\n\\n## Malicious User secret interpolation mechanism\\n\\n> note: all the parameters mentioned below are elements in the finite field mentioned above.\\n\\nThe private inputs to the circuit are as follows: -\\n```\\nidentitySecret: the randomly generated secret of the user\\nidentityPathIndex: the index of the commitment derived from the secret\\npathElements: elements included in the path to the index of the commitment\\n```\\n\\nFollowing are the public inputs to the circuit -\\n```\\nx: hash of the signal to the finite field\\nrlnIdentifier: application-specific identifier which this proof is being generated for\\nepoch: the timestamp which this proof is being generated for\\n```\\n\\nThe outputs of the circuit are as follows: -\\n```\\ny: result of Shamir\'s secret sharing calculation\\nroot: root of the Merkle tree obtained after applying the inclusion proof\\nnullifier: uniquely identifies a message, derived from rlnIdentifier, epoch, and the user\'s secret\\n```\\n\\nWith the above data in mind, following is the circuit pseudocode -\\n\\n```\\nidentityCommitment = Poseidon([identitySecret])\\nroot = MerkleInclusionProof(identityCommitment, identityPathIndex, pathElements)\\nexternalNullifier = Poseidon([epoch, rlnIdentifier])\\na1 = Poseidon([identitySecret, externalNullifier])\\ny = identitySecret + a1 * x\\nnullifier = Poseidon([a1])\\n```\\n\\nTo interpolate the secret of a user who has sent multiple signals during the same epoch to the same rln-based application, we may make use of the following formula -\\n\\n$$a_1 = {(y_1 - y_2) \\\\over (x_1 - x_2)}$$\\n\\nwhere $x_1$, $y_1$ and $x_2$, $y_2$ are shares from different messages\\n\\nsubsequently, we may use one pair of the shares, $x_1$ and $y_1$ to obtain the `identitySecret`\\n\\n$$identitySecret = y_1 - a_1 * x$$\\n\\nThis enables RLN to be used for rate limiting with a *global* limit. For arbitrary limits,\\nplease refer to an article written by @curryrasul, [rln-v2](https://mirror.xyz/privacy-scaling-explorations.eth/iCLmH1JVb7fDqp6Mms2NR001m2_n5OOSHsLF2QrxDnQ).\\n\\n\\n## Waku\'s problem with DoS\\n\\nIn a decentralized, privacy focused messaging system like [Waku](https://waku.org),\\nDenial of Service (DoS) vulnerabilities are very common, and must be addressed to promote network scale and optimal bandwidth utilization.\\n\\n### DoS prevention with user metadata\\n\\nThere are a couple of ways a user can be rate-limited, either -\\n1. IP Logging\\n2. KYC Logging\\n\\nBoth IP and KYC logging prevent systems from being truly anonymous, and hence, cannot be used as a valid DoS prevention mechanism for Waku.\\n\\nRLN can be used as an alternative, which provides the best of both worlds, i.e a permissioned membership set, as well as anonymous signaling.\\nHowever, we are bound by k-anonymity rules of the membership set.\\n\\n[Waku-RLN-Relay](https://rfc.vac.dev/spec/17/) is a [libp2p](https://libp2p.io) pubsub validator that verifies if a proof attached to a given message is valid.\\nIn case the proof is valid, the message is relayed.\\n\\n## Performance analysis\\n\\n> Test bench specs: AMD EPYC 7502P 32-Core, 4x32GB DDR4 Reg.ECC Memory \\n\\nThis simulation was conducted by @alrevuelta, and is described in more detail [here](https://github.com/waku-org/research/issues/23).\\n\\nThe simulation included 100 waku nodes running in parallel.\\n\\nProof generation times - \\n![img](/img/rln-relay-2023-update//proof_generation_time.png)\\n\\nProof verification times -\\n![img](/img/rln-relay-2023-update/proof_verification_time.png)\\n\\nA spammer node publishes 3000 msg/epoch, which is detected by all connected nodes, and subsequently disconnect to prevent further spam -\\n![img](/img/rln-relay-2023-update/spam_prevention_in_action.png)\\n\\n\\n## Security analysis\\n\\n[Barbulescu and Duquesne](https://doi.org/10.1007/s00145-018-9280-5)\\nconclude that that the `bn254` curve has only 100 bits of security.\\nSince the bn254 curve has a small embedding degree,\\nit is vulnerable to the [MOV attack](https://en.wikipedia.org/wiki/MOV_attack).\\nHowever, the MOV attack is only applicable to pairings,\\nand not to the elliptic curve itself.\\nIt is acceptable to use the bn254 curve for RLN,\\nsince the circuit does not make use of pairings.\\n\\n[An analysis](https://github.com/vacp2p/research/issues/155) on the number of rounds in the Poseidon hash function was done,\\nwhich concluded that the hashing rounds should *not* be reduced, \\n\\nThe [smart contracts](https://github.com/vacp2p/rln-contract) have *not* been audited, and are not recommended for real world deployments *yet*.\\n\\n\\n## Storage analysis\\n\\n$$\\ncommitment\\\\_size = 32\\\\ bytes \\\\\\\\\\ntree\\\\_height =20 \\\\\\\\\\ntotal\\\\_leaves = 2^{20} \\\\\\\\ \\nmax\\\\_tree\\\\_size = total\\\\_leaves * commitment\\\\_size \\\\\\\\\\nmax\\\\_tree\\\\_size = 2^{20} * 32 = 33,554,432 \\\\\\\\\\n\u2234max\\\\_tree\\\\_size = 33.55\\\\ megabytes\\n$$\\nThe storage overhead introduced by RLN is minimal.\\nRLN only requires 34 megabytes of storage, which poses no problem on most end-user hardware, with the exception of IoT/microcontrollers.\\nStill, we are working on further optimizations allowing proof generation without having to store the full tree.\\n\\n## The bare minimum requirements to run RLN\\n\\nWith proof generation time in sub-second latency, along with low storage overhead for the tree,\\nit is possible for end users to generate and verify RLN proofs on a modern smartphone.\\n\\nFollowing is a demo provided by @rramos that demonstrates\\n[waku-rln-relay used in react native](https://drive.google.com/file/d/1ITLYrDOQrHQX2_3Q6O5EqKPYJN8Ye2gF/view?usp=sharing).\\n\\n> Warning: The react native sdk will be deprecated soon, and the above demo should serve as a PoC for RLN on mobiles\\n\\n## RLN usage guide\\n\\n[Zerokit](https://github.com/vacp2p/zerokit) implements api\'s that allow users to handle operations to the tree, \\nas well as generate/verify RLN proofs.\\n\\nOur main implementation of RLN can be accessed via this Rust [crate](https://crates.io/crates/rln),\\nwhich is documented [here](https://docs.rs/rln/0.4.1/rln/public/struct.RLN.html).\\nIt can used in other langugages via the FFI API, which is documented [here](https://docs.rs/rln/0.4.1/rln/ffi/index.html).\\nThe usage of RLN in Waku is detailed in our [RLN Implementers guide](https://hackmd.io/7cBCMU5hS5OYv8PTaW2wAQ?view),\\nwhich provides step-by-step instructions on how to run Waku-RLN-Relay.\\n\\nFollowing is a diagram that will help understand the dependency tree -\\n\\n![rln-dep-tree](/img/rln-relay-2023-update/rln_dep_tree.jpg)\\n\\n## Future work\\n\\n- Optimizations to zerokit for proof generation time.\\n- Incrementing tree depth from 20 to 32, to allow more memberships.\\n- Optimizations to the smart contract.\\n- An ability to signal validity of a message in different time windows.\\n- Usage of proving systems other than Groth16.\\n\\n## References\\n\\n* [RLN Circuits](https://github.com/rate-limiting-nullifier/circom-rln)\\n* [Zerokit](https://github.com/vacp2p/zerokit)\\n* [RLN-V1 RFC](https://rfc.vac.dev/spec/32/)\\n* [RLN-V2 RFC](https://rfc.vac.dev/spec/58/)\\n* [RLN Implementers guide](https://hackmd.io/7cBCMU5hS5OYv8PTaW2wAQ?view)\\n* [groth16](https://eprint.iacr.org/2016/260.pdf)\\n* [bn254](https://eprint.iacr.org/2013/879.pdf)\\n* [Poseidon Hash](https://eprint.iacr.org/2019/458.pdf)\\n* [Sparse Indexed Merkle Tree](https://github.com/rate-limiting-nullifier/pmtree)\\n* [Updating key size estimations for pairings](https://doi.org/10.1007/s00145-018-9280-5)"},{"id":"GossipSub Improvements","metadata":{"permalink":"/rlog/GossipSub Improvements","source":"@site/rlog/2023-09-27-gossipimprovements.mdx","title":"GossipSub Improvements: Evolution of Overlay Design and Message Dissemination in Unstructured P2P Networks","description":"GossipSub Improvements: Evolution of Overlay Design and Message Dissemination in Unstructured P2P Networks","date":"2023-11-06T12:00:00.000Z","formattedDate":"November 6, 2023","tags":[],"readingTime":13.815,"hasTruncateMarker":true,"authors":[{"name":"Umar Farooq","github":"ufarooqstatus","key":"farooq"}],"frontMatter":{"title":"GossipSub Improvements: Evolution of Overlay Design and Message Dissemination in Unstructured P2P Networks","date":"2023-11-06T12:00:00.000Z","authors":"farooq","published":true,"slug":"GossipSub Improvements","categories":"research","toc_min_heading_level":2,"toc_max_heading_level":5},"prevItem":{"title":"Strengthening Anonymous DoS Prevention with Rate Limiting Nullifiers in Waku","permalink":"/rlog/rln-anonymous-dos-prevention"},"nextItem":{"title":"Nescience - A zkVM leveraging hiding properties","permalink":"/rlog/Nescience-A-zkVM-leveraging-hiding-properties"}},"content":"GossipSub Improvements: Evolution of Overlay Design and Message Dissemination in Unstructured P2P Networks \\r\\n\\r\\n\x3c!--truncate--\x3e\\r\\n\\r\\n## Motivitation\\r\\nWe have been recently working on analyzing and improving the performance of the GossipSub protocol for large messages, \\r\\nas in the case of Ethereum Improvement Proposal [EIP-4844](https://eips.ethereum.org/EIPS/eip-4844).\\r\\nThis work led to a comprehensive study of unstructured P2P networks. \\r\\nThe intention was to identify the best practices that can serve as guidelines for performance improvement and scalability of P2P networks.\\r\\n\\r\\n## Introduction\\r\\n\\r\\nNodes in an unstructured p2p network form self-organizing overlay(s) on top of the IP infrastructure to facilitate different services like information dissemination,\\r\\nquery propagation, file sharing, etc. The overlay(s) can be as optimal as a tree-like structure or as enforcing as a fully connected mesh. \\r\\n\\r\\nDue to peer autonomy and a trustless computing environment, some peers may deviate from the expected operation or even leave the network.\\r\\nAt the same time, the underlying IP layer is unreliable. \\r\\n\\r\\nTherefore, tree-like overlays are not best suited for reliable information propagation.\\r\\nMoreover, tree-based solutions usually result in significantly higher message dissemination latency due to suboptimal branches. \\r\\n\\r\\nFlooding-based solutions, on the other hand, result in maximum resilience against adversaries and achieve minimal message dissemination latency because the message propagates through all (including the optimal) paths. \\r\\nRedundant transmissions help maintain the integrity and security of the network in the presence of adversaries and high node failure but significantly increase network-wide bandwidth utilization, cramming the bottleneck links. \\r\\n\\r\\nAn efficient alternative is to lower the number of redundant transmissions by D-regular broadcasting, where a peer will likely receive (or relay) a message from up to $D$ random peers.\\r\\nPublishing through a D-regular overlay triggers approximately $N \\\\times D$ transmissions.\\r\\nReducing $D$ reduces the redundant transmissions but compromises reachability and latency. \\r\\nSharing metadata through a K-regular overlay (where $K > D$) allows nodes to pull missing messages. \\r\\n\\r\\nGossipSub [[1](https://arxiv.org/pdf/2007.02754.pdf)] benefits from full-message (D-regular) and metadata-only (k-regular) overlays.\\r\\nAlternatively, a metadata-only overlay can be used, requiring a pull-based operation that significantly minimizes bandwidth utilization at the cost of increased latency. \\r\\n\\r\\nStriking the right balance between parameters like $D, K$, pull-based operation, etc., can yield application-specific performance tuning, but scalability remains a problem.\\r\\n\\r\\nAt the same time, many other aspects can significantly contribute to the network\'s performance and scalability.\\r\\nOne option is to realize peers\' suitability and continuously changing capabilities while forming overlays. \\r\\n\\r\\nFor instance, a low-bandwidth link near a publisher can significantly demean the entire network\'s performance.\\r\\nReshuffling of peering links according to the changing network conditions can lead to superior performance. \\r\\n\\r\\nLaying off additional responsibilities to more capable nodes (super nodes) can alleviate peer cramming, but it makes the network susceptible to adversaries/peer churn.\\r\\nGrouping multiple super nodes to form virtual node(s) can solve this problem. \\r\\n\\r\\n\\r\\nSimilarly, flat (single-tier) overlays cannot address the routing needs in large (geographically dispersed) networks.\\r\\n\\r\\nHierarchical (Multi-tier) overlays with different intra/inter-overlay routing solutions can better address these needs.\\r\\nMoreover, using message aggregation schemes for grouping multiple messages can save bandwidth and provide better resilience against adversaries/peer churn.\\r\\n\\r\\n\\r\\nThis article\'s primary objective is to investigate the possible choices that can empower an unstructured P2P network to achieve superior performance for the broadest set of applications. \\r\\nWe look into different constraints imposed by application-specific needs (performance goals) and investigate various choices that can augment the network\'s performance. \\r\\nWe explore overlay designs/freshness, peer selection approaches, message-relaying mechanisms, and resilience against adversaries/peer churn. \\r\\nWe consider GossipSub a baseline protocol to explore various possibilities and decisively commit to the ones demonstrating superior performance.\\r\\nWe also discuss the current state and, where applicable, propose a strategic plan for embedding new features to the GossipSub protocol. \\r\\n\\r\\n\\r\\n## GOAL1: Low Latency Operation\\r\\nDifferent applications, like blockchain, streaming, etc., impose strict time bounds on network-wide message dissemination latency. \\r\\nA message delivered after the imposed time bounds is considered as dropped. \\r\\nAn early message delivery in applications like live streaming can further enhance the viewing quality.\\r\\n\\r\\nThe properties and nature of the overlay network topology significantly impact the performance of services and applications executed on top of them. \\r\\nStudying and devising mechanisms for better overlay design and message dissemination is paramount to achieving superior performance.\\r\\n\\r\\nInterestingly, shortest-path message delivery trees have many limitations: \\r\\n\\r\\n1) Changing network dynamics requires a quicker and continuous readjustment of the multicast tree. \\r\\n2) The presence of resource-constrained (bandwidth/compute, etc.) nodes in the overlay can result in congestion. \\r\\n3) Node failure can result in partitions, making many segments unreachable. \\r\\n4) Assuring a shortest-path tree-like structure requires a detailed view of the underlying (and continuously changing) network topology. \\r\\n\\r\\n\\r\\nSolutions involve creating multiple random trees to add redundancy [[2](https://ieeexplore.ieee.org/abstract/document/6267905)].\\r\\nAlternatives involve building an overlay mesh and forwarding messages through the multicast delivery tree (eager push). \\r\\n\\r\\nMetadata is shared through the overlay links so that the nodes can ask for missing messages (lazy push or pull-based operation) through the overlay links. \\r\\nNew nodes are added from the overlay on node failure, but it requires non-faulty node selection.\\r\\n\\r\\nGossipSub uses eager push (through overlay mesh) and lazy push (through IWANT messages). \\r\\n\\r\\nThe mesh degree $D_{Low} \\\\leq D \\\\leq D_{High}$ is crucial in deciding message dissemination latency. \\r\\nA smaller value for $D$ results in higher latency due to increased rounds, whereas a higher $D$ reduces latency on the cost of increased bandwidth. \\r\\nAt the same time, keeping $D$ independent of the growing network size ($N$) may increase network-wide message dissemination latency.\\r\\nAdjusting $D$ with $N$ maintains similar latency on the cost of increased workload for peers. \\r\\nAuthors in [[3](https://infoscience.epfl.ch/record/83478/files/EugGueKerMas04IEEEComp.pdf)] suggest only a logarithmic increase in $D$ to maintain a manageable workload for peers.\\r\\nIn [[4](https://inria.hal.science/tel-02375909/document)], it is reported that the average mesh degree should not exceed $D_{avg} = \\\\ln(N) + C$ for an optimal operation, \\r\\nwhere $C$ is a small constant.\\r\\n\\r\\nMoreover, quicker shuffling of peers results in better performance in the presence of resource-constrained nodes or node failure [[4](https://inria.hal.science/tel-02375909/document)].\\r\\n\\r\\n## GOAL2: Considering Heterogeneity In Overlay Design\\r\\nRandom peering connections in P2P overlays represent a stochastic process. It is inherently difficult to precisely model the performance of such systems. \\r\\nMost of the research on P2P networks provides simulation results assuming nodes with similar capabilities. \\r\\nThe aspect of dissimilar capabilities and resource-constrained nodes is less explored.\\r\\n\\r\\nIt is discussed in GOAL1 that overlay mesh results in better performance if $D_{avg}$ does not exceed $\\\\ln(N) + C$. \\r\\nEnforcing all the nodes to have approximately $\\\\ln(N) + C$ peers makes resource-rich nodes under-utilized, while resource-constrained nodes are overloaded. \\r\\nAt the same time, connecting high-bandwidth nodes through a low-bandwidth node undermines the network\'s performance.\\r\\nIdeally, the workload on any node should not exceed its available resources.\\r\\nA better solution involves a two-phased operation:\\r\\n\\r\\n\\r\\n1. Every node computes its available bandwidth and selects a node degree $D$ proportional to its available bandwidth [[4](https://inria.hal.science/tel-02375909/document)].\\r\\n Different bandwidth estimation approaches are suggested in literature [[5](https://ieeexplore.ieee.org/abstract/document/1224454),[6](https://ieeexplore.ieee.org/abstract/document/1248658)]. \\r\\n Simple bandwidth estimation approaches like variable packet size probing [[6](https://ieeexplore.ieee.org/abstract/document/1248658)] yield similar results with less complexity.\\r\\n It is also worth mentioning that many nodes may want to allocate only a capped share of their bandwidth to the network. \\r\\n Lowering $D$ according to the available bandwidth can still prove helpful. \\r\\n Additionally, bandwidth preservation at the transport layer through approaches like \xb5TP can be useful.\\r\\n To further conform to the suggested mesh-degree average $D_{avg}$, every node tries achieving this average within its neighborhood, resulting in an overall similar $D_{avg}$.\\r\\n\\r\\n2. From the available local view, every node tries connecting peers with the lowest latency until $D$ connections are made.\\r\\n We suggest referring to the peering solution discussed in GOAL5 to avoid network partitioning.\\r\\n\\r\\nThe current GossipSub design considers homogeneous peers, and every node tries maintaining $D_{Low} \\\\leq D \\\\leq D_{High}$ connections. \\r\\n\\r\\n\\r\\n## GOAL3: Bandwidth Optimization\\r\\nRedundant message transmissions are essential for handling adversaries/node failure. However, these transmissions result in traffic bursts, cramming many overlay links. \\r\\nThis not only adds to the network-wide message dissemination latency but a significant share of the network\'s bandwidth is wasted on (usually) unnecessary transmissions. \\r\\nIt is essential to explore solutions that can minimize the number of redundant transmissions while assuring resilience against node failures. \\r\\n\\r\\nMany efforts have been made to minimize the impact of redundant transmissions. \\r\\nThese solutions include multicast delivery trees, metadata sharing to enable pull-based operation, in-network information caching, etc. [[7](https://dl.acm.org/doi/abs/10.1145/945445.945473),[8](https://link.springer.com/chapter/10.1007/11558989_12)]. \\r\\nGossipSub employs a hybrid of eager push (message dissemination through the overlay) and lazy push (a pull-based operation by the nodes requiring information through IWANT messages). \\r\\n\\r\\nA better alternative to simple redundant transmission is to use message aggregation [[9](https://ieeexplore.ieee.org/abstract/document/8737576),[10](https://dl.acm.org/doi/abs/10.1145/1993636.1993676),[11](https://ieeexplore.ieee.org/abstract/document/4276446)] for the GossipSub protocol. \\r\\nAs a result, redundant message transmissions can serve as a critical advantage of the GossipSub protocol. \\r\\nSuppose that we have three equal-length messages $x1, x2, x3$. Assuming an XOR coding function,\\r\\nwe know two trivial properties: $x1 \\\\oplus x2 \\\\oplus x2 = x1$ and $\\\\vert x1 \\\\vert = \\\\vert x1 \\\\oplus x2 \\\\oplus x2 \\\\vert$. \\r\\n\\r\\nThis implies that instead of sending messages individually, we can encode and transmit composite message(s) to the network. \\r\\nThe receiver can reconstruct the original message from encoded segments. \\r\\nAs a result, fewer transmissions are sufficient for sending more messages to the network. \\r\\n\\r\\nHowever, sharing linear combinations of messages requires organizing messages in intervals, \\r\\nand devising techniques to identify all messages belonging to each interval.\\r\\nIn addition, combining messages from different publishers requires more complex arrangements, \\r\\ninvolving embedding publisher/message IDs, delayed forwarding (to accommodate more messages), and mechanisms to ensure the decoding of messages at all peers.\\r\\nCareful application-specific need analysis can help decide the benefits against the added complexity. \\r\\n\\r\\n## GOAL4: Handling Large Messages\\r\\nMany applications require transferring large messages for their successful operation. For instance, database/blockchain transactions [[12](https://eips.ethereum.org/EIPS/eip-4844)]. \\r\\nThis introduces two challenges: \\r\\n\\r\\n1) Redundant large message transmissions result in severe network congestion. \\r\\n2) Message transmissions follow a store/forward process at all peers, which is inefficient in the case of large messages. \\r\\n\\r\\nThe above-mentioned challenges result in a noticeable increase in message dissemination latency and bandwidth wastage. \\r\\nMost of the work done for handling large messages involves curtailing redundant transmissions using multicast delivery trees,\\r\\nreducing the number of fanout nodes, employing in-network message caching, pull-based operation, etc.\\r\\n\\r\\nApproaches like message aggregation also prove helpful in minimizing bandwidth wastage.\\r\\n\\r\\nOur recent work on GossipSub improvements (still a work in progress) suggests the following solutions to deal with large message transmissions: \\r\\n\\r\\n1. Using IDontWant message proposal [[13](https://github.com/libp2p/specs/pull/413)] and staggered sending. \\r\\n\\r\\n IDontWant message helps curtail redundant transmissions by letting other peers know we have already received the message.\\r\\n Staggered sending enables relaying the message to a short subset of peers in each round.\\r\\n We argue that simultaneously relaying a message to all peers hampers the effectiveness of the IDontWant message.\\r\\n Therefore, using the IDontWant message with staggered sending can yield better results by allowing timely reception and processing of IDontWant messages.\\r\\n\\r\\n2. Message transmissions follow a store/forward process at all peers that is inefficient in the case of large messages.\\r\\n We can parallelize message transmission by partitioning large messages into smaller fragments, letting intermediate peers relay these fragments as soon as they receive them.\\r\\n\\r\\n\\r\\n## GOAL5: Scalability\\r\\nP2P networks are inherently scalable because every incoming node brings in bandwidth and compute resources.\\r\\nIn other words, we can keep adding nodes to the network as long as every incoming node brings at-least $R \\\\times D$ bandwidth, \\r\\nwhere $R$ is average data arrival rate. \\r\\nIt is worth mentioning that network-wide message dissemination requires at-least $\\\\lceil \\\\log_D (N) \\\\rceil$ hops. \\r\\nTherefore, increasing network size increases message dissemination latency, assuming D is independent of the network size.\\r\\n\\r\\nAdditionally, problems like peer churn, adversaries, heterogeneity, distributed operation, etc., significantly hamper the network\'s performance.\\r\\nMost efforts for bringing scalability to the P2P systems have focused on curtailing redundant transmissions and flat overlay adjustments.\\r\\nHierarchical overlay designs, on the other hand, are less explored.\\r\\n\\r\\nPlacing a logical structure in unstructured P2P systems can help scale P2P networks. \\r\\n\\r\\nOne possible solution is to use a hierarchical overlay inspired by the approaches [[14](https://link.springer.com/article/10.1007/s12083-016-0460-5),[15](https://link.springer.com/chapter/10.1007/978-3-030-19223-5_16),[16](https://ieeexplore.ieee.org/abstract/document/9826458)]. \\r\\nAn abstract operation of such overlay design is provided below:\\r\\n\\r\\n1. Clustering nodes based on locality, assuming that such peers will have relatively lower intra-cluster latency and higher bandwidth. \\r\\n For this purpose, every node tries connecting peers with the lowest latency until $D$ connections are made or the cluster limit is reached.\\r\\n\\r\\n2. A small subset of nodes having the highest bandwidth and compute resources is selected from each cluster. \\r\\n These super nodes form a fully connected mesh and jointly act as a virtual node, \\r\\n mitigating the problem of peer churn among super nodes.\\r\\n \\r\\n3. Virtual nodes form a fully connected mesh to construct a hierarchical overlay. \\r\\n Each virtual node is essentially a collection of super nodes; \\r\\n a link to any of the constituent super nodes represents a link to the virtual node.\\r\\n\\r\\n4. One possible idea is to use GossipSub for intra-cluster message dissemination and FloodSub for inter-cluster message dissemination.\\r\\n\\r\\n## Summary\\r\\nOverlay acts as a virtual backbone for a P2P network. A flat overlay is more straightforward and allows effortless readjustment to application needs. \\r\\nOn the other hand, a hierarchical overlay can bring scalability at the cost of increased complexity. \\r\\nRegardless of the overlay design, a continuous readjustment to appropriate peering links is essential for superior performance. \\r\\nAt the same time, bandwidth preservation (through message aggregation, caching at strategic locations, metadata sharing, pull-based operation, etc.) can help minimize latency.\\r\\nHowever, problems like peer churn and in-network adversaries can be best alleviated through balanced redundant coverage, and frequent reshuffling of the peering links.\\r\\n\\r\\n# References\\r\\n\\r\\n* [1] D. Vyzovitis, Y. Napora, D. McCormick, D. Dias, and Y. Psaras, \u201cGossipsub: Attack-resilient message propagation in the filecoin and eth2. 0 networks,\u201d arXiv preprint arXiv:2007.02754, 2020. Retrieved from https://arxiv.org/pdf/2007.02754.pdf\\r\\n* [2] M. Matos, V. Schiavoni, P. Felber, R. Oliveira, and E. Riviere, \u201cBrisa: Combining efficiency and reliability in epidemic data dissemination,\u201d in 2012 IEEE 26th International Parallel and Distributed Processing Symposium. IEEE, 2012, pp. 983\u2013994. Retrieved from https://ieeexplore.ieee.org/abstract/document/6267905\\r\\n* [3] P. T. Eugster, R. Guerraoui, A. M. Kermarrec, and L. Massouli, \u201cEpidemic information dissemination in distributed systems,\u201d IEEE Computer, vol. 37, no. 5, 2004. Retrieved from https://infoscience.epfl.ch/record/83478/files/EugGueKerMas04IEEEComp.pdf\\r\\n* [4] D. Frey, \u201cEpidemic protocols: From large scale to big data,\u201d Ph.D. dissertation, Universite De Rennes 1, 2019. Retrieved from https://inria.hal.science/tel-02375909/document\\r\\n* [5] M. Jain and C. Dovrolis, \u201cEnd-to-end available bandwidth: measurement methodology, dynamics, and relation with tcp throughput,\u201d IEEE/ACM Transactions on networking, vol. 11, no. 4, pp. 537\u2013549, 2003. Retrieved from https://ieeexplore.ieee.org/abstract/document/1224454\\r\\n* [6] R. Prasad, C. Dovrolis, M. Murray, and K. Claffy, \u201cBandwidth estimation: metrics, measurement techniques, and tools,\u201d IEEE network, vol. 17, no. 6, pp. 27\u201335, 2003. Retrieved from https://ieeexplore.ieee.org/abstract/document/1248658\\r\\n* [7] D. Kostic, A. Rodriguez, J. Albrecht, and A. Vahdat, \u201cBullet: High bandwidth data dissemination using an overlay mesh,\u201d in Proceedings of the nineteenth ACM symposium on Operating systems principles, 2003, pp. 282\u2013297. Retrieved from https://dl.acm.org/doi/abs/10.1145/945445.945473\\r\\n* [8] V. Pai, K. Kumar, K. Tamilmani, V. Sambamurthy, and A. E. Mohr, \u201cChainsaw: Eliminating trees from overlay multicast,\u201d in Peer-to-Peer Systems IV: 4th International Workshop, IPTPS 2005, Ithaca, NY, USA, February 24-25, 2005. Revised Selected Papers 4. Springer, 2005, pp. 127\u2013140. Retrieved from https://link.springer.com/chapter/10.1007/11558989_12\\r\\n* [9] Y.-D. Bromberg, Q. Dufour, and D. Frey, \u201cMultisource rumor spreading with network coding,\u201d in IEEE INFOCOM 2019-IEEE Conference on Computer Communications. IEEE, 2019, pp. 2359\u20132367. Retrieved from https://ieeexplore.ieee.org/abstract/document/8737576\\r\\n* [10] B. Haeupler, \u201cAnalyzing network coding gossip made easy,\u201d in Proceedings of the forty-third annual ACM symposium on Theory of computing, 2011, pp. 293\u2013302. Retrieved from https://dl.acm.org/doi/abs/10.1145/1993636.1993676\\r\\n* [11] S. Yu and Z. Li, \u201cMassive data delivery in unstructured peer-to-peer networks with network coding,\u201d in 6th IEEE/ACIS International Conference on Computer and Information Science (ICIS 2007). IEEE, 2007, pp. 592\u2013597. Retrieved from https://ieeexplore.ieee.org/abstract/document/4276446\\r\\n* [12] V. Buterin, D. Feist, D. Loerakker, G. Kadianakis, M. Garnett, M. Taiwo, and A. Dietrichs, \u201cEip-4844: Shard blob transactions scale data-availability of ethereum in a simple, forwards-compatible manner,\u201d 2022. Retrieved from https://eips.ethereum.org/EIPS/eip-4844\\r\\n* [13] A. Manning, \u201cGossipsub extension for epidemic meshes (v1.2.0),\u201d 2022. Retrieved from https://github.com/libp2p/specs/pull/413\\r\\n* [14] Z. Duan, C. Tian, M. Zhou, X. Wang, N. Zhang, H. Du, and L. Wang, \u201cTwo-layer hybrid peer-to-peer networks,\u201d Peer-to-Peer Networking and Applications, vol. 10, pp. 1304\u20131322, 2017. Retrieved from https://link.springer.com/article/10.1007/s12083-016-0460-5\\r\\n* [15] W. Hao, J. Zeng, X. Dai, J. Xiao, Q. Hua, H. Chen, K.-C. Li, and H. Jin, \u201cBlockp2p: Enabling fast blockchain broadcast with scalable peer-to-peer network topology,\u201d in Green, Pervasive, and Cloud Computing: 14th International Conference, GPC 2019, Uberlandia, Brazil, May 26\u201328, 2019, Proceedings 14. Springer, 2019, pp. 223\u2013237. Retrieved from https://link.springer.com/chapter/10.1007/978-3-030-19223-5_16\\r\\n* [16] H. Qiu, T. Ji, S. Zhao, X. Chen, J. Qi, H. Cui, and S. Wang, \u201cA geography-based p2p overlay network for fast and robust blockchain systems,\u201d IEEE Transactions on Services Computing, 2022. Retrieved from https://ieeexplore.ieee.org/abstract/document/9826458"},{"id":"Nescience-A-zkVM-leveraging-hiding-properties","metadata":{"permalink":"/rlog/Nescience-A-zkVM-leveraging-hiding-properties","source":"@site/rlog/2023-08-28-Nescience.mdx","title":"Nescience - A zkVM leveraging hiding properties","description":"Nescience, a privacy-first blockchain zkVM.","date":"2023-08-28T12:00:00.000Z","formattedDate":"August 28, 2023","tags":[],"readingTime":31.34,"hasTruncateMarker":true,"authors":[{"name":"Moudy","github":"moudyellaz","key":"moudy"}],"frontMatter":{"title":"Nescience - A zkVM leveraging hiding properties","date":"2023-08-28T12:00:00.000Z","authors":"moudy","published":true,"slug":"Nescience-A-zkVM-leveraging-hiding-properties","categories":"research","toc_min_heading_level":2,"toc_max_heading_level":5},"prevItem":{"title":"GossipSub Improvements: Evolution of Overlay Design and Message Dissemination in Unstructured P2P Networks","permalink":"/rlog/GossipSub Improvements"},"nextItem":{"title":"Device Pairing in Js-waku and Go-waku","permalink":"/rlog/device-pairing-in-js-waku-and-go-waku"}},"content":"Nescience, a privacy-first blockchain zkVM. \\n\\n\x3c!--truncate--\x3e\\n\\n## Introduction\\n\\nNescience is a privacy-first blockchain project that aims to enable private transactions and provide a general-purpose execution environment for classical applications. \\nThe goals include creating a state separation architecture for public/private computation, \\ndesigning a versatile virtual machine based on mainstream instruction sets, \\ncreating proofs for private state updates, implementing a kernel-based architecture for correct execution of private functions, \\nand implementing core DeFi protocols such as AMMs and staking from a privacy perspective. \\n\\nIt intends to create a user experience that is similar to public blockchains, but with additional privacy features that users can leverage at will. \\nTo achieve this goal, Nescience will implement a versatile virtual machine that can be used to implement existing blockchain applications, \\nwhile also enabling the development of privacy-centric protocols such as private staking and private DEXs.\\n\\nTo ensure minimal trust assumptions and prevent information leakage, Nescience proposes a proof system that allows users to create proofs for private state updates, \\nwhile the verification of the proofs and the execution of the public functions inside the virtual machine can be delegated to an external incentivised prover. \\n\\nIt also aims to implement a seamless interaction between public and private state, enabling composability between contracts, and private and public functions. \\nFinally, Nescience intends to implement permissive licensing, which means that the source code will be open-source, \\nand developers will be able to use and modify the code without any restriction.\\n\\nOur primary objective is the construction of the Zero-Knowledge Virtual Machine (zkVM). This document serves as a detailed exploration of the multifaceted challenges, \\npotential solutions, and alternatives that lay ahead. Each step is a testament to our commitment to thoroughness; \\nwe systematically test various possibilities and decisively commit to the one that demonstrates paramount performance and utility. \\nFor instance, as we progress towards achieving Goal 2, we are undertaking a rigorous benchmarking of the Nova proof system against its contemporaries. \\nShould Nova showcase superior performance metrics, we stand ready to integrate it as our proof system of choice. Through such meticulous approaches, \\nwe not only reinforce the foundation of our project but also ensure its scalability and robustness in the ever-evolving landscape of blockchain technology.\\n\\n\\n## Goal 1: Create a State Separation Architecture\\n\\nThe initial goal revolves around crafting a distinctive architecture that segregates public and private computations, \\nemploying an account-based framework for the public state and a UTXO-based structure for the private state. \\n\\nThe UTXO model [[1]( https://bitcoin.org/bitcoin.pdf),[2](https://iohk.io/en/blog/posts/2021/03/11/cardanos-extended-utxo-accounting-model/)], notably utilized in Bitcoin, generates new UTXOs to serve future transactions, \\nwhile the account-based paradigm assigns balances to accounts that transactions can modify. \\nAlthough the UTXO model bolsters privacy by concealing comprehensive balances, \\nthe pursuit of a dual architecture mandates a meticulous synchronization of these state models, \\nensuring that private transactions remain inconspicuous in the wider public network state. \\n\\nThis task is further complicated by the divergent transaction processing methods intrinsic to each model, \\nnecessitating a thoughtful and innovative approach to harmonize their functionality. \\nTo seamlessly bring together the dual architecture, harmonizing the account-based model for public state with the UTXO-based model for private state, \\na comprehensive strategy is essential.\\n\\nThe concept of blending an account-based structure with a UTXO-based model for differentiating between public and private states is intriguing. \\nIt seeks to leverage the strengths of both models: the simplicity and directness of the account-based model with the privacy enhancements of the UTXO model.\\n\\nHere\'s a breakdown and a potential strategy for harmonizing these models:\\n\\n### Rationale Behind the Dual Architecture: \\n\\n* **Account-Based Model:** This model is intuitive and easy to work with. Every participant has an account, \\nand transactions directly modify the balances of these accounts. It\'s conducive for smart contracts and a broad range of applications.\\n\\n* **UTXO-Based Model:** This model treats every transaction as a new output, which can then be used as an input for future transactions. \\nBy not explicitly associating transaction outputs with user identities, it offers a degree of privacy.\\n\\n### Harmonizing the Two Systems: \\n\\n1. Translation Layer\\n\\n * Role: Interface between UTXO and account-based states.\\n\\n * _UTXO-to-Account Adapter:_ When UTXOs are spent, the adapter can translate these into the corresponding account balance modifications. \\n This could involve creating a temporary \'pseudo-account\' that mirrors the \\n UTXO\'s attributes.\\n\\n * _Account-to-UTXO Adapter:_ When an account wishes to make a private transaction, \\n it would initiate a process converting a part of its balance to a UTXO, facilitating a privacy transaction.\\n\\n2. Unified Identity Management\\n\\n * Role: Maintain a unified identity (or address) system that works across both state models, \\n allowing users to easily manage their public and private states without requiring separate identities.\\n\\n * _Deterministic Wallets:_ Use Hierarchical Deterministic (HD) wallets [[3](https://medium.com/mycrypto/the-journey-from-mnemonic-phrase-to-address-6c5e86e11e14),[4](https://github.com/bitcoin/bips/blob/master/bip-0032.mediawiki)], enabling users to generate multiple addresses (both UTXO and account-based) from a single seed. \\n This ensures privacy while keeping management centralized for the user.\\n\\n\\n3. State Commitments\\n\\n * Role: Use cryptographic commitments to commit to the state of both models. This can help in efficiently validating cross-model transactions.\\n \\n * _Verkle Trees:_ Verkle Trees combine Vector Commitment and the KZG polynomial commitment scheme to produce a structure that\'s efficient in terms of both proofs and verification.\\n Verkle proofs are considerably small in size (less data to store and transmit), where Transaction and state verifications can be faster due to the smaller proof sizes and computational efficiencies.\\n\\n * _Mimblewimble-style Aggregation_ [[5](https://github.com/mimblewimble/grin/blob/master/doc/intro.md)]: For UTXOs, techniques similar to those used in Mimblewimble can be used to aggregate transactions, keeping the state compact and enhancing privacy.\\n\\n\\n4. Batch Processing & Anonymity Sets\\n\\n * Role: Group several UTXO-based private transactions into a single public account-based transaction. \\n This can provide a level of obfuscation and can make synchronization between the two models more efficient.\\n\\n * _CoinJoin Technique_ [[6](https://en.bitcoin.it/wiki/CoinJoin)]: As seen in Bitcoin, multiple users can combine their UTXO transactions into one, enhancing privacy.\\n\\n * _Tornado Cash Principle_ [[7](https://github.com/tornadocash/tornado-classic-ui)]: For account-based systems wanting to achieve privacy, methods like those used in Tornado Cash can be implemented, \\n providing zk-SNARKs-based private transactions.\\n\\n5. Event Hooks & Smart Contracts\\n\\n * Role: Implement event-driven mechanisms that trigger specific actions in one model based on events in the other. \\n For instance, a private transaction (UTXO-based) can trigger a corresponding public notification or event in the account-based model.\\n\\n * _Conditional Execution:_ Smart contracts could be set to execute based on events in the UTXO system. For instance, \\n a smart contract might release funds (account-based) once a specific UTXO is spent.\\n\\n * _Privacy Smart Contracts:_ Using zk-SNARKs or zk-STARKs to bring privacy to the smart contract layer, \\n allowing for private logic execution.\\n\\n\\n### Challenges and Solutions \\n\\n1. Synchronization Overhead\\n\\n * Challenge: Combining two distinct transaction models creates an inherent synchronization challenge.\\n\\n * State Channels: By allowing transactions to be conducted off-chain between participants, state channels can alleviate synchronization stresses. \\n Only the final state needs to be settled on-chain, drastically reducing the amount of data and frequency of updates required.\\n\\n * Sidechains: These act as auxiliary chains to the main blockchain. Transactions can be processed on the sidechain and then periodically synced with the main chain. \\n This structure helps reduce the immediate load on the primary system.\\n\\n * Checkpointing: Introduce periodic checkpoints where the two systems\' states are verified and harmonized. \\n This can ensure consistency without constant synchronization.\\n\\n2. Double Spending\\n\\n * Challenge: With two models operating in tandem, there\'s an increased risk of double-spending attacks.\\n\\n * Multi-Signature Transactions: Implementing transactions that require signatures from both systems can prevent unauthorized movements.\\n\\n * Cross-Verification Mechanisms: Before finalizing a transaction, it undergoes verification in both UTXO and account-based systems. \\n If discrepancies arise, the transaction can be halted.\\n\\n * Timestamping: By attaching a timestamp to each transaction, it\'s possible to order them sequentially, making it easier to spot and prevent double spending.\\n\\n3. Complexity in User Experience\\n\\n * Challenge: The dual model, while powerful, is inherently complex.\\n\\n * Abstracted User Interfaces: Design UIs that handle the complexity behind the scenes, \\n allowing users to make transactions without needing to understand the nuances of the dual model.\\n\\n * Guided Tutorials: Offer onboarding tutorials to acquaint users with the system\'s features, \\n especially emphasizing when and why they might choose one transaction type over the other.\\n\\n * Feedback Systems: Implement systems where users can provide feedback on any complexities or challenges they encounter. \\n This real-time feedback can be invaluable for iterative design improvements.\\n\\n4. Security\\n\\n * Challenge: Merging two systems can introduce unforeseen vulnerabilities.\\n\\n * Threat Modeling: Regularly conduct threat modeling exercises to anticipate potential attack vectors, \\n especially those that might exploit the interaction between the two systems.\\n\\n * Layered Security Protocols: Beyond regular audits, introduce multiple layers of security checks. \\n Each layer can act as a fail-safe if a potential threat bypasses another.\\n\\n * Decentralized Watchtowers: These are third-party services that monitor the network for malicious activities. \\n If any suspicious activity is detected, they can take corrective measures or raise alerts.\\n\\n5. Gas & Fee Management:\\n\\n * Challenge: A dual model can lead to convoluted fee structures.\\n\\n * Dynamic Fee Adjustment: Implement algorithms that adjust fees based on network congestion and transaction type. \\n This can ensure fairness and prevent network abuse.\\n\\n * Fee Estimation Tools: Provide tools that can estimate fees before a transaction is initiated. \\n This helps users understand potential costs upfront.\\n\\n * Unified Gas Stations: Design platforms where users can purchase or allocate gas for both transaction types simultaneously, \\n simplifying the gas acquisition process.\\n\\n\\nBy addressing these challenges head-on with a detailed and systematic approach, it\'s possible to unlock the full potential of a dual-architecture system, \\ncombining the strengths of both UTXO and account-based models without their standalone limitations.\\n\\n\\n| Aspect \\t| Details \\t|\\n|------------------------\\t|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------\\t|\\n| **Harmony** \\t| - **Advanced VM Development:** Design tailored for private smart contracts. - **Leverage Established Architectures:** Use WASM or RISC-V to harness their versatile and encompassing nature suitable for zero-knowledge applications. - **Support for UTXO & Account-Based Models:** Enhance adaptability across various blockchain structures. \\t|\\n| **Challenges** \\t| - **Adaptation Concerns:** WASM and RISC-V weren\'t designed with zero-knowledge proofs as a primary focus, posing integration challenges. - **Complexities with Newer Systems:** Systems like (Super)Nova, STARKs, and Sangria are relatively nascent, adding another layer of intricacy to the integration. - **Optimization Concerns:** Ensuring that these systems are optimized for zero-knowledge proofs. \\t|\\n| **Proposed Solutions** \\t| - **Integration of Nova:** Consider Nova\'s proof system for its potential alignment with project goals. - **Comprehensive Testing:** Rigorously test and benchmark against alternatives like Halo2, Plonky, and Starky to validate choices. - **Poseidon Recursion Technique:** To conduct exhaustive performance tests, providing insights into each system\'s efficiency and scalability. \\t|\\n\\n\\n## Goal 2: Virtual Machine Creation\\n\\nThe second goal entails the creation of an advanced virtual machine by leveraging established mainstream instruction sets like WASM or RISC-V. \\nAlternatively, the objective involves pioneering a new, specialized instruction set meticulously optimized for Zero-Knowledge applications.\\n\\nThis initiative seeks to foster a versatile and efficient environment for executing computations within the privacy-focused context of the project. \\nBoth WASM and RISC-V exhibit adaptability to both UTXO and account-based models due to their encompassing nature as general-purpose instruction set architectures.\\n\\n _WASM_, operating as a low-level virtual machine, possesses the capacity to execute code derived from a myriad of high-level programming languages, \\n and boasts seamless integration across diverse blockchain platforms. \\n \\n Meanwhile, _RISC-V_ emerges as a versatile option, accommodating both models, and can be seamlessly integrated with secure enclaves like SGX or TEE, \\n elevating the levels of security and privacy. However, it is crucial to acknowledge that employing WASM or RISC-V might present challenges, \\n given their original design without specific emphasis on optimizing for Zero-Knowledge Proofs (ZKPs). \\n \\n Further complexity arises with the consideration of more potent proof systems like (Super)Nova, STARKs, and Sangria, which, \\n while potentially addressing optimization concerns, necessitate extensive research and testing due to their relatively nascent status within the field. \\n This accentuates the need for a judicious balance between established options and innovative solutions in pursuit of an architecture harmoniously amalgamating privacy, security, and performance.\\n\\nThe ambition to build a powerful virtual machine tailored to zero-knowledge (ZK) applications is both commendable and intricate. \\nThe combination of two renowned instruction sets, WASM and RISC-V, in tandem with ZK, is an innovation that could redefine privacy standards in blockchain. \\nLet\'s dissect the challenges and possibilities inherent in this goal:\\n\\n1. Established Mainstream Instruction Sets - WASM and RISC-V\\n\\n * Strengths:\\n\\n * _WASM_: Rooted in its ability to execute diverse high-level language codes, its potential for cross-chain compatibility makes it a formidable contender. \\n Serving as a low-level virtual machine, its role in the blockchain realm is analogous to that of the Java Virtual Machine in the traditional computing landscape.\\n\\n * _RISC-V_: This open-standard instruction set architecture has made waves due to its customizable nature. \\n Its adaptability to both UTXO and account-based structures coupled with its compatibility with trusted execution environments like SGX and TEE augments its appeal, \\n especially in domains that prioritize security and privacy.\\n\\n * Challenges: Neither WASM nor RISC-V was primarily designed with ZKPs in mind. While they offer flexibility, \\n they might lack the necessary optimizations for ZK-centric tasks. Adjustments to these architectures might demand intensive R&D efforts.\\n\\n\\n\\n2. Pioneering a New, Specialized Instruction Set\\n\\n * Strengths: A bespoke instruction set can be meticulously designed from the ground up with ZK in focus, \\n potentially offering unmatched performance and optimizations tailored to the project\'s requirements.\\n \\n * Challenges: Crafting a new instruction set is a monumental task requiring vast resources, including expertise, time, and capital.\\n It would also need to garner community trust and support over time.\\n\\n\\n\\n3. Contemporary Proof Systems - (Super)Nova, STARKs, Sangria\\n\\n * Strengths: These cutting-edge systems, being relatively new, might offer breakthrough cryptographic efficiencies that older systems lack: designed with modern challenges in mind, \\n they could potentially bridge the gap where WASM and RISC-V might falter in terms of ZKP optimization.\\n\\n * Challenges: Their nascent nature implies a dearth of exhaustive testing, peer reviews, and potentially limited community support. \\n The unknowns associated with these systems could introduce unforeseen vulnerabilities or complexities. \\n While they could offer optimizations that address challenges presented by WASM and RISC-V, their young status demands rigorous vetting and testing.\\n\\n\\n
\\n\\n| | Mainstream (WASM, RISC-V) | ZK-optimized (New Instruction Set) |\\n|:------------------:|:-------------------------:|:----------------------------------:|\\n| Existing Tooling | YES | NO |\\n| Blockchain-focused | NO | YES |\\n| Performant | DEPENDS | YES |\\n\\n
\\n\\n### Optimization Concerns for WASM and RISC-V: \\n\\n* _Cryptography Libraries_: ZKP applications rely heavily on specific cryptographic primitives. Neither WASM nor RISC-V natively supports all of these primitives. \\nThus, a comprehensive library of cryptographic functions, optimized for these platforms, needs to be developed.\\n\\n* _Parallel Execution_: Given the heavy computational demands of ZKPs, leveraging parallel processing capabilities can optimize the time taken. \\nBoth WASM and RISC-V would need modifications to handle parallel execution of ZKP processes efficiently.\\n\\n* _Memory Management_: ZKP computations can sometimes require significant amounts of memory, especially during the proof generation phase. \\nFine-tuned memory management mechanisms are essential to prevent bottlenecks.\\n\\n\\n### Emerging ZKP Optimized Systems Considerations: \\n\\n* _Proof Size_: Different systems generate proofs of varying sizes. A smaller proof size is preferable for blockchain applications to save on storage and bandwidth. \\nThe trade-offs between proof size, computational efficiency, and security need to be balanced.\\n\\n* _Universality_: Some systems can support any computational statement (universal), while others might be tailored to specific tasks. \\nA universal system can be more versatile for diverse applications on the blockchain.\\n\\n* _Setup Requirements_: Certain ZKP systems, like zk-SNARKs, require a trusted setup, which can be a security concern. \\nAlternatives like zk-STARKs don\'t have this requirement but come with other trade-offs.\\n\\n\\n### Strategies for Integration: \\n\\n* _Iterative Development_: Given the complexities, an iterative development approach can be beneficial. \\nStart with a basic integration of WASM or RISC-V for general tasks and gradually introduce specialized ZKP functionalities.\\n\\n* _Benchmarking_: Establish benchmark tests specifically for ZKP operations. This will provide continuous feedback on the performance of the system as modifications are made, ensuring optimization.\\n\\n* _External Audits & Research_: Regular checks from cryptographic experts and collaboration with academic researchers can help in staying updated and ensuring secure implementations.\\n\\n\\n## Goal 3: Proofs Creation and Verification\\n\\nThe process of generating proofs for private state updates is vested in the hands of the user, aligning with our commitment to minimizing trust assumptions and enhancing privacy. \\nConcurrently, the responsibility of verifying these proofs and executing public functions within the virtual machine can be effectively delegated to an external prover, \\na role that is incentivized to operate with utmost honesty and integrity. This intricate balance seeks to safeguard against information leakage, \\npreserving the confidentiality of private transactions. Integral to this mechanism is the establishment of a robust incentivization framework.\\n\\nTo ensure the prover\u2019s steadfast commitment to performing tasks with honesty, we should introduce a mechanism that facilitates both rewards for sincere behavior and penalties for any deviation from the expected standards. \\nThis two-pronged approach serves as a compelling deterrent against dishonest behavior and fosters an environment of accountability. \\nIn addition to incentivization, a crucial consideration is the economic aspect of verification and execution. \\nThe verification process has been intentionally designed to be more cost-effective than execution. \\n\\nThis strategic approach prevents potential malicious actors from exploiting the system by flooding it with spurious proofs, a scenario that could arise when the costs align favorably. \\nBy maintaining a cost balance that favors verification, we bolster the system\u2019s resilience against fraudulent activities while ensuring its efficiency. \\nIn sum, our multifaceted approach endeavors to strike an intricate equilibrium between user-initiated proof creation, external verification, and incentivization. \\nThis delicate interplay of mechanisms ensures a level of trustworthiness that hinges on transparency, accountability, and economic viability.\\n\\nAs a result, we are poised to cultivate an ecosystem where users\u2019 privacy is preserved, incentives are aligned, \\nand the overall integrity of the system is fortified against potential adversarial actions. To achieve the goals of user-initiated proof creation, \\nexternal verification, incentivization, and cost-effective verification over execution, several options and mechanisms can be employed:\\n\\n1. **User-Initiated Proof Creation:** Users are entrusted with the generation of proofs for private state updates, thus ensuring greater privacy and reducing trust dependencies.\\n\\n * Challenges:\\n\\n * Maintaining the quality and integrity of the proofs generated by users.\\n\\n * Ensuring that users have the tools and knowledge to produce valid proofs.\\n\\n * Solutions:\\n\\n * Offer extensive documentation, tutorials, and user-friendly tools to streamline the proof-generation process.\\n\\n * Implement checks at the verifier\'s end to ensure the quality of proofs.\\n\\n\\n2. **External Verification by Provers:** An external prover verifies the proofs and executes public functions within the virtual machine.\\n\\n * Challenges:\\n\\n * Ensuring that the external prover acts honestly.\\n\\n * Avoiding centralized points of failure.\\n \\n * Solutions:\\n\\n * Adopt a decentralized verification approach, with multiple provers cross-verifying each other\u2019s work.\\n\\n * Use reputation systems to rank provers based on their past performances, creating a trust hierarchy.\\n\\n3. ** Incentivization Framework:** A system that rewards honesty and penalizes dishonest actions, ensuring provers\' commitment to the task.\\n\\n * Challenges:\\n\\n * Determining the right balance of rewards and penalties.\\n\\n * Ensuring that the system cannot be gamed for undue advantage.\\n\\n * Solutions[^1]: \\n\\n * Implement a dynamic reward system that adjusts based on network metrics and provers\' performance.\\n\\n * Use a staking mechanism where provers need to lock up a certain amount of assets. \\n Honest behavior earns rewards, while dishonest behavior could lead to loss of staked assets.\\n\\n4. **Economic Viability through Cost Dynamics:** Making verification more cost-effective than execution to deter spamming and malicious attacks.\\n\\n * Challenges: \\n\\n * Setting the right cost metrics for both verification and execution.\\n\\n * Ensuring that genuine users aren\u2019t priced out of the system.\\n\\n * Solutions:\\n\\n * Use a dynamic pricing model, adjusting costs in real-time based on network demand.\\n\\n * Implement gas-like mechanisms to differentiate operation costs and ensure fairness.\\n\\n5. ** Maintaining Trustworthiness:** Create a system that\'s transparent, holds all actors accountable, and is economically sound.\\n\\n * Challenges: \\n\\n * Keeping the balance where users feel their privacy is intact, while provers feel incentivized.\\n\\n * Ensuring the system remains resilient against adversarial attacks.\\n\\n * Solutions:\\n\\n * Implement layered checks and balances.\\n\\n * Foster community involvement, allowing them to participate in decision-making, potentially through a decentralized autonomous organization (DAO).\\n\\nEach of these options can be combined or customized to suit the specific requirements of your project, striking a balance between user incentives, \\ncost dynamics, and verification integrity. A thoughtful combination of these mechanisms ensures that the system remains robust, resilient, \\nand conducive to the objectives of user-initiated proof creation, incentivized verification, and cost- effective validation.\\n\\n
\\n\\n| Aspect \\t| Details \\t|\\n|-------------------------------\\t|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------\\t|\\n| **Design Principle** \\t| - **User Responsibility:** Generating proofs for private state updates. - **External Prover:** Delegated the task of verifying proofs and executing public VM functions. \\t|\\n| **Trust & Privacy** \\t| - **Minimized Trust Assumptions:** Place proof generation in users\' hands. - **Enhanced Privacy:** Ensure confidentiality of private transactions and prevent information leakage. \\t|\\n| **Incentivization Framework** \\t| - **Rewards:** Compensate honest behavior. - **Penalties:** Deter and penalize dishonest behavior. \\t|\\n| **Economic Considerations** \\t| - **Verification vs. Execution:** Make verification more cost-effective than execution to prevent spurious proofs flooding. - **Cost Balance:** Strengthen resilience against fraudulent activities and maintain efficiency. \\t|\\n| **Outcome** \\t| An ecosystem where: - Users\' privacy is paramount. - Incentives are appropriately aligned. - The system is robust against adversarial actions. \\t|\\n\\n
\\n\\n[^1]: Incentive Mechanisms:\\n * Token Rewards: Design a token-based reward system where honest provers are compensated with tokens for their verification services. \\n This incentivizes participation and encourages integrity.\\n \\n * Staking and Slashing: Introduce a staking mechanism where provers deposit tokens as collateral. \\n Dishonest behavior results in slashing (partial or complete loss) of the staked tokens, while honest actions are rewarded.\\n \\n * Proof of Work/Proof of Stake: Implement a proof-of-work or proof-of- stake consensus mechanism for verification, \\n aligning incentives with the blockchain\u2019s broader consensus mechanism.\\n\\n\\n## Goal 4: Kernel-based Architecture Implementation\\n\\nThis goal centers on the establishment of a kernel-based architecture, akin to the model observed in ZEXE, to facilitate the attestation of accurate private function executions. \\nThis innovative approach employs recursion to construct a call stack, which is then validated through iterative recursive computations. \\nAt its core, this technique harnesses a recursive Succinct Non-Interactive Argument of Knowledge (SNARK) mechanism, where each function call\u2019s proof accumulates within the call stack.\\n\\nThe subsequent verification of this stack\u2019s authenticity leverages recursive SNARK validation. \\nWhile this method offers robust verification of private function executions, it\u2019s essential to acknowledge its associated intricacies.\\n\\nThe generation of SNARK proofs necessitates a substantial computational effort, which, in turn, may lead to elevated gas fees for users. \\nMoreover, the iterative recursive computations could potentially exhibit computational expansion as the depth of recursion increases. \\nThis calls for a meticulous balance between the benefits of recursive verification and the resource implications it may entail.\\n\\nIn essence, Goal 4 embodies a pursuit of enhanced verification accuracy through a kernel-based architecture. \\nBy weaving recursion and iterative recursive computations into the fabric of our system, we aim to establish a mechanism that accentuates the trustworthiness of private function executions, \\nwhile conscientiously navigating the computational demands that ensue.\\n\\nTo accomplish the goal of implementing a kernel-based architecture for recursive verification of private function executions, \\nseveral strategic steps and considerations can be undertaken: recursion handling and depth management.\\n\\n Recursion Handling \\n\\n* _Call Stack Management:_ \\n\\n * Implement a data structure to manage the call stack, recording each recursive function call\u2019s details, parameters, and state.\\n\\n* _Proof Accumulation: _\\n\\n * Design a mechanism to accumulate proof data for each function call within the call stack. \\n This includes cryptographic commitments, intermediate results, and cryptographic challenges.\\n\\n * Ensure that the accumulated proof data remains secure and tamper-resistant throughout the recursion process.\\n\\n* _Intermediary SNARK Proofs:_\\n\\n * Develop an intermediary SNARK proof for each function call\u2019s correctness within the call stack. \\n This proof should demonstrate that the function executed correctly and produced expected outputs.\\n\\n * Ensure that the intermediary SNARK proof for each recursive call can be aggregated and verified together, maintaining the integrity of the entire call stack.\\n\\n Depth management \\n\\n* _Depth Limitation:_\\n\\n * Define a threshold for the maximum allowable recursion depth based on the system\u2019s computational capacity, gas limitations, and performance considerations.\\n\\n * Implement a mechanism to prevent further recursion beyond the defined depth limit, safeguarding against excessive computational growth.\\n\\n* _Graceful Degradation:_\\n\\n * Design a strategy for graceful degradation when the recursion depth approaches or reaches the defined limit. \\n This may involve transitioning to alternative execution modes or optimization techniques.\\n\\n * Communicate the degradation strategy to users and ensure that the system gracefully handles scenarios where recursion must be curtailed.\\n\\n* _Resource Monitoring:_\\n\\n * Develop tools to monitor resource consumption (such as gas usage and computational time) as recursion progresses. \\n Provide real-time feedback to users about the cost and impact of recursive execution.\\n\\n* _Dynamic Depth Adjustment:_\\n\\n * Consider implementing adaptive depth management that dynamically adjusts the recursion depth based on network conditions, transaction fees, and available resources.\\n\\n * Utilize algorithms to assess the optimal recursion depth for efficient execution while adhering to gas cost constraints.\\n\\n* _Fallback Mechanisms:_\\n\\n * Create fallback mechanisms that activate if the recursion depth limit is reached or if the system encounters resource constraints. \\n These mechanisms could involve alternative verification methods or delayed execution.\\n\\n* _User Notifications:_\\n\\n * Notify users when the recursion depth limit is approaching, enabling them to make informed decisions about the complexity of their transactions and potential resource usage.\\n\\n\\nGoal 4 underscores the project\'s ambition to integrate the merits of a kernel-based architecture with recursive verifications to bolster the reliability of private function executions. \\nWhile the approach promises robust outcomes, it\'s pivotal to maneuver through its intricacies with astute strategies, ensuring computational efficiency and economic viability. \\nBy striking this balance, the architecture can realize its full potential in ensuring trustworthy and efficient private function executions.\\n\\n\\n## Goal 5: Seamless Interaction Design\\n\\nGoal 5 revolves around the meticulous design of a seamless interaction between public and private states within the blockchain ecosystem. \\nThis objective envisions achieving not only composability between contracts but also the harmonious integration of private and public functions.\\n\\nA notable challenge in this endeavor lies in the intricate interplay between public and private states, \\nwherein the potential linkage of a private transaction to a public one raises concerns about unintended information leakage.\\n\\nThe essence of this goal entails crafting an architecture that facilitates the dynamic interaction of different states while ensuring that the privacy and confidentiality of private transactions remain unbreached. \\nThis involves the formulation of mechanisms that enable secure composability between contracts, guaranteeing the integrity of interactions across different layers of functionality.\\n\\nA key focus of this goal is to surmount the challenge of information leakage by implementing robust safeguards. \\nThe solution involves devising strategies to mitigate the risk of revealing private transaction details when connected to corresponding public actions. \\nBy creating a nuanced framework that com- partmentalizes private and public interactions, the architecture aims to uphold privacy while facilitating seamless interoperability.\\n\\nGoal 5 encapsulates a multifaceted undertaking, calling for the creation of an intricate yet transparent framework that empowers users to confidently engage in both public and private functions, \\nwithout compromising the confidentiality of private transactions. The successful realization of this vision hinges on a delicate blend of architectural ingenuity, cryptographic sophistication, and user-centric design.\\n\\nTo achieve seamless interaction between public and private states, composability, and privacy preservation, a combination of solutions and approaches can be employed. \\nIn the table below, a comprehensive list of solutions that address these objectives:\\n\\n
\\n\\n| **Solution Category** \\t| **Description** \\t|\\n|:-----------------------------------------:\\t|:--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------:\\t|\\n| **Layer 2 Solutions** \\t| Employ zk-Rollups, Optimistic Rollups, and state channels to handle private interactions off-chain and settle them on-chain periodically. Boost scalability and cut transaction costs. \\t|\\n| **Intermediary Smart Contracts** \\t| Craft smart contracts as intermediaries for secure public-private interactions. Use these to manage data exchange confidentially. \\t|\\n| **Decentralized Identity & Pseudonymity** \\t| Implement decentralized identity systems for pseudonymous interactions. Validate identity using cryptographic proofs. \\t|\\n| **Confidential Sidechains & Cross-Chain** \\t| Set up confidential sidechains and employ cross-chain protocols to ensure private and composability across blockchains. \\t|\\n| **Temporal Data Structures** \\t| Create chronological data structures for secure interactions. Utilize cryptographic methods for data integrity and privacy. \\t|\\n| **Homomorphic Encryption & MPC** \\t| Apply homomorphic encryption and MPC for computations on encrypted data and interactions between state layers. \\t|\\n| **Commit-Reveal Schemes** \\t| Introduce commit-reveal mechanisms for private transactions, revealing data only post necessary public actions. \\t|\\n| **Auditability & Verifiability** \\t| Use on-chain tools for auditing and verifying interactions. Utilize cryptographic commitments for third-party validation. \\t|\\n| **Data Fragmentation & Sharding** \\t| Fragment data across shards for private interactions and curtailed data exposure. Bridge shards securely with cryptography. \\t|\\n| **Ring Signatures & CoinJoin** \\t| Incorporate ring signatures and CoinJoin protocols to mask transaction details and mix transactions collaboratively. \\t|\\n\\n
\\n\\n## Goal 6: Integration of DeFi Protocols with a Privacy-Preserving Framework\\n\\nThe primary aim of Goal 6 is to weave key DeFi protocols, such as AMMs and staking, into a user-centric environment that accentuates privacy. \\nThis endeavor comes with inherent challenges, especially considering the heterogeneity of existing DeFi protocols, predominantly built on Ethereum. \\nThese variations in programming languages and VMs exacerbate the quest for interoperability. Furthermore, the success and functionality of DeFi protocols is closely tied to liquidity, \\nwhich in turn is influenced by user engagement and the amount of funds locked into the system.\\n\\n## Strategic Roadmap for Goal 6 \\n\\n1. _** Pioneering Privacy-Centric DeFi Models: **_ Initiate the development of AMMs and staking solutions that are inherently protective of users\' transactional privacy and identity.\\n\\n2. _** Specialized Smart Contracts with Privacy: **_ Architect distinct smart contracts infused with privacy elements, setting the stage for secure user interactions within this new, confidential DeFi landscape.\\n\\n3. _** Optimized User Interfaces: **_ Craft interfaces that resonate with user needs, simplifying the journey through the private DeFi space without compromising on security.\\n\\n4. _** Tackling Interoperability: **_ \\n\\n * Deploy advanced bridge technologies and middleware tools to foster efficient data exchanges and guarantee operational harmony across a spectrum of programming paradigms and virtual environments.\\n \\n * Design and enforce universal communication guidelines that bridge the privacy-centric DeFi entities with the larger DeFi world seamlessly.\\n\\n\\n5. _** Enhancing and Sustaining Liquidity: **_\\n\\n * Unveil innovative liquidity stimuli and yield farming incentives, compelling users to infuse liquidity into the private DeFi space.\\n \\n * Incorporate adaptive liquidity frameworks that continually adjust based on the evolving market demands, ensuring consistent liquidity.\\n\\n * Forge robust alliances with other DeFi stalwarts, jointly maximizing liquidity stores and honing sustainable token distribution strategies.\\n\\n\\n6. _** Amplifying Community Engagement:**_ Design and roll out enticing incentive schemes to rally users behind privacy-focused AMMs and staking systems, \\nthereby nurturing a vibrant, privacy-advocating DeFi community.\\n\\n\\nThrough the integration of these approaches, we aim to achieve Goal 6, providing users with a privacy-focused platform for engaging effortlessly in core DeFi functions such as AMMs and staking, \\nall while effectively overcoming the obstacles related to interoperability and liquidity concerns.\\n\\n\\n## Summary of the Architecture\\n\\nIn our quest to optimize privacy, we\'re proposing a Zero-Knowledge Virtual Machine (Zkvm) that harnesses the power of Zero-Knowledge Proofs (ZKPs).\\nThese proofs ensure that while private state data remains undisclosed, public state transitions can still be carried out and subsequently verified by third parties. \\nThis blend of public and private state is envisaged to be achieved through a state tree representing the public state, while the encrypted state leaves stand for the private state. \\nEach user\'s private state indicates validity through the absence of a corresponding nullifier.\\nA nullifier is a unique cryptographic value generated in privacy-preserving blockchain transactions to prevent double-spending, \\nensuring that each private transaction is spent only once without revealing its details.\\n\\nPrivate functions\' execution mandates users to offer a proof underscoring the accurate execution of all encapsulated private calls. \\nFor validating a singular private function call, we\'re leaning into the kernel-based model inspired by the ZEXE protocol. \\nDefined as kernel circuits, these functions validate the correct execution of each private function call. \\nDue to their recursive circuit structure, a succession of private function calls can be executed by calculating proofs in an iterative manner. \\nExecution-relevant data, like private and public call stacks and additions to the state tree, are incorporated as public inputs.\\n\\nOur method integrates the verification keys for these functions within a merkle tree. Here\'s the innovation: a user\'s ZKP showcases the existence of the verification key in this tree, yet keeps the executed function concealed. \\nThe unique function identifier can be presented as the verification key, with all contracts merkleized for hiding functionalities.\\n\\nWe suggest a nuanced shift from the ZEXE protocol\'s identity function, which crafts an identity for smart contracts delineating its behavior, access timeframes, and other functionalities. \\nInstead of the ZEXE protocol\'s structure, our approach pivots to a method anchored in the \\nsecurity of a secret combined with the uniqueness from hashing with the contract address. \\nThe underlying rationale is straightforward: the sender, equipped with a unique nonce and salt for the transaction, hashes the secret, payload, nonce, and salt. \\nThis result is then hashed with the contract address for the final value. The hash function\'s unidirectional nature ensures that the input cannot be deduced easily from its output. \\nA specific concern, however, is the potential repetition of secret and payload values across transactions, which could jeopardize privacy. \\nYet, by embedding the function\'s hash within the hash of the contract address, users can validate a specific function\'s execution without divulging the function, navigating this limitation.\\n\\nAlternative routes do exist: We could employ signature schemes like ECDSA, focusing on uniqueness and authenticity, albeit at the cost of complex key management. \\nFully Homomorphic Encryption (FHE) offers another pathway, enabling function execution on encrypted data, or Multi-Party Computation (MPC) which guarantees non-disclosure of function or inputs. \\nYet, integrating ZKPs with either FHE or MPC presents a challenge. Combining cryptographic functions like SHA-3 and BLAKE2 can also bolster security and uniqueness. \\nIt\'s imperative to entertain these alternatives, especially when hashing might not serve large input/output functions effectively or might fall short in guaranteeing uniqueness.\\n\\n## Current State\\n\\nOur aim is to revolutionize the privacy and security paradigms through Nescience.\\nAs we strive to set milestones and achieve groundbreaking advancements, \\nour current focus narrows onto the realization of Goal 2 and Goal 3.\\n\\nOur endeavors to build a powerful virtual machine tailored for Zero-Knowledge applications have led us down the path of rigorous exploration and testing. \\nWe believe that integrating the right proof system is pivotal to our project\'s success, which brings us to Nova [[8](https://eprint.iacr.org/2021/370)].\\nIn our project journey, we have opted to integrate the Nova proof system, recognizing its potential alignment with our overarching goals. \\nHowever, as part of our meticulous approach to innovation and optimization, we acknowledge the need to thoroughly examine Nova\u2019s performance capabilities, \\nparticularly due to its status as a pioneering and relatively unexplored proof system.\\n\\nThis critical evaluation entails a comprehensive process of benchmarking and comparative analysis [[9]](https://github.com/vacp2p/zk-explorations), \\npitting Nova against other prominent proof systems in the field, including Halo2 [[10](https://electriccoin.co/blog/explaining-halo-2/)], \\nPlonky2 [[11](https://polygon.technology/blog/introducing-plonky2)], and Starky [[12](https://eprint.iacr.org/2021/582)]. \\nThis ongoing and methodical initiative is designed to ensure a fair and impartial assessment, enabling us to draw meaningful conclusions about Nova\u2019s strengths and limitations in relation to its counterparts. \\nBy leveraging the Poseidon recursion technique, we are poised to conduct an exhaustive performance test that delves into intricate details. \\nThrough this testing framework, we aim to discern whether Nova possesses the potential to outshine its contemporaries in terms of efficiency, scalability, and overall performance. \\nThe outcome of this rigorous evaluation will be pivotal in shaping our strategic decisions moving forward. \\nArmed with a comprehensive understanding of Nova\u2019s performance metrics vis-\xe0-vis other proof systems, \\nwe can confidently chart a course that maximizes the benefits of our project\u2019s optimization efforts.\\n\\nMoreover, as we ambitiously pursue the establishment of a robust mechanism for proof creation and verification, our focus remains resolute on preserving user privacy, \\nincentivizing honest behaviour, and ensuring the cost-effective verification of transactions. \\nAt the heart of this endeavor is our drive to empower users by allowing them the autonomy of generating proofs for private state updates, \\nthereby reducing dependencies and enhancing privacy.\\nWe would like to actively work on providing comprehensive documentation, user-friendly tools, \\nand tutorials to aid users in this intricate process.\\n\\nParallelly, we\'re looking into decentralized verification processes, harnessing the strength of multiple external provers that cross-verify each other\'s work. \\nOur commitment is further cemented by our efforts to introduce a dynamic reward system that adjusts based on network metrics and prover performance. \\nThis intricate balance, while challenging, aims to fortify our system against potential adversarial actions, aligning incentives, and preserving the overall integrity of the project.\\n\\n\\n# References\\n\\n[1] Nakamoto, S. (2008). Bitcoin: A Peer-to-Peer Electronic Cash System. Retrieved from https://bitcoin.org/bitcoin.pdf\\n\\n[2] Sanchez, F. (2021). Cardano\u2019s Extended UTXO accounting model. Retrived from https://iohk.io/en/blog/posts/2021/03/11/cardanos-extended-utxo-accounting-model/\\n\\n[3] Morgan, D. (2020). HD Wallets Explained: From High Level to Nuts and Bolts. Retrieved from https://medium.com/mycrypto/the-journey-from-mnemonic-phrase-to-address-6c5e86e11e14\\n\\n[4] Wuille, P. (012). Bitcoin Improvement Proposal (BIP) 44. Retrieved from https://github.com/bitcoin/bips/blob/master/bip-0032.mediawiki\\n\\n[5] Jedusor, T. (2020). Introduction to Mimblewimble and Grin. Retrieved from https://github.com/mimblewimble/grin/blob/master/doc/intro.md\\n\\n[6] Bitcoin\'s official wiki overview of the CoinJoin method. Retrieved from https://en.bitcoin.it/wiki/CoinJoin\\n\\n[7] TornadoCash official Github page. Retrieved from https://github.com/tornadocash/tornado-classic-ui\\n\\n[8] Kothapalli, A., Setty, S., Tzialla, I. (2021). Nova: Recursive Zero-Knowledge Arguments from Folding Schemes. Retrieved from https://eprint.iacr.org/2021/370\\n\\n[9] ZKvm Github page. Retrieved from https://github.com/vacp2p/zk-explorations\\n\\n[10] Electric Coin Company (2020). Explaining Halo 2. Retrieved from https://electriccoin.co/blog/explaining-halo-2/\\n\\n[11] Polygon Labs (2022). Introducing Plonky2. Retrieved from https://polygon.technology/blog/introducing-plonky2\\n\\n[12] StarkWare (2021). ethSTARK Documentation. Retrieved from https://eprint.iacr.org/2021/582"},{"id":"device-pairing-in-js-waku-and-go-waku","metadata":{"permalink":"/rlog/device-pairing-in-js-waku-and-go-waku","source":"@site/rlog/2023-04-24-device-pairing-in-js-waku-and-go-waku.mdx","title":"Device Pairing in Js-waku and Go-waku","description":"Device pairing and secure message exchange using Waku and noise protocol.","date":"2023-04-24T12:00:00.000Z","formattedDate":"April 24, 2023","tags":[],"readingTime":4.09,"hasTruncateMarker":true,"authors":[{"name":"Richard","twitter":"richardramos_me","github":"richard-ramos","website":"https://richard-ramos.github.io/","key":"rramos"}],"frontMatter":{"layout":"post","name":"Device Pairing in Js-waku and Go-waku","title":"Device Pairing in Js-waku and Go-waku","date":"2023-04-24T12:00:00.000Z","authors":"rramos","published":true,"slug":"device-pairing-in-js-waku-and-go-waku","categories":"platform"},"prevItem":{"title":"Nescience - A zkVM leveraging hiding properties","permalink":"/rlog/Nescience-A-zkVM-leveraging-hiding-properties"},"nextItem":{"title":"The Future of Waku Network: Scaling, Incentivization, and Heterogeneity","permalink":"/rlog/future-of-waku-network"}},"content":"Device pairing and secure message exchange using Waku and noise protocol.\\n\\n\x3c!--truncate--\x3e\\n\\nAs the world becomes increasingly connected through the internet, the need for secure and reliable communication becomes paramount. In [this article](https://vac.dev/wakuv2-noise) it is described how the Noise protocol can be used as a key-exchange mechanism for Waku.\\n\\nRecently, this feature was introduced in [js-waku](https://github.com/waku-org/js-noise) and [go-waku](https://github.com/waku-org/go-waku), providing a simple API for developers to implement secure communication protocols using the Noise Protocol framework. These open-source libraries provide a solid foundation for building secure and decentralized applications that prioritize data privacy and security.\\n\\nThis functionality is designed to be simple and easy to use, even for developers who are not experts in cryptography. The library offers a clear and concise API that abstracts away the complexity of the Noise Protocol framework and provides an straightforward interface for developers to use. Using this, developers can effortlessly implement secure communication protocols on top of their JavaScript and Go applications, without having to worry about the low-level details of cryptography.\\n\\nOne of the key benefits of using Noise is that it provides end-to-end encryption, which means that the communication between two parties is encrypted from start to finish. This is essential for ensuring the security and privacy of sensitive information\\n\\n### Device Pairing\\n\\nIn today\'s digital world, device pairing has become an integral part of our lives. Whether it\'s connecting our smartphones with other computers or web applications, the need for secure device pairing has become more crucial than ever. With the increasing threat of cyber-attacks and data breaches, it\'s essential to implement secure protocols for device pairing to ensure data privacy and prevent unauthorized access.\\n\\nTo demonstrate how device pairing can be achieved using Waku and Noise, we have examples available at https://examples.waku.org/noise-js/. You can try pairing different devices, such as mobile and desktop, via a web application. This can be done by scanning a QR code or opening a URL that contains the necessary data for a secure handshake.\\n\\nThe process works as follows:\\n\\nActors:\\n\\n- Alice the initiator\\n- Bob the responder\\n\\n1. The first step in achieving secure device pairing using Noise and Waku is for Bob generate the pairing information which could be transmitted out-of-band. For this, Bob opens https://examples.waku.org/noise-js/ and a QR code is generated, containing the data required to do the handshake. This pairing QR code is timeboxed, meaning that after 2 minutes, it will become invalid and a new QR code must be generated\\n2. Alice scans the QR code using a mobile phone. This will open the app with the QR code parameters initiating the handshake process which is described in [43/WAKU2-DEVICE-PAIRING](https://rfc.vac.dev/spec/43/#protocol-flow). These messages are exchanged between two devices over Waku to establish a secure connection. The handshake messages consist of three main parts: the initiator\'s message, the responder\'s message, and the final message, which are exchanged to establish a secure connection. While using js-noise, the developer is abstracted of this process, since the messaging happens automatically depending on the actions performed by the actors in the pairing process.\\n3. Both Alice and Bob will be asked to verify each other\'s identity. This is done by confirming if an 8-digits authorization code match in both devices. If both actors confirm that the authorization code is valid, the handshake concludes succesfully\\n4. Alice and Bob receive a set of shared keys that can be used to start exchanging encrypted messages. The shared secret keys generated during the handshake process are used to encrypt and decrypt messages sent between the devices. This ensures that the messages exchanged between the devices are secure and cannot be intercepted or modified by an attacker.\\n\\nThe above example demonstrates device pairing using js-waku. Additionally, You can also try building and experimenting with other noise implementations like nwaku, or go-waku, with an example available at https://github.com/waku-org/go-waku/tree/master/examples/noise in which the same flow described before is done with Bob (the receiver) using go-waku instead of js-waku.\\n\\n### Conclusion\\n\\nWith its easy to use API built on top of the Noise Protocol framework and the LibP2P networking stack, if you are a developer looking to implement secure messaging in their applications that are both decentralized and censorship resistant, Waku is definitely an excellent choice worth checking out!\\n\\nWaku is also Open source with a MIT and APACHEv2 licenses, which means that developers are encouraged to contribute code, report bugs, and suggest improvements to make it even better.\\n\\nDon\'t hesitate to try the live example at https://examples.waku.org/noise-js and build your own webapp using https://github.com/waku-org/js-noise, https://github.com/waku-org/js-waku and https://github.com/waku-org/go-waku. This will give you a hands-on experience of implementing secure communication protocols using the Noise Protocol framework in a practical setting. Happy coding!\\n\\n### References\\n\\n- [Noise handshakes as key-exchange mechanism for Waku](https://vac.dev/wakuv2-noise)\\n- [Noise Protocols for Waku Payload Encryption](https://rfc.vac.dev/spec/35/)\\n- [Session Management for Waku Noise](https://rfc.vac.dev/spec/37/)\\n- [Device pairing and secure transfers with Noise](https://rfc.vac.dev/spec/43/)\\n- [go-waku Noise\'s example](https://github.com/waku-org/go-waku/tree/master/examples/noise)\\n- [js-waku Noise\'s example](https://github.com/waku-org/js-waku-examples/tree/master/examples/noise-js)\\n- [js-noise](https://github.com/waku-org/js-noise/)\\n- [go-noise](https://github.com/waku-org/js-noise/)"},{"id":"future-of-waku-network","metadata":{"permalink":"/rlog/future-of-waku-network","source":"@site/rlog/2023-04-03-waku-as-a-network.mdx","title":"The Future of Waku Network: Scaling, Incentivization, and Heterogeneity","description":"Learn how the Waku Network is evolving through scaling, incentivization, and diverse ecosystem development and what the future might look like.","date":"2023-04-03T00:00:00.000Z","formattedDate":"April 3, 2023","tags":[],"readingTime":5.745,"hasTruncateMarker":true,"authors":[{"name":"Franck","twitter":"fryorcraken","github":"fryorcraken","key":"franck"}],"frontMatter":{"layout":"post","name":"The Future of Waku Network: Scaling, Incentivization, and Heterogeneity","title":"The Future of Waku Network: Scaling, Incentivization, and Heterogeneity","date":"2023-04-03T00:00:00.000Z","authors":"franck","published":true,"slug":"future-of-waku-network","categories":"platform, operator, network","image":"/img/black-waku-logo-with-name.png","discuss":"https://forum.vac.dev/t/discussion-the-future-of-waku-network-scaling-incentivization-and-heterogeneity/173","hide_table_of_contents":false},"prevItem":{"title":"Device Pairing in Js-waku and Go-waku","permalink":"/rlog/device-pairing-in-js-waku-and-go-waku"},"nextItem":{"title":"Waku for All Decentralized Applications and Infrastructures","permalink":"/rlog/waku-for-all"}},"content":"Learn how the Waku Network is evolving through scaling, incentivization, and diverse ecosystem development and what the future might look like.\\n\\n\x3c!--truncate--\x3e\\n\\nWaku is preparing for production with a focus on the Status Communities use case. In this blog post, we will provide an\\noverview of recent discussions and research outputs, aiming to give you a better understanding of how the Waku network\\nmay look like in terms of scaling and incentivization.\\n\\n## DOS Mitigation for Status Communities\\n\\nWaku is actively exploring DOS mitigation mechanisms suitable for Status Communities. While RLN\\n(Rate Limiting Nullifiers) remains the go-to DOS protection solution due to its privacy-preserving and\\ncensorship-resistant properties, there is still more work to be done. We are excited to collaborate with PSE\\n(Privacy & Scaling Explorations) in this endeavor. Learn more about their latest progress in this [tweet](https://twitter.com/CPerezz19/status/1640373940634939394?s=20).\\n\\n## A Heterogeneous Waku Network\\n\\nAs we noted in a previous [forum post](https://forum.vac.dev/t/waku-payment-models/166/3), Waku\'s protocol\\nincentivization model needs to be flexible to accommodate various business models. Flexibility ensures that projects\\ncan choose how they want to use Waku based on their specific needs.\\n\\n### Reversing the Incentivization Question\\n\\nTraditionally, the question of incentivization revolves around how to incentivize operators to run nodes. We\'d like to\\nreframe the question and instead ask, \\"How do we pay for the infrastructure?\\"\\n\\nWaku does not intend to offer a free lunch.\\nEthereum\'s infrastructure is supported by transaction fees and inflation, with validators receiving rewards from both sources.\\nHowever, this model does not suit a communication network like Waku.\\nUsers and platforms would not want to pay for every single message they send. Additionally, Waku aims to support instant\\nephemeral messages that do not require consensus or long-term storage.\\n\\nProjects that use Waku to enable user interactions, whether for chat messages, gaming, private DeFi, notifications, or\\ninter-wallet communication, may have different value extraction models. Some users might provide services for the\\nproject and expect to receive value by running nodes, while others may pay for the product or run infrastructure to\\ncontribute back. Waku aims to support each of these use cases, which means there will be various ways to \\"pay for the\\ninfrastructure.\\"\\n\\nIn [his talk](https://vac.dev/building-privacy-protecting-infrastructure), Oskar addressed two strategies: RLN and service credentials.\\n\\n### RLN and Service Credentials\\n\\nRLN enables DOS protection across the network in a privacy-preserving and permission-less manner: stake in a contract,\\nand you can send messages.\\n\\nService credentials establish a customer-provider relationship. Users might pay to have messages they are interested in\\nstored and served by a provider. Alternatively, a community owner could pay a service provider to host their community.\\n\\nProviders could offer trial or limited free services to Waku users, similar to Slack or Discord. Once a trial is expired or outgrown,\\na community owner could pay for more storage or bandwidth, similar to Slack\'s model.\\nAlternatively, individual users could contribute financially, akin to Discord\'s Server Boost, or by sharing their own\\nresources with their community.\\n\\nWe anticipate witnessing various scenarios across the spectrum: from users sharing resources to users paying for access to the network and everything in between.\\n\\n## Waku Network: Ethereum or Cosmos?\\n\\nAnother perspective is to consider whether the Waku network will resemble Ethereum or Cosmos.\\n\\nFor those not familiar with the difference between both, in a very concise manner:\\n\\n- Ethereum is a set of protocols and software that are designed to operate on one common network and infrastructure\\n- Cosmos is a set of protocols and software (SDKs) designed to be deployed in separate yet interoperable networks and infrastructures by third parties\\n\\nWe want Waku to be decentralized to provide censorship resistance and privacy-preserving communication.\\nIf each application has to deploy its own network, we will not achieve this goal.\\nTherefore, we aim Waku to be not only an open source set of protocols, but also a shared infrastructure that anyone can leverage to build applications on top, with some guarantees in terms of decentralization and anonymity.\\nThis approach is closer in spirit to Ethereum than Cosmos.\\nDo note that, similarly to Ethereum, anyone is free to take Waku software and protocols and deploy their own network.\\n\\nYet, because of the difference in the fee model, the Waku Network is unlikely to be as unified as Ethereum\'s.\\nWe currently assume that there will be separate gossipsub networks with different funding models.\\nSince there is no consensus on Waku, each individual operator can decide which network to support, enabling Waku to maintain its permission-less property.\\n\\nMost likely, the Waku network will be heterogeneous, and node operators will choose the incentivization model they prefer.\\n\\n## Scalability and Discovery Protocols\\n\\nTo enable scalability, the flow of messages in the Waku network will be divided in shards,\\nso that not every node has to forward every message of the whole network.\\nDiscovery protocols will facilitate users connecting to the right nodes to receive the messages they are interested in.\\n\\nDifferent shards could be subject to a variety of rate limiting techniques (globally, targeted to that shard or something in-between).\\n\\nMarketplace protocols may also be developed to help operators understand how they can best support the network and where\\ntheir resources are most needed. However, we are still far from establishing or even assert that such a marketplace will be needed.\\n\\n## Open Problems\\n\\nSplitting traffic between shards reduces bandwidth consumption for every Waku Relay node.\\nThis improvement increases the likelihood that users with home connections can participate and contribute to the gossipsub network without encountering issues.\\n\\nHowever, it does not cap traffic.\\nThere are still open problems regarding how to guarantee that someone can use Waku with lower Internet bandwidth or run critical services, such as a validation node, on the same connection.\\n\\nWe have several ongoing initiatives:\\n\\n- Analyzing the Status Community protocol to confirm efficient usage of Waku [[4]](https://github.com/vacp2p/research/issues/177)\\n- Simulating the Waku Network to measure actual bandwidth usage [[5]](https://github.com/waku-org/pm/issues/2)\\n- Segregating chat messages from control and media messages [[6]](https://rfc.vac.dev/spec/57/#control-message-shards)\\n\\nThe final solution will likely be a combination of protocols that reduce bandwidth usage or mitigate the risk of DOS attacks, providing flexibility for users and platforms to enable the best experience.\\n\\n## The Evolving Waku Network\\n\\nThe definition of the \\"Waku Network\\" will likely change over time. In the near future, it will transition from a single\\ngossipsub network to a sharded set of networks unified by a common discovery layer. This change will promote scalability\\nand allow various payment models to coexist within the Waku ecosystem.\\n\\nIn conclusion, the future of Waku Network entails growth, incentivization, and heterogeneity while steadfastly\\nmaintaining its core principles. As Waku continues to evolve, we expect it to accommodate a diverse range of use cases\\nand business models, all while preserving privacy, resisting censorship, avoiding surveillance, and remaining accessible\\nto devices with limited resources.\\n\\n## References\\n\\n1. [51/WAKU2-RELAY-SHARDING](https://rfc.vac.dev/spec/51/)\\n2. [57/STATUS-Simple-Scaling](https://rfc.vac.dev/spec/57/)\\n3. [58/RLN-V2](https://rfc.vac.dev/spec/58/)\\n4. [Scaling Status Communities: Potential Problems](https://github.com/vacp2p/research/issues/177)\\n5. [Waku Network Testing](https://github.com/waku-org/pm/issues/2)\\n6. [51/WAKU2-RELAY-SHARDING: Control Message Shards](https://rfc.vac.dev/spec/57/#control-message-shards)"},{"id":"waku-for-all","metadata":{"permalink":"/rlog/waku-for-all","source":"@site/rlog/2022-11-08-waku-for-all-decentralize-applications.mdx","title":"Waku for All Decentralized Applications and Infrastructures","description":"Waku is an open communication protocol and network. Decentralized apps and infrastructure can use Waku for their","date":"2022-11-08T00:00:00.000Z","formattedDate":"November 8, 2022","tags":[],"readingTime":6.145,"hasTruncateMarker":true,"authors":[{"name":"Franck","twitter":"fryorcraken","github":"fryorcraken","key":"franck"}],"frontMatter":{"layout":"post","name":"Waku for All Decentralized Applications and Infrastructures","title":"Waku for All Decentralized Applications and Infrastructures","date":"2022-11-08T00:00:00.000Z","authors":"franck","published":true,"slug":"waku-for-all","categories":"waku, dapp, infrastructure, public good, platform, operator","image":"/img/black-waku-logo-with-name.png","discuss":"https://forum.vac.dev/t/discussion-waku-for-all-decentralized-applications-and-infrastructures/163"},"prevItem":{"title":"The Future of Waku Network: Scaling, Incentivization, and Heterogeneity","permalink":"/rlog/future-of-waku-network"},"nextItem":{"title":"Building Privacy-Protecting Infrastructure","permalink":"/rlog/building-privacy-protecting-infrastructure"}},"content":"Waku is an open communication protocol and network. Decentralized apps and infrastructure can use Waku for their\\ncommunication needs. It is designed to enable dApps and decentralized infrastructure projects to have secure, private,\\nscalable communication. Waku is available in several languages and platforms, from Web to mobile to desktop to cloud.\\nInitially, We pushed Waku adoption to the Web ecosystem, we learned that Waku is usable in a variety of complex applications\\nand infrastructure projects. We have prioritized our effort to make Waku usable on various platforms and environments.\\n\\n\x3c!--truncate--\x3e\\n\\n## Background\\n\\nWe have built Waku to be the communication layer for Web3. Waku is a collection of protocols to chose from for your\\nmessaging needs. It enables secure, censorship-resistant, privacy-preserving, spam-protected communication for its user.\\nIt is designed to run on any device, from mobile to the cloud.\\n\\nWaku is available on many systems and environments and used by several applications and SDKs for decentralized communications.\\n\\nThis involved research efforts in various domains: conversational security, protocol incentivization, zero-knowledge,\\netc.\\n\\nWaku uses novel technologies. Hence, we knew that early dogfooding of Waku was necessary. Even if research\\nwas still _in progress_ [[1]](#references). Thus, as soon as Waku protocols and software were usable, we started to push\\nfor the adoption of Waku. This started back in 2021.\\n\\nWaku is the communication component of the Web3 trifecta. This trifecta was Ethereum (contracts), Swarm\\n(storage) and Whisper (communication). Hence, it made sense to first target dApps which already uses one of the pillars:\\nEthereum.\\n\\nAs most dApps are web apps, we started the development of [js-waku for the browser](https://vac.dev/presenting-js-waku).\\n\\nOnce ready, we reached out to dApps to integrate Waku, added [prizes to hackathons](https://twitter.com/waku_org/status/1451400128791605254?s=20&t=Zhc0BEz6RVLkE_SeE6UyFA)\\nand gave [talks](https://docs.wakuconnect.dev/docs/presentations/).\\n\\nWe also assumed we would see patterns in the usage of Waku, that we would facilitate with the help of\\n[SDKs](https://github.com/status-im/wakuconnect-vote-poll-sdk).\\n\\nFinally, we created several web apps:\\n[examples](https://docs.wakuconnect.dev/docs/examples/)\\nand [PoCs](https://github.com/status-iM/gnosis-safe-waku).\\n\\nBy discussing with Waku users and watching it being used, we learned a few facts:\\n\\n1. The potential use cases for Waku are varied and many:\\n\\n- Wallet <> dApp communication: [WalletConnect](https://medium.com/walletconnect/walletconnect-v2-0-protocol-whats-new-3243fa80d312), [XMTP](https://xmtp.org/docs/dev-concepts/architectural-overview/)\\n- Off-chain (and private) marketplace:\\n [RAILGUN](https://twitter.com/RAILGUN_Project/status/1556780629848727552?s=20&t=NEKQJiJAfg5WJqvuF-Ym_Q) &\\n [Decentralized Uber](https://twitter.com/TheBojda/status/1455557282318721026)\\n- Signature exchange for a multi-sign wallet: [Gnosis Safe x Waku](https://github.com/status-im/gnosis-safe-waku)\\n- Off-chain Game moves/actions: [Super Card Game (EthOnline 2021)](https://showcase.ethglobal.com/ethonline2021/super-card-game)\\n- Decentralized Pastebin: [Debin](https://debin.io/)\\n\\n2. Many projects are interested in having an embedded chat in their dApp,\\n3. There are complex applications that need Waku as a solution. Taking RAILGUN as an example:\\n\\n- Web wallet\\n- \\\\+ React Native mobile wallet\\n- \\\\+ NodeJS node/backend.\\n\\n(1) means that it is not that easy to create SDKs for common use cases.\\n\\n(2) was a clear candidate for an SDK. Yet, building a chat app is a complex task. Hence, the Status app team tackled\\nthis in the form of [Status Web](https://github.com/status-im/status-web/).\\n\\nFinally, (3) was the most important lesson. We learned that multi-tier applications need Waku for decentralized and\\ncensorship-resistant communications. For these projects, js-waku is simply not enough. They need Waku to work in their\\nGolang backend, Unity desktop game and React Native mobile app.\\n\\nWe understood that we should see the whole Waku software suite\\n([js-waku](https://github.com/waku-org/js-waku),\\n[nwaku](https://github.com/status-im/nwaku),\\n[go-waku](https://github.com/status-im/go-waku),\\n[waku-react-native](https://github.com/waku-org/waku-react-native),\\n[etc](https://github.com/waku-org)) as an asset for its success.\\nThat we should not limit outreach, marketing, documentation efforts to the web, but target all platforms.\\n\\nFrom a market perspective, we identified several actors:\\n\\n- platforms: Projects that uses Waku to handle communication,\\n- operators: Operators run Waku nodes and are incentivized to do so,\\n- developers: Developers are usually part of a platforms or solo hackers learning Web3,\\n- contributors: Developers and researchers with interests in decentralization, privacy, censorship-resistance,\\n zero-knowledge, etc.\\n\\n## Waku for All Decentralized Applications and Infrastructures\\n\\nIn 2022, we shifted our focus to make the various Waku implementations **usable and used**.\\n\\nWe made Waku [multi-plaform](https://github.com/status-im/go-waku/tree/master/examples).\\n\\nWe shifted Waku positioning to leverage all Waku implementations and better serve the user\'s needs:\\n\\n- Running a node for your projects and want to use Waku? Use [nwaku](https://github.com/status-im/nwaku).\\n- Going mobile? Use [Waku React Native](https://github.com/status-im/waku-react-native).\\n- C++ Desktop Game? Use [go-waku\'s C-Bindings](https://github.com/status-im/go-waku/tree/master/examples/c-bindings).\\n- Web app? Use [js-waku](https://github.com/status-im/js-waku).\\n\\nWe are consolidating the documentation for all implementations on a single website ([work in progress](https://github.com/waku-org/waku.org/issues/15))\\nto improve developer experience.\\n\\nThis year, we also started the _operator outreach_ effort to push for users to run their own Waku nodes. We have\\nrecently concluded our [first operator trial run](https://github.com/status-im/nwaku/issues/828).\\n[Nwaku](https://vac.dev/introducing-nwaku)\'s documentation, stability and performance has improved. It is now easier to\\nrun your [own Waku node](https://github.com/status-im/nwaku/tree/master/docs/operators).\\n\\nToday, operator wannabes most likely run their own nodes to support or use the Waku network.\\nWe are [dogfooding](https://twitter.com/oskarth/status/1582027828295790593?s=20&t=DPEP6fXK6KWbBjV5EBCBMA)\\n[Waku RLN](https://github.com/status-im/nwaku/issues/827), our novel economic spam protection protocol,\\nand looking at [incentivizing the Waku Store protocol](https://github.com/vacp2p/research/issues/99).\\nThis way, we are adding reasons to run your own Waku node.\\n\\nFor those who were following us in 2021, know that we are retiring the _Waku Connect_ branding in favour of the _Waku_\\nbranding.\\n\\n## Waku for Your Project\\n\\nAs discussed, Waku is now available on various platforms. The question remains: How can Waku benefit **your** project?\\n\\nHere are a couple of use cases we recently investigated:\\n\\n## Layer-2 Decentralization\\n\\nMost ([[2] [3]](#references) roll-ups use a centralized sequencer or equivalent. Running several sequencers is not as straightforward as running several execution nodes.\\nWaku can help:\\n\\n- Provide a neutral marketplace for a mempool: If sequencers compete for L2 tx fees, they may not be incentivized to\\n share transactions with other sequencers. Waku nodes can act as a neutral network to enable all sequences to access\\n transactions.\\n- Enable censorship-resistant wallet<>L2 communication,\\n- Provide rate limiting mechanism for spam protection: Using [RLN](https://rfc.vac.dev/spec/32/) to prevent DDOS.\\n\\n## Device pairing and communication\\n\\nWith [Waku Device Pairing](https://rfc.vac.dev/spec/43/), a user can setup a secure encrypted communication channel\\nbetween their devices. As this channel would operate over Waku, it would be censorship-resistant and privacy preserving.\\nThese two devices could be:\\n\\n- Ethereum node and mobile phone to access a remote admin panel,\\n- Alice\'s phone and Bob\'s phone for any kind of secure communication,\\n- Mobile wallet and desktop/browser dApp for transaction and signature exchange.\\n\\nCheck [js-waku#950](https://github.com/waku-org/js-waku/issues/950) for the latest update on this.\\n\\n## Get Involved\\n\\nDeveloper? Grab any of the Waku implementations and integrate it in your app: https://waku.org/platform.\\n\\nResearcher? See https://vac.dev/contribute to participate in Waku research.\\n\\nTech-savvy? Try to run your own node: https://waku.org/operator.\\n\\nOtherwise, play around with the various [web examples](https://github.com/waku-org/js-waku-examples#readme).\\n\\nIf you want to help, we are [hiring](https://jobs.status.im/)!\\n\\n## Moving Forward\\n\\nWhat you can expect next:\\n\\n- [Scalability and performance studies](https://forum.vac.dev/t/waku-v2-scalability-studies/142/9) and improvement across Waku software,\\n- [New websites](https://github.com/waku-org/waku.org/issues/15) to easily find documentation about Waku and its implementations,\\n- New Waku protocols implemented in all code bases and cross client PoCs\\n ([noise](https://rfc.vac.dev/spec/35/), [noise-sessions](https://rfc.vac.dev/spec/37/),\\n [waku-rln-relay](https://rfc.vac.dev/spec/17/), etc),\\n- Easier to [run your own waku node](https://github.com/status-im/nwaku/issues/828), more operator trials,\\n- Dogfooding and Improvement of existing protocols (e.g. [Waku Filter](https://github.com/vacp2p/rfc/issues?q=is%3Aissue+is%3Aopen+sort%3Aupdated-desc++12%2FWAKU2-FILTER)),\\n- Continue our focus Waku portability: Browser,\\n [Raspberry Pi Zero](https://twitter.com/richardramos_me/status/1574405469912932355?s=20&t=DPEP6fXK6KWbBjV5EBCBMA) and other restricted-resource environments,\\n- More communication & marketing effort around Waku and the Waku developer community.\\n\\n---\\n\\n## References\\n\\n- \\\\[1\\\\] Waku is modular; it is a suite of protocols; hence some Waku protocols may be mature, while\\n new protocols are still being designed. Which means that research continues to be _ongoing_ while\\n Waku is already used in production.\\n- [[2]](https://community.optimism.io/docs/how-optimism-works/#block-production) The Optimism Foundation runs the only block produce on the Optimism network.\\n- [[3]](https://l2beat.com/) Top 10 L2s are documented has having a centralized operator."},{"id":"building-privacy-protecting-infrastructure","metadata":{"permalink":"/rlog/building-privacy-protecting-infrastructure","source":"@site/rlog/2022-11-04-building-privacy-protecting-infrastructure.mdx","title":"Building Privacy-Protecting Infrastructure","description":"What is privacy-protecting infrastructure? Why do we need it and how we can build it? We\'ll look at Waku, the communication layer for Web3. We\'ll see how it uses ZKPs to incentivize and protect the Waku network. We\'ll also look at Zerokit, a library that makes it easier to use ZKPs in different environments. After reading this, I hope you\'ll better understand the importance of privacy-protecting infrastructure and how we can build it.","date":"2022-11-04T12:00:00.000Z","formattedDate":"November 4, 2022","tags":[],"readingTime":18.595,"hasTruncateMarker":true,"authors":[{"name":"Oskar","twitter":"oskarth","github":"oskarth","key":"oskarth"}],"frontMatter":{"layout":"post","name":"Building Privacy-Protecting Infrastructure","title":"Building Privacy-Protecting Infrastructure","date":"2022-11-04T12:00:00.000Z","authors":"oskarth","published":true,"slug":"building-privacy-protecting-infrastructure","categories":"research","image":"/img/building_private_infra_intro.png","discuss":"https://forum.vac.dev/t/discussion-building-privacy-protecting-infrastructure/161"},"prevItem":{"title":"Waku for All Decentralized Applications and Infrastructures","permalink":"/rlog/waku-for-all"},"nextItem":{"title":"Waku Privacy and Anonymity Analysis Part I: Definitions and Waku Relay","permalink":"/rlog/wakuv2-relay-anon"}},"content":"What is privacy-protecting infrastructure? Why do we need it and how we can build it? We\'ll look at Waku, the communication layer for Web3. We\'ll see how it uses ZKPs to incentivize and protect the Waku network. We\'ll also look at Zerokit, a library that makes it easier to use ZKPs in different environments. After reading this, I hope you\'ll better understand the importance of privacy-protecting infrastructure and how we can build it.\\n\\n\x3c!--truncate--\x3e\\n\\n_This write-up is based on a talk given at DevCon 6 in Bogota, a video can be found [here](https://www.youtube.com/watch?v=CW1DYJifdhs)_\\n\\n### Intro\\n\\nIn this write-up, we are going to talk about building privacy-protecting\\ninfrastructure. What is it, why do we need it and how can we build it?\\n\\nWe\'ll look at Waku, the communication layer for Web3. We\'ll look at how we are\\nusing Zero Knowledge (ZK) technology to incentivize and protect the Waku\\nnetwork. We\'ll also look at Zerokit, a library we are writing to make ZKP easier\\nto use in different environments.\\n\\nAt the end of this write-up, I hope you\'ll come away with an understanding of\\nthe importance of privacy-protecting infrastructure and how we can build it.\\n\\n### About\\n\\nFirst, briefly about Vac. We build public good protocols for the decentralized\\nweb, with a focus on privacy and communication. We do applied research based on\\nwhich we build protocols, libraries and publications. We are also the custodians\\nof protocols that reflect a set of principles.\\n\\n![Principles](/img/building_private_infra_principles.png)\\n\\nIt has its origins in the [Status app](https://status.im/) and trying to improve\\nthe underlying protocols and infrastructure. We build [Waku](https://waku.org/),\\namong other things.\\n\\n### Why build privacy-protecting infrastructure?\\n\\nPrivacy is the power to selectively reveal yourself. It is a requirement for\\nfreedom and self-determination.\\n\\nJust like you need decentralization in order to get censorship-resistance, you\\nneed privacy to enable freedom of expression.\\n\\nTo build applications that are decentralized and privacy-protecting, you need\\nthe base layer, the infrastructure itself, to have those properties.\\n\\nWe see this a lot. It is easier to make trade-offs at the application layer than\\ndoing them at the base layer. You can build custodial solutions on top of a\\ndecentralized and non-custodial network where participants control their own\\nkeys, but you can\'t do the opposite.\\n\\nIf you think about it, buildings can be seen as a form of privacy-protecting\\ninfrastructure. It is completely normal and obvious in many ways, but when it\\ncomes to the digital realm our mental models and way of speaking about it hasn\'t\\ncaught up yet for most people.\\n\\nI\'m not going too much more into the need for privacy or what happens when you\\ndon\'t have it, but suffice to say it is an important property for any open\\nsociety.\\n\\nWhen we have conversations, true peer-to-peer offline conversations, we can talk\\nprivately. If we use cash to buy things we can do commerce privately.\\n\\nOn the Internet, great as it is, there are a lot of forces that makes this\\nnatural state of things not the default. Big Tech has turned users into a\\ncommodity, a product, and monetized user\'s attention for advertising. To\\noptimize for your attention they need to surveil your habits and activities, and\\nhence breach your privacy. As opposed to more old-fashioned models, where\\nsomeone is buying a useful service from a company and the incentives are more\\naligned.\\n\\nWe need to build credibly neutral infrastructure that protects your privacy at\\nthe base layer, in order to truly enable applications that are\\ncensorship-resistant and encourage meaningful freedom of expression.\\n\\n### Web3 infrastructure\\n\\nInfrastructure is what lies underneath. Many ways of looking at this but I\'ll\\nkeep it simple as per the original Web3 vision. You had Ethereum for\\ncompute/consensus, Swarm for storage, and Whisper for messaging. Waku has taken\\nover the mantle from Whisper and is a lot more\\n[usable](https://vac.dev/fixing-whisper-with-waku) today than Whisper ever was,\\nfor many reasons.\\n\\n![Web3 Infrastructure](/img/web3_holy_trinity.png)\\n\\nOn the privacy-front, we see how Ethereum is struggling. It is a big UX problem,\\nespecially when you try to add privacy back \\"on top\\". It takes a lot of effort\\nand it is easier to censor. We see this with recent action around Tornado Cash.\\nCompare this with something like Zcash or Monero, where privacy is there by\\ndefault.\\n\\nThere are also problems when it comes to the p2p networking side of things, for\\nexample with Ethereum validator privacy and hostile actors and jurisdictions. If\\nsomeone can easily find out where a certain validator is physically located,\\nthat\'s a problem in many parts of the world. Being able to have stronger\\nprivacy-protection guarantees would be very useful for high-value targets.\\n\\nThis doesn\'t begin to touch on the so called \\"dapps\\" that make a lot of\\nsacrifices in how they function, from the way domains work, to how websites are\\nhosted and the reliance on centralized services for communication. We see this\\ntime and time again, where centralized, single points of failure systems work\\nfor a while, but then eventually fail.\\n\\nIn many cases an individual user might not care enough though, and for platforms\\nthe lure to take shortcuts is strong. That is why it is important to be\\nprincipled, but also pragmatic in terms of the trade-offs that you allow on top.\\nWe\'ll touch more on this in the design goals around modularity that Waku has.\\n\\n### ZK for privacy-protecting infrastructure\\n\\nZKPs are a wonderful new tool. Just like smart contracts enables programmable\\nmoney, ZKPs allow us to express fundamentally new things. In line with the great\\ntradition of trust-minimization, we can prove statement while revealing the\\nabsolute minimum information necessary. This fits the definition of privacy, the\\npower to selectively reveal yourself, perfectly. I\'m sure I don\'t need to tell\\nanyone reading this but this is truly revolutionary. The technology is advancing\\nextremely fast and often it is our imagination that is the limit.\\n\\n![Zero knowledge](/img/building_private_infra_zk.png)\\n\\n### Waku\\n\\nWhat is Waku? It is a set of modular protocols for p2p communication. It has a\\nfocus on privacy, security and being able to run anywhere. It is the spiritual\\nsuccess to Whisper.\\n\\nBy modular we mean that you can pick and choose protocols and how you use them\\ndepending on constraints and trade-offs. For example, bandwidth usage vs\\nprivacy.\\n\\nIt is designed to work in resource restricted environments, such as mobile\\nphones and in web browsers. It is important that infrastructure meets users\\nwhere they are and supports their real-world use cases. Just like you don\'t need\\nyour own army and a castle to have your own private bathroom, you shouldn\'t need\\nto have a powerful always-on node to get reasonable privacy and\\ncensorship-resistance. We might call this self-sovereignty.\\n\\n### Waku - adaptive nodes\\n\\nOne way of looking at Waku is as an open service network. There are nodes with\\nvarying degrees of capabilities and requirements. For example when it comes to\\nbandwidth usage, storage, uptime, privacy requirements, latency requirements,\\nand connectivity restrictions.\\n\\nWe have a concept of adaptive nodes that can run a variety of protocols. A node\\noperator can choose which protocols they want to run. Naturally, there\'ll be\\nsome nodes that do more consumption and other nodes that do more provisioning.\\nThis gives rise to the idea of a service network, where services are provided\\nfor and consumed.\\n\\n![Adaptive Nodes](/img/building_private_infra_adaptive.png)\\n\\n### Waku - protocol interactions\\n\\nThere are many protocols that interact. Waku Relay protocol is based on libp2p\\nGossipSub for p2p messaging. We have filter for bandwidth-restricted nodes to\\nonly receive subset of messages. Lightpush for nodes with short connection\\nwindows to push messages into network. Store for nodes that want to retrieve\\nhistorical messages.\\n\\nOn the payload layer, we provide support for Noise handshakes/key-exchanges.\\nThis means that as a developers, you can get end-to-end encryption and expected\\nguarantees out of the box. We have support for setting up a secure channel from\\nscratch, and all of this paves the way for providing Signal\'s Double Ratchet at\\nthe protocol level much easier. We also have experimental support for\\nmulti-device usage. Similar features have existed in for example the Status app\\nfor a while, but with this we make it easier for any platform using Waku to use\\nit.\\n\\nThere are other protocols too, related to peer discovery, topic usage, etc. See\\n[specs](https://rfc.vac.dev/) for more details.\\n\\n![Protocol Interactions](/img/building_private_infra_interactions.png)\\n\\n### Waku - Network\\n\\nFor the Waku network, there are a few problems. For example, when it comes to\\nnetwork spam and incentivizing service nodes. We want to address these while\\nkeeping privacy-guarantees of the base layer. I\'m going to go into both of\\nthese.\\n\\nThe spam problem arises on the gossip layer when anyone can overwhelm the\\nnetwork with messages. The service incentivization is a problem when nodes don\'t\\ndirectly benefit from the provisioning of a certain service. This can happen if\\nthey are not using the protocol directly themselves as part of normal operation,\\nor if they aren\'t socially inclined to provide a certain service. This depends a\\nlot on how an individual platform decides to use the network.\\n\\n![Waku Network](/img/building_private_infra_network.png)\\n\\n### Dealing with network spam and RLN Relay\\n\\nSince the p2p relay network is open to anyone, there is a problem with spam. If\\nwe look at existing solutions for dealing with spam in traditional messaging\\nsystems, a lot of entities like Google, Facebook, Twitter, Telegram, Discord use\\nphone number verification. While this is largely sybil-resistant, it is\\ncentralized and not private at all.\\n\\nHistorically, Whisper used PoW which isn\'t good for heterogenerous networks.\\nPeer scoring is open to sybil attacks and doesn\'t directly address spam\\nprotection in an anonymous p2p network.\\n\\nThe key idea here is to use RLN for private economic spam protection using\\nzkSNARKs.\\n\\nI\'m not going to go into too much detail of RLN here. If you are interested, I\\ngave a [talk](https://www.youtube.com/watch?v=g41nHQ0mLoA) in Amsterdam at\\nDevconnect about this. We have some write-ups on RLN\\n[here](https://vac.dev/rln-relay) by Sanaz who has been pushing a lot of this\\nfrom our side. There\'s also another talk at Devcon by Tyler going into RLN in\\nmore detail. Finally, here\'s the [RLN spec](https://rfc.vac.dev/spec/32/).\\n\\nI\'ll briefly go over what it is, the interface and circuit and then talk about\\nhow it is used in Waku.\\n\\n### RLN - Overview and Flow\\n\\nRLN stands for Rate Limiting Nullifier. It is an anonyomous rate limiting\\nmechanism based on zkSNARKs. By rate limiting we mean you can only send N\\nmessages in a given period. By anonymity we mean that you can\'t link message to\\na publisher. We can think of it as a voting booth, where you are only allowed to\\nvote once every election.\\n\\n![Voting Booth](/img/building_private_infra_vote.png)\\n\\nIt can be used for spam protection in p2p messaging systems, and also rate\\nlimiting in general, such as for a decentralized captcha.\\n\\nThere are three parts to it. You register somewhere, then you can signal and\\nfinally there\'s a verification/slashing phase. You put some capital at risk,\\neither economic or social, and if you double signal you get slashed.\\n\\n### RLN - Circuit\\n\\nHere\'s what the private and public inputs to the circuit look like. The identity\\nsecret is generated locally, and we create an identity commitment that is\\ninserted into a Merkle tree. We then use Merkle proofs to prove membership.\\nRegistered member can only signal once for a given epoch or external nullifier,\\nfor example every ten seconds in Unix time. RLN identifer is for a specific RLN\\napp.\\n\\nWe also see what the circuit output looks like. This is calculated locally. `y`\\nis a share of the secret equation, and the (internal) nullifier acts as a unique\\nfingerprint for a given app/user/epoch combination. How do we calculate `y` and\\nthe internal nullifier?\\n\\n```\\n// Private input\\nsignal input identity_secret;\\nsignal input path_elements[n_levels][1];\\nsignal input identity_path_index[n_levels];\\n\\n// Public input\\nsignal input x; // signal_hash\\nsignal input epoch; // external_nullifier\\nsignal input rln_identifier;\\n\\n// Circuit output\\nsignal output y;\\nsignal output root;\\nsignal output nullifier;\\n```\\n\\n### RLN - Shamir\'s secret sharing\\n\\nThis is done using [Shamir\'s secret\\nsharing](https://en.wikipedia.org/wiki/Shamir%27s_Secret_Sharing). Shamir\u2019s\\nsecret sharing is based on idea of splitting a secret into shares. This is how\\nwe enable slashing of funds.\\n\\nIn this case, we have two shares. If a given identity `a0` signals twice in\\nepoch/external nullifier, `a1` is the same. For a given RLN app,\\n`internal_nullifier` then stays the same. `x` is signal hash which is different,\\nand `y` is public, so we can reconstruct `identity_secret`. With the identity\\nsecret revealed, this gives access to e.g. financial stake.\\n\\n```\\na_0 = identity_secret // secret S\\na_1 = poseidonHash([a0, external_nullifier])\\n\\ny = a_0 + x * a_1\\n\\ninternal_nullifier = poseidonHash([a_1, rln_identifier])\\n```\\n\\n![Shamir\'s secret sharing](/img/building_private_infra_shamir.png)\\n\\n### RLN Relay\\n\\nThis is how RLN is used with Relay/GossipSub protocol. A node registers and\\nlocks up funds, and after that it can send messages. It publishes a message\\ncontaining the Zero Knowledge proof and some other details.\\n\\nEach relayer node listens to the membership contract for new members, and it\\nalso keeps track of relevant metadata and merkle tree. Metadata is needed to be\\nable to detect double signaling and perform slashing.\\n\\nBefore forwarding a message, it does some verification checks to ensure there\\nare no duplicate messages, ZKP is valid and no double signaling has occured. It\\nis worth noting that this can be combined with peer scoring, for example for\\nduplicate messages or invalid ZK proofs.\\n\\nIn line of Waku\'s goals of modularity, RLN Relay is applied on a specific subset\\nof pubsub and content topics. You can think of it as an extra secure channel.\\n\\n![RLN Relay](/img/building_private_infra_rlnrelay.png)\\n\\n### RLN Relay cross-client testnet\\n\\nWhere are we with RLN Relay deployment? We\'ve recently launched our second\\ntestnet. This is using RLN Relay with a smart contract on Goerli. It integrates\\nwith our example p2p chat application, and it does so through three different\\nclients, nwaku, go-waku and js-waku for browsers. This is our first p2p\\ncross-client testnet for RLN Relay.\\n\\nHere\'s a [video](https://www.youtube.com/watch?v=-vVrJWW0fls) that shows a user\\nregistering in a browser, signaling through JS-Waku. It then gets relayed to a\\nnwaku node, that verifies the proof. The second\\n[video](https://www.youtube.com/watch?v=Xz5q2ZhkFYs) shows what happens in the\\nspam case. when more than one message is sent in a given epoch, it detects it as\\nspam and discards it. Slashing hasn\'t been implemented fully yet in the client\\nand is a work in progress.\\n\\nIf you are curious and want to participate, you can join the effort on our [Vac\\nDiscord](https://discord.gg/PQFdubGt6d). We also have\\n[tutorials](https://github.com/status-im/nwaku/blob/master/docs/tutorial/rln-chat-cross-client.md)\\nsetup for all clients so you can play around with it.\\n\\nAs part of this, and to make it work in multiple different environments, we\'ve\\nalso been developing a new library called Zerokit. I\'ll talk about this a bit\\nlater.\\n\\n### Private settlement / Service credentials\\n\\nGoing back to the service network idea, let\'s talk about service credentials.\\nThe idea behind service credentials and private settlement is to enable two\\nactors to pay for and provide services without compromising their privacy. We do\\nnot want the payment to create a direct public link between the service provider\\nand requester.\\n\\nRecall the Waku service network illustration with adaptive nodes that choose\\nwhich protocols they want to run. Many of these protocols aren\'t very heavy and\\njust work by default. For example the relay protocol is enabled by default.\\nOther protocols are much heavier to provide, such as storing historical\\nmessages.\\n\\nIt is desirable to have additional incentives for this, especially for platforms\\nthat aren\'t community-based where some level of altruism can be assumed (e.g.\\nStatus Communities, or WalletConnect cloud infrastructure).\\n\\nYou have a node Alice that is often offline and wants to consume historical\\nmessages on some specific content topics. You have another node Bob that runs a\\nserver at home where they store historical messages for the last several weeks.\\nBob is happy to provide this service for free because he\'s excited about running\\nprivacy-preserving infrastructure and he\'s using it himself, but his node is\\ngetting overwhelmed by freeloaders and he feels like he should be paid something\\nfor continuing to provide this service.\\n\\nAlice deposits some funds in a smart contract which registers it in a tree,\\nsimilar to certain other private settlement mechanisms. A fee is taken or\\nburned. In exchange, she gets a set of tokens or service credentials. When she\\nwants to do a query with some criteria, she sends this to Bob. Bob responds with\\nsize of response, cost, and receiver address. Alice then sends a proof of\\ndelegation of a service token as a payment. Bob verifies the proof and resolves\\nthe query.\\n\\nThe end result is that Alice has consumed some service from Bob, and Bob has\\nreceived payment for this. There\'s no direct transaction link between Alice and\\nBob, and gas fees can be minimized by extending the period before settling on\\nchain.\\n\\nThis can be complemented with altruistic service provisioning, for example by\\nsplitting the peer pool into two slots, or only providing a few cheap queries\\nfor free.\\n\\nThe service provisioning is general, and can be generalized for any kind of\\nrequest/response service provisoning that we want to keep private.\\n\\nThis isn\'t a perfect solution, but it is an incremental improvement on top of\\nthe status quo. It can be augmented with more advanced techniques such as better\\nnon-repudiable node reputation, proof of correct service provisioning, etc.\\n\\nWe are currently in the raw spec / proof of concept stage of this. We expect to\\nlaunch a testnet of this later this year or early next year.\\n\\n![Service credentials flow](/img/building_private_infra_servicecred.png)\\n\\n### Zerokit\\n\\n[Zerokit](https://github.com/vacp2p/zerokit) is a set of Zero Knowledge modules,\\nwritten in Rust and designed to be used in many different environments. The\\ninitial goal is to get the best of both worlds with Circom/Solidity/JS and\\nRust/ZK ecosystem. This enables people to leverage Circom-based constructs from\\nnon-JS environments.\\n\\nFor the RLN module, it is using Circom circuits via ark-circom and Rust for\\nscaffolding. It exposes a C FFI API that can be used through other system\\nprogramming environments, like Nim and Go. It also exposes an experimental WASM\\nAPI that can be used through web browsers.\\n\\nWaku is p2p infrastructure running in many different environments, such as\\nNim/JS/Go/Rust, so this a requirement for us.\\n\\nCircom and JS strengths are access to Dapp developers, tooling, generating\\nverification code, circuits etc. Rust strengths is that it is systems-based and\\neasy to interface with other language runtime such as Nim, Go, Rust, C. It also\\ngives access to other Rust ZK ecosystems such as arkworks. This opens door for\\nusing other constructs, such as Halo2. This becomes especially relevant for\\nconstructs where you don\'t want to do a trusted setup or where circuits are more\\ncomplex/custom and performance requirements are higher.\\n\\nIn general with Zerokit, we want to make it easy to build and use ZKP in a\\nmultitude of environments, such as mobile phones and web browsers. Currently it\\nis too complex to write privacy-protecting infrastructure with ZKPs considering\\nall the languages and tools you have to learn, from JS, Solidity and Circom to\\nRust, WASM and FFI. And that isn\'t even touching on things like secure key\\nstorage or mobile dev. Luckily more and more projects are working on this,\\nincluding writing DSLs etc. It\'d also be exciting if we can make a useful\\ntoolstack for JS-less ZK dev to reduce cognitive overhead, similar to what we\\nhave with something like Foundry.\\n\\n### Other research\\n\\nI also want to mention a few other things we are doing. One thing is\\n[protocol specifications](https://rfc.vac.dev/). We think this is very important\\nfor p2p infra, and we see a lot of other projects that claim to do it p2p\\ninfrastructure but they aren\'t clear about guarantees or how stable something\\nis. That makes it hard to have multiple implementations, to collaborate across\\ndifferent projects, and to analyze things objectively.\\n\\nRelated to that is publishing [papers](https://vac.dev/publications). We\'ve put\\nout three so far, related to Waku and RLN-Relay. This makes it easier to\\ninterface with academia. There\'s a lot of good researchers out there and we want\\nto build a better bridge between academia and industry.\\n\\nAnother thing is [network](https://vac.dev/wakuv2-relay-anon)\\n[privacy](https://github.com/vacp2p/research/issues/107). Waku is modular with\\nrespect to privacy guarantees, and there are a lot of knobs to turn here\\ndepending on specific deployments. For example, if you are running the full\\nrelay protocol you currently have much stronger receiver anonymity than if you\\nare running filter protocol from a bandwidth or connectivity-restricted node.\\n\\nWe aim to make this pluggable depending on user needs. E.g. mixnets such as Nym\\ncome with some trade-offs but are a useful tool in the arsenal. A good mental\\nmodel to keep in mind is the anonymity trilemma, where you can only pick 2/3 out\\nof low latency, low bandwidth usage and strong anonymity.\\n\\nWe are currently exploring [Dandelion-like\\nadditions](https://github.com/vacp2p/research/issues/119) to the relay/gossip\\nprotocol, which would provide for stronger sender anonymity, especially in a\\nmulti-node/botnet attacker model. As part of this we are looking into different\\nparameters choices and general possibilities for lower latency usage. This could\\nmake it more amenable for latency sensitive environments, such as validator\\nprivacy, for specific threat models. The general theme here is we want to be\\nrigorous with the guarantees we provide, under what conditions and for what\\nthreat models.\\n\\nAnother thing mentioned earlier is [Noise payload\\nencryption](https://vac.dev/wakuv2-noise), and specifically things like allowing\\nfor pairing different devices with e.g. QR codes. This makes it easier for\\ndevelopers to provide secure messaging in many realistic scenarios in a\\nmulti-device world.\\n\\n![Other research](/img/building_private_infra_misc.png)\\n\\n### Summary\\n\\nWe\'ve gone over what privacy-protecting infrastructure is, why we want it and\\nhow we can build it. We\'ve seen how ZK is a fundamental building block for this.\\nWe\'ve looked at Waku, the communication layer for Web3, and how it uses Zero\\nKnowledge proofs to stay private and function better. We\'ve also looked at\\nZerokit and how we can make it easier to do ZKP in different environments.\\n\\nFinally we also looked at some other research we\'ve been doing. All of the\\nthings mentioned in this article, and more, is available as\\n[write-ups](https://vac.dev/research), [specs](https://rfc.vac.dev/), or\\ndiscussions on our [forum](forum.vac.dev/) or [Github](github.com/vacp2p/).\\n\\nIf you find any of this exciting to work on, feel free to reach out on our\\nDiscord. We are also [hiring](https://jobs.status.im/), and we have started\\nexpanding into other privacy infrastructure tech like private and provable\\ncomputation with ZK-WASM."},{"id":"wakuv2-relay-anon","metadata":{"permalink":"/rlog/wakuv2-relay-anon","source":"@site/rlog/2022-07-22-relay-anonymity.mdx","title":"Waku Privacy and Anonymity Analysis Part I: Definitions and Waku Relay","description":"Introducing a basic threat model and privacy/anonymity analysis for the Waku v2 relay protocol.","date":"2022-07-22T10:00:00.000Z","formattedDate":"July 22, 2022","tags":[],"readingTime":16.78,"hasTruncateMarker":true,"authors":[{"name":"Daniel","github":"kaiserd","key":"kaiserd"}],"frontMatter":{"layout":"post","name":"Waku Privacy and Anonymity Analysis Part I: Definitions and Waku Relay","title":"Waku Privacy and Anonymity Analysis Part I: Definitions and Waku Relay","date":"2022-07-22T10:00:00.000Z","authors":"kaiserd","published":true,"slug":"wakuv2-relay-anon","categories":"research","image":"/img/anonymity_trilemma.svg","discuss":"https://forum.vac.dev/t/discussion-waku-privacy-and-anonymity-analysis/149","_includes":["math"],"toc_min_heading_level":2,"toc_max_heading_level":5},"prevItem":{"title":"Building Privacy-Protecting Infrastructure","permalink":"/rlog/building-privacy-protecting-infrastructure"},"nextItem":{"title":"Noise handshakes as key-exchange mechanism for Waku","permalink":"/rlog/wakuv2-noise"}},"content":"Introducing a basic threat model and privacy/anonymity analysis for the Waku v2 relay protocol.\\n\\n\x3c!--truncate--\x3e\\n\\n[Waku v2](https://rfc.vac.dev/spec/10/) enables secure, privacy preserving communication using a set of modular P2P protocols.\\nWaku v2 also aims at protecting the user\'s anonymity.\\nThis post is the first in a series about Waku v2 security, privacy, and anonymity.\\nThe goal is to eventually have a full privacy and anonymity analysis for each of the Waku v2 protocols, as well as covering the interactions of various Waku v2 protocols.\\nThis provides transparency with respect to Waku\'s current privacy and anonymity guarantees, and also identifies weak points that we have to address.\\n\\nIn this post, we first give an informal description of security, privacy and anonymity in the context of Waku v2.\\nFor each definition, we summarize Waku\'s current guarantees regarding the respective property.\\nWe also provide attacker models, an attack-based threat model, and a first anonymity analysis of [Waku v2 relay](https://rfc.vac.dev/spec/11/) within the respective models.\\n\\nWaku comprises many protocols that can be combined in a modular way.\\nFor our privacy and anonymity analysis, we start with the relay protocol because it is at the core of Waku v2 enabling Waku\'s publish subscribe approach to P2P messaging.\\nIn its current form, Waku relay is a minor extension of [libp2p GossipSub](https://github.com/libp2p/specs/blob/master/pubsub/gossipsub/README.md).\\n\\n![Figure 1: The Waku v2 relay mesh is based on the [GossipSub mesh](https://docs.libp2p.io/concepts/publish-subscribe#types-of-peering)](/img/libp2p_gossipsub_types_of_peering.png)\\n\\n## Informal Definitions: Security, Privacy, and Anonymity\\n\\nThe concepts of security, privacy, and anonymity are linked and have quite a bit of overlap.\\n\\n### Security\\n\\nOf the three, [Security](https://en.wikipedia.org/wiki/Information_security) has the clearest agreed upon definition,\\nat least regarding its key concepts: _confidentiality_, _integrity_, and _availability_.\\n\\n- confidentiality: data is not disclosed to unauthorized entities.\\n- integrity: data is not modified by unauthorized entities.\\n- availability: data is available, i.e. accessible by authorized entities.\\n\\nWhile these are the key concepts, the definition of information security has been extended over time including further concepts,\\ne.g. [authentication](https://en.wikipedia.org/wiki/Authentication) and [non-repudiation](https://en.wikipedia.org/wiki/Non-repudiation).\\nWe might cover these in future posts.\\n\\n### Privacy\\n\\nPrivacy allows users to choose which data and information\\n\\n- they want to share\\n- and with whom they want to share it.\\n\\nThis includes data and information that is associated with and/or generated by users.\\nProtected data also comprises metadata that might be generated without users being aware of it.\\nThis means, no further information about the sender or the message is leaked.\\nMetadata that is protected as part of the privacy-preserving property does not cover protecting the identities of sender and receiver.\\nIdentities are protected by the [anonymity property](#anonymity).\\n\\nOften privacy is realized by the confidentiality property of security.\\nThis neither makes privacy and security the same, nor the one a sub category of the other.\\nWhile security is abstract itself (its properties can be realized in various ways), privacy lives on a more abstract level using security properties.\\nPrivacy typically does not use integrity and availability.\\nAn adversary who has no access to the private data, because the message has been encrypted, could still alter the message.\\n\\nWaku offers confidentiality via secure channels set up with the help of the [Noise Protocol Framework](https://noiseprotocol.org/).\\nUsing these secure channels, message content is only disclosed to the intended receivers.\\nThey also provide good metadata protection properties.\\nHowever, we do not have a metadata protection analysis as of yet,\\nwhich is part of our privacy/anonymity roadmap.\\n\\n### Anonymity\\n\\nPrivacy and anonymity are closely linked.\\nBoth the identity of a user and data that allows inferring a user\'s identity should be part of the privacy policy.\\nFor the purpose of analysis, we want to have a clearer separation between these concepts.\\n\\nWe define anonymity as _unlinkablity of users\' identities and their shared data and/or actions_.\\n\\nWe subdivide anonymity into _receiver anonymity_ and _sender anonymity_.\\n\\n#### Receiver Anonymity\\n\\nWe define receiver anonymity as _unlinkability of users\' identities and the data they receive and/or related actions_.\\nThe data transmitted via Waku relay must be a [Waku message](https://rfc.vac.dev/spec/14/), which contains a content topic field.\\nBecause each message is associated with a content topic, and each receiver is interested in messages with specific content topics,\\nreceiver anonymity in the context of Waku corresponds to _subscriber-topic unlinkability_.\\nAn example for the \\"action\\" part of our receiver anonymity definition is subscribing to a specific topic.\\n\\nThe Waku message\'s content topic is not related to the libp2p pubsub topic.\\nFor now, Waku uses a single libp2p pubsub topic, which means messages are propagated via a single mesh of peers.\\nWith this, the receiver discloses its participation in Waku on the gossipsub layer.\\nWe will leave the analysis of libp2p gossipsub to a future article within this series, and only provide a few hints and pointers here.\\n\\nWaku offers k-anonymity regarding content topic interest in the global adversary model.\\n[K-anonymity](https://en.wikipedia.org/wiki/K-anonymity) in the context of Waku means an attacker can link receivers to content topics with a maximum certainty of $1/k$.\\nThe larger $k$, the less certainty the attacker gains.\\nReceivers basically hide in a pool of $k$ content topics, any subset of which could be topics they subscribed to.\\nThe attacker does not know which of those the receiver actually subscribed to,\\nand the receiver enjoys [plausible deniability](https://en.wikipedia.org/wiki/Plausible_deniability#Use_in_cryptography) regarding content topic subscription.\\nAssuming there are $n$ Waku content topics, a receiver has $n$-anonymity with respect to association to a specific content topic.\\n\\nTechnically, Waku allows distributing messages over several libp2p pubsub topics.\\nThis yields $k$-anonymity, assuming $k$ content topics share the same pubsub topic.\\nHowever, if done wrongly, such sharding of pubsub topics can breach anonymity.\\nA formal specification of anonymity-preserving topic sharding building on the concepts of [partitioned topics](https://specs.status.im/spec/10#partitioned-topic) is part of our roadmap.\\n\\nAlso, Waku is not directly concerned with 1:1 communication, so for this post, 1:1 communication is out of scope.\\nChannels for 1:1 communication can be implemented on top of Waku relay.\\nIn the future, a 1:1 communication protocol might be added to Waku.\\nSimilar to topic sharding, it would maintain receiver anonymity leveraging [partitioned topics](https://specs.status.im/spec/10#partitioned-topic).\\n\\n#### Sender Anonymity\\n\\nWe define sender anonymity as _unlinkability of users\' identities and the data they send and/or related actions_.\\nBecause the data in the context of Waku is Waku messages, sender anonymity corresponds to _sender-message unlinkability_.\\n\\nIn summary, Waku offers weak sender anonymity because of [Waku\'s strict no sign policy](https://rfc.vac.dev/spec/11/#signature-policy),\\nwhich has its origins in the [Ethereum consensus specs](https://github.com/ethereum/consensus-specs/blob/dev/specs/phase0/p2p-interface.md#why-are-we-using-the-strictnosign-signature-policy).\\n[17/WAKU-RLN-RELAY](https://rfc.vac.dev/spec/17/) and [18/WAKU2-SWAP](https://rfc.vac.dev/spec/18/) mitigate replay and injection attacks.\\n\\nWaku currently does not offer sender anonymity in stronger attacker models, as well as cannot protect against targeted attacks in weaker attacker models like the single or multi node attacker.\\nWe will cover this in more detail in later sections.\\n\\n### Anonymity Trilemma\\n\\n[The Anonymity trilemma](https://freedom.cs.purdue.edu/projects/trilemma.html) states that only two out of _strong anonymity_, _low bandwidth_, and _low latency_ can be guaranteed in the global on-net attacker model.\\nWaku\'s goal, being a modular set of protocols, is to offer any combination of two out of these three properties, as well as blends.\\nAn example for blending is an adjustable number of pubsub topics and peers in the respective pubsub topic mesh; this allows tuning the trade-off between anonymity and bandwidth.\\n\\n![Figure 2: Anonymity Trilemma: pick two. ](/img/anonymity_trilemma.svg)\\n\\nA fourth factor that influences [the anonymity trilemma](https://freedom.cs.purdue.edu/projects/trilemma.html) is _frequency and patterns_ of messages.\\nThe more messages there are, and the more randomly distributed they are, the better the anonymity protection offered by a given anonymous communication protocol.\\nSo, incentivising users to use the protocol, for instance by lowering entry barriers, helps protecting the anonymity of all users.\\nThe frequency/patterns factor is also related to the above described k-anonymity.\\n\\n### Censorship Resistance\\n\\nAnother security related property that Waku aims to offer is censorship resistance.\\nCensorship resistance guarantees that users can participate even if an attacker tries to deny them access.\\nSo, censorship resistance ties into the availability aspect of security.\\nIn the context of Waku that means users should be able to send messages as well as receive all messages they are interested in,\\neven if an attacker tries to prevent them from disseminating messages or tries to deny them access to messages.\\n\\nCurrently, Waku only guarantees censorship resistance in the weak single node attacker model.\\nWhile currently employed secure channels mitigate targeted censorship, e.g. blocking specific content topics,\\ngeneral censorship resistance in strong attacker models is part of our roadmap.\\nAmong other options, we will investigate [Pluggable Transports](https://www.pluggabletransports.info/about/) in future articles.\\n\\n## Attacker Types\\n\\nThe following lists various attacker types with varying degrees of power.\\nThe more power an attacker has, the more difficult it is to gain the respective attacker position.\\n\\nEach attacker type comes in a passive and an active variant.\\nWhile a passive attacker can stay hidden and is not suspicious,\\nthe respective active attacker has more (or at least the same) deanonymization power.\\n\\nWe also distinguish between internal and external attackers.\\n\\n### Internal\\n\\nWith respect to Waku relay, an internal attacker participates in the same pubsub topic as its victims.\\nWithout additional measures on higher layer protocols, access to an internal position is easy to get.\\n\\n#### Single Node\\n\\nThis attacker controls a single node.\\nBecause this position corresponds to normal usage of Waku relay, it is trivial to obtain.\\n\\n#### Multi Node\\n\\nThis attacker controls several nodes. We assume a smaller static number of controlled nodes.\\nThe multi node position can be achieved relatively easily by setting up multiple nodes.\\nBotnets might be leveraged to increase the number of available hosts.\\nMulti node attackers could use [Sybil attacks](https://en.wikipedia.org/wiki/Sybil_attack) to increase the number of controlled nodes.\\nA countermeasure is for nodes to only accept libp2p gossipsub graft requests from peers with different IP addresses, or even different subnets.\\n\\n#### Linearly Scaling Nodes\\n\\nThis attacker controls a number of nodes that scales linearly with the number of nodes in the network.\\nThis attacker is especially interesting to investigate in the context of DHT security,\\nwhich Waku uses for ambient peer discovery.\\n\\n### External\\n\\nAn external attacker can only see encrypted traffic (protected by a secure channel set up with [Noise](https://rfc.vac.dev/spec/35/)).\\nBecause an internal position can be easily obtained,\\nin practice external attackers would mount combined attacks that leverage both internal an external attacks.\\nWe cover this more below when describing attacks.\\n\\n#### Local\\n\\nA local attacker has access to communication links in a local network segment.\\nThis could be a rogue access point (with routing capability).\\n\\n#### AS\\n\\nAn AS attacker controls a single AS (autonomous system).\\nA passive AS attacker can listen to traffic on arbitrary links within the AS.\\nAn active AS attacker can drop, inject, and alter traffic on arbitrary links within the AS.\\n\\nIn practice, a malicious ISP would be considered as an AS attacker.\\nA malicious ISP could also easily setup a set of nodes at specific points in the network,\\ngaining internal attack power similar to a strong multi node attacker.\\n\\n#### Global On-Net\\n\\nA global on-net attacker has complete overview over the whole network.\\nA passive global attacker can listen to traffic on all links,\\nwhile the active global attacker basically carries the traffic: it can freely drop, inject, and alter traffic at all positions in the network.\\nThis basically corresponds to the [Dolev-Yao model](https://en.wikipedia.org/wiki/Dolev%E2%80%93Yao_model).\\n\\nAn entity with this power would, in practice, also have the power of the internal linearly scaling nodes attacker.\\n\\n## Attack-based Threat Analysis\\n\\nThe following lists various attacks including the weakest attacker model in which the attack can be successfully performed.\\nThe respective attack can be performed in all stronger attacker models as well.\\n\\nAn attack is considered more powerful if it can be successfully performed in a weaker attacker model.\\n\\nIf not stated otherwise, we look at these attacks with respect to their capability to deanonymize the message sender.\\n\\n### Scope\\n\\nIn this post, we introduce a simple tightly scoped threat model for Waku v2 Relay, which will be extended in the course of this article series.\\n\\nIn this first post, we will look at the relay protocol in isolation.\\nEven though many threats arise from layers Waku relay is based on, and layers that in turn live on top of relay,\\nwe want to first look at relay in isolation because it is at the core of Waku v2.\\nAddressing and trying to solve all security issues of a complex system at once is an overwhelming task, which is why we focus on the soundness of relay first.\\n\\nThis also goes well with the modular design philosophy of Waku v2, as layers of varying levels of security guarantees can be built on top of relay, all of which can relay on the guarantees that Waku provides.\\nInstead of looking at a multiplicative explosion of possible interactions, we look at the core in this article, and cover the most relevant combinations in future posts.\\n\\nFurther restricting the scope, we will look at the data field of a relay message as a black box.\\nIn a second article on Waku v2 relay, we will look into the data field, which according to the [specification of Waku v2 relay](https://rfc.vac.dev/spec/11/#message-fields) must be a [Waku v2 message](https://rfc.vac.dev/spec/14/).\\nWe only consider messages with version field `2`, which indicates that the payload has to be encoded using [35/WAKU2-NOISE](https://rfc.vac.dev/spec/35/).\\n\\n### Prerequisite: Get a Specific Position in the Network\\n\\nSome attacks require the attacker node(s) to be in a specific position in the network.\\nIn most cases, this corresponds to trying to get into the mesh peer list for the desired pubsub topic of the victim node.\\n\\nIn libp2p gossipsub, and by extension Waku v2 relay, nodes can simply send a graft message for the desired topic to the victim node.\\nIf the victim node still has open slots, the attacker gets the desired position.\\nThis only requires the attacker to know the gossipsub multiaddress of the victim node.\\n\\nA linearly scaling nodes attacker can leverage DHT based discovery systems to boost the probability of malicious nodes being returned, which in turn significantly increases the probability of attacker nodes ending up in the peer lists of victim nodes.\\n[Waku v2 discv5](https://vac.dev/wakuv2-apd) will employ countermeasures that mitigate the amplifying effect this attacker type can achieve.\\n\\n### Replay Attack\\n\\nIn the scope we defined above, Waku v2 is resilient against replay attacks.\\nGossipSub nodes, and by extension Waku relay nodes, feature a `seen` cache, and only relay messages they have not seen before.\\nFurther, replay attacks will be punished by [RLN](https://rfc.vac.dev/spec/17/) and [SWAP](https://rfc.vac.dev/spec/18/).\\n\\n### Neighbourhood Surveillance\\n\\nThis attack can be performed by a single node attacker that is connected to all peers of the victim node $v$ with respect to a specific topic mesh.\\nThe attacker also has to be connected to $v$.\\nIn this position, the attacker will receive messages $m_v$ sent by $v$ both on the direct path from $v$, and on indirect paths relayed by peers of $v$.\\nIt will also receive messages $m_x$ that are not sent by $v$. These messages $m_x$ are relayed by both $v$ and the peers of $v$.\\nMessages that are received (significantly) faster from $v$ than from any other of $v$\'s peers are very likely messages that $v$ sent,\\nbecause for these messages the attacker is one hop closer to the source.\\n\\nThe attacker can (periodically) measure latency between itself and $v$, and between itself and the peers of $v$ to get more accurate estimates for the expected timings.\\nAn AS attacker (and if the topology allows, even a local attacker) could also learn the latency between $v$ and its well-behaving peers.\\nAn active AS attacker could also increase the latency between $v$ and its peers to make the timing differences more prominent.\\nThis, however, might lead to $v$ switching to other peers.\\n\\nThis attack cannot (reliably) distinguish messages $m_v$ sent by $v$ from messages $m_y$ relayed by peers of $v$ the attacker is not connected to.\\nStill, there are hop-count variations that might be leveraged.\\nMessages $m_v$ always have a hop-count of 1 on the path from $v$ to the attacker, while all other paths are longer.\\nMessages $m_y$ might have the same hop-count on the path from $v$ as well as on other paths.\\n\\n### Controlled Neighbourhood\\n\\nIf a multi node attacker manages to control all peers of the victim node, it can trivially tell which messages originated from $v$.\\n\\n### Observing Messages\\n\\nIf Waku relay was not protected with Noise, the AS attacker could simply check for messages leaving $v$ which have not been relayed to $v$.\\nThese are the messages sent by $v$.\\nWaku relay protects against this attack by employing secure channels setup using Noise.\\n\\n### Correlation\\n\\nMonitoring all traffic (in an AS or globally), allows the attacker to identify traffic correlated with messages originating from $v$.\\nThis (alone) does not allow an external attacker to learn which message $v$ sent, but it allows identifying the respective traffic propagating through the network.\\nThe more traffic in the network, the lower the success rate of this attack.\\n\\nCombined with just a few nodes controlled by the attacker, the actual message associated with the correlated traffic can eventually be identified.\\n\\n### DoS\\n\\nAn active single node attacker could run a disruption attack by\\n\\n- (1) dropping messages that should be relayed\\n- (2) flooding neighbours with bogus messages\\n\\nWhile (1) has a negative effect on availability, the impact is not significant.\\nA linearly scaling botnet attacker, however, could significantly disrupt the network with such an attack.\\n(2) is thwarted by [RLN](https://rfc.vac.dev/spec/17/).\\nAlso [SWAP](https://rfc.vac.dev/spec/18/) helps mitigating DoS attacks.\\n\\nA local attacker can DoS Waku by dropping all Waku traffic within its controlled network segment.\\nAn AS attacker can DoS Waku within its authority, while a global attacker can DoS the whole network.\\nA countermeasure are censorship resistance techniques like [Pluggable Transports](https://www.pluggabletransports.info/about/).\\n\\n## Summary and Future Work\\n\\nCurrently, Waku v2 relay offers k-anonymity with respect to receiver anonymity.\\nThis also includes k-anonymity towards legitimate members of the same topic.\\n\\nWaku v2 relay offers sender anonymity in the single node attacker model with its [strict no sign policy](https://rfc.vac.dev/spec/11/#signature-policy).\\nCurrently, Waku v2 does not guarantee sender anonymity in the multi node and stronger attacker models.\\nHowever, we are working on modular anonymity-preserving protocols and building blocks as part of our privacy/anonymity roadmap.\\nThe goal is to allow tunable anonymity with respect to trade offs between _strong anonymity_, _low bandwidth_, and _low latency_.\\nAll of these cannot be fully guaranteed as the [the anonymity trilemma](https://freedom.cs.purdue.edu/projects/trilemma.html) states.\\nSome applications have specific requirements, e.g. low latency, which require a compromise on anonymity.\\nAnonymity-preserving mechanisms we plan to investigate and eventually specify as pluggable anonymity protocols for Waku comprise\\n\\n- [Dandelion++](https://arxiv.org/abs/1805.11060) for lightweight anonymity;\\n- [onion routing](https://en.wikipedia.org/wiki/Onion_routing) as a building block adding a low latency anonymization layer;\\n- [a mix network](https://en.wikipedia.org/wiki/Mix_network) for providing strong anonymity (on top of onion routing) even in the strongest attacker model at the cost of higher latency.\\n\\nThese pluggable anonymity-preserving protocols will form a sub-set of the Waku v2 protocol set.\\nAs an intermediate step, we might directly employ Tor for onion-routing, and [Nym](https://nymtech.net/) as a mix-net layer.\\n\\nIn future research log posts, we will cover further Waku v2 protocols and identify anonymity problems that will be added to our roadmap.\\nThese protocols comprise\\n\\n- [13/WAKU2-STORE](https://rfc.vac.dev/spec/13/), which can violate receiver anonymity as it allows filtering by content topic.\\n A countermeasure is using the content topic exclusively for local filters.\\n- [12/WAKU2-FILTER](https://rfc.vac.dev/spec/12/), which discloses nodes\' interest in topics;\\n- [19/WAKU2-LIGHTPUSH](https://rfc.vac.dev/spec/19/), which also discloses nodes\' interest in topics and links the lightpush client as the sender of a message to the lightpush service node;\\n- [21/WAKU2-FTSTORE](https://rfc.vac.dev/spec/21/), which discloses nodes\' interest in specific time ranges allowing to infer information like online times.\\n\\nWhile these protocols are not necessary for the operation of Waku v2, and can be seen as pluggable features,\\nwe aim to provide alternatives without the cost of lowering the anonymity level.\\n\\n## References\\n\\n- [10/WAKU2](https://rfc.vac.dev/spec/10/)\\n- [11/WAKU2-RELAY](https://rfc.vac.dev/spec/11/)\\n- [libp2p GossipSub](https://github.com/libp2p/specs/blob/master/pubsub/gossipsub/README.md)\\n- [Security](https://en.wikipedia.org/wiki/Information_security)\\n- [Authentication](https://en.wikipedia.org/wiki/Authentication)\\n- [Non-repudiation](https://en.wikipedia.org/wiki/Non-repudiation)\\n- [Noise Protocol Framework](https://noiseprotocol.org/)\\n- [plausible deniability](https://en.wikipedia.org/wiki/Plausible_deniability#Use_in_cryptography)\\n- [Waku v2 message](https://rfc.vac.dev/spec/14/)\\n- [partitioned topics](https://specs.status.im/spec/10#partitioned-topic)\\n- [Sybil attack](https://en.wikipedia.org/wiki/Sybil_attack)\\n- [Dolev-Yao model](https://en.wikipedia.org/wiki/Dolev%E2%80%93Yao_model)\\n- [35/WAKU2-NOISE](https://rfc.vac.dev/spec/35/)\\n- [33/WAKU2-DISCV5](https://vac.dev/wakuv2-apd)\\n- [strict no sign policy](https://github.com/ethereum/consensus-specs/blob/dev/specs/phase0/p2p-interface.md#why-are-we-using-the-strictnosign-signature-policy)\\n- [Waku v2 strict no sign policy](https://rfc.vac.dev/spec/11/#signature-policy)\\n- [17/WAKU-RLN-RELAY](https://rfc.vac.dev/spec/17/)\\n- [anonymity trilemma](https://freedom.cs.purdue.edu/projects/trilemma.html)\\n- [18/WAKU2-SWAP](https://rfc.vac.dev/spec/18/)\\n- [Pluggable Transports](https://www.pluggabletransports.info/about/)\\n- [Nym](https://nymtech.net/)\\n- [Dandelion++](https://arxiv.org/abs/1805.11060)\\n- [13/WAKU2-STORE](https://rfc.vac.dev/spec/13/)\\n- [12/WAKU2-FILTER](https://rfc.vac.dev/spec/12/)\\n- [19/WAKU2-LIGHTPUSH](https://rfc.vac.dev/spec/19/)\\n- [21/WAKU2-FTSTORE](https://rfc.vac.dev/spec/21/)"},{"id":"wakuv2-noise","metadata":{"permalink":"/rlog/wakuv2-noise","source":"@site/rlog/2022-05-17-noise.mdx","title":"Noise handshakes as key-exchange mechanism for Waku","description":"We provide an overview of the Noise Protocol Framework as a tool to design efficient and secure key-exchange mechanisms in Waku2.","date":"2022-05-17T10:00:00.000Z","formattedDate":"May 17, 2022","tags":[],"readingTime":21.115,"hasTruncateMarker":true,"authors":[{"name":"s1fr0","github":"s1fr0","key":"s1fr0"}],"frontMatter":{"layout":"post","name":"Noise handshakes as key-exchange mechanism for Waku","title":"Noise handshakes as key-exchange mechanism for Waku","date":"2022-05-17T10:00:00.000Z","authors":"s1fr0","published":true,"slug":"wakuv2-noise","categories":"research","summary":null,"image":"/img/noise/NM.png","discuss":"https://forum.vac.dev/t/discussion-noise-handshakes-as-key-exchange-mechanism-for-waku/137","_includes":["math"]},"prevItem":{"title":"Waku Privacy and Anonymity Analysis Part I: Definitions and Waku Relay","permalink":"/rlog/wakuv2-relay-anon"},"nextItem":{"title":"Waku v2 Ambient Peer Discovery","permalink":"/rlog/wakuv2-apd"}},"content":"We provide an overview of the Noise Protocol Framework as a tool to design efficient and secure key-exchange mechanisms in Waku2.\\n\\n\x3c!--truncate--\x3e\\n\\n## Introduction\\n\\nIn this post we will provide an overview of how [Waku v2](https://rfc.vac.dev/spec/10/) users can adopt [Noise handshakes](http://www.noiseprotocol.org/noise.html) to agree on cryptographic keys used to securely encrypt messages.\\n\\nThis process belongs to the class of _key-exchange_ mechanisms, consisting of all those protocols that, with different levels of complexity and security guarantees, allow two parties to publicly agree on a secret without letting anyone else know what this secret is.\\n\\nBut why do we need key-exchange mechanisms in the first place?\\n\\nWith the advent of [public-key cryptography](https://en.wikipedia.org/wiki/Public-key_cryptography), it become possible to decouple encryption from decryption through use of two distinct cryptographic keys: one _public_, used to encrypt information and that can be made available to anyone, and one _private_ (kept secret), which enables decryption of messages encrypted with its corresponding public key. The same does not happen in the case of [symmetric encryption schemes](https://en.wikipedia.org/wiki/Symmetric-key_algorithm) where, instead, the same key is used for both encryption and decryption operations and hence cannot be publicly revealed as for public keys.\\n\\nIn order to address specific application needs, many different public, symmetric and hybrid cryptographic schemes were designed: [Waku v1](https://rfc.vac.dev/spec/6/) and [Waku v2](https://rfc.vac.dev/spec/10/), which inherits part of their design from the Ethereum messaging protocol [Whisper](https://ethereum.org/en/developers/docs/networking-layer/#whisper), provide [support](https://rfc.vac.dev/spec/26/) to both public-key primitives ([`ECIES`](https://en.wikipedia.org/wiki/Integrated_Encryption_Scheme), [`ECDSA`](https://en.wikipedia.org/wiki/Elliptic_Curve_Digital_Signature_Algorithm)) and symmetric primitives ([`AES-256-GCM`](https://en.wikipedia.org/wiki/Galois/Counter_Mode), [`KECCAK-256`](https://en.wikipedia.org/wiki/SHA-3)), used to sign, hash, encrypt and decrypt exchanged messages.\\n\\nIn principle, when communications employ public-key based encryption schemes (`ECIES`, in the case of Waku), there is no need for a key-agreement among parties: messages can be directly encrypted using the recipient\'s public-key before being sent over the network. However, public-key encryption and decryption primitives are usually very inefficient in processing large amount of data, and this may constitute a bottleneck for many of today\'s applications. Symmetric encryption schemes such as `AES-256-GCM`, on the other hand, are much more efficient, but the encryption/decryption key needs to be shared among users beforehand any encrypted messages is exchanged.\\n\\nTo counter the downsides given by each of these two approaches while taking advantage of their strengths, hybrid constructions were designed. In these, public-key primitives are employed to securely agree on a secret key which, in turn, is used with a symmetric cipher for encrypting messages. In other words, such constructions specify a (public-key based) key-agreement mechanism!\\n\\nWaku, up to [payload version 1](https://rfc.vac.dev/spec/14/#payload-encryption), does not implement nor recommend any protocol for exchanging symmetric ciphers\' keys, leaving such task to the application layer. It is important to note that the kind of key-agreement employed has a direct impact on the security properties that can be granted on later encrypted messages, while security requirements usually depend on the specific application for which encryption is needed in the first place.\\n\\nIn this regard, [Status](https://status.im), which builds on top of Waku, [implements](https://specs.status.im/spec/5) a custom version of the [X3DH](https://signal.org/docs/specifications/x3dh/) key-agreement protocol, in order to allow users to instantiate end-to-end encrypted communication channels. However, although such a solution is optimal when applied to (distributed) E2E encrypted chats, it is not flexible enough to fit or simplify the variety of applications Waku aims to address.\\nHence, proposing and implementing one or few key-agreements which provide certain (presumably _strong_) security guarantees, would inevitably degrade performances of all those applications for which, given their security requirements, more tailored and efficient key-exchange mechanisms can be employed.\\n\\nGuided by different examples, in the following sections we will overview Noise, a protocol framework we are [currently integrating](https://rfc.vac.dev/spec/35/) in Waku, for building secure key-agreements between two parties. One of the great advantage of using Noise is that it is possible to add support to new key-exchanges by just specifying users\' actions from a predefined list, requiring none to minimal modifications to existing implementations. Furthermore, Noise provides a framework to systematically analyze protocols\' security properties and the corresponding attacker threat models. This allows not only to easily design new key-agreements eventually optimized for specific applications we want to address, but also to easily analyze or even [formally verify](https://noiseexplorer.com/) any of such custom protocol!\\n\\nWe believe that with its enormous flexibility and features, Noise represents a perfect candidate for bringing key-exchange mechanisms in Waku.\\n\\n## The Diffie-Hellman Key-exchange\\n\\nThe formalization of modern public-key cryptography started with the pioneering work of Whitefield Diffie and Martin Hellman, who detailed one of the earliest known key-agreement protocols: the famous [Diffie-Hellman Key-Exchange](https://en.wikipedia.org/wiki/Diffie%E2%80%93Hellman_key_exchange).\\n\\nDiffie-Hellman (DH) key-exchange is largely used today and represents the main cryptographic building block on which Noise handshakes\' security is based.\\n\\nIn turn, the security of DH is based on a mathematical problem called [discrete logarithm](https://en.wikipedia.org/wiki/Discrete_logarithm) which is believed to be hard when the agreement is practically instantiated using certain [elliptic curves](https://en.wikipedia.org/wiki/Elliptic_curve) $E$ defined over finite fields $\\\\mathbb{F}_p$.\\n\\nInformally, a DH exchange between Alice and Bob proceeds as follows:\\n\\n- Alice picks a secret scalar $s_A\\\\in\\\\mathbb{F}_p$ and computes, using the underlying [curve\'s arithmetic](https://en.wikipedia.org/wiki/Elliptic_curve_point_multiplication), the point $P_A = s_A\\\\cdot P\\\\in E(\\\\mathbb{F}_p)$ for a certain pre-agreed public generator $P$ of the elliptic curve $E(\\\\mathbb{F}_p)$. She then sends $P_A$ to Bob.\\n- Similarly, Bob picks a secret scalar $s_B\\\\in\\\\mathbb{F}_p$, computes $P_B = s_B\\\\cdot P\\\\in E(\\\\mathbb{F}_p)$ and sends $P_B$ to Alice.\\n- By commutativity of scalar multiplication, both Alice and Bob can now compute the point $P_{AB} = s_As_B\\\\cdot P$, using the elliptic curve point received from the other party and their secret scalar.\\n\\nThe assumed hardness of computing discrete logarithms in the elliptic curve, ensures that it is not possible to compute $s_A$ or $s_B$ from $P_A$ and $P_B$, respectively. Another security assumption (named [Computational Diffie-Hellman assumption](https://en.wikipedia.org/wiki/Computational_Diffie%E2%80%93Hellman_assumption)) ensures that it is not possible to compute $P_{AB}$ from $P$, $P_A$ and $P_B$. Hence the point $P_{AB}$ shared by Alice and Bob at the end of the above protocol cannot be efficiently computed by an attacker intercepting $P_A$ and $P_B$, and can then be used to generate a secret to be later employed, for example, as a symmetric encryption key.\\n\\nOn a side note, this protocol shows the interplay between two components typical to public-key based schemes: the scalars $s_A$ and $s_B$ can be seen as _private keys_ associated to the _public keys_ $P_A$ and $P_B$, respectively, which allow Alice and Bob only to compute the shared secret point $P_{AB}$.\\n\\n## Ephemeral and Static Public Keys\\n\\nAlthough we assumed that it is practically impossible for an attacker to compute the randomly picked secret scalar from the corresponding public elliptic curve point, it may happen that such scalar gets compromised or can be guessed due to a faulty employed random number generator. In such cases, an attacker will be able to recover the final shared secret and all encryption keys eventually derived from that, with clear catastrophic consequences for the privacy of exchanged messages.\\n\\nTo mitigate such issues, multiple DH operations can be combined using two different types of exchanged elliptic curve points or, better, _public keys_: _ephemeral keys_, that is random keys used only once in a DH operation, and long-term _static keys_, used mainly for authentication purposes since employed multiple times.\\n\\nJust to provide an example, let us suppose Alice and Bob perform the following custom DH-based key-exchange protocol:\\n\\n- Alice generates an ephemeral key $E_A=e_A\\\\cdot P$ by picking a random scalar $e_A$ and sends $E_A$ to Bob;\\n- Similarly, Bob generates an ephemeral key $E_B=e_B\\\\cdot P$ and sends $E_B$ to Alice;\\n- Alice and Bob computes $E_{AB} = e_Ae_B \\\\cdot P$ and from it derive a secret encryption key $k$.\\n- Bob sends to Alice his static key $S_B = s_B\\\\cdot P$ encrypted with $k$.\\n- Alice encrypts with $k$ her static key $S_A = s_A\\\\cdot P$ and sends it to Bob.\\n- Alice and Bob decrypt the received static keys, compute the secret $S_{AB} = s_As_B \\\\cdot P$ and use it together with $E_{AB}$ to derive a new encryption key $\\\\tilde{k}$ to be later used with a symmetric cipher.\\n\\nIn this protocol, if Alice\'s and/or Bob\'s static keys get compromised, it would not possible to derive the final secret key $\\\\tilde{k}$, since at least one ephemeral key among $E_A$ and $E_B$ has to be compromised too in order to recover the secret $E_{AB}$. Furthermore, since Alice\'s and Bob\'s long-term static keys are encrypted, an attacker intercepting exchanged (encrypted) public keys will not be able to link such communication to Alice or Bob, unless one of the ephemeral key is compromised (and, even in such case, none of the messages encrypted under the key $\\\\tilde{k}$ can be decrypted).\\n\\n## The Noise Protocol Framework\\n\\nIn previous section we gave a small intuition on how multiple DH operations over ephemeral and static users\' public keys can be combined to create different key-exchange protocols.\\n\\nThe [Noise Protocol Framework](http://www.noiseprotocol.org/noise.html), defines various rules for building custom key-exchange protocols while allowing easy analysis of the security properties and threat models provided given the type and order of the DH operations employed.\\n\\nIn Noise terminology, a key-agreement or _Noise protocol_ consists of one or more _Noise handshakes_. During a Noise handshake, Alice and Bob exchange multiple (handshake) messages containing their ephemeral keys and/or static keys. These public keys are then used to perform a handshake-dependent sequence of Diffie-Hellman operations, whose results are all hashed into a shared secret key. Similarly as we have seen above, after a handshake is complete, each party will use the derived secret key to send and receive [authenticated encrypted data](https://en.wikipedia.org/wiki/Authenticated_encryption) by employing a symmetric cipher.\\n\\nDepending on the _handshake pattern_ adopted, different security guarantees can be provided on messages encrypted using a handshake-derived key.\\n\\nThe Noise handshakes we support in Waku all provide the following security properties:\\n\\n- **Confidentiality**: the adversary should not be able to learn what data is being sent between Alice and Bob.\\n- **Strong forward secrecy**: an active adversary cannot decrypt messages nor infer any information on the employed encryption key, even in the case he has access to Alice\'s and Bob\'s long-term private keys (during or after their communication).\\n- **Authenticity**: the adversary should not be able to cause either Alice or Bob to accept messages coming from a party different than their original senders.\\n- **Integrity**: the adversary should not be able to cause Alice or Bob to accept data that has been tampered with.\\n- **Identity-hiding**: once a secure communication channel is established, a passive adversary should not be able to link exchanged encrypted messages to their corresponding sender and recipient by knowing their long-term static keys.\\n\\nWe refer to [Noise specification](http://www.noiseprotocol.org/noise.html) for more formal security definitions and precise threat models relative to Waku [supported Noise Handshake patterns](#Supported-Noise-Handshakes-in-Waku).\\n\\n## Message patterns\\n\\nNoise handshakes involving DH operations over ephemeral and static keys can be succinctly sketched using the following set of _handshake message tokens_: `e`,`s`,`ee`,`se`,`es`,`ss`.\\n\\nTokens employing single letters denote (the type of) users\' public keys: `e` refers to randomly generated ephemeral key(s), while `s` indicates the users\' long-term static key(s).\\n\\nTwo letters tokens, instead, denotes DH operations over the two users\' public keys the token refers to, given that the left token letter refers to the handshake _initiator\'s_ public key, while the right token letter indicates the used _responder\'s_ public key. Thus, if Alice started a handshake with Bob, the `es` token will shortly represent a DH operation among Alice\'s ephemeral key `e` and Bob\'s static key `s`.\\n\\nSince, in order to perform any DH operations users need to share (or pre-share) the corresponding public keys, Noise compactly represents messages\' exchanges using the two direction `->` and `<-`, where the `->` denotes a message (arbitrary and/or DH public key) from the initiator to the responder, while `<-` the opposite.\\n\\nHence a _message pattern_ consisting of a direction and one or multiple tokens such as `<- e, s, es` has to be interpreted one token at a time: in this example, the responder is sending his ephemeral and static key to the initiator and is then executing a DH operation over the initiator\'s ephemeral key `e` (shared in a previously exchanged message pattern) and his static key `s`. On the other hand, such message indicates also that the initiator received the responder\'s ephemeral and static keys `e` and `s`, respectively, and performed a DH operation over his ephemeral key and the responder\'s just received static key `s`. In this way, both parties will be able to derive at the end of each message pattern processed the same shared secret, which is eventually used to update any derived symmetric encryption keys computed so far.\\n\\nIn some cases, DH public keys employed in a handshake are pre-shared before the handshake itself starts. In order to chronologically separate exchanged keys and DH operations performed before and during a handshake, Noise employs the `...` delimiter.\\n\\nFor example, the following message patterns\\n\\n```\\n<- e\\n...\\n-> e, ee\\n```\\n\\nindicates that the initiator knew the responder\'s ephemeral key before he sends his own ephemeral key and executes a DH operation between both parties ephemeral keys (similarly, the responder receives the initiator\'s ephemeral key and does a `ee` DH operation).\\n\\nAt this point it should be clear how such notation is able to compactly represent a large variety of DH based key-agreements. Nevertheless, we can easily define additional tokens and processing rules in order to address specific applications and security requirements, such as the [`psk`](http://www.noiseprotocol.org/noise.html#handshake-tokens) token used to process arbitrary pre-shared key material.\\n\\nAs an example of Noise flexibility, the custom protocol we detailed [above](#Ephemeral-and-Static-Public-Keys) can be shortly represented as _(Alice is on the left)_:\\n\\n```\\n-> e\\n<- e, ee, s\\n-> s, ss\\n```\\n\\nwhere after each DH operation an encryption key is derived (along with the secrets computed by all previously executed DH operations) in order to encrypt/decrypt any subsequent sent/received message.\\n\\nAnother example is given by the possibility to replicate within Noise the well established Signal\'s [X3DH](https://signal.org/docs/specifications/x3dh/) key-agreement protocols, thus making the latter a general framework to design and study security of many practical and widespread DH-based key-exchange protocols.\\n\\n## The Noise State Objects\\n\\nWe mentioned multiple times that parties derive an encryption key each time they perform a DH operation, but how does this work in more details?\\n\\nNoise defines three _state object_: a _Handshake State_, a _Symmetric State_ and a _Cipher State_, each encapsulated into each other and instantiated during the execution of a handshake.\\n\\nThe Handshake State object stores the user\'s and other party\'s received ephemeral and static keys (if any) and embeds a Symmetric State object.\\n\\nThe Symmetric State, instead, stores a handshake hash value `h`, iteratively updated with any message read/received and DH secret computed, and a chaining key `ck`, updated using a key derivation function every time a DH secret is computed. This object further embeds a Cipher State.\\n\\nLastly, the Cipher State stores a symmetric encryption `k` key and a counter `n` used to encrypt and decrypt messages exchanged during the handshake (not only static keys, but also arbitrary payloads). These key and counter are refreshed every time the chaining key is updated.\\n\\nWhile processing each handshake\'s message pattern token, all these objects are updated according to some specific _processing rules_ which employ a combination of public-key primitives, hash and key-derivation functions and symmetric ciphers. It is important to note, however, that at the end of each processed message pattern, the two users will share the same Symmetric and Cipher State embedded in their respective Handshake States.\\n\\nOnce a handshake is complete, users derive two new Cipher States and can then discard the Handshake State object (and, thus, the embedded Symmetric State and Cipher State objects)\\nemployed during the handshake.\\n\\nThese two Cipher states are used to encrypt and decrypt all outbound and inbound after-handshake messages, respectively, and only to these will be granted the confidentiality, authenticity, integrity and identity-hiding properties we detailed above.\\n\\nFor more details on processing rules, we refer to [Noise specifications](http://www.noiseprotocol.org/noise.html).\\n\\n## Supported Noise Handshakes in Waku\\n\\nThe Noise handshakes we provided support to in Waku address four typical scenarios occurring when an encrypted communication channel between Alice and Bob is going to be created:\\n\\n- Alice and Bob know each others\' static key.\\n- Alice knows Bob\'s static key;\\n- Alice and Bob share no key material and they don\'t know each others\' static key.\\n- Alice and Bob share some key material, but they don\'t know each others\' static key.\\n\\nThe possibility to have handshakes based on the reciprocal knowledge parties have of each other, allows designing Noise handshakes that can quickly reach the desired level of security on exchanged encrypted messages while keeping the number of interactions between Alice and Bob minimum.\\n\\nNonetheless, due to the pure _token-based_ nature of handshake processing rules, implementations can easily add support to any custom handshake pattern with minor modifications, in case more specific application use-cases need to be addressed.\\n\\nOn a side note, we already mentioned that identity-hiding properties can be guaranteed against a passive attacker that only reads the communication occurring between Alice and Bob. However, an active attacker who compromised one party\'s static key and actively interferes with the parties\' exchanged messages, may lower the identity-hiding security guarantees provided by some handshake patterns. In our security model we exclude such adversary, but, for completeness, in the following we report a summary of possible de-anonymization attacks that can be performed by such an active attacker.\\n\\nFor more details on supported handshakes and on how these are implemented in Waku, we refer to [35/WAKU2-NOISE](https://rfc.vac.dev/spec/35/) RFC.\\n\\n### The K1K1 Handshake\\n\\nIf Alice and Bob know each others\' static key (e.g., these are public or were already exchanged in a previous handshake) , they MAY execute a `K1K1` handshake. In Noise notation _(Alice is on the left)_ this can be sketched as:\\n\\n```\\n K1K1:\\n -> s\\n <- s\\n ...\\n -> e\\n <- e, ee, es\\n -> se\\n```\\n\\nWe note that here only ephemeral keys are exchanged. This handshake is useful in case Alice needs to instantiate a new separate encrypted communication channel with Bob, e.g. opening multiple parallel connections, file transfers, etc.\\n\\n**Security considerations on identity-hiding (active attacker)**: no static key is transmitted, but an active attacker impersonating Alice can check candidates for Bob\'s static key.\\n\\n### The XK1 Handshake\\n\\nHere, Alice knows how to initiate a communication with Bob and she knows his public static key: such discovery can be achieved, for example, through a publicly accessible register of users\' static keys, smart contracts, or through a previous public/private advertisement of Bob\'s static key.\\n\\nA Noise handshake pattern that suits this scenario is `XK1`:\\n\\n```\\n XK1:\\n <- s\\n ...\\n -> e\\n <- e, ee, es\\n -> s, se\\n```\\n\\nWithin this handshake, Alice and Bob reciprocally authenticate their static keys `s` using ephemeral keys `e`. We note that while Bob\'s static key is assumed to be known to Alice (and hence is not transmitted), Alice\'s static key is sent to Bob encrypted with a key derived from both parties ephemeral keys and Bob\'s static key.\\n\\n**Security considerations on identity-hiding (active attacker)**: Alice\'s static key is encrypted with forward secrecy to an authenticated party. An active attacker initiating the handshake can check candidates for Bob\'s static key against recorded/accepted exchanged handshake messages.\\n\\n### The XX and XXpsk0 Handshakes\\n\\nIf Alice is not aware of any static key belonging to Bob (and neither Bob knows anything about Alice), she can execute an `XX` handshake, where each party tran**X**mits to the other its own static key.\\n\\nThe handshake goes as follows:\\n\\n```\\n XX:\\n -> e\\n <- e, ee, s, es\\n -> s, se\\n```\\n\\nWe note that the main difference with `XK1` is that in second step Bob sends to Alice his own static key encrypted with a key obtained from an ephemeral-ephemeral Diffie-Hellman exchange.\\n\\nThis handshake can be slightly changed in case both Alice and Bob pre-shares some secret `psk` which can be used to strengthen their mutual authentication during the handshake execution. One of the resulting protocol, called `XXpsk0`, goes as follow:\\n\\n```\\n XXpsk0:\\n -> psk, e\\n <- e, ee, s, es\\n -> s, se\\n```\\n\\nThe main difference with `XX` is that Alice\'s and Bob\'s static keys, when transmitted, would be encrypted with a key derived from `psk` as well.\\n\\n**Security considerations on identity-hiding (active attacker)**: Alice\'s static key is encrypted with forward secrecy to an authenticated party for both `XX` and `XXpsk0` handshakes. In `XX`, Bob\'s static key is encrypted with forward secrecy but is transmitted to a non-authenticated user which can then be an active attacker. In `XXpsk0`, instead, Bob\'s secret key is protected by forward secrecy to a partially authenticated party (through the pre-shared secret `psk` but not through any static key), provided that `psk` was not previously compromised (in such case identity-hiding properties provided by the `XX` handshake applies).\\n\\n## Session Management and Multi-Device Support\\n\\nWhen two users complete a Noise handshake, an encryption/decryption session - or _Noise session_ - consisting of two Cipher States is instantiated.\\n\\nBy identifying Noise session with a `session-id` derived from the handshake\'s cryptographic material, we can take advantage of the [PubSub/GossipSub](https://github.com/libp2p/specs/tree/master/pubsub) protocols used by Waku for relaying messages in order to manage instantiated Noise sessions.\\n\\nThe core idea is to exchange after-handshake messages (encrypted with a Cipher State specific to the Noise session), over a content topic derived from the (secret) `session-id` the corresponding session refers to.\\n\\nThis allows to decouple the handshaking phase from the actual encrypted communication, thus improving users\' identity-hiding capabilities.\\n\\nFurthermore, by publicly revealing a value derived from `session-id` on the corresponding session content topic, a Noise session can be marked as _stale_, enabling peers to save resources by discarding any eventually [stored](https://rfc.vac.dev/spec/13/) message sent to such content topic.\\n\\nOne relevant aspect in today\'s applications is the possibility for users to employ different devices in their communications. In some cases, this is non-trivial to achieve since, for example, encrypted messages might be required to be synced on different devices which do not necessarily share the necessary key material for decryption and may be temporarily offline.\\n\\nWe address this by requiring each user\'s device to instantiate multiple Noise sessions either with all user\'s other devices which, in turn, all together share a Noise session with the other party, or by directly instantiating a Noise session with all other party\'s devices.\\n\\nWe named these two approaches $N11M$ and $NM$, respectively, which are in turn loosely based on the paper [\u201cMulti-Device for Signal\u201d](https://eprint.iacr.org/2019/1363.pdf) and [Signal\u2019s Sesame Algorithm](https://signal.org/docs/specifications/sesame/).\\n\\n![](//img/noise/N11M.png)\\n\\nInformally, in the $N11M$ session management scheme, once the first Noise session between any of Alice\u2019s and Bob\u2019s device is instantiated, its session information is securely propagated to all other devices using previously instantiated Noise sessions. Hence, all devices are able to send and receive new messages on the content topic associated to such session.\\n\\n![](//img/noise/NM.png)\\n\\nIn the $NM$ session management scheme, instead, all pairs of Alice\'s and Bob\'s devices have a distinct Noise session: a message is then sent from the currently-in-use sender\u2019s device to all recipient\u2019s devices, by properly encrypting and sending it to the content topics of each corresponding Noise session. If sent messages should be available on all sender\u2019s devices as well, we require each pair of sender\u2019s devices to instantiate a Noise session used for syncing purposes.\\n\\nFor more technical details on how Noise sessions are instantiated and managed within these two mechanisms and the different trade-offs provided by the latter, we refer to [37/WAKU2-NOISE-SESSIONS](https://rfc.vac.dev/spec/37/).\\n\\n## Conclusions\\n\\nIn this post we provided an overview of Noise, a protocol framework for designing Diffie-Hellman based key-exchange mechanisms allowing systematic security and threat model analysis.\\n\\nThe flexibility provided by Noise components allows not only to fully replicate with same security guarantees well established key-exchange primitives such as X3DH, currently employed by Status [5/TRANSPORT-SECURITY](https://specs.status.im/spec/5), but enables also optimizations based on the reciprocal knowledge parties have of each other while allowing easier protocols\' security analysis and (formal) verification.\\n\\nFurthermore, different handshakes can be combined and executed one after each other, a particularly useful feature to authenticate multiple static keys employed by different applications but also to ease keys revocation.\\n\\nThe possibility to manage Noise sessions over multiple devices and the fact that handshakes can be concretely instantiated using modern, fast and secure cryptographic primitives such as [ChaChaPoly](https://datatracker.ietf.org/doc/html/rfc7539) and [BLAKE2b](https://datatracker.ietf.org/doc/html/rfc7693), make Noise one of the best candidates for efficiently and securely address the many different needs of applications built on top of Waku requiring key-agreement.\\n\\n## Future steps\\n\\nThe available [implementation](https://github.com/status-im/nwaku/tree/master/waku/v2/waku_noise) of Noise in `nwaku`, although mostly complete, is still in its testing phase. As future steps we would like to:\\n\\n- have an extensively tested and robust Noise implementation;\\n- formalize, implement and test performances of the two proposed $N11M$ and $NM$ session management mechanisms and their suitability for common use-case scenarios;\\n- provide Waku network nodes a native protocol to readily support key-exchanges, strongly-encrypted communication and multi-device session management mechanisms with none-to-little interaction besides applications\' connection requests.\\n\\n## References\\n\\n- [6/WAKU1](https://rfc.vac.dev/spec/6/)\\n- [10/WAKU2](https://rfc.vac.dev/spec/10/)\\n- [13/WAKU2-STORE](https://rfc.vac.dev/spec/13/)\\n- [26/WAKU-PAYLOAD](https://rfc.vac.dev/spec/26/)\\n- [35/WAKU2-NOISE](https://rfc.vac.dev/spec/35/)\\n- [37/WAKU2-NOISE-SESSIONS](https://rfc.vac.dev/spec/37/)\\n- [5/TRANSPORT-SECURITY](https://specs.status.im/spec/5)\\n- [The PubSub/GossipSub Protocols](https://github.com/libp2p/specs/tree/master/pubsub)\\n- [The Noise Protocol Framework](http://www.noiseprotocol.org/noise.html)\\n- [The X3DH Key-agreement Protocol](https://signal.org/docs/specifications/x3dh/)\\n- [\u201cMulti-Device for Signal\u201d](https://eprint.iacr.org/2019/1363.pdf)\\n- [Signal\u2019s Sesame Algorithm](https://signal.org/docs/specifications/sesame/).\\n- [Public-key cryptography](https://en.wikipedia.org/wiki/Public-key_cryptography)\\n- [Elliptic curves](https://en.wikipedia.org/wiki/Elliptic_curve)\\n- [Elliptic Curve point multiplication](https://en.wikipedia.org/wiki/Elliptic_curve_point_multiplication)\\n- [Symmetric key algorithm](https://en.wikipedia.org/wiki/Symmetric-key_algorithm)\\n- [Authenticated encryption](https://en.wikipedia.org/wiki/Authenticated_encryption)\\n- [Diffie-Hellman Key-Exchange](https://en.wikipedia.org/wiki/Diffie%E2%80%93Hellman_key_exchange)\\n- [The Discrete Logarithm Problem](https://en.wikipedia.org/wiki/Discrete_logarithm)\\n- [Computational Diffie-Hellman Assumption](https://en.wikipedia.org/wiki/Computational_Diffie%E2%80%93Hellman_assumption)\\n- [The ECIES Encryption Algorithm](https://en.wikipedia.org/wiki/Integrated_Encryption_Scheme)\\n- [The ECDSA Signature Algorithm](https://en.wikipedia.org/wiki/Elliptic_Curve_Digital_Signature_Algorithm)\\n- [The Galois Counter Mode mode of operation](https://en.wikipedia.org/wiki/Galois/Counter_Mode)\\n- [The ChaChaPoly AEAD Cipher](https://datatracker.ietf.org/doc/html/rfc7539)\\n- [The BLAKE2b Hash Function](https://datatracker.ietf.org/doc/html/rfc7693)\\n- [The SHA-3 Hash Function](https://en.wikipedia.org/wiki/SHA-3)"},{"id":"wakuv2-apd","metadata":{"permalink":"/rlog/wakuv2-apd","source":"@site/rlog/2022-05-09-ambient-peer-discovery.mdx","title":"Waku v2 Ambient Peer Discovery","description":"Introducing and discussing ambient peer discovery methods currently used by Waku v2, as well as future plans in this area.","date":"2022-05-09T10:00:00.000Z","formattedDate":"May 9, 2022","tags":[],"readingTime":17.67,"hasTruncateMarker":true,"authors":[{"name":"Daniel","github":"kaiserd","key":"kaiserd"}],"frontMatter":{"layout":"post","name":"Waku v2 Ambient Peer Discovery","title":"Waku v2 Ambient Peer Discovery","date":"2022-05-09T10:00:00.000Z","authors":"kaiserd","published":true,"slug":"wakuv2-apd","categories":"research","image":"/img/waku_v2_discv5_random_walk_estimation.svg","discuss":"https://forum.vac.dev/t/discussion-waku-v2-ambient-peer-discovery/133","_includes":["math"]},"prevItem":{"title":"Noise handshakes as key-exchange mechanism for Waku","permalink":"/rlog/wakuv2-noise"},"nextItem":{"title":"Introducing nwaku","permalink":"/rlog/introducing-nwaku"}},"content":"Introducing and discussing ambient peer discovery methods currently used by Waku v2, as well as future plans in this area.\\n\\n\x3c!--truncate--\x3e\\n\\n[Waku v2](https://rfc.vac.dev/spec/10/) comprises a set of modular protocols for secure, privacy preserving communication.\\nAvoiding centralization, these protocols exchange messages over a P2P network layer.\\nIn order to build a P2P network, participating nodes first have to discover peers within this network.\\nThis is where [_ambient peer discovery_](https://docs.libp2p.io/concepts/publish-subscribe/#discovery) comes into play:\\nit allows nodes to find peers, making it an integral part of any decentralized application.\\n\\nIn this post the term _node_ to refers to _our_ endpoint or the endpoint that takes action,\\nwhile the term _peer_ refers to other endpoints in the P2P network.\\nThese endpoints can be any device connected to the Internet: e.g. servers, PCs, notebooks, mobile devices, or applications like a browser.\\nAs such, nodes and peers are the same. We use these terms for the ease of explanation without loss of generality.\\n\\nIn Waku\'s modular design, ambient peer discovery is an umbrella term for mechanisms that allow nodes to find peers.\\nVarious ambient peer discovery mechanisms are supported, and each is specified as a separate protocol.\\nWhere do these protocols fit into Waku\'s protocol stack?\\nThe P2P layer of Waku v2 builds on [libp2p gossipsub](https://github.com/libp2p/specs/blob/10712c55ab309086a52eec7d25f294df4fa96528/pubsub/gossipsub/README.md).\\nNodes participating in a gossipsub protocol manage a mesh network that is used for routing messages.\\nThis mesh network is an [unstructured P2P network](https://en.wikipedia.org/wiki/Peer-to-peer#Unstructured_networks)\\noffering high robustness and resilience against attacks.\\nGossipsub implements many improvements overcoming the shortcomings typically associated with unstructured P2P networks, e.g. inefficient flooding based routing.\\nThe gossipsub mesh network is managed in a decentralized way, which requires each node to know other participating peers.\\nWaku v2 may use any combination of its ambient discovery protocols to find appropriate peers.\\n\\nSummarizing, Waku v2 comprises a _peer management layer_ based on libp2p gossipsub,\\nwhich manages the peers of nodes, and an _ambient peer discovery layer_,\\nwhich provides information about peers to the peer management layer.\\n\\nWe focus on ambient peer discovery methods that are in line with our goal of building a fully decentralized, generalized, privacy-preserving and censorship-resistant messaging protocol.\\nSome of these protocols still need adjustments to adhere to our privacy and anonymity requirements. For now, we focus on operational stability and feasibility.\\nHowever, when choosing techniques, we pay attention to selecting mechanisms that can feasibly be tweaked for privacy in future research efforts.\\nBecause of the modular design and the fact that Waku v2 has several discovery methods at its disposal, we could even remove a protocol in case future evaluation deems it not fitting our standards.\\n\\nThis post covers the current state and future considerations of ambient peer discovery for Waku v2,\\nand gives reason for changes and modifications we made or plan to make.\\nThe ambient peer discovery protocols currently supported by Waku v2 are a modified version of Ethereum\'s [Discovery v5](https://github.com/ethereum/devp2p/blob/6b0abc3d956a626c28dce1307ee9f546db17b6bd/discv5/discv5.md)\\nand [DNS-based discovery](https://vac.dev/dns-based-discovery).\\nWaku v2 further supports [gossipsub\'s peer exchange protocol](https://github.com/libp2p/specs/blob/10712c55ab309086a52eec7d25f294df4fa96528/pubsub/gossipsub/gossipsub-v1.1.md#prune-backoff-and-peer-exchange).\\nIn addition, we plan to introduce protocols for general peer exchange and capability discovery, respectively.\\nThe former allows resource restricted nodes to outsource querying for peers to stronger peers,\\nthe latter allows querying peers for their supported capabilities.\\nBesides these new protocols, we are working on integrating capability discovery in our existing ambient peer discovery protocols.\\n\\n## Static Node Lists\\n\\nThe simplest method of learning about peers in a P2P network is via static node lists.\\nThese can be given to nodes as start-up parameters or listed in a config-file.\\nThey can also be provided in a script-parseable format, e.g. in JSON.\\nWhile this method of providing bootstrap nodes is very easy to implement, it requires static peers, which introduce centralized elements.\\nAlso, updating static peer information introduces significant administrative overhead:\\ncode and/or config files have to be updated and released.\\nTypically, static node lists only hold a small number of bootstrap nodes, which may lead to high load on these nodes.\\n\\n## DNS-based Discovery\\n\\nCompared to static node lists,\\n[DNS-based discovery](https://vac.dev/dns-based-discovery) (specified in [EIP-1459](https://eips.ethereum.org/EIPS/eip-1459))\\nprovides a more dynamic way of discovering bootstrap nodes.\\nIt is very efficient, can easily be handled by resource restricted devices and provides very good availability.\\nIn addition to a naive DNS approach, Ethereum\'s DNS-based discovery introduces efficient authentication leveraging [Merkle trees](https://en.wikipedia.org/wiki/Merkle_tree).\\n\\nA further advantage over static node lists is the separation of code/release management and bootstrap node management.\\nHowever, changing and updating the list of bootstrap nodes still requires administrative privileges because DNS records have to be added or updated.\\n\\nWhile this method of discovery still requires centralized elements,\\nnode list management can be delegated to various DNS zones managed by other entities mitigating centralization.\\n\\n## Discovery V5\\n\\nA much more dynamic method of ambient peer discovery is [Discovery v5](https://github.com/ethereum/devp2p/blob/6b0abc3d956a626c28dce1307ee9f546db17b6bd/discv5/discv5.md), which is Ethereum\'s peer discovery protocol.\\nIt is based on the [Kademlia](https://en.wikipedia.org/wiki/Kademlia) distributed hashtable (DHT).\\nAn [introduction to discv5 and its history](https://vac.dev/kademlia-to-discv5), and a [discv5 Waku v2 feasibility study](https://vac.dev/feasibility-discv5)\\ncan be found in previous posts on this research log.\\n\\nWe use Discovery v5 as an ambient peer discovery method for Waku v2 because it is decentralized, efficient, actively researched, and has web3 as its main application area.\\nDiscv5 also offers mitigation techniques for various attacks, which we cover later in this post.\\n\\nUsing a DHT (structured P2P network) as a means for ambient peer discovery, while using the gossipsub mesh network (unstructured P2P network) for transmitting actual messages,\\nWaku v2 leverages advantages from both worlds.\\nOne of the main benefits of DHTs is offering a global view over participating nodes.\\nThis, in turn, allows sampling random sets of nodes which is important for equally distributing load.\\nGossipsub, on the other hand, offers great robustness and resilience against attacks.\\nEven if discv5 discovery should not work in advent of a DoS attack, Waku v2 can still operate switching to different discovery methods.\\n\\nDiscovery methods that use separate P2P networks still depend on bootstrapping,\\nwhich Waku v2 does via parameters on start-up or via DNS-based discovery.\\nThis might raise the question of why such discovery methods are beneficial.\\nThe answer lies in the aforementioned global view of DHTs. Without discv5 and similar methods, the bootstrap nodes are used as part of the gossipsub mesh.\\nThis might put heavy load on these nodes and further, might open pathways to inference attacks.\\nDiscv5, on the other hand, uses the bootstrap nodes merely as an entry to the discovery network and can provide random sets of nodes (sampled from a global view)\\nfor bootstrapping or expanding the mesh.\\n\\n### DHT Background\\n\\nDistributed Hash Tables are a class of structured P2P overlay networks.\\nA DHT can be seen as a distributed node set of which each node is responsible for a part of the hash space.\\nIn contrast to unstructured P2P networks, e.g. the mesh network maintained by gossipsub,\\nDHTs have a global view over the node set and the hash space (assuming the participating nodes behave well).\\n\\nDHTs are susceptible to various kinds of attacks, especially [Sybil attacks](https://en.wikipedia.org/wiki/Sybil_attack)\\nand [eclipse attacks](https://www.usenix.org/conference/usenixsecurity15/technical-sessions/presentation/heilman).\\nWhile security aspects have been addressed in various research papers, general practical solutions are not available.\\nHowever, discv5 introduced various practical mitigation techniques.\\n\\n### Random Walk Discovery\\n\\nWhile discv5 is based on the Kademlia DHT, it only uses the _distributed node set_ aspect of DHTs.\\nIt does not map values (items) into the distributed hash space.\\nThis makes sense, because the main purpose of discv5 is discovering other nodes that support discv5, which are expected to be Ethereum nodes.\\nEthereum nodes that want to discover other Ethereum nodes simply query the discv5 network for a random set of peers.\\nIf Waku v2 would do the same, only a small subset of the retrieved nodes would support Waku v2.\\n\\nA first naive solution for Waku v2 discv5 discovery is\\n\\n- retrieve a random node set, which is achieved by querying for a set of randomly chosen node IDs\\n- filter the returned nodes on the query path based on Waku v2 capability via the [Waku v2 ENR](https://rfc.vac.dev/spec/31/)\\n- repeat until enough Waku v2 capable nodes are found\\n\\nThis query process boils down to random walk discovery, which is very resilient against attacks, but also very inefficient if the number of nodes supporting the desired capability is small.\\nWe refer to this as the needle-in-the-haystack problem.\\n\\n### Random Walk Performance Estimation\\n\\nThis subsection provides a rough estimation of the overhead introduced by random walk discovery.\\n\\nGiven the following parameters:\\n\\n- $n$ number of total nodes participating in discv5\\n- $p$ percentage of nodes supporting Waku\\n- $W$ the event of having at least one Waku node in a random sample\\n- $k$ the size of a random sample (default = 16)\\n- $\\\\alpha$ the number of parallel queries started\\n- $b$ bits per hop\\n- $q$ the number of queries\\n\\nA query takes $log_{2^b}n$ hops to retrieve a random sample of nodes.\\n\\n$P(W) = 1 - (1-p/100)^k$ is the probability of having at least one Waku node in the sample.\\n\\n$P(W^q) = 1 - (1-p/100)^{kq}$ is the probability of having at least one Waku node in the union of $q$ samples.\\n\\nExpressing this in terms of $q$, we can write:\\n$$P(W^q) = 1 - (1-p/100)^{kq} \\\\iff q = log_{(1-p/100)^k}(1-P(W^q))$$\\n\\nFigure 1 shows a log-log plot for $P(W^q) = 90\\\\%$.\\n\\n![Figure 1: log-log plot showing the number of queries necessary to retrieve a Waku v2 node with a probability of 90% in relation to the Waku v2 node concentration in the network.](/img/waku_v2_discv5_random_walk_estimation.svg)\\n\\nAssuming $p=0.1$, we would need\\n\\n$$0.9 = 1 - (1-0.1/100)^{16q} => q \\\\approx 144$$\\n\\nqueries to get a Waku node with 90% probability, which leads to $\\\\approx 144 * 18 = 2592$ overlay hops.\\nChoosing $b=3$ would reduce the number to $\\\\approx 144 * 6 = 864$.\\nEven when choosing $\\\\alpha = 10$ we would have to wait at least 80 RTTs.\\nThis effort is just for retrieving a single Waku node. Ideally, we want at least 3 Waku nodes for bootstrapping a Waku relay.\\n\\n[The discv5 doc](https://github.com/ethereum/devp2p/blob/6b0abc3d956a626c28dce1307ee9f546db17b6bd/discv5/discv5-theory.md#ad-placement-and-topic-radius) roughly estimates $p=1%$ to be the threshold for acceptably efficient random walk discovery.\\nThis is in line with our estimation:\\n\\n$$0.9 = 1 - (1-1/100)^{16q} => q \\\\approx 14$$\\n\\nThe number of necessary queries is linearly dependent on the percentage $p$ of Waku nodes.\\nThe number of hops per query is logarithmically dependent on $n$.\\nThus, random walk searching is inefficient for small percentages $p$.\\nStill, random walks are more resilient against attacks.\\n\\nWe can conclude that a Waku node concentration below 1% renders vanilla discv5 unfit for our needs.\\nOur current solution and future plans for solving this issue are covered in the next subsections.\\n\\n### Simple Solution: Separate Discovery Network\\n\\nThe simple solution we currently use for [Waku v2 discv5](https://rfc.vac.dev/spec/33/) is a separate discv5 network.\\nAll (well behaving) nodes in this network support Waku v2, resulting in a very high query efficiency.\\nHowever, this solution reduces resilience because the difficulty of attacking a DHT scales with the number of participating nodes.\\n\\n### Discv5 Topic Discovery\\n\\nWe did not base our solution on the [current version of discv5 topic discovery](https://github.com/ethereum/devp2p/blob/master/discv5/discv5-theory.md#topic-advertisement),\\nbecause, similar to random walk discovery, it suffers from poor performance for relatively rare capabilities/topics.\\n\\nHowever, there is [ongoing research](https://github.com/harnen/service-discovery-paper) in discv5 topic discovery which is close to ideas we explored when pondering efficient and resilient Waku discv5 solutions.\\nWe keep a close eye on this research, give feedback, and make suggestions, as we plan to switch to this version of topic discovery in the future.\\n\\nIn a nutshell, topic discovery will manage separate routing tables for each topic.\\nThese topic specific tables are initialized with nodes from the discv5 routing table.\\nWhile the buckets of the discv5 routing table represent distance intervals from the node\'s `node ID`, the topic table buckets represent distance intervals from `topic ID`s.\\n\\nNodes that want to register a topic try to register that topic at one random peer per bucket.\\nThis leads to registering the topic at peers in closer and closer neighbourhoods around the topic ID, which\\nyields a very efficient and resilient compromise between random walk discovery and DHT discovery.\\nPeers in larger neighbourhoods around the topic ID are less efficient to discover, however more resilient against eclipse attacks and vice versa.\\n\\nFurther, this works well with the overload and DoS protection discv5 employs.\\nDiscv5 limits the amount of nodes registered per topic on a single peer. Further, discv5 enforces a waiting time before nodes can register topics at peers.\\nSo, for popular topics, a node might fail to register the topic in a close neighbourhood.\\nHowever, because the topic is popular (has a high occurrence percentage $p$), it can still be efficiently discovered.\\n\\nIn the future, we also plan to integrate Waku v2 capability discovery, which will not only allow asking for nodes that support Waku v2,\\nbut asking for Waku v2 nodes supporting specific Waku v2 protocols like filter or store.\\nFor the store protocol we envision sub-capabilities reflecting message topics and time frames of messages.\\nWe will also investigate related security implications.\\n\\n### Attacks on DHTs\\n\\nIn this post, we only briefly describe common attacks on DHTs.\\nThese attacks are mainly used for denial of service (DoS),\\nbut can also used as parts of more sophisticated attacks, e.g. deanonymization attacks.\\nA future post on this research log will cover security aspects of ambient peer discovery with a focus on privacy and anonymity.\\n\\n_Sybil Attack_\\n\\nThe power of an attacker in a DHT is proportional to the number of controlled nodes.\\nControlling nodes comes at a high resource cost and/or requires controlling a botnet via a preliminary attack.\\n\\nIn a Sybil attack, an attacker generates lots of virtual node identities.\\nThis allows the attacker to control a large portion of the ID space in a DHT at a relatively low cost.\\nSybil attacks are especially powerful when the attacker can freely choose the IDs of generated nodes,\\nbecause this allows positioning at chosen points in the DHT.\\n\\nBecause Sybil attacks amplify the power of many attacks against DHTs,\\nmaking Sybil attacks as difficult as possible is the basis for resilient DHT operation.\\nThe typical abstract mitigation approach is binding node identities to physical network interfaces.\\nTo some extend, this can be achieved by introducing IP address based limits.\\nFurther, generating node IDs can be bound by proof of work (PoW),\\nwhich, however, comes with a set of shortcomings, e.g. relatively high costs on resource restricted devices.\\n[The discv5 doc](https://github.com/ethereum/devp2p/blob/6b0abc3d956a626c28dce1307ee9f546db17b6bd/discv5/discv5-rationale.md#sybil-and-eclipse-attacks)\\ndescribes both Sybil and eclipse attacks, as well as concrete mitigation techniques employed by discv5.\\n\\n_Eclipse Attack_\\n\\nIn an eclipse attack, nodes controlled by the attacker poison the routing tables of other nodes in a way that parts of the DHT become eclipsed, i.e. invisible.\\nWhen a controlled node is asked for the next step in a path,\\nit provides another controlled node as the next step,\\neffectively navigating the querying node around or away from certain areas of the DHT.\\nWhile several mitigation techniques have been researched, there is no definitive protection against eclipse attacks available as of yet.\\nOne mitigation technique is increasing $\\\\alpha$, the number of parallel queries, and following each concurrent path independently for the lookup.\\n\\nThe eclipse attack becomes very powerful in combination with a successful Sybil attack;\\nespecially when the attacker can freely choose the position of the Sybil nodes.\\n\\nThe aforementioned new topic discovery of discv5 provides a good balance between protection against eclipse attacks and query performance.\\n\\n## Peer Exchange Protocol\\n\\nWhile discv5 based ambient peer discovery has many desirable properties, resource restricted nodes and nodes behind restrictive NAT setups cannot run discv5 satisfactory.\\nWith these nodes in mind, we started working on a simple _peer exchange protocol_ based on ideas proposed [here](https://github.com/libp2p/specs/issues/222).\\nThe peer exchange protocol will allow nodes to ask peers for additional peers.\\nSimilar to discv5, the peer exchange protocol will also support capability discovery.\\n\\nThe new peer exchange protocol can be seen as a simple replacement for the [Rendezvous protocol](https://github.com/libp2p/specs/blob/10712c55ab309086a52eec7d25f294df4fa96528/rendezvous/README.md), which Waku v2 does not support.\\nWhile the rendezvous protocol involves nodes registering at rendezvous peers, the peer exchange protocol simply allows nodes to ask any peer for a list of peers (with a certain set of capabilities).\\nRendezvous tends to introduce centralized elements as rendezvous peers have a super-peer role.\\n\\nIn the future, we will investigate resource usage of [Waku v2 discv5](https://rfc.vac.dev/spec/33/) and provide suggestions for minimal resources nodes should have to run discv5 satisfactory.\\n\\n## Further Protocols Related to Discovery\\n\\nWaku v2 comprises further protocols related to ambient peer discovery. We shortly mention them for context, even though they are not strictly ambient peer discovery protocols.\\n\\n### Gossipsub Peer Exchange Protocol\\n\\nGossipsub provides an integrated [peer exchange](https://github.com/libp2p/specs/blob/10712c55ab309086a52eec7d25f294df4fa96528/pubsub/gossipsub/gossipsub-v1.1.md#prune-backoff-and-peer-exchange) mechanism which is also supported by Waku v2.\\nGossipsub peer exchange works in a _push_ manner. Nodes send peer lists to peers they prune from the active mesh.\\nThis pruning is part of the gossipsub peer management, blurring the boundaries of _peer management_ and _ambient peer discovery_.\\n\\nWe will investigate anonymity implications of this protocol and might disable it in favour of more anonymity-preserving protocols.\\nSending a list of peers discloses information about the sending node.\\nWe consider restricting these peer lists to cached peers that are currently not used in the active gossipsub mesh.\\n\\n### Capability Negotiation\\n\\nSome of the ambient peer discovery methods used by Waku2 will support capability discovery.\\nThis allows to narrow down the set of retrieved peers to peers that support specific capabilities.\\nThis is efficient because it avoids establishing connections to nodes that we are not interested in.\\n\\nHowever, the ambient discovery interface does not require capability discovery, which will lead to nodes having peers with unknown capabilities in their peer lists.\\nWe work on a _capability negotiation protocol_ which allows nodes to ask peers\\n\\n- for their complete list of capabilities, and\\n- whether they support a specific capability\\n\\nWe will investigate security implications, especially when sending full capability lists.\\n\\n## NAT traversal\\n\\nFor [NAT traversal](https://docs.libp2p.io/concepts/nat/), Waku v2 currently supports the port mapping protocols [UPnP](https://en.wikipedia.org/wiki/Universal_Plug_and_Play) and [NAT-PMP](https://datatracker.ietf.org/doc/html/rfc6886) / [PCP](https://datatracker.ietf.org/doc/html/rfc6887).\\n\\nIn the future, we plan to add support for parts of [ICE](https://datatracker.ietf.org/doc/html/rfc8445), e.g. [STUN](https://datatracker.ietf.org/doc/html/rfc7350).\\nWe do not plan to support [TURN](https://www.rfc-editor.org/rfc/rfc5928) because TURN relays would introduce a centralized element.\\nA modified decentralized version of TURN featuring incentivization might be an option in the future;\\nstrong peers could offer a relay service similar to TURN.\\n\\nThere are [plans to integrate more NAT traversal into discv5](https://github.com/ethereum/devp2p/issues/199), in which we might participate.\\nSo far, the only traversal technique supported by discv5 is nodes receiving their external IP address in pong messages.\\n\\nWhile NAT traversal is very important, adding more NAT traversal techniques is not a priority at the moment.\\nNodes behind restrictive symmetric NAT setups cannot be discovered, but they can still discover peers in less restrictive setups.\\nWhile we wish to have as many nodes as possible to be discoverable via ambient peer discovery, two nodes behind a restrictive symmetric NAT can still exchange Waku v2 messages if they discovered a shared peer.\\nThis is one of the nice resilience related properties of flooding based routing algorithms.\\n\\nFor mobile nodes, which suffer from changing IP addresses and double NAT setups, we plan using the peer exchange protocol to ask peers for more peers.\\nBesides saving resources on resource restricted devices, this approach works as long as peers are in less restrictive environments.\\n\\n## Conclusion and Future Prospects\\n\\n_Ambient peer discovery_ is an integral part of decentralized applications. It allows nodes to learn about peers in the network.\\nAs of yet, Waku v2 supports DNS-based discovery and a slightly modified version of discv5.\\nWe are working on further protocols, including a peer exchange protocol that allows resource restricted nodes to ask stronger peers for peer lists.\\nFurther, we are working on adding capability discovery to our ambient discovery protocols, allowing nodes to find peers with desired properties.\\n\\nThese protocols can be combined in a modular way and allow Waku v2 nodes to build a strong and resilient mesh network,\\neven if some discovery methods are not available in a given situation.\\n\\nWe will investigate security properties of these discovery mechanisms with a focus on privacy and anonymity in a future post on this research log.\\nAs an outlook we can already state that DHT approaches typically allow inferring information about the querying node.\\nFurther, sending peer lists allows inferring the position of a node within the mesh, and by extension information about the node.\\nWaku v2 already provides some mitigation, because the mesh for transmitting actual messages, and the peer discovery network are separate.\\nTo mitigate information leakage by transmitting peer lists, we plan to only reply with lists of peers that nodes do not use in their active meshes.\\n\\n---\\n\\n## References\\n\\n- [Waku v2](https://rfc.vac.dev/spec/10/)\\n- [libp2p gossipsub](https://github.com/libp2p/specs/blob/10712c55ab309086a52eec7d25f294df4fa96528/pubsub/gossipsub/README.md)\\n- [unstructured P2P network](https://en.wikipedia.org/wiki/Peer-to-peer#Unstructured_networks)\\n- [ambient peer discovery](https://docs.libp2p.io/concepts/publish-subscribe/#discovery)\\n- [Discovery v5](https://github.com/ethereum/devp2p/blob/6b0abc3d956a626c28dce1307ee9f546db17b6bd/discv5/discv5.md)\\n- [Kademlia](https://en.wikipedia.org/wiki/Kademlia)\\n- [Discv5 history](https://vac.dev/kademlia-to-discv5)\\n- [Discv5 Waku v2 feasibility study](https://vac.dev/feasibility-discv5)\\n- [DNS-based discovery](https://vac.dev/dns-based-discovery)\\n- [EIP-1459](https://eips.ethereum.org/EIPS/eip-1459)\\n- [Merkle trees](https://en.wikipedia.org/wiki/Merkle_tree)\\n- [Sybil attack](https://en.wikipedia.org/wiki/Sybil_attack)\\n- [eclipse attack](https://www.usenix.org/conference/usenixsecurity15/technical-sessions/presentation/heilman)\\n- [Waku v2 ENR](https://rfc.vac.dev/spec/31/)\\n- [Discv5 topic discovery](https://github.com/ethereum/devp2p/blob/6b0abc3d956a626c28dce1307ee9f546db17b6bd/discv5/discv5-theory.md#ad-placement-and-topic-radius)\\n- [Discv5 paper](https://github.com/harnen/service-discovery-paper)\\n- [Discv5 vs Sybil and eclipse attacks](https://github.com/ethereum/devp2p/blob/6b0abc3d956a626c28dce1307ee9f546db17b6bd/discv5/discv5-rationale.md#sybil-and-eclipse-attacks)\\n- [peer exchange idea](https://github.com/libp2p/specs/issues/222)\\n- [Rendezvous protocol](https://github.com/libp2p/specs/blob/10712c55ab309086a52eec7d25f294df4fa96528/rendezvous/README.md)\\n- [Waku v2 discv5](https://rfc.vac.dev/spec/33/)\\n- [Gossipsub peer exchange](https://github.com/libp2p/specs/blob/10712c55ab309086a52eec7d25f294df4fa96528/pubsub/gossipsub/gossipsub-v1.1.md#prune-backoff-and-peer-exchange)\\n- [NAT traversal](https://docs.libp2p.io/concepts/nat/)\\n- [UPnP](https://en.wikipedia.org/wiki/Universal_Plug_and_Play)\\n- [NAT-PMP](https://datatracker.ietf.org/doc/html/rfc6886)\\n- [PCP](https://datatracker.ietf.org/doc/html/rfc6887).\\n- [Discv5 topic efficiency issue](https://github.com/ethereum/devp2p/issues/199)"},{"id":"introducing-nwaku","metadata":{"permalink":"/rlog/introducing-nwaku","source":"@site/rlog/2022-04-12-introducing-nwaku.mdx","title":"Introducing nwaku","description":"Introducing nwaku, a Nim-based Waku v2 client, including a summary of recent developments and preview of current and future focus areas.","date":"2022-04-12T10:00:00.000Z","formattedDate":"April 12, 2022","tags":[],"readingTime":10.765,"hasTruncateMarker":true,"authors":[{"name":"Hanno Cornelius","twitter":"4aelius","github":"jm-clius","key":"hanno"}],"frontMatter":{"layout":"post","name":"Introducing nwaku","title":"Introducing nwaku","date":"2022-04-12T10:00:00.000Z","authors":"hanno","published":true,"slug":"introducing-nwaku","categories":"research","discuss":"https://forum.vac.dev/","toc_min_heading_level":2,"toc_max_heading_level":5},"prevItem":{"title":"Waku v2 Ambient Peer Discovery","permalink":"/rlog/wakuv2-apd"},"nextItem":{"title":"Opinion: Pseudo-ethics in the Surveillance Tech Industry","permalink":"/rlog/ethics-surveillance-tech"}},"content":"Introducing nwaku, a Nim-based Waku v2 client, including a summary of recent developments and preview of current and future focus areas.\\n\\n\x3c!--truncate--\x3e\\n\\n## Background\\n\\nIf you\'ve been following our [research log](https://vac.dev/research-log/),\\nyou\'ll know that many things have happened in the world of Waku v2 since [our last general update](/waku-v2-ethereum-coscup).\\nIn line with our [long term goals](https://vac.dev/#about),\\nwe\'ve introduced new protocols,\\ntweaked our existing protocols\\nand expanded our team.\\nWe\'ve also shown [in a series of practical experiments](/waku-v1-v2-bandwidth-comparison) that Waku v2 does indeed deliver on some of the [theoretical advantages](/waku-v2-plan) it was designed to have over its predecessor, Waku v1.\\nA [sustainability and business workshop](https://forum.vac.dev/t/vac-sustainability-and-business-workshop/116) led to the formulation of a clearer vision for Vac as a team.\\n\\nFrom the beginning, our protocol development has been complemented by various client implementations of these protocols,\\nfirst in [Nim](https://github.com/status-im/nim-waku),\\nbut later also in [JavaScript](https://github.com/status-im/js-waku)\\nand [Go](https://github.com/status-im/go-waku).\\nA follow-up post will clarify the purposes, similarities and differences between these three clients.\\nThe [Nim client](https://github.com/status-im/nim-waku/tree/d2fccb5220144893f994a67f2cc26661247f101f/waku/v2), is our reference implementation,\\ndeveloped by the research team in parallel with the specs\\nand building on a home-grown implementation of [`libp2p`](https://github.com/status-im/nim-libp2p).\\nThe Nim client is suitable to run as [a standalone adaptive node](/waku-update),\\nmanaged by individual operators\\nor as an encapsulated service node in other applications.\\nThis post looks at some recent developments within the Nim client.\\n\\n## 1. _**nim-waku**_ is now known as _**nwaku**_\\n\\nPronounced NWHA-koo.\\nYou may already have seen us refer to \\"`nwaku`\\" on Vac communication channels,\\nbut it is now official:\\nThe `nim-waku` Waku v2 client has been named `nwaku`.\\nWhy? Well, we needed a recognizable name for our client that could easily be referred to in everyday conversations\\nand `nim-waku` just didn\'t roll off the tongue.\\nWe\'ve followed the example of the closely related [`nimbus` project](https://github.com/status-im/nimbus-eth2) to find a punchier name\\nthat explicitly links the client to both the Waku set of protocols and the Nim language.\\n\\n## 2. Improvements in stability and performance\\n\\nThe initial implementation of Waku v2 demonstrated how the suite of protocols can be applied\\nto form a generalized, peer-to-peer messaging network,\\nwhile addressing a wide range of adaptive requirements.\\nThis allowed us to lift several protocol [specifications](https://rfc.vac.dev/) from `raw` to `draft` status,\\nindicating that a reference implementation exists for each.\\nHowever, as internal dogfooding increased and more external applications started using `nwaku`,\\nwe stepped up our focus on the client\'s stability and performance.\\nThis is especially true where we want `nwaku` to run unsupervised in a production environment\\nwithout any degradation in the services it provides.\\n\\nSome of the more significant productionization efforts over the last couple of months included:\\n\\n1. Reworking the `store` implementation to maintain stable memory usage\\n while storing historical messages\\n and serving multiple clients querying history simultaneously.\\n Previously, a `store` node would see gradual service degradation\\n due to inefficient memory usage when responding to history queries.\\n Queries that often took longer than 8 mins now complete in under 100 ms.\\n\\n2. Improved peer management.\\n For example, `filter` nodes will now remove unreachable clients after a number of connection failures,\\n whereas they would previously keep accumulating dead peers.\\n\\n3. Improved disk usage.\\n `nwaku` nodes that persist historical messages on disk now manage their own storage size based on the `--store-capacity`.\\n This can significantly improve node start-up times.\\n\\nMore stability issues may be addressed in future as `nwaku` matures,\\nbut we\'ve noticed a marked improvement in the reliability of running `nwaku` nodes.\\nThese include environments where `nwaku` nodes are expected to run with a long uptime.\\nVac currently operates two long-running fleets of `nwaku` nodes, `wakuv2.prod` and `wakuv2.test`,\\nfor internal dogfooding and\\nto serve as experimental bootstrapping nodes.\\nStatus has also recently deployed similar fleets for production and testing based on `nwaku`.\\nOur goal is to have `nwaku` be stable, performant and flexible enough\\nto be an attractive option for operators to run and maintain their own Waku v2 nodes.\\nSee also the [future work](#future-work) section below for more on our general goal of _`nwaku` for operators_.\\n\\n## 3. Improvements in interoperability\\n\\nWe\'ve implemented several features that improve `nwaku`\'s usability in different environments\\nand its interoperability with other Waku v2 clients.\\nOne major step forward here was adding support for both secure and unsecured WebSocket connections as `libp2p` transports.\\nThis allows direct connectivity with `js-waku`\\nand paves the way for native browser usage.\\nWe\'ve also added support for parsing and resolving DNS-type `multiaddrs`,\\ni.e. multiaddress protocol schemes [`dns`, `dns4`, `dns6` and `dnsaddr`](https://github.com/multiformats/multiaddr/blob/b746a7d014e825221cc3aea6e57a92d78419990f/protocols.csv#L8-L11).\\nA `nwaku` node can now also be [configured with its own IPv4 DNS domain name](https://github.com/status-im/nim-waku/tree/d2fccb5220144893f994a67f2cc26661247f101f/waku/v2#configuring-a-domain-name)\\nallowing dynamic IP address allocation without impacting a node\'s reachability by its peers.\\n\\n## 4. Peer discovery\\n\\n_Peer discovery_ is the method by which nodes become aware of each other\u2019s existence.\\nThe question of peer discovery in a Waku v2 network has been a focus area since the protocol was first conceptualized.\\nSince then several different approaches to discovery have been proposed and investigated.\\nWe\'ve implemented three discovery mechanisms in `nwaku` so far:\\n\\n### DNS-based discovery\\n\\n`nwaku` nodes can retrieve an authenticated, updateable list of peers via DNS to bootstrap connection to a Waku v2 network.\\nOur implementation is based on [EIP-1459](https://eips.ethereum.org/EIPS/eip-1459).\\n\\n### GossipSub peer exchange\\n\\n[GossipSub Peer Exchange (PX)](https://github.com/libp2p/specs/blob/10712c55ab309086a52eec7d25f294df4fa96528/pubsub/gossipsub/gossipsub-v1.1.md#prune-backoff-and-peer-exchange) is a GossipSub v1.1 mechanism\\nwhereby a pruning peer may provide a pruned peer with a set of alternative peers\\nwhere it can connect to reform its mesh.\\nThis is a very suitable mechanism to gradually discover more peers\\nfrom an initial connection to a small set of bootstrap peers.\\nIt is enabled in a `nwaku` node by default.\\n\\n### Waku Node Discovery Protocol v5\\n\\nThis is a DHT-based discovery mechanism adapted to store and relay _node records_.\\nOur implementation is based on [Ethereum\'s Discovery v5 protocol](https://github.com/ethereum/devp2p/blob/fa6428ada7385c13551873b2ae6ad2457c228eb8/discv5/discv5-theory.md)\\nwith some [minor modifications](https://rfc.vac.dev/spec/33/) to isolate our discovery network from that of Ethereum.\\nThe decision to separate the Waku Discovery v5 network from Ethereum\'s was made on considerations of lookup efficiency.\\nThis comes at a possible tradeoff in network resilience.\\nWe are considering merging with the Ethereum Discovery v5 network in future,\\nor even implement a hybrid solution.\\n[This post](https://forum.vac.dev/t/waku-v2-discv5-roadmap-discussion/121/8) explains the decision and future steps.\\n\\n## 5. Spam protection using RLN\\n\\nAn early addition to our suite of protocols was [an extension of `11/WAKU-RELAY`](https://rfc.vac.dev/spec/32/)\\nthat provided spam protection using [Rate Limiting Nullifiers (RLN)](https://rfc.vac.dev/spec/32/).\\nThe `nwaku` client now contains a working demonstration and integration of RLN relay.\\nCheck out [this tutorial](https://github.com/status-im/nim-waku/blob/ee96705c7fbe4063b780ac43b7edee2f6c4e351b/docs/tutorial/rln-chat2-live-testnet.md) to see the protocol in action using a toy chat application built on `nwaku`.\\nWe\'d love for people to join us in dogfooding RLN spam protection as part of our operator incentive testnet.\\nFeel free to join our [Vac Discord](https://discord.gg/KNj3ctuZvZ) server\\nand head to the `#rln` channel for more information.\\n\\n## Future work\\n\\nAs we continue working towards our goal of a fully decentralized, generalized and censorship-resistant messaging protocol,\\nthese are some of the current and future focus areas for `nwaku`:\\n\\n### Reaching out to operators:\\n\\nWe are starting to push for operators to run and maintain their own Waku v2 nodes,\\npreferably contributing to the default Waku v2 network as described by the default pubsub topic (`/waku/2/default-waku/proto`).\\nAmongst other things, a large fleet of stable operator-run Waku v2 nodes will help secure the network,\\nprovide valuable services to a variety of applications\\nand ensure the future sustainability of both Vac as a research organization and the Waku suite of protocols.\\n\\nWe are targeting `nwaku` as the main option for operator-run nodes. \\nSpecifically, we aim to provide through `nwaku`:\\n\\n1. a lightweight and robust Waku v2 client.\\n This client must be first in line to support innovative and new Waku v2 protocols,\\n but configurable enough to serve the adaptive needs of various operators.\\n2. an easy-to-follow guide for operators to configure,\\n set up and maintain their own nodes\\n3. a set of operator-focused tools to monitor and maintain a running node\\n\\n### Better conversational security layer guarantees\\n\\nConversational security guarantees in Waku v2 are currently designed around the Status application.\\nDevelopers building their own applications on top of Waku would therefore\\neither have to reimplement a set of tools similar to Status\\nor build their own security solutions on the application layer above Waku.\\nWe are working on [a set of features](https://github.com/vacp2p/research/issues/97) built into Waku\\nthat will provide the general security properties Waku users may desire\\nand do so in a modern and simple way.\\nThis is useful for applications outside of Status that want similar security guarantees.\\nAs a first step, we\'ve already made good progress toward [integrating noise handshakes](https://forum.vac.dev/t/noise-handshakes-as-key-exchange-mechanism-for-waku2/130) as a key exchange mechanism in Waku v2.\\n\\n### Protocol incentivization\\n\\nWe want to design incentivization around our protocols to encourage desired behaviors in the Waku network,\\nrewarding nodes providing costly services\\nand punishing adversarial actions.\\nThis will increase the overall security of the network\\nand encourage operators to run their own Waku nodes.\\nIn turn, the sustainability of Vac as an organization will be better guaranteed.\\nAs such, protocol incentivization was a major focus in our recent [Vac Sustainability and Business Workshop](https://forum.vac.dev/t/vac-sustainability-and-business-workshop/).\\nOur first step here is to finish integrating RLN relay into Waku\\nwith blockchain interaction to manage members,\\npunish spammers\\nand reward spam detectors.\\nAfter this, we want to design monetary incentivization for providers of `store`, `lightpush` and `filter` services.\\nThis may also tie into a reputation mechanism for service nodes based on a network-wide consensus on service quality.\\nA big challenge for protocol incentivization is doing it in a private fashion,\\nso we can keep similar metadata protection guarantees as the Waku base layer.\\nThis ties into our focus on [Zero Knowledge tech](https://forum.vac.dev/t/vac-3-zk/97).\\n\\n### Improved store capacity\\n\\nThe `nwaku` store currently serves as an efficient in-memory store for historical messages,\\ndimensioned by the maximum number of messages the store node is willing to keep.\\nThis makes the `nwaku` store appropriate for keeping history over a short term\\nwithout any time-based guarantees,\\nbut with the advantage of providing fast responses to history queries.\\nSome applications, such as Status, require longer-term historical message storage\\nwith time-based dimensioning\\nto guarantee that messages will be stored for a specified minimum period.\\nBecause of the relatively high cost of memory compared to disk space,\\na higher capacity store, with time guarantees, should operate as a disk-only database of historical messages.\\nThis is an ongoing effort.\\n\\n### Multipurpose discovery\\n\\nIn addition to [the three discovery methods](#4-peer-discovery) already implemented in `nwaku`,\\nwe are working on improving discovery on at least three fronts:\\n\\n#### _Capability discovery:_\\n\\nWaku v2 nodes may be interested in peers with specific capabilities, for example:\\n\\n1. peers within a specific pubsub topic mesh,\\n2. peers with **store** capability,\\n3. **store** peers with x days of history for a specific content topic, etc.\\n\\nCapability discovery entails mechanisms by which such capabilities can be advertised and discovered/negotiated.\\nOne major hurdle to overcome is the increased complexity of finding a node with specific capabilities within the larger network (a needle in a haystack).\\nSee the [original problem statement](https://github.com/vacp2p/rfc/issues/429) for more.\\n\\n#### _Improvements in Discovery v5_\\n\\nOf the implemented discovery methods,\\nDiscovery v5 best addresses our need for a decentralized and scalable discovery mechanism.\\nWith the basic implementation done,\\nthere are some improvements planned for Discovery v5,\\nincluding methods to increase security such as merging with the Ethereum Discovery v5 network,\\nintroducing explicit NAT traversal\\nand utilizing [topic advertisement](https://github.com/ethereum/devp2p/blob/fa6428ada7385c13551873b2ae6ad2457c228eb8/discv5/discv5-theory.md#topic-advertisement).\\nThe [Waku v2 Discovery v5 Roadmap](https://forum.vac.dev/t/waku-v2-discv5-roadmap-discussion/121) contains more details.\\n\\n#### _Generalized peer exchange_\\n\\n`nwaku` already implements [GossipSub peer exchange](https://github.com/libp2p/specs/blob/10712c55ab309086a52eec7d25f294df4fa96528/pubsub/gossipsub/gossipsub-v1.1.md#prune-backoff-and-peer-exchange).\\nWe now need a general request-response mechanism outside of GossipSub\\nby which a node may learn about other Waku v2 nodes\\nby requesting and receiving a list of peers from a neighbor.\\nThis could, for example, be a suitable way for resource-restricted devices to request a stronger peer\\nto perform a random Discovery v5 lookup on their behalf\\nor simply to be informed of a subset of the peers known to that neighbor.\\nSee [this issue](https://github.com/vacp2p/rfc/issues/495) for more.\\n\\n---\\n\\nThis concludes a general outline of some of the main recent developments in the `nwaku` client\\nand a summary of the current and future focus areas.\\nMuch more is happening behind the scenes, of course,\\nso for more information, or to join the conversation,\\nfeel free to join our [Vac Discord](https://discord.gg/KNj3ctuZvZ) server\\nor to check out the [`nwaku` repo on Github](https://github.com/status-im/nim-waku).\\nYou can also view the changelog for past releases [here](https://github.com/status-im/nim-waku/releases).\\n\\n## References\\n\\n- [17/WAKU-RLN-RELAY](https://rfc.vac.dev/spec/17/)\\n- [32/RLN](https://rfc.vac.dev/spec/32/)\\n- [33/WAKU2-DISCV5](https://rfc.vac.dev/spec/33/)\\n- [Capabilities advertising](https://github.com/vacp2p/rfc/issues/429)\\n- [Configuring a domain name](https://github.com/status-im/nim-waku/tree/d2fccb5220144893f994a67f2cc26661247f101f/waku/v2#configuring-a-domain-name)\\n- [Conversational security](https://github.com/vacp2p/research/issues/97)\\n- [Discovery v5 Topic Advertisement](https://github.com/ethereum/devp2p/blob/fa6428ada7385c13551873b2ae6ad2457c228eb8/discv5/discv5-theory.md#topic-advertisement)\\n- [EIP-1459](https://eips.ethereum.org/EIPS/eip-1459)\\n- [GossipSub Peer Exchange](https://github.com/libp2p/specs/blob/10712c55ab309086a52eec7d25f294df4fa96528/pubsub/gossipsub/gossipsub-v1.1.md#prune-backoff-and-peer-exchange)\\n- [go-waku](https://github.com/status-im/go-waku)\\n- [js-waku](https://github.com/status-im/js-waku)\\n- [`multiaddr` formats](https://github.com/multiformats/multiaddr/blob/b746a7d014e825221cc3aea6e57a92d78419990f/protocols.csv#L8-L11)\\n- [nimbus-eth2](https://github.com/status-im/nimbus-eth2)\\n- [nim-libp2p](https://github.com/status-im/nim-libp2p)\\n- [nim-waku](https://github.com/status-im/nim-waku)\\n- [nim-waku releases](https://github.com/status-im/nim-waku/releases)\\n- [Node Discovery Protocol v5 - Theory](https://github.com/ethereum/devp2p/blob/fa6428ada7385c13551873b2ae6ad2457c228eb8/discv5/discv5-theory.md)\\n- [Noise handshakes](https://forum.vac.dev/t/noise-handshakes-as-key-exchange-mechanism-for-waku2/130)\\n- [RLN tutorial](https://github.com/status-im/nim-waku/blob/ee96705c7fbe4063b780ac43b7edee2f6c4e351b/docs/tutorial/rln-chat2-live-testnet.md)\\n- [Vac <3 ZK](https://forum.vac.dev/t/vac-3-zk/97)\\n- [Vac About page](https://vac.dev/#about)\\n- [Vac Research log](https://vac.dev/research-log/)\\n- [Vac RFC site](https://rfc.vac.dev/)\\n- [Vac Sustainability and Business Workshop](https://forum.vac.dev/t/vac-sustainability-and-business-workshop/)\\n- [Waku Update](/waku-update)\\n- [Waku v1 vs Waku v2: Bandwidth Comparison](/waku-v1-v2-bandwidth-comparison)\\n- [Waku v2 Peer Exchange](https://github.com/vacp2p/rfc/issues/495)\\n- [Waku v2 Discovery v5 Roadmap](https://forum.vac.dev/t/waku-v2-discv5-roadmap-discussion/121)\\n- [What\'s the Plan for Waku v2?](/waku-v2-plan)"},{"id":"ethics-surveillance-tech","metadata":{"permalink":"/rlog/ethics-surveillance-tech","source":"@site/rlog/2021-12-03-ethics-surveillance-tech.mdx","title":"Opinion: Pseudo-ethics in the Surveillance Tech Industry","description":"A look at typical ethical shortfalls in the global surveillance tech industry.","date":"2021-12-03T10:00:00.000Z","formattedDate":"December 3, 2021","tags":[],"readingTime":11.715,"hasTruncateMarker":true,"authors":[{"name":"Circe","twitter":"vacp2p","github":"thecirce","key":"circe"}],"frontMatter":{"layout":"post","name":"Opinion: Pseudo-ethics in the Surveillance Tech Industry","title":"Opinion: Pseudo-ethics in the Surveillance Tech Industry","date":"2021-12-03T10:00:00.000Z","authors":"circe","published":true,"slug":"ethics-surveillance-tech","categories":"research","summary":null,"discuss":null},"prevItem":{"title":"Introducing nwaku","permalink":"/rlog/introducing-nwaku"},"nextItem":{"title":"Waku v1 vs Waku v2: Bandwidth Comparison","permalink":"/rlog/waku-v1-v2-bandwidth-comparison"}},"content":"A look at typical ethical shortfalls in the global surveillance tech industry.\\n\\n\x3c!--truncate--\x3e\\n\\n_This is an opinion piece by pseudonymous contributor, circe._\\n\\n## Preface\\n\\nThe Vac team aims to provide a public good in the form of freely available, open source tools and protocols for decentralized communication.\\nAs such, we value our independence and the usefulness of our protocols for a wide range of applications.\\nAt the same time, we realize that all technical development, including ours, has a moral component.\\nAs a diverse team we are guided by a shared devotion to the principles of human rights and liberty.\\nThis explains why we place such a high premium on security, censorship-resistance and privacy -\\na stance we [share with the wider Status Network](https://our.status.im/our-principles/).\\nThe post below takes a different approach from our usual more technical analyses,\\nby starting to peel back the curtain on the ethical shortfalls of the global surveillance tech industry.\\n\\n## Spotlight on an industry\\n\\n[Apple\'s announcement](https://www.apple.com/newsroom/2021/11/apple-sues-nso-group-to-curb-the-abuse-of-state-sponsored-spyware/) of their lawsuit against Israel\'s NSO Group\\nmarks the latest in a series of recent setbacks for the surveillance tech company.\\nIn early November, the [United States blacklisted the firm](https://public-inspection.federalregister.gov/2021-24123.pdf),\\nciting concerns about the use of their spyware by foreign governments targeting civilians such as \\"journalists, businesspeople, activists\\" and more.\\nThe company is already [embroiled in a lawsuit with Whatsapp](https://www.reuters.com/article/us-facebook-cyber-whatsapp-nsogroup-idUSKBN1X82BE)\\nover their exploit of the chat app\'s video calling service to install malware on target devices.\\nNSO Group\'s most infamous product, [Pegasus](https://forbiddenstories.org/case/the-pegasus-project/), operates as a hidden exploit installed on victims\' mobile phones,\\nsometimes without even requiring as much as an unguarded click on a malicious link.\\nIt has the potential to lay bare, and report to its owners, _everything_ within the reach of the infected device.\\nFor most people this amounts to a significant portion of their private lives and thoughts.\\nPegasus can read your private messages (even encrypted), collect your passwords, record calls, track your location and access your device\'s microphone and camera.\\nNo activity or application on an infected phone would be hidden.\\n\\nThe latest controversies are perhaps less because of the novelty of the revelations -\\nthe existence of Pegasus has been known to civil activists [since at least 2016](https://www.bbc.com/news/technology-37192670).\\nRather, the public was reminded again of the potential scope of surveillance tech\\nin the indiscriminate use of Pegasus on private citizens.\\nThis has far-reaching implications for human freedoms worldwide.\\nEarlier this year, a [leaked list of over 50,000 targets](https://www.theguardian.com/world/2021/jul/18/revealed-leak-uncovers-global-abuse-of-cyber-surveillance-weapon-nso-group-pegasus), or possible targets, of Pegasus included\\nthe phone numbers of human rights advocates, independent journalists, lawyers and political activists.\\nThis should have come as no surprise.\\nThe type of autocratically inclined agents, and governments, who would venture to buy and use such invasive cyber-arms often target those they find politically inconvenient.\\nPegasus, and similar technologies, simply extend the reach and capacity of such individuals and governments -\\nno border or distance, no political rank or social advantage, no sanctity of profession or regard for dignity,\\nprovide any indemnity from becoming a victim.\\nYour best hope is to remain uninteresting enough to escape consideration.\\n\\nThe NSO Group has, of course, denied allegations of culpability and questions the authenticity of the list.\\nAt this stage, the latter is almost beside the point:\\nAmnesty International\'s cybersecurity team, Security Lab, _did_ find [forensic evidence of Pegasus](https://www.amnesty.org/en/latest/research/2021/07/forensic-methodology-report-how-to-catch-nso-groups-pegasus/#_ftn1) on the phones of several volunteers whose numbers appeared on the original list,\\nincluding those of journalists and human rights activists.\\n(Security Lab has since opened up their [infection finding tool](https://github.com/mvt-project/mvt) to the public.)\\nFrench intelligence has similarly [inspected and confirmed](https://www.theguardian.com/news/2021/aug/02/pegasus-spyware-found-on-journalists-phones-french-intelligence-confirms) infection of at least three devices belonging to journalists.\\nThe phones of several people who were close to the Saudi-American journalist, Jamal Khashoggi, were [confirmed hacked](https://www.bbc.com/news/world-57891506)\\nboth before and after Khashoggi\'s brutal murder at the Saudi embassy in Istanbul in 2018.\\n[More reports](https://www.theguardian.com/news/2021/sep/21/hungary-journalist-daniel-nemeth-phones-infected-with-nso-pegasus-spyware) of confirmed Pegasus hacks are still published with some regularity.\\nIt is now an open secret that many authoritarian governments have bought Pegasus.\\nIt\'s not difficult to extrapolate from existing reports and such clients\' track records\\nwhat the potential injuries to human freedoms are that they can inflict with access to such a powerful cyberweapon.\\n\\n## A typical response\\n\\n[NSO\'s response](https://www.theguardian.com/news/2021/jul/18/response-from-nso-and-governments) to the allegations follows a textbook approach\\nof avoiding earnest ethical introspection on the manufacturing, and selling, of cyber-arms.\\nFirstly, shift ethical responsibility to a predetermined process, a list of checkboxes of your own making.\\nThe Group, for example, claims to sell only to \\"vetted governments\\", following a classification process\\nof which they have now [published some procedural details](https://www.nsogroup.com/wp-content/uploads/2021/06/ReportBooklet.pdf) but no tangible criteria.\\nThe next step is to reaffirm continuously, and repetitively, your dedication to the _legal_ combat against crime,\\n[\\"legitimate law enforcement agencies\\"](https://www.nsogroup.com/wp-content/uploads/2021/06/ReportBooklet.pdf) (note the almost tautological phrasing),\\nadherence to international arms trade laws,\\ncompliance clauses in customer contracts, etc.\\nThirdly, having been absolved of any moral suspicions that might exist about product and process,\\nfrom conception to engineering to trade,\\ndistance yourself from the consequences of its use in the world.\\n[\\"NSO does not operate its technology, does not collect, nor possesses, nor has any access to any kind of data of its customers.\\"](https://www.theguardian.com/news/2021/jul/18/response-from-nso-and-governments)\\nIt is interesting that directly after this statement they claim with contradictory confidence that\\ntheir \\"technology was not associated in any way with the heinous murder of Jamal Khashoggi\\".\\nThe unapologetic tone seems hardly appropriate when the same document confirms that the Group had to\\nshut down customers\' systems due to \\"confirmed misuse\\" and have had to do so \\"multiple times\\" in the past.\\nGiven all this, the response manages to evade any serious interrogation of the \\"vetting\\" process itself,\\nwhich forced the company to reject \\"approximately 15% of potential new opportunities for Pegasus\\" in one year.\\nCourageous.\\n\\nWe have heard this all before.\\nThere exists a multi-billion dollar industry of private companies and engineering firms [thriving on proceeds](https://www.economist.com/business/2019/12/12/offering-software-for-snooping-to-governments-is-a-booming-business) from\\nselling surveillance tools and cyber-arms to dubious agencies and foreign governments.\\nIn turn, the most power-hungry and oppressive regimes often _rely_ on such technological innovations -\\nfor which they lack the in-country engineering expertise -\\nto maintain control, suppress uprisings, intimidate opposing journalists, and track their citizens.\\nIt\'s a lucrative business opportunity, and resourceful companies have sprung up everywhere to supply this demand,\\noften in countries where citizens, including employees of the company, would be horrified if they were similarly subject to the oppressions of their own products.\\nWhen, in 2014, Italy\'s _HackingTeam_ were pulsed by the United Nations about their (then alleged) selling of spyware to Sudan,\\nwhich would have been a contravention of the UN\'s weapon export ban,\\nthey simply replied that their product was not controlled as a weapon and therefore not subject to such scrutiny.\\nThey remained within their legal bounds, technically.\\nFurthermore, they similarly shifted ethical responsibility to external standards of legitimacy,\\nclaiming their [\\"software is not sold to governments that are blacklisted by the EU, the US, NATO, and similar international organizations\\"](https://citizenlab.ca/2014/02/mapping-hacking-teams-untraceable-spyware/).\\nWhen the company themselves were [hacked in 2015](https://www.wired.com/2015/07/hacking-team-breach-shows-global-spying-firm-run-amok/),\\nrevelations (confirmations, that is) of widespread misuse by repressive governments were damaging enough to force them to disappear and rebrand as Memento Labs.\\n[Their website](https://www.mem3nt0.com/en/) boasts an impressive list of statutes, regulations, procedures, export controls and legal frameworks,\\nall of which the rebranded hackers proudly comply with.\\nSurely no further ethical scrutiny is necessary?\\n\\n## Ethics != the law\\n\\n### The law is trailing behind\\n\\nSuch recourse to the _legality_ of your action as ethical justification is moot for several reasons.\\nThe first is glaringly obvious -\\nour laws are ill-equipped to address the implications of modern technology.\\nLegal systems are a cumbersome inheritance built over generations.\\nThis is especially true of the statutes and regulations governing international trade, behind which these companies so often hide.\\nOur best legal systems are trailing miles behind the technology for which we seek guidelines.\\nLegislators are still struggling to make sense of technologies like face recognition,\\nthe repercussions of smart devices acting \\"on their own\\" and biases in algorithms.\\nTo claim you are performing ethical due diligence by resorting to an outdated and incomplete system of legal codes is disingenuous.\\n\\n### The law depends on ethics\\n\\nThe second reason is more central to my argument,\\nand an important flaw in these sleight of hand justifications appearing from time to time in the media.\\nEthics can in no way be confused as synonymous with legality or legitimacy.\\nThese are incommensurable concepts.\\nIn an ideal world, of course, the law is meant to track the minimum standards of ethical conduct in a society.\\nLaws are often drafted exactly from some ethical, and practical, impulse to minimize harmful conduct\\nand provide for corrective and punitive measures where transgressions do occur.\\nThe law, however, has a much narrower scope than ethics.\\nIt can be just or unjust.\\nIn fact, it is in need of ethics to constantly reform.\\nEthics and values are born out of collective self-reflection.\\nIt develops in our conversation with ourselves and others about the type of society we strive for.\\nAs such, an ethical worldview summarizes our deepest intuitions about how we should live and measure our impact on the world.\\nFor this reason, ethics is primarily enforced by social and internal pressures, not legal boundaries -\\nour desire to do what _ought_ to be done, however we define that.\\nEthics is therefore a much grander scheme than global legal systems\\nand the diplomatic frameworks that grants legitimacy to governments.\\nThese are but one limited outflow of the human aspiration to form societies in accordance with our ideologies and ethics.\\n\\n### International law is vague and exploitable\\n\\nOf course, the cyber-arms trade has a favorite recourse, _international_ law, which is even more limited.\\nSince such products are seldomly sold to governments and agencies within the country of production,\\nit enables a further distancing from consequences.\\nMany private surveillance companies are based in fairly liberal societies with (seemingly) strict emphases on human rights in their domestic laws.\\nInternational laws are much more complicated - for opportunists a synonym for \\"more grey areas in which to hide\\".\\nCompany conduct can now be governed, and excused, by a system that follows\\nthe whims of autocrats with exploitative intent and vastly different ethical conceptions from the company\'s purported aims.\\nInternational law, and the ways it is most often enforced by way of, say, UN-backed sanctions,\\nhave long been shaped by the compromises of international diplomacy.\\nTo be blunt: these laws are weak and subject to exactly the sort of narrow interests behind which mercenaries have always hidden.\\nThe surveillance tech industry is no exception.\\n\\n## Conclusion\\n\\nMy point is simple:\\nselling cyber-arms with the potential to become vast tools of oppression to governments and bodies with blatant histories of human rights violations,\\nand all but the publicly announced intention to continue operating in this way,\\nis categorically unconscionable.\\nThis seems obvious no matter what ethics system you argue from,\\nprovided it harbors any consideration for human dignity and freedom.\\nIt is a sign of poor moral discourse that such recourses to law and legitimacy are often considered synonymous with ethical justification.\\n\\"_I have acted within the bounds of law_\\", _\\"We supply only to legitimate law enforcement agencies\\"_, etc. are no substitutes.\\nEthical conduct requires an honest evaluation of an action against some conception of \\"the good\\",\\nhowever you define that.\\nToo often the surveillance tech industry precisely sidesteps this question,\\nboth in internal processes and external rationalisations to a concerned public.\\n\\nJohn Locke, he of the life-liberty-and-property, articulated the idea that government exists solely through the consent of the governed.\\nTowards the end of the 17th century, he wrote in his _Second Treatise on Civil Government_,\\n\\"[w]henever legislators endeavor to take away,\\nand destroy the property of the people, or to reduce them to slavery under arbitrary power,\\nthey put themselves in a state of war with the people, who are thereupon absolved from any further obedience\\".\\nThe inference is straightforward and humanist in essence:\\nlegitimacy is not something that is conferred by governments and institutions.\\nRather, they derive their legitimacy from us, their citizens, holding them to standards of ethics and societal ideals.\\nThis legitimacy only remains in tact as long as this mandate is honored and continuously extended by a well-informed public.\\nThis is the principle of informed consent on which all reciprocal ethics is based.\\n\\nThe surveillance tech industry may well have nothing more or less noble in mind than profit-making within legal bounds\\nwhen developing and selling their products.\\nHowever, when such companies are revealed again and again to have supplied tools of gross human rights violations to known human rights violators,\\nthey will do well to remember that ethics always _precedes_ requirements of legality and legitimacy.\\nIt is a fallacy to take normative guidance from the concept of \\"legitimacy\\"\\nif the concept itself depends on such normative guidelines for definition.\\nWithout examining the ethical standards by which institutions, governments, and laws, were created,\\nno value-judgements about their legitimacy can be made.\\nHiding behind legal compliance as substitute for moral justification is not enough.\\nTargets of increasingly invasive governmental snooping are too often chosen precisely to suppress the mechanisms from which the legitimacy of such governments flow -\\nthe consent of ordinary civilians.\\nFree and fair elections, free speech, free media, freedom of thought are all at risk.\\n\\n## References\\n\\n- [Status Principles](https://our.status.im/our-principles/)\\n- [Federal Register: Addition of Certain Entities to the Entity List](https://public-inspection.federalregister.gov/2021-24123.pdf)\\n- [forbiddenstories.org: The Pegasus Project](https://forbiddenstories.org/case/the-pegasus-project/)\\n- [theguardian.com: The Pegasus Project](https://www.theguardian.com/news/series/pegasus-project)\\n- [amnesty.org Forensic Methodology Report: How to catch NSO Group\u2019s Pegasus](https://www.amnesty.org/en/latest/research/2021/07/forensic-methodology-report-how-to-catch-nso-groups-pegasus/#_ftn1)\\n- [Apple sues NSO Group to curb the abuse of state-sponsored spyware](https://www.apple.com/newsroom/2021/11/apple-sues-nso-group-to-curb-the-abuse-of-state-sponsored-spyware/)\\n- [bbc.com: Who are the hackers who cracked the iPhone?](https://www.bbc.com/news/technology-37192670)\\n- [bbc.com: Pegasus: Who are the alleged victims of spyware targeting?](https://www.bbc.com/news/world-57891506)\\n- [citizenlab.ca: Mapping Hacking Team\u2019s \u201cUntraceable\u201d Spyware](https://citizenlab.ca/2014/02/mapping-hacking-teams-untraceable-spyware/)\\n- [economist.com: Offering software for snooping to governments is a booming business](https://www.economist.com/business/2019/12/12/offering-software-for-snooping-to-governments-is-a-booming-business)\\n- [Memento Labs](https://www.mem3nt0.com/en/)\\n- [Mobile Verification Toolkit to identify compromised devices](https://github.com/mvt-project/mvt)\\n- [NSO Group: Transparency and Responsibility Report 2021](https://www.nsogroup.com/wp-content/uploads/2021/06/ReportBooklet.pdf)\\n- [reuters.com: WhatsApp sues Israel\'s NSO for allegedly helping spies hack phones around the world](https://www.reuters.com/article/us-facebook-cyber-whatsapp-nsogroup-idUSKBN1X82BE)\\n- [wired.com: Hacking Team Breach Shows a Global Spying Firm Run Amok](https://www.wired.com/2015/07/hacking-team-breach-shows-global-spying-firm-run-amok/)"},{"id":"waku-v1-v2-bandwidth-comparison","metadata":{"permalink":"/rlog/waku-v1-v2-bandwidth-comparison","source":"@site/rlog/2021-10-25-waku-v1-vs-waku-v2.mdx","title":"Waku v1 vs Waku v2: Bandwidth Comparison","description":"A local comparison of bandwidth profiles showing significantly improved scalability in Waku v2 over Waku v1.","date":"2021-11-03T10:00:00.000Z","formattedDate":"November 3, 2021","tags":[],"readingTime":9.345,"hasTruncateMarker":true,"authors":[{"name":"Hanno Cornelius","twitter":"4aelius","github":"jm-clius","key":"hanno"}],"frontMatter":{"layout":"post","name":"Waku v1 vs Waku v2: Bandwidth Comparison","title":"Waku v1 vs Waku v2: Bandwidth Comparison","date":"2021-11-03T10:00:00.000Z","authors":"hanno","published":true,"slug":"waku-v1-v2-bandwidth-comparison","categories":"research","image":"/img/waku1-vs-waku2/waku1-vs-waku2-overall-network-size.png","discuss":"https://forum.vac.dev/t/discussion-waku-v1-vs-waku-v2-bandwidth-comparison/110"},"prevItem":{"title":"Opinion: Pseudo-ethics in the Surveillance Tech Industry","permalink":"/rlog/ethics-surveillance-tech"},"nextItem":{"title":"[Talk at COSCUP] Vac, Waku v2 and Ethereum Messaging","permalink":"/rlog/waku-v2-ethereum-coscup"}},"content":"A local comparison of bandwidth profiles showing significantly improved scalability in Waku v2 over Waku v1.\\n\\n\x3c!--truncate--\x3e\\n\\n## Background\\n\\nThe [original plan](https://vac.dev/waku-v2-plan) for Waku v2 suggested theoretical improvements in resource usage over Waku v1,\\nmainly as a result of the improved amplification factors provided by GossipSub.\\nIn its turn, [Waku v1 proposed improvements](https://vac.dev/fixing-whisper-with-waku) over its predecessor, Whisper.\\n\\nGiven that Waku v2 is aimed at resource restricted environments,\\nwe are specifically interested in its scalability and resource usage characteristics.\\nHowever, the theoretical performance improvements of Waku v2 over Waku v1,\\nhas never been properly benchmarked and tested.\\n\\nAlthough we\'re working towards a full performance evaluation of Waku v2,\\nthis would require significant planning and resources,\\nif it were to simulate \\"real world\\" conditions faithfully and measure bandwidth and resource usage across different network connections,\\nrobustness against attacks/losses, message latencies, etc.\\n(There already exists a fairly comprehensive [evaluation of GossipSub v1.1](https://research.protocol.ai/publications/gossipsub-v1.1-evaluation-report/vyzovitis2020.pdf),\\non which [`11/WAKU2-RELAY`](https://rfc.vac.dev/spec/11/) is based.)\\n\\nAs a starting point,\\nthis post contains a limited and local comparison of the _bandwidth_ profile (only) between Waku v1 and Waku v2.\\nIt reuses and adapts existing network simulations for [Waku v1](https://github.com/status-im/nim-waku/blob/master/waku/v1/node/quicksim.nim) and [Waku v2](https://github.com/status-im/nim-waku/blob/master/waku/v2/node/quicksim2.nim)\\nand compares bandwidth usage for similar message propagation scenarios.\\n\\n## Theoretical improvements in Waku v2\\n\\nMessages are propagated in Waku v1 using [flood routing]().\\nThis means that every peer will forward every new incoming message to all its connected peers (except the one it received the message from).\\nThis necessarily leads to unnecessary duplication (termed _amplification factor_),\\nwasting bandwidth and resources.\\nWhat\'s more, we expect this effect to worsen the larger the network becomes,\\nas each _connection_ will receive a copy of each message,\\nrather than a single copy per peer.\\n\\nMessage routing in Waku v2 follows the `libp2p` _GossipSub_ protocol,\\nwhich lowers amplification factors by only sending full message contents to a subset of connected peers.\\nAs a Waku v2 network grows, each peer will limit its number of full-message (\\"mesh\\") peerings -\\n`libp2p` suggests a maximum of `12` such connections per peer.\\nThis allows much better scalability than a flood-routed network.\\nFrom time to time, a Waku v2 peer will send metadata about the messages it has seen to other peers (\\"gossip\\" peers).\\n\\nSee [this explainer](https://hackmd.io/@vac/main/%2FYYlZYBCURFyO_ZG1EiteWg#11WAKU2-RELAY-gossipsub) for a more detailed discussion.\\n\\n## Methodology\\n\\nThe results below contain only some scenarios that provide an interesting contrast between Waku v1 and Waku v2.\\nFor example, [star network topologies](https://en.wikipedia.org/wiki/Star_network) do not show a substantial difference between Waku v1 and Waku v2.\\nThis is because each peer relies on a single connection to the central node for every message,\\nwhich barely requires any routing:\\neach connection receives a copy of every message for both Waku v1 and Waku v2.\\nHybrid topologies similarly show only a difference between Waku v1 and Waku v2 for network segments with [mesh-like connections](https://en.wikipedia.org/wiki/Mesh_networking),\\nwhere routing decisions need to be made.\\n\\nFor this reason, the following approach applies to all iterations:\\n\\n1. Simulations are run **locally**.\\n This limits the size of possible scenarios due to local resource constraints,\\n but is a way to quickly get an approximate comparison.\\n2. Nodes are treated as a **blackbox** for which we only measure bandwidth,\\n using an external bandwidth monitoring tool.\\n In other words, we do not consider differences in the size of the envelope (for v1) or the message (for v2).\\n3. Messages are published at a rate of **50 new messages per second** to each network,\\n except where explicitly stated otherwise.\\n4. Each message propagated in the network carries **8 bytes** of random payload, which is **encrypted**.\\n The same symmetric key cryptographic algorithm (with the same keys) are used in both Waku v1 and v2.\\n5. Traffic in each network is **generated from 10 nodes** (randomly-selected) and published in a round-robin fashion to **10 topics** (content topics for Waku v2).\\n In practice, we found no significant difference in _average_ bandwidth usage when tweaking these two parameters (the number of traffic generating nodes and the number of topics).\\n6. Peers are connected in a decentralized **full mesh topology**,\\n i.e. each peer is connected to every other peer in the network.\\n Waku v1 is expected to flood all messages across all existing connections.\\n Waku v2 gossipsub will GRAFT some of these connections for full-message peerings,\\n with the rest being gossip-only peerings.\\n7. After running each iteration, we **verify that messages propagated to all peers** (comparing the number of published messages to the metrics logged by each peer).\\n\\nFor Waku v1, nodes are configured as \\"full\\" nodes (i.e. with full bloom filter),\\nwhile Waku v2 nodes are `relay` nodes, all subscribing and publishing to the same PubSub topic.\\n\\n## Network size comparison\\n\\n### Iteration 1: 10 nodes\\n\\nLet\'s start with a small network of 10 nodes only and see how Waku v1 bandwidth usage compares to that of Waku v2.\\nAt this small scale we don\'t expect to see improved bandwidth usage in Waku v2 over Waku v1,\\nsince all connections, for both Waku v1 and Waku v2, will be full-message connections.\\nThe number of connections is low enough that Waku v2 nodes will likely GRAFT all connections to full-message peerings,\\nessentially flooding every message on every connection in a similar fashion to Waku v1.\\nIf our expectations are confirmed, it helps validate our methodology,\\nshowing that it gives more or less equivalent results between Waku v1 and Waku v2 networks.\\n\\n![](//img/waku1-vs-waku2/waku1-vs-waku2-10-nodes.png)\\n\\nSure enough, the figure shows that in this small-scale setup,\\nWaku v1 actually has a lower per-peer bandwidth usage than Waku v2.\\nOne reason for this may be the larger overall proportion of control messages in a gossipsub-routed network such as Waku v2.\\nThese play a larger role when the total network traffic is comparatively low, as in this iteration.\\nAlso note that the average bandwidth remains more or less constant as long as the rate of published messages remains stable.\\n\\n### Iteration 2: 30 nodes\\n\\nNow, let\'s run the same scenario for a larger network of highly-connected nodes, this time consisting of 30 nodes.\\nAt this point, the Waku v2 nodes will start pruning some connections to limit the number of full-message peerings (to a maximum of `12`),\\nwhile the Waku v1 nodes will continue flooding messages to all connected peers.\\nWe therefore expect to see a somewhat improved bandwidth usage in Waku v2 over Waku v1.\\n\\n![](//img/waku1-vs-waku2/waku1-vs-waku2-30-nodes.png)\\n\\nBandwidth usage in Waku v2 has increased only slightly from the smaller network of 10 nodes (hovering between 2000 and 3000 kbps).\\nThis is because there are only a few more full-message peerings than before.\\nCompare this to the much higher increase in bandwidth usage for Waku v1, which now requires more than 4000 kbps on average.\\n\\n### Iteration 3: 50 nodes\\n\\nFor an even larger network of 50 highly connected nodes,\\nthe divergence between Waku v1 and Waku v2 is even larger.\\nThe following figure shows comparative average bandwidth usage for a throughput of 50 messages per second.\\n\\n![](//img/waku1-vs-waku2/waku1-vs-waku2-50-nodes.png)\\n\\nAverage bandwidth usage (for the same message rate) has remained roughly the same for Waku v2 as it was for 30 nodes,\\nindicating that the number of full-message peerings per node has not increased.\\n\\n### Iteration 4: 85 nodes\\n\\nWe already see a clear trend in the bandwidth comparisons above,\\nso let\'s confirm by running the test once more for a network of 85 nodes.\\nDue to local resource constraints, the effective throughput for Waku v1 falls to below 50 messages per second,\\nso the v1 results below have been normalized and are therefore approximate.\\nThe local Waku v2 simulation maintains the message throughput rate without any problems.\\n\\n![](//img/waku1-vs-waku2/waku1-vs-waku2-85-nodes.png)\\n\\n### Iteration 5: 150 nodes\\n\\nFinally, we simulate message propagation in a network of 150 nodes.\\nDue to local resource constraints, we run this simulation at a lower rate -\\n35 messages per second -\\nand for a shorter amount of time.\\n\\n![](//img/waku1-vs-waku2/waku1-vs-waku2-150-nodes.png)\\n\\nNotice how the Waku v1 bandwidth usage is now more than 10 times worse than that of Waku v2.\\nThis is to be expected, as each Waku v1 node will try to flood each new message to 149 other peers,\\nwhile the Waku v2 nodes limit their full-message peerings to no more than 12.\\n\\n### Discussion\\n\\nLet\'s summarize average bandwidth growth against network growth for a constant message propagation rate.\\nSince we are particularly interested in how Waku v1 compares to Waku v2 in terms of bandwidth usage,\\nthe results are normalised to the Waku v2 average bandwidth usage for each network size.\\n\\n![](//img/waku1-vs-waku2/waku1-vs-waku2-overall-network-size.png)\\n\\nExtrapolation is a dangerous game,\\nbut it\'s safe to deduce that the divergence will only grow for even larger network topologies.\\nAlthough control signalling contributes more towards overall bandwidth for Waku v2 networks,\\nthis effect becomes less noticeable for larger networks.\\nFor network segments with more than ~18 densely connected nodes,\\nthe advantage of using Waku v2 above Waku v1 becomes clear.\\n\\n## Network traffic comparison\\n\\nThe analysis above controls the average message rate while network size grows.\\nIn reality, however, active users (and therefore message rates) are likely to grow in conjunction with the network.\\nThis will have an effect on bandwidth for both Waku v1 and Waku v2, though not in equal measure.\\nConsider the impact of an increasing rate of messages in a network of constant size:\\n\\n![](//img/waku1-vs-waku2/waku1-vs-waku2-overall-message-rate.png)\\n\\nThe _rate_ of increase in bandwidth for Waku v2 is slower than that for Waku v1 for a corresponding increase in message propagation rate.\\nIn fact, for a network of 30 densely-connected nodes,\\nif the message propagation rate increases by 1 per second,\\nWaku v1 requires an increased average bandwidth of almost 70kbps at each node.\\nA similar traffic increase in Waku v2 requires on average 40kbps more bandwidth per peer, just over half that of Waku v1.\\n\\n## Conclusions\\n\\n- **Waku v2 scales significantly better than Waku v1 in terms of average bandwidth usage**,\\n especially for densely connected networks.\\n- E.g. for a network consisting of **150** or more densely connected nodes,\\n Waku v2 provides more than **10x** better average bandwidth usage rates than Waku v1.\\n- As the network continues to scale, both in absolute terms (number of nodes) and in network traffic (message rates) the disparity between Waku v2 and Waku v1 becomes even larger.\\n\\n## Future work\\n\\nNow that we\'ve confirmed that Waku v2\'s bandwidth improvements over its predecessor matches theory,\\nwe can proceed to a more in-depth characterisation of Waku v2\'s resource usage.\\nSome questions that we want to answer include:\\n\\n- What proportion of Waku v2\'s bandwidth usage is used to propagate _payload_ versus bandwidth spent on _control_ messaging to maintain the mesh?\\n- To what extent is message latency (time until a message is delivered to its destination) affected by network size and message rate?\\n- How _reliable_ is message delivery in Waku v2 for different network sizes and message rates?\\n- What are the resource usage profiles of other Waku v2 protocols (e.g.[`12/WAKU2-FILTER`](https://rfc.vac.dev/spec/12/) and [`19/WAKU2-LIGHTPUSH`](https://rfc.vac.dev/spec/19/))?\\n\\nOur aim is to get ever closer to a \\"real world\\" understanding of Waku v2\'s performance characteristics,\\nidentify and fix vulnerabilities\\nand continually improve the efficiency of our suite of protocols.\\n\\n## References\\n\\n- [Evaluation of GossipSub v1.1](https://research.protocol.ai/publications/gossipsub-v1.1-evaluation-report/vyzovitis2020.pdf)\\n- [Fixing Whisper with Waku](https://vac.dev/fixing-whisper-with-waku)\\n- [GossipSub vs flood routing](https://hackmd.io/@vac/main/%2FYYlZYBCURFyO_ZG1EiteWg#11WAKU2-RELAY-gossipsub)\\n- [Network topologies: star](https://www.techopedia.com/definition/13335/star-topology#:~:text=Star%20topology%20is%20a%20network,known%20as%20a%20star%20network.)\\n- [Network topologies: mesh](https://en.wikipedia.org/wiki/Mesh_networking)\\n- [Waku v2 original plan](https://vac.dev/waku-v2-plan)"},{"id":"waku-v2-ethereum-coscup","metadata":{"permalink":"/rlog/waku-v2-ethereum-coscup","source":"@site/rlog/2021-08-06-coscup-waku-ethereum.mdx","title":"[Talk at COSCUP] Vac, Waku v2 and Ethereum Messaging","description":"Learn more about Waku v2, its origins, goals, protocols, implementation and ongoing research. Understand how it is used and how it can be useful for messaging in Ethereum.","date":"2021-08-06T12:00:00.000Z","formattedDate":"August 6, 2021","tags":[],"readingTime":7.12,"hasTruncateMarker":true,"authors":[{"name":"Oskar","twitter":"oskarth","github":"oskarth","key":"oskarth"}],"frontMatter":{"layout":"post","name":"[Talk at COSCUP] Vac, Waku v2 and Ethereum Messaging","title":"[Talk at COSCUP] Vac, Waku v2 and Ethereum Messaging","date":"2021-08-06T12:00:00.000Z","authors":"oskarth","published":true,"slug":"waku-v2-ethereum-coscup","categories":"research","image":"/img/coscup-waku/talk.png","discuss":"https://forum.vac.dev/t/discussion-talk-at-coscup-vac-waku-v2-and-ethereum-messaging/95"},"prevItem":{"title":"Waku v1 vs Waku v2: Bandwidth Comparison","permalink":"/rlog/waku-v1-v2-bandwidth-comparison"},"nextItem":{"title":"Presenting JS-Waku: Waku v2 in the Browser","permalink":"/rlog/presenting-js-waku"}},"content":"Learn more about Waku v2, its origins, goals, protocols, implementation and ongoing research. Understand how it is used and how it can be useful for messaging in Ethereum.\\n\\n\x3c!--truncate--\x3e\\n\\n_This is the English version of a talk originally given in Chinese at COSCUP in Taipei._\\n\\n[video recording with Chinese and English subtitles.](https://www.youtube.com/watch?v=s0ATpQ4_XFc)\\n\\n---\\n\\n## Introduction\\n\\nHi everyone!\\n\\nToday I\'ll talk to you about Waku v2. What it is, what problems it is solving,\\nand how it can be useful for things such as messaging in Ethereum. First, let me\\nstart with some brief background.\\n\\n## Brief history and background\\n\\nBack when Ethereum got started, there used to be this concept of the \\"holy\\ntrinity\\". You had Ethereum for compute/consensus, Swarm for storage, and Whisper\\nfor messaging. This is partly where the term Web3 comes from.\\n\\nStatus started out as an app with the goal of being a window onto Ethereum and\\na secure messenger. As one of the few, if not the only, apps using Whisper in\\nproduction, not to mention on a mobile phone, we quickly realized there were\\nproblems with the underlying protocols and infrastructure. Protocols such as\\nWhisper weren\'t quite ready for prime time yet when it came to things such as\\nscalability and working in the real world.\\n\\nAs we started addressing some of these challenges, and moved from app\\ndevelopement to focusing on protocols, research and infrastructure, we created\\nVac. Vac is an r&d unit doing protocol research focused on creating modular p2p\\nmessaging protocols for private, secure, censorship resistant communication.\\n\\nI won\'t go into too much detail on the issues with Whisper, if you are\\ninterested in this check out this talk\\n[here](https://www.youtube.com/watch?v=6lLT33tsJjs) or this\\n[article](https://vac.dev/fixing-whisper-with-waku).\\n\\nIn a nutshell, we forked Whisper to address immediate shortcomings and this\\nbecame Waku v1. Waku v2 is complete re-thought implementation from scratch on top\\nof libp2p. This will be the subject of today\'s talk.\\n\\n## Waku v2\\n\\n### Overview\\n\\nWaku v2 is a privacy-preserving peer-to-peer messaging protocol for resource\\nrestricted devices. We can look at Waku v2 as several things:\\n\\n- Set of protocols\\n- Set of implementations\\n- Network of nodes\\n\\nLet\'s first look at what the goals are.\\n\\n### Goals\\n\\nWaku v2 provides a PubSub based messaging protocol with the following\\ncharacteristics:\\n\\n1. **Generalized messaging**. Applications that require a messaging protocol to\\n communicate human to human, machine to machine, or a mix.\\n2. **Peer-to-peer**. For applications that require a p2p solution.\\n3. **Resource restricted**. For example, running with limited bandwidth, being\\n mostly-offline, or in a browser.\\n4. **Privacy**. Applications that have privacy requirements, such as pseudonymity,\\n metadata protection, etc.\\n\\nAnd to provide these properties in a modular fashion, where applications can\\nchoose their desired trade-offs.\\n\\n### Protocols\\n\\nWaku v2 consists of several protocols. Here we highlight a few of the most\\nimportant ones:\\n\\n- 10/WAKU2 - main specification, details how all the pieces fit together\\n- 11/RELAY - thin layer on top of GossipSub for message dissemination\\n- 13/STORE - fetching of historical messages\\n- 14/MESSAGE - message payload\\n\\nThis is the recommended subset for a minimal Waku v2 client.\\n\\nIn addition to this there are many other types of specifications at various\\nstages of maturity, such as: content based filtering, bridge mode to Waku v1,\\nJSON RPC API, zkSNARKS based spam protection with RLN, accounting and\\nsettlements with SWAP, fault-tolerant store nodes, recommendations around topic\\nusage, and more.\\n\\nSee https://rfc.vac.dev/ for a full overview.\\n\\n### Implementations\\n\\nWaku v2 consists of multiple implementations. This allows for client diversity,\\nmakes it easier to strengthen the protocols, and allow people to use Waku v2 in\\ndifferent contexts.\\n\\n- nim-waku - the reference client written in Nim, most full-featured.\\n- js-waku - allow usage of Waku v2 from browsers, focus on interacting with dapps.\\n- go-waku - subset of Waku v2 to ease integration into the Status app.\\n\\n### Testnet Huilong and dogfooding\\n\\nIn order to test the protocol we have setup a testnet across all implementations\\ncalled Huilong. Yes, that\'s the Taipei subway station!\\n\\n![](/img/coscup-waku/huilong.jpg)\\n\\nAmong us core devs we have disabled the main #waku Discord channel used for\\ndevelopment, and people run their own node connected to this toy chat application.\\n\\nFeel free to join and say hi! Instructions can be found here:\\n\\n- [nim-waku chat](https://github.com/status-im/nim-waku/blob/master/docs/tutorial/chat2.md)\\n\\n- [js-waku chat](https://status-im.github.io/js-waku/)\\n\\n- [go-waku chat](https://github.com/status-im/go-waku/tree/master/examples/chat2)\\n\\n### Research\\n\\nWhile Waku v2 is being used today, we are actively researching improvements.\\nSince the design is modular, we can gracefully introduce new capabilities. Some\\nof these research areas are:\\n\\n- Privacy-preserving spam protection using zkSNARKs and RLN\\n- Accounting and settlement of resource usage to incentivize nodes to provide services with SWAP\\n- State synchronization for store protocol to make it easier to run a store node without perfect uptime\\n- Better node discovery\\n- More rigorous privacy analysis\\n- Improving interaction with wallets and dapp\\n\\n## Use cases\\n\\nLet\'s look at where Waku v2 is and can be used.\\n\\n### Prelude: Topics in Waku v2\\n\\nTo give some context, there are two different types of topics in Waku v2. One is\\na PubSub topic, for routing. The other is a content topic, which is used for\\ncontent based filtering. Here\'s an example of the default PubSub topic:\\n\\n`/waku/2/default-waku/proto`\\n\\nThis is recommended as it increases privacy for participants and it is stored by\\ndefault, however this is up to the application.\\n\\nThe second type of topic is a content topic, which is application specific. For\\nexample, here\'s the content topic used in our testnet:\\n\\n`/toychat/2/huilong/proto`\\n\\nFor more on topics, see https://rfc.vac.dev/spec/23/\\n\\n### Status app\\n\\nIn the Status protocol, content topics - topics in Whisper/Waku v1 - are used for several things:\\n\\n- Contact code topic to discover X3DH bundles for perfect forward secrecy\\n - Partitioned into N (currently 5000) content topics to balance privacy with efficiency\\n- Public chats correspond to hash of the plaintext name\\n- Negotiated topic for 1:1 chat with DHKE derived content topic\\n\\nSee more here https://specs.status.im/spec/10\\n\\nCurrently, Status app is in the process of migrating to and testing Waku v2.\\n\\n### DappConnect: Ethereum messaging\\n\\nIt is easy to think of Waku as being for human messaging, since that\'s how it is\\nprimarily used in the Status app, but the goal is to be useful for generalized\\nmessaging, which includes Machine-To-Machine (M2M) messaging.\\n\\nRecall the concept of the holy trinity with Ethereum/Swarm/Whisper and Web3 that\\nwe mentioned in the beginning. Messaging can be used as a building block for\\ndapps, wallets, and users to communicate with each other. It can be used for\\nthings such as:\\n\\n- Multisig and DAO vote transactions only needing one on-chain operation\\n- Giving dapps ability to send push notifications to users\\n- Giving users ability to directly respond to requests from dapps\\n- Decentralized WalletConnect\\n- Etc\\n\\nBasically anything that requires communication and doesn\'t have to be on-chain.\\n\\n### WalletConnect v2\\n\\nWalletConnect is an open protocol for connecting dapps to wallets with a QR\\ncode. Version 2 is using Waku v2 as a communication channel to do so in a\\ndecentralized and private fashion.\\n\\n![](/img/coscup-waku/walletconnect.png)\\n\\nSee for more: https://docs.walletconnect.org/v/2.0/tech-spec\\n\\nWalletConnect v2 is currently in late alpha using Waku v2.\\n\\n### More examples\\n\\n- Gasless voting and vote aggregation off-chain\\n- Dapp games using Waku as player discovery mechanism\\n- Send encrypted message to someone with an Ethereum key\\n- <Your dapp here>\\n\\nThese are all things that are in progress / proof of concept stage.\\n\\n## Contribute\\n\\nWe\'d love to see contributions of any form!\\n\\n- You can play with it here: [nim-waku chat](https://github.com/status-im/nim-waku/blob/master/docs/tutorial/chat2.md) (/ [js-waku browser chat](https://status-im.github.io/js-waku/))\\n- Use Waku to build a dapp: [js-waku docs](https://status-im.github.io/js-waku/docs/)\\n- Contribute to code: [js-waku](https://github.com/status-im/js-waku) / [nim-waku](https://github.com/status-im/nim-waku)\\n- Contribute to specs: [vacp2p/rfc](https://github.com/vacp2p/rfc)\\n- We are hiring: Wallet & Dapp Integration Developer, Distributed Systems Engineer, Protocol Engineer, Protocol Researcher - all [job listings](https://status.im/our_team/jobs.html)\\n- Join our new [Discord](https://discord.gg/bJCTqS5H)\\n\\n## Conclusion\\n\\nIn this talk we\'ve gone over the original vision for Web3 and how Waku came to\\nbe. We\'ve also looked at what Waku v2 aims to do. We looked at its protocols,\\nimplementations, the current testnet as well as briefly on some ongoing\\nresearch for Vac.\\n\\nWe\'ve also looked at some specific use cases for Waku. First we looked at how\\nStatus uses it with different topics. Then we looked at how it can be useful for\\nmessaging in Ethereum, including for things like WalletConnect.\\n\\nI hope this talk gives you a better idea of what Waku is, why it exists, and\\nthat it inspires you to contribute, either to Waku itself or by using it in your\\nown project!"},{"id":"presenting-js-waku","metadata":{"permalink":"/rlog/presenting-js-waku","source":"@site/rlog/2021-06-04-presenting-js-waku.mdx","title":"Presenting JS-Waku: Waku v2 in the Browser","description":"JS-Waku is bringing Waku v2 to the browser. Learn what we achieved so far and what is next in our pipeline!","date":"2021-06-04T12:00:00.000Z","formattedDate":"June 4, 2021","tags":[],"readingTime":6.84,"hasTruncateMarker":true,"authors":[{"name":"Franck","twitter":"fryorcraken","github":"fryorcraken","key":"franck"}],"frontMatter":{"layout":"post","name":"Presenting JS-Waku: Waku v2 in the Browser","title":"Presenting JS-Waku: Waku v2 in the Browser","date":"2021-06-04T12:00:00.000Z","authors":"franck","published":true,"slug":"presenting-js-waku","categories":"platform","image":"/img/js-waku-gist.png","discuss":"https://forum.vac.dev/t/discussion-presenting-js-waku-waku-v2-in-the-browser/81"},"prevItem":{"title":"[Talk at COSCUP] Vac, Waku v2 and Ethereum Messaging","permalink":"/rlog/waku-v2-ethereum-coscup"},"nextItem":{"title":"Privacy-preserving p2p economic spam protection in Waku v2","permalink":"/rlog/rln-relay"}},"content":"JS-Waku is bringing Waku v2 to the browser. Learn what we achieved so far and what is next in our pipeline!\\n\\n\x3c!--truncate--\x3e\\n\\nFor the past 3 months, we have been working on bringing Waku v2 to the browser.\\nOur aim is to empower dApps with Waku v2, and it led to the creation of a new library.\\nWe believe now is good time to introduce it!\\n\\n## Waku v2\\n\\nFirst, let\'s review what Waku v2 is and what problem it is trying to solve.\\n\\nWaku v2 comes from a need to have a more scalable, better optimised solution for the Status app to achieve decentralised\\ncommunications on resource restricted devices (i.e., mobile phones).\\n\\nThe Status chat feature was initially built over Whisper.\\nHowever, Whisper has a number of caveats which makes it inefficient for mobile phones.\\nFor example, with Whisper, all devices are receiving all messages which is not ideal for limited data plans.\\n\\nTo remediate this, a Waku mode (then Waku v1), based on devp2p, was introduced.\\nTo further enable web and restricted resource environments, Waku v2 was created based on libp2p.\\nThe migration of the Status chat feature to Waku v2 is currently in progress.\\n\\nWe see the need of such solution in the broader Ethereum ecosystem, beyond Status.\\nThis is why we are building Waku v2 as a decentralised communication platform for all to use and build on.\\nIf you want to read more about Waku v2 and what it aims to achieve,\\ncheckout [What\'s the Plan for Waku v2?](/waku-v2-plan).\\n\\nSince last year, we have been busy defining and implementing Waku v2 protocols in [nim-waku](https://github.com/status-im/nim-waku),\\nfrom which you can build [wakunode2](https://github.com/status-im/nim-waku#wakunode).\\nWakunode2 is an adaptive and modular Waku v2 node,\\nit allows users to run their own node and use the Waku v2 protocols they need.\\nThe nim-waku project doubles as a library, that can be used to add Waku v2 support to native applications.\\n\\n## Waku v2 in the browser\\n\\nWe believe that dApps and wallets can benefit from the Waku network in several ways.\\nFor some dApps, it makes sense to enable peer-to-peer communications.\\nFor others, machine-to-machine communications would be a great asset.\\nFor example, in the case of a DAO,\\nWaku could be used for gas-less voting.\\nEnabling the DAO to notify their users of a new vote,\\nand users to vote without interacting with the blockchain and spending gas.\\n\\n[Murmur](https://github.com/status-im/murmur) was the first attempt to bring Whisper to the browser,\\nacting as a bridge between devp2p and libp2p.\\nOnce Waku v2 was started and there was a native implementation on top of libp2p,\\na [chat POC](https://github.com/vacp2p/waku-web-chat) was created to demonstrate the potential of Waku v2\\nin web environment.\\nIt showed how using js-libp2p with few modifications enabled access to the Waku v2 network.\\nThere was still some unresolved challenges.\\nFor example, nim-waku only support TCP connections which are not supported by browser applications.\\nHence, to connect to other node, the POC was connecting to a NodeJS proxy application using websockets,\\nwhich in turn could connect to wakunode2 via TCP.\\n\\nHowever, to enable dApp and Wallet developers to easily integrate Waku in their product,\\nwe need to give them a library that is easy to use and works out of the box:\\nintroducing [JS-Waku](https://github.com/status-im/js-waku).\\n\\nJS-Waku is a JavaScript library that allows your dApp, wallet or other web app to interact with the Waku v2 network.\\nIt is available right now on [npm](https://www.npmjs.com/package/js-waku):\\n\\n`npm install js-waku`.\\n\\nAs it is written in TypeScript, types are included in the npm package to allow easy integration with TypeScript, ClojureScript and other typed languages that compile to JavaScript.\\n\\nKey Waku v2 protocols are already available:\\n[message](https://rfc.vac.dev/spec/14/), [store](https://rfc.vac.dev/spec/13/), [relay](https://rfc.vac.dev/spec/11/) and [light push](https://rfc.vac.dev/spec/19/),\\nenabling your dApp to:\\n\\n- Send and receive near-instant messages on the Waku network (relay),\\n- Query nodes for messages that may have been missed, e.g. due to poor cellular network (store),\\n- Send messages with confirmations (light push).\\n\\nJS-Waku needs to operate in the same context from which Waku v2 was born:\\na restricted environment were connectivity or uptime are not guaranteed;\\nJS-Waku brings Waku v2 to the browser.\\n\\n## Achievements so far\\n\\nWe focused the past month on developing a [ReactJS Chat App](https://status-im.github.io/js-waku/).\\nThe aim was to create enough building blocks in JS-Waku to enable this showcase web app that\\nwe now [use for dogfooding](https://github.com/status-im/nim-waku/issues/399) purposes.\\n\\nMost of the effort was on getting familiar with the [js-libp2p](https://github.com/libp2p/js-libp2p) library\\nthat we heavily rely on.\\nJS-Waku is the second implementation of Waku v2 protocol,\\nso a lot of effort on interoperability was needed.\\nFor example, to ensure compatibility with the nim-waku reference implementation,\\nwe run our [tests against wakunode2](https://github.com/status-im/js-waku/blob/90c90dea11dfd1277f530cf5d683fb92992fe141/src/lib/waku_relay/index.spec.ts#L137) as part of the CI.\\n\\nThis interoperability effort helped solidify the current Waku v2 specifications:\\nBy clarifying the usage of topics\\n([#327](https://github.com/vacp2p/rfc/issues/327), [#383](https://github.com/vacp2p/rfc/pull/383)),\\nfix discrepancies between specs and nim-waku\\n([#418](https://github.com/status-im/nim-waku/issues/418), [#419](https://github.com/status-im/nim-waku/issues/419))\\nand fix small nim-waku & nim-libp2p bugs\\n([#411](https://github.com/status-im/nim-waku/issues/411), [#439](https://github.com/status-im/nim-waku/issues/439)).\\n\\nTo fully access the waku network, JS-Waku needs to enable web apps to connect to nim-waku nodes.\\nA standard way to do so is using secure websockets as it is not possible to connect directly to a TCP port from the browser.\\nUnfortunately websocket support is not yet available in [nim-libp2p](https://github.com/status-im/nim-libp2p/issues/407) so\\nwe ended up deploying [websockify](https://github.com/novnc/websockify) alongside wakunode2 instances.\\n\\nAs we built the [web chat app](https://github.com/status-im/js-waku/tree/main/examples/web-chat),\\nwe were able to fine tune the API to provide a simple and succinct interface.\\nYou can start a node, connect to other nodes and send a message in less than ten lines of code:\\n\\n```javascript\\nimport { Waku } from \'js-waku\'\\n\\nconst waku = await Waku.create({})\\n\\nconst nodes = await getStatusFleetNodes()\\nawait Promise.all(nodes.map((addr) => waku.dial(addr)))\\n\\nconst msg = WakuMessage.fromUtf8String(\\n \'Here is a message!\',\\n \'/my-cool-app/1/my-use-case/proto\',\\n)\\nawait waku.relay.send(msg)\\n```\\n\\nWe have also put a bounty at [0xHack](https://0xhack.dev/) for using JS-Waku\\nand running a [workshop](https://www.youtube.com/watch?v=l77j0VX75QE).\\nWe were thrilled to have a couple of hackers create new software using our libraries.\\nOne of the projects aimed to create a decentralised, end-to-end encrypted messenger app,\\nsimilar to what the [ETH-DM](https://rfc.vac.dev/spec/20/) protocol aims to achieve.\\nAnother project was a decentralised Twitter platform.\\nSuch projects allow us to prioritize the work on JS-Waku and understand how DevEx can be improved.\\n\\nAs more developers use JS-Waku, we will evolve the API to allow for more custom and fine-tune usage of the network\\nwhile preserving this out of the box experience.\\n\\n## What\'s next?\\n\\nNext, we are directing our attention towards [Developer Experience](https://github.com/status-im/js-waku/issues/68).\\nWe already have [documentation](https://www.npmjs.com/package/js-waku) available but we want to provide more:\\n[Tutorials](https://github.com/status-im/js-waku/issues/56), various examples\\nand showing how [JS-Waku can be used with Web3](https://github.com/status-im/js-waku/issues/72).\\n\\nBy prioritizing DevEx we aim to enable JS-Waku integration in dApps and wallets.\\nWe think JS-Waku builds a strong case for machine-to-machine (M2M) communications.\\nThe first use cases we are looking into are dApp notifications:\\nEnabling dApp to notify their user directly in their wallets!\\nLeveraging Waku as a decentralised infrastructure and standard so that users do not have to open their dApp to be notified\\nof events such as DAO voting.\\n\\nWe already have some POC in the pipeline to enable voting and polling on the Waku network,\\nallowing users to save gas by **not** broadcasting each individual vote on the blockchain.\\n\\nTo facilitate said applications, we are looking at improving integration with Web3 providers by providing examples\\nof signing, validating, encrypting and decrypting messages using Web3.\\nWaku is privacy conscious, so we will also provide signature and encryption examples decoupled from users\' Ethereum identity.\\n\\nAs you can read, we have grand plans for JS-Waku and Waku v2.\\nThere is a lot to do, and we would love some help so feel free to\\ncheck out the new role in our team:\\n[js-waku: Wallet & Dapp Integration Developer](https://status.im/our_team/jobs.html?gh_jid=3157894).\\nWe also have a number of [positions](https://status.im/our_team/jobs.html) open to work on Waku protocol and nim-waku.\\n\\nIf you are as excited as us by JS-Waku, why not build a dApp with it?\\nYou can find documentation on the [npmjs page](https://www.npmjs.com/package/js-waku).\\n\\nWhether you are a developer, you can come chat with us using [WakuJS Web Chat](https://status-im.github.io/js-waku/)\\nor [chat2](https://github.com/status-im/nim-waku/blob/master/docs/tutorial/chat2.md).\\nYou can get support in #dappconnect-support on [Vac Discord](https://discord.gg/j5pGbn7MHZ) or [Telegram](https://t.me/dappconnectsupport).\\nIf you have any ideas on how Waku could enable a specific dapp or use case, do share, we are always keen to hear it."},{"id":"rln-relay","metadata":{"permalink":"/rlog/rln-relay","source":"@site/rlog/2021-03-03-rln-relay.mdx","title":"Privacy-preserving p2p economic spam protection in Waku v2","description":"This post is going to give you an overview of how spam protection can be achieved in Waku Relay through rate-limiting nullifiers. We will cover a summary of spam-protection methods in centralized and p2p systems, and the solution overview and details of the economic spam-protection method. The open issues and future steps are discussed in the end.","date":"2021-03-05T12:00:00.000Z","formattedDate":"March 5, 2021","tags":[],"readingTime":20.775,"hasTruncateMarker":true,"authors":[{"name":"Sanaz","twitter":"sanaz2016","github":"staheri14","key":"sanaz"}],"frontMatter":{"layout":"post","name":"Privacy-preserving p2p economic spam protection in Waku v2","title":"Privacy-preserving p2p economic spam protection in Waku v2","date":"2021-03-05T12:00:00.000Z","authors":"sanaz","published":true,"slug":"rln-relay","categories":"reserach","image":"/img/rain.png","discuss":"https://forum.vac.dev/t/privacy-preserving-p2p-economic-spam-protection-in-waku-v2-with-rate-limiting-nullfiers/66","toc_min_heading_level":2,"toc_max_heading_level":5},"prevItem":{"title":"Presenting JS-Waku: Waku v2 in the Browser","permalink":"/rlog/presenting-js-waku"},"nextItem":{"title":"[Talk] Vac, Waku v2 and Ethereum Messaging","permalink":"/rlog/waku-v2-ethereum-messaging"}},"content":"This post is going to give you an overview of how spam protection can be achieved in Waku Relay through rate-limiting nullifiers. We will cover a summary of spam-protection methods in centralized and p2p systems, and the solution overview and details of the economic spam-protection method. The open issues and future steps are discussed in the end.\\n\\n\x3c!--truncate--\x3e\\n\\n## Introduction\\n\\nThis post is going to give you an overview of how spam protection can be achieved in Waku Relay protocol[^2] through Rate-Limiting Nullifiers[^3] [^4] or RLN for short.\\n\\nLet me give a little background about Waku(v2)[^1]. Waku is a privacy-preserving peer-to-peer (p2p) messaging protocol for resource-restricted devices. Being p2p means that Waku relies on **No** central server. Instead, peers collaboratively deliver messages in the network. Waku uses GossipSub[^16] as the underlying routing protocol (as of the writeup of this post). At a high level, GossipSub is based on publisher-subscriber architecture. That is, _peers, congregate around topics they are interested in and can send messages to topics. Each message gets delivered to all peers subscribed to the topic_. In GossipSub, a peer has a constant number of direct connections/neighbors. In order to publish a message, the author forwards its message to a subset of neighbors. The neighbors proceed similarly till the message gets propagated in the network of the subscribed peers. The message publishing and routing procedures are part of the Waku Relay[^17] protocol.\\n![Figure 1: An overview of privacy-preserving p2p economic spam protection in Waku v2 RLN-Relay protocol.](/img/rln-relay/rln-relay-overview.png)\\n\\n## What do we mean by spamming?\\n\\nIn centralized messaging systems, a spammer usually indicates an entity that uses the messaging system to send an unsolicited message (spam) to large numbers of recipients. However, in Waku with a p2p architecture, spam messages not only affect the recipients but also all the other peers involved in the routing process as they have to spend their computational power/bandwidth/storage capacity on processing spam messages. As such, we define a spammer as an entity that uses the messaging system to publish a large number of messages in a short amount of time. The messages issued in this way are called spam. In this definition, we disregard the intention of the spammer as well as the content of the message and the number of recipients.\\n\\n## Possible Solutions\\n\\nHas the spamming issue been addressed before? Of course yes! Here is an overview of the spam protection techniques with their trade-offs and use-cases. In this overview, we distinguish between protection techniques that are targeted for centralized messaging systems and those for p2p architectures.\\n\\n### Centralized Messaging Systems\\n\\nIn traditional centralized messaging systems, spam usually signifies unsolicited messages sent in bulk or messages with malicious content like malware. Protection mechanisms include\\n\\n- authentication through some piece of personally identifiable information e.g., phone number\\n- checksum-based filtering to protect against messages sent in bulk\\n- challenge-response systems\\n- content filtering on the server or via a proxy application\\n\\nThese methods exploit the fact that the messaging system is centralized and a global view of the users\' activities is available based on which spamming patterns can be extracted and defeated accordingly. Moreover, users are associated with an identifier e.g., a username which enables the server to profile each user e.g., to detect suspicious behavior like spamming. Such profiling possibility is against the user\'s anonymity and privacy.\\n\\nAmong the techniques enumerated above, authentication through phone numbers is a some-what economic-incentive measure as providing multiple valid phone numbers will be expensive for the attacker. Notice that while using an expensive authentication method can reduce the number of accounts owned by a single spammer, cannot address the spam issue entirely. This is because the spammer can still send bulk messages through one single account. For this approach to be effective, a centralized mediator is essential. That is why such a solution would not fit the p2p environments where no centralized control exists.\\n\\n### P2P Systems\\n\\nWhat about spam prevention in p2p messaging platforms? There are two techniques, namely _Proof of Work_[^8] deployed by Whisper[^9] and _Peer scoring_[^6] method (namely reputation-based approach) adopted by LibP2P. However, each of these solutions has its own shortcomings for real-life use-cases as explained below.\\n\\n#### Proof of work\\n\\nThe idea behind the Proof Of Work i.e., POW[^8] is to make messaging a computationally costly operation hence lowering the messaging rate of **all** the peers including the spammers. In specific, the message publisher has to solve a puzzle and the puzzle is to find a nonce such that the hash of the message concatenated with the nonce has at least z leading zeros. z is known as the difficulty of the puzzle. Since the hash function is one-way, peers have to brute-force to find a nonce. Hashing is a computationally-heavy operation so is the brute-force. While solving the puzzle is computationally expensive, it is comparatively cheap to verify the solution.\\n\\nPOW is also used as the underlying mining algorithm in Ethereum and Bitcoin blockchain. There, the goal is to contain the mining speed and allow the decentralized network to come to a consensus, or agree on things like account balances and the order of transactions.\\n\\nWhile the use of POW makes perfect sense in Ethereum / Bitcoin blockchain, it shows practical issues in heterogeneous p2p messaging systems with resource-restricted peers. Some peers won\'t be able to carry the designated computation and will be effectively excluded. Such exclusion showed to be practically an issue in applications like Status, which used to rely on POW for spam-protection, to the extent that the difficulty level had to be set close to zero.\\n\\n#### Peer Scoring\\n\\nThe peer scoring method[^6] that is utilized by libp2p is to limit the number of messages issued by a peer in connection to another peer. That is each peer monitors all the peers to which it is directly connected and adjusts their messaging quota i.e., to route or not route their messages depending on their past activities. For example, if a peer detects its neighbor is sending more than x messages per month, can drop its quota to z.x where z is less than one. The shortcoming of this solution is that scoring is based on peers\' local observations and the concept of the score is defined in relation to one single peer. This leaves room for an attack where a spammer can make connections to k peers in the system and publishes k.(x-1) messages by exploiting all of its k connections. Another attack scenario is through botnets consisting of a large number of e.g., a million bots. The attacker rents a botnet and inserts each of them as a legitimate peer to the network and each can publish x-1 messages per month[^7].\\n\\n#### Economic-Incentive Spam protection\\n\\nIs this the end of our spam-protection journey? Shall we simply give up and leave spammers be? Certainly not!\\nWaku RLN-Relay gives us a p2p spam-protection method which:\\n\\n- suits **p2p** systems and does not rely on any central entity.\\n- is **efficient** i.e., with no unreasonable computational, storage, memory, and bandwidth requirement! as such, it fits the network of **heterogeneous** peers.\\n- respects users **privacy** unlike reputation-based and centralized methods.\\n- deploys **economic-incentives** to contain spammers\' activity. Namely, there is a financial sacrifice for those who want to spam the system. How? follow along ...\\n\\nWe devise a general rule to save everyone\'s life and that is\\n\\n**No one can publish more than M messages per epoch without being financially charged!**\\n\\nWe set M to 1 for now, but this can be any arbitrary value. You may be thinking \\"This is too restrictive! Only one per epoch?\\". Don\'t worry, we set the epoch to a reasonable value so that it does not slow down the communication of innocent users but will make the life of spammers harder! Epoch here can be every second, as defined by UTC date-time +-20s.\\n\\nThe remainder of this post is all about the story of how to enforce this limit on each user\'s messaging rate as well as how to impose the financial cost when the limit gets violated. This brings us to the Rate Limiting Nullifiers and how we integrate this technique into Waku v2 (in specific the Waku Relay protocol) to protect our valuable users against spammers.\\n\\n## Technical Terms\\n\\n**Zero-knowledge proof**: Zero-knowledge proof (ZKP)[^14] allows a _prover_ to show a _verifier_ that they know something, without revealing what that something is. This means you can do the trust-minimized computation that is also privacy-preserving. As a basic example, instead of showing your ID when going to a bar you simply give them proof that you are over 18, without showing the doorman your id. In this write-up, by ZKP we essentially mean zkSNARK[^15] which is one of the many types of ZKPs.\\n\\n**Threshold Secret Sharing Scheme**: (m,n) Threshold secret-sharing is a method by which you can split a secret value s into n pieces in a way that the secret s can be reconstructed by having m pieces (m <= n). The economic-incentive spam protection utilizes a (2,n) secret sharing realized by Shamir Secret Sharing Scheme[^13].\\n\\n## Overview: Economic-Incentive Spam protection through Rate Limiting Nullifiers\\n\\n**Context**: We started the idea of economic-incentive spam protection more than a year ago and conducted a feasibility study to identify blockers and unknowns. The results are published in our prior [post](https://vac.dev/feasibility-semaphore-rate-limiting-zksnarks). Since then major progress has been made and the prior identified blockers that are listed below are now addressed. Kudos to [Barry WhiteHat](https://github.com/barryWhiteHat), [Onur Kilic](https://github.com/kilic), [Koh Wei Jie](https://github.com/weijiekoh/perpetualpowersoftau) for all of their hard work, research, and development which made this progress possible.\\n\\n- the proof time[^22] which was initially in the order of minutes ~10 mins and now is almost 0.5 seconds\\n- the prover key size[^21] which was initially ~110MB and now is ~3.9MB\\n- the lack of Shamir logic[^19] which is now implemented and part of the RLN repository[^4]\\n- the concern regarding the potential multi-party computation for the trusted setup of zkSNARKs which got resolved[^20]\\n- the lack of end-to-end integration that now we made it possible, have it implemented, and are going to present it in this post. New blockers are also sorted out during the e2e integration which we will discuss in the [Feasibility and Open Issues](#feasibility-and-open-issues) section.\\n\\nNow that you have more context, let\'s see how the final solution works. The fundamental point is to make it economically costly to send more than your share of messages and to do so in a privacy-preserving and e2e fashion. To do that we have the following components:\\n\\n- 1- **Group**: We manage all the peers inside a large group (later we can split peers into smaller groups, but for now consider only one). The group management is done via a smart contract which is devised for this purpose and is deployed on the Ethereum blockchain.\\n- 2- **Membership**: To be able to send messages and in specific for the published messages to get routed by all the peers, publishing peers have to register to the group. Membership involves setting up public and private key pairs (think of it as the username and password). The private key remains at the user side but the public key becomes a part of the group information on the contract (publicly available) and everyone has access to it. Public keys are not human-generated (like usernames) and instead they are random numbers, as such, they do not reveal any information about the owner (think of public keys as pseudonyms). Registration is mandatory for the users who want to publish a message, however, users who only want to listen to the messages are more than welcome and do not have to register in the group.\\n- **Membership fee**: Membership is not for free! each peer has to lock a certain amount of funds during the registration (this means peers have to have an Ethereum account with sufficient balance for this sake). This fund is safely stored on the contract and remains intact unless the peer attempts to break the rules and publish more than one message per epoch.\\n- **Zero-knowledge Proof of membership**: Do you want your message to get routed to its destination, fine, but you have to prove that you are a member of the group (sorry, no one can escape the registration phase!). Now, you may be thinking that should I attach my public key to my message to prove my membership? Absolutely Not! we said that our solution respects privacy! membership proofs are done in a zero-knowledge manner that is each message will carry cryptographic proof asserting that \\"the message is generated by one of the current members of the group\\", so your identity remains private and your anonymity is preserved!\\n- **Slashing through secret sharing**: Till now it does not seem like we can catch spammers, right? yes, you are right! now comes the exciting part, detecting spammers and slashing them. The core idea behind the slashing is that each publishing peer (not routing peers!) has to integrate a secret share of its private key inside the message. The secret share is deterministically computed over the private key and the current epoch. The content of this share is harmless for the peer\'s privacy (it looks random) unless the peer attempts to publish more than one message in the same epoch hence disclosing more than one secret share of its private key. Indeed two distinct shares of the private key under the same epoch are enough to reconstruct the entire private key. Then what should you do with the recovered private key? hurry up! go to the contract and withdraw the private key and claim its fund and get rich!! Are you thinking what if spammers attach junk values instead of valid secret shares? Of course, that wouldn\'t be cool! so, there is a zero-knowledge proof for this sake as well where the publishing peer has to prove that the secret shares are generated correctly.\\n\\nA high-level overview of the economic spam protection is shown in Figure 1.\\n\\n## Flow\\n\\nIn this section, we describe the flow of the economic-incentive spam detection mechanism from the viewpoint of a single peer. An overview of this flow is provided in Figure 3.\\n\\n## Setup and Registration\\n\\nA peer willing to publish a message is required to register. Registration is moderated through a smart contract deployed on the Ethereum blockchain. The state of the contract contains the list of registered members\' public keys. An overview of registration is illustrated in Figure 2.\\n\\nFor the registration, a peer creates a transaction that sends x amount of Ether to the contract. The peer who has the \\"private key\\" `sk` associated with that deposit would be able to withdraw x Ether by providing valid proof. Note that `sk` is initially only known by the owning peer however it may get exposed to other peers in case the owner attempts spamming the system i.e., sending more than one message per epoch.\\nThe following relation holds between the `sk` and `pk` i.e., `pk = H(sk)` where `H` denotes a hash function.\\n![Figure 2: Registration](/img/rln-relay/rln-relay.png)\\n\\n## Maintaining the membership Merkle Tree\\n\\nThe ZKP of membership that we mentioned before relies on the representation of the entire group as a [Merkle Tree](/#). The tree construction and maintenance is delegated to the peers (the initial idea was to keep the tree on the chain as part of the contract, however, the cost associated with member deletion and insertion was high and unreasonable, please see [Feasibility and Open Issues](#Feasibility-and-Open-Issues) for more details). As such, each peer needs to build the tree locally and sync itself with the contract updates (peer insertion and deletion) to mirror them on its tree.\\nTwo pieces of information of the tree are important as they enable peers to generate zero-knowledge proofs. One is the root of the tree and the other is the membership proof (or the authentication path). The tree root is public information whereas the membership proof is private data (or more precisely the index of the peer in the tree).\\n\\n## Publishing\\n\\nIn order to publish at a given epoch, each message must carry a proof i.e., a zero-knowledge proof signifying that the publishing peer is a registered member, and has not exceeded the messaging rate at the given epoch.\\n\\nRecall that the enforcement of the messaging rate was through associating a secret shared version of the peer\'s `sk` into the message together with a ZKP that the secret shares are constructed correctly. As for the secret sharing part, the peer generates the following data:\\n\\n1. `shareX`\\n2. `shareY`\\n3. `nullifier`\\n\\nThe pair (`shareX`, `shareY`) is the secret shared version of `sk` that are generated using Shamir secret sharing scheme. Having two such pairs for an identical `nullifier` results in full disclosure of peer\'s `sk` and hence burning the associated deposit. Note that the `nullifier` is a deterministic value derived from `sk` and `epoch` therefore any two messages issued by the same peer (i.e., using the same `sk`) for the same `epoch` are guaranteed to have identical `nullifier`s.\\n\\nFinally, the peer generates a zero-knowledge proof `zkProof` asserting the membership of the peer in the group and the correctness of the attached secret share (`shareX`, `shareY`) and the `nullifier`. In order to generate a valid proof, the peer needs to have two private inputs i.e., its `sk` and its authentication path. Other inputs are the tree root, epoch, and the content of the message.\\n\\n**Privacy Hint:** Note that the authentication path of each peer depends on the recent list of members (hence changes when new peers register or leave). As such, it is recommended (and necessary for privacy/anonymity) that the publisher updates her authentication path based on the latest status of the group and attempts the proof using the updated version.\\n\\nAn overview of the publishing procedure is provided in Figure 3.\\n\\n## Routing\\n\\nUpon the receipt of a message, the routing peer needs to decide whether to route it or not. This decision relies on the following factors:\\n\\n1. If the epoch value attached to the message has a non-reasonable gap with the routing peer\'s current epoch then the message must be dropped (this is to prevent a newly registered peer spamming the system by messaging for all the past epochs).\\n2. The message MUST contain valid proof that gets verified by the routing peer.\\n If the preceding checks are passed successfully, then the message is relayed. In case of an invalid proof, the message is dropped. If spamming is detected, the publishing peer gets slashed (see [Spam Detection and Slashing](#Spam-Detection-and-Slashing)).\\n\\nAn overview of the routing procedure is provided in Figure 3.\\n\\n### Spam Detection and Slashing\\n\\nIn order to enable local spam detection and slashing, routing peers MUST record the `nullifier`, `shareX`, and `shareY` of any incoming message conditioned that it is not spam and has valid proof. To do so, the peer should follow the following steps.\\n\\n1. The routing peer first verifies the `zkProof` and drops the message if not verified.\\n2. Otherwise, it checks whether a message with an identical `nullifier` has already been relayed.\\n - a) If such message exists and its `shareX` and `shareY` components are different from the incoming message, then slashing takes place (if the `shareX` and `shareY` fields of the previously relayed message is identical to the incoming message, then the message is a duplicate and shall be dropped).\\n - b) If none found, then the message gets relayed.\\n\\nAn overview of the slashing procedure is provided in Figure 3.\\n![Figure 3: Publishing, Routing and Slashing workflow.](/img/rln-relay/rln-message-verification.png)\\n\\n## Feasibility and Open Issues\\n\\nWe\'ve come a long way since a year ago, blockers resolved, now we have implemented it end-to-end. We learned lot and could identify further issues and unknowns some of which are blocking getting to production. The summary of the identified issues are presented below.\\n\\n## Storage overhead per peer\\n\\nCurrently, peers are supposed to maintain the entire tree locally and it imposes storage overhead which is linear in the size of the group (see this [issue](https://github.com/vacp2p/research/issues/57)[^11] for more details). One way to cope with this is to use the light-node and full-node paradigm in which only a subset of peers who are more resourceful retain the tree whereas the light nodes obtain the necessary information by interacting with the full nodes. Another way to approach this problem is through a more storage efficient method (as described in this research issue[^12]) where peers store a partial view of the tree instead of the entire tree. Keeping the partial view lowers the storage complexity to O(log(N)) where N is the size of the group. There are still unknown unknowns to this solution, as such, it must be studied further to become fully functional.\\n\\n## Cost-effective way of member insertion and deletion\\n\\nCurrently, the cost associated with RLN-Relay membership is around 30 USD[^10]. We aim at finding a more cost-effective approach. Please feel free to share with us your solution ideas in this regard in this [issue](https://github.com/vacp2p/research/issues/56).\\n\\n## Exceeding the messaging rate via multiple registrations\\n\\nWhile the economic-incentive solution has an economic incentive to discourage spamming, we should note that there is still **expensive attack(s)**[^23] that a spammer can launch to break the messaging rate limit. That is, the attacker can pay for multiple legit registrations e.g., k, hence being able to publish k messages per epoch. We believe that the higher the membership fee is, the less probable would be such an attack, hence a stronger level of spam-protection can be achieved. Following this argument, the high fee associated with the membership (which we listed above as an open problem) can indeed be contributing to a better protection level.\\n\\n## Conclusion and Future Steps\\n\\nAs discussed in this post, Waku RLN Relay can achieve a privacy-preserving economic spam protection through rate-limiting nullifiers. The idea is to financially discourage peers from publishing more than one message per epoch. In specific, exceeding the messaging rate results in a financial charge. Those who violate this rule are called spammers and their messages are spam. The identification of spammers does not rely on any central entity. Also, the financial punishment of spammers is cryptographically guaranteed.\\nIn this solution, privacy is guaranteed since: 1) Peers do not have to disclose any piece of personally identifiable information in any phase i.e., neither in the registration nor in the messaging phase 2) Peers can prove that they have not exceeded the messaging rate in a zero-knowledge manner and without leaving any trace to their membership accounts.\\nFurthermore, all the computations are light hence this solution fits the heterogenous p2p messaging system. Note that the zero-knowledge proof parts are handled through zkSNARKs and the benchmarking result can be found in the RLN benchmark report[^5].\\n\\n**Future steps**:\\n\\nWe are still at the PoC level, and the development is in progress. As our future steps,\\n\\n- we would like to evaluate the running time associated with the Merkle tree operations. Indeed, the need to locally store Merkle tree on each peer was one of the unknowns discovered during this PoC and yet the concrete benchmarking result in this regard is not available.\\n- We would also like to pursue our storage-efficient Merkle Tree maintenance solution in order to lower the storage overhead of peers.\\n- In line with the storage optimization, the full-node light-node structure is another path to follow.\\n- Another possible improvement is to replace the membership contract with a distributed group management scheme e.g., through distributed hash tables. This is to address possible performance issues that the interaction with the Ethereum blockchain may cause. For example, the registration transactions are subject to delay as they have to be mined before being visible in the state of the membership contract. This means peers have to wait for some time before being able to publish any message.\\n\\n## Acknowledgement\\n\\nThanks to Onur K\u0131l\u0131\xe7 for his explanation and pointers and for assisting with development and runtime issues. Also thanks to Barry Whitehat for his time and insightful comments. Special thanks to Oskar Thoren for his constructive comments and his guides during the development of this PoC and the writeup of this post.\\n\\n## References\\n\\n[^1]: Waku v2: https://rfc.vac.dev/spec/10/\\n[^2]: RLN-Relay specification: https://rfc.vac.dev/spec/17/\\n[^3]: RLN documentation: [https://hackmd.io/tMTLMYmTR5eynw2lwK9n1w?both](https://hackmd.io/tMTLMYmTR5eynw2lwK9n1w?both)\\n[^4]: RLN repositories: [https://github.com/kilic/RLN](https://github.com/kilic/RLN) and [https://github.com/kilic/rlnapp](https://github.com/kilic/rlnapp)\\n[^5]: RLN Benchmark: [https://hackmd.io/tMTLMYmTR5eynw2lwK9n1w?view#Benchmarks](https://hackmd.io/tMTLMYmTR5eynw2lwK9n1w?view#Benchmarks)\\n[^6]: Peer Scoring: [https://github.com/libp2p/specs/blob/master/pubsub/gossipsub/gossipsub-v1.1.md#peer-scoring](https://github.com/libp2p/specs/blob/master/pubsub/gossipsub/gossipsub-v1.1.md#peer-scoring)\\n[^7]: Peer scoring security issues: [https://github.com/vacp2p/research/issues/44](https://github.com/vacp2p/research/issues/44)\\n[^8]: Proof of work: [http://www.infosecon.net/workshop/downloads/2004/pdf/clayton.pdf](http://www.infosecon.net/workshop/downloads/2004/pdf/clayton.pdf) and [https://link.springer.com/content/pdf/10.1007/3-540-48071-4_10.pdf](https://link.springer.com/content/pdf/10.1007/3-540-48071-4_10.pdf)\\n[^9]: EIP-627 Whisper: https://eips.ethereum.org/EIPS/eip-627\\n[^10]: Cost-effective way of member insertion and deletion: [https://github.com/vacp2p/research/issues/56](https://github.com/vacp2p/research/issues/56)\\n[^11]: Storage overhead per peer: [https://github.com/vacp2p/research/issues/57](https://github.com/vacp2p/research/issues/57)\\n[^12]: Storage-efficient Merkle Tree maintenance: [https://github.com/vacp2p/research/pull/54](https://github.com/vacp2p/research/pull/54)\\n[^13]: Shamir Secret Sharing Scheme: [https://en.wikipedia.org/wiki/Shamir%27s_Secret_Sharing](https://en.wikipedia.org/wiki/Shamir%27s_Secret_Sharing)\\n[^14]: Zero Knowledge Proof: [https://dl.acm.org/doi/abs/10.1145/3335741.3335750](https://dl.acm.org/doi/abs/10.1145/3335741.3335750) and [https://en.wikipedia.org/wiki/Zero-knowledge_proof](https://en.wikipedia.org/wiki/Zero-knowledge_proof)\\n[^15]: zkSNARKs: [https://link.springer.com/chapter/10.1007/978-3-662-49896-5_11](https://link.springer.com/chapter/10.1007/978-3-662-49896-5_11) and [https://coinpare.io/whitepaper/zcash.pdf](https://coinpare.io/whitepaper/zcash.pdf)\\n[^16]: GossipSub: [https://docs.libp2p.io/concepts/publish-subscribe/](https://docs.libp2p.io/concepts/publish-subscribe/)\\n[^17]: Waku Relay: https://rfc.vac.dev/spec/11/\\n[^18]: Prior blockers of RLN-Relay: [https://vac.dev/feasibility-semaphore-rate-limiting-zksnarks](https://vac.dev/feasibility-semaphore-rate-limiting-zksnarks)\\n[^19]: The lack of Shamir secret sharing in zkSNARKs: [https://github.com/vacp2p/research/issues/10](https://github.com/vacp2p/research/issues/10)\\n[^20]: The MPC required for zkSNARKs trusted setup: [https://github.com/vacp2p/research/issues/9](https://github.com/vacp2p/research/issues/9)\\n[^21]: Prover key size: [https://github.com/vacp2p/research/issues/8](https://github.com/vacp2p/research/issues/8)\\n[^22]: zkSNARKs proof time: [https://github.com/vacp2p/research/issues/7](https://github.com/vacp2p/research/issues/7)\\n[^23]: Attack on the messaging rate: [https://github.com/vacp2p/specs/issues/251](https://github.com/vacp2p/specs/issues/251)"},{"id":"waku-v2-ethereum-messaging","metadata":{"permalink":"/rlog/waku-v2-ethereum-messaging","source":"@site/rlog/2020-11-10-waku-v2-ethereum-messaging.mdx","title":"[Talk] Vac, Waku v2 and Ethereum Messaging","description":"Talk from Taipei Ethereum Meetup. Read on to find out about our journey from Whisper to Waku v2, as well as how Waku v2 can be useful for Etherum Messaging.","date":"2020-11-10T12:00:00.000Z","formattedDate":"November 10, 2020","tags":[],"readingTime":9.51,"hasTruncateMarker":true,"authors":[{"name":"Oskar","twitter":"oskarth","github":"oskarth","key":"oskarth"}],"frontMatter":{"layout":"post","name":"[Talk] Vac, Waku v2 and Ethereum Messaging","title":"[Talk] Vac, Waku v2 and Ethereum Messaging","date":"2020-11-10T12:00:00.000Z","authors":"oskarth","published":true,"slug":"waku-v2-ethereum-messaging","categories":"research","image":"/img/taipei_ethereum_meetup_slide.png","discuss":"https://forum.vac.dev/t/discussion-talk-vac-waku-v2-and-ethereum-messaging/60"},"prevItem":{"title":"Privacy-preserving p2p economic spam protection in Waku v2","permalink":"/rlog/rln-relay"},"nextItem":{"title":"Waku v2 Update","permalink":"/rlog/waku-v2-update"}},"content":"Talk from Taipei Ethereum Meetup. Read on to find out about our journey from Whisper to Waku v2, as well as how Waku v2 can be useful for Etherum Messaging.\\n\\n\x3c!--truncate--\x3e\\n\\n_The following post is a transcript of the talk given at the [Taipei Ethereum meetup, November 5](https://www.meetup.com/Taipei-Ethereum-Meetup/events/274033344/). There is also a [video recording](https://www.youtube.com/watch?v=lUDy1MoeYnI)._\\n\\n---\\n\\n## 0. Introduction\\n\\nHi! My name is Oskar and I\'m the protocol research lead at Vac. This talk will be divided into two parts. First I\'ll talk about the journey from Whisper, to Waku v1 and now to Waku v2. Then I\'ll talk about messaging in Ethereum. After this talk, you should have an idea of what Waku v2 is, the problems it is trying to solve, as well as where it can be useful for messaging in Ethereum.\\n\\n## PART 1 - VAC AND THE JOURNEY FROM WHISPER TO WAKU V1 TO WAKU V2\\n\\n## 1. Vac intro\\n\\nFirst, what is Vac? Vac grew out of our efforts Status to create a window on to Ethereum and secure messenger. Vac is modular protocol stack for p2p secure messaging, paying special attention to resource restricted devices, privacy and censorship resistance.\\n\\nToday we are going to talk mainly about Waku v2, which is the transport privacy / routing aspect of the Vac protocol stack. It sits \\"above\\" the p2p overlay, such as libp2p dealing with transports etc, and below a conversational security layer dealing with messaging encryption, such as using Double Ratchet etc.\\n\\n## 2. Whisper to Waku v1\\n\\nIn the beginning, there was Whisper. Whisper was part of the holy trinity of Ethereum. You had Ethereum for consensus/computation, Whisper for messaging, and Swarm for storage.\\n\\nHowever, for various reasons, Whisper didn\'t get the attention it deserved. Development dwindled, it promised too much and it suffered from many issues, such as being extremely inefficient and not being suitable for running on e.g. mobile phone. Despite this, Status used it in its app from around 2017 to 2019. As far as I know, it was one of very few, if not the only, production uses of Whisper.\\n\\nIn an effort to solve some of its immediate problems, we forked Whisper into Waku and formalized it with a proper specification. This solved immediate bandwidth issues for light nodes, introduced rate limiting for better spam protection, improved historical message support, etc.\\n\\nIf you are interested in this journey, checkout the [EthCC talk Dean and I gave in Paris earlier this year](https://www.youtube.com/watch?v=6lLT33tsJjs).\\n\\nStatus upgraded to Waku v1 early 2020. What next?\\n\\n## 3. Waku v1 to v2\\n\\nWe were far from done. The changes we had made were quite incremental and done in order to get tangible improvements as quickly as possible. This meant we couldn\'t address more fundamental issues related to full node routing scalability, running with libp2p for more transports, better security, better spam protection and incentivization.\\n\\nThis kickstarted Waku v2 efforts, which is what we\'ve been working on since July. This work was and is initally centered around a few pieces:\\n\\n(a) Moving to libp2p\\n\\n(b) Better routing\\n\\n(c) Accounting and user-run nodes\\n\\nThe general theme was: making the Waku network more scalable and robust.\\n\\nWe also did a scalability study to show at what point the network would run into issues, due to the inherent lack of routing that Whisper and Waku v1 provided.\\n\\nYou can read more about this [here](https://vac.dev/waku-v2-plan).\\n\\n## 3.5 Waku v2 - Design goals\\n\\nTaking a step back, what problem does Waku v2 attempt to solve compared to all the other solutions that exists out there? What type of applications should use it and why? We have the following design goals:\\n\\n1. **Generalized messaging**. Many applications requires some form of messaging protocol to communicate between different subsystems or different nodes. This messaging can be human-to-human or machine-to-machine or a mix.\\n\\n2. **Peer-to-peer**. These applications sometimes have requirements that make them suitable for peer-to-peer solutions.\\n\\n3. **Resource restricted**. These applications often run in constrained environments, where resources or the environment is restricted in some fashion. E.g.:\\n\\n - limited bandwidth, CPU, memory, disk, battery, etc\\n - not being publicly connectable\\n - only being intermittently connected; mostly-offline\\n\\n4. **Privacy**. These applications have a desire for some privacy guarantees, such as pseudonymity, metadata protection in transit, etc.\\n\\nAs well as to do so in a modular fashion. Meaning you can find a reasonable trade-off depending on your exact requirements. For example, you usually have to trade off some bandwidth to get metadata protection, and vice versa.\\n\\nThe concept of designing for resource restricted devices also leads to the concept of adaptive nodes, where you have more of a continuum between full nodes and light nodes. For example, if you switch your phone from mobile data to WiFi you might be able to handle more bandwidth, and so on.\\n\\n## 4. Waku v2 - Breakdown\\n\\nWhere is Waku v2 at now, and how is it structured?\\n\\nIt is running over libp2p and we had our second internal testnet last week or so. As a side note, we name our testnets after subway stations in Taipei, the first one being Nangang, and the most recent one being Dingpu.\\n\\nThe main implementation is written in Nim using nim-libp2p, which is also powering Nimbus, an Ethereum 2 client. There is also a PoC for running Waku v2 in the browser. On a spec level, we have the following specifications that corresponds to the components that make up Waku v2:\\n\\n- Waku v2 - this is the main spec that explains the goals of providing generalized messaging, in a p2p context, with a focus on privacy and running on resources restricted devices.\\n- Relay - this is the main PubSub spec that provides better routing. It builds on top of GossipSub, which is what Eth2 heavily relies on as well.\\n- Store - this is a 1-1 protocol for light nodes to get historical messages, if they are mostly-offline.\\n- Filter - this is a 1-1 protocol for light nodes that are bandwidth restricted to only (or mostly) get messages they care about.\\n- Message - this explains the payload, to get some basic encryption and content topics. It corresponds roughly to envelopes in Whisper/Waku v1.\\n- Bridge - this explains how to do bridging between Waku v1 and Waku v2 for compatibility.\\n\\nRight now, all protocols, with the exception of bridge, are in draft mode, meaning they have been implemented but are not yet being relied upon in production.\\n\\nYou can read more about the breakdown in this [update](https://vac.dev/waku-v2-update) though some progress has been made since then, as well was in the [main Waku v2 spec](https://rfc.vac.dev/spec/10).\\n\\n## 5. Waku v2 - Upcoming\\n\\nWhat\'s coming up next? There are a few things.\\n\\nFor Status to use it in production, it needs to be integrated into the main app using the Nim Node API. The bridge also needs to be implemented and tested.\\n\\nFor other users, we are currently overhauling the API to allow usage from a browser, e.g. To make this experience great, there are also a few underlying infrastructure things that we need in nim-libp2p, such as a more secure HTTP server in Nim, Websockets and WebRTC support.\\n\\nThere are also some changes we made to at what level content encryption happens, and this needs to be made easier to use in the API. This means you can use a node without giving your keys to it, which is useful in some environments.\\n\\nMore generally, beyond getting to production-ready use, there are a few bigger pieces that we are working on or will work on soon. These are things like:\\n\\n- Better scaling, by using topic sharding.\\n- Accounting and user-run nodes, to account for and incentives full nodes.\\n- Stronger and more rigorous privacy guarantees, e.g. through study of GossipSub, unlinkable packet formats, etc.\\n- Rate Limit Nullifier for privacy preserving spam protection, a la what Barry Whitehat has presented before.\\n\\nAs well as better support for Ethereum M2M Messaging. Which is what I\'ll talk about next.\\n\\n## PART 2 - ETHEREUM MESSAGING\\n\\nA lot of what follows is inspired by exploratory work that John Lea has done at Status, previously Head of UX Architecture at Ubuntu.\\n\\n## 6. Ethereum Messaging - Why?\\n\\nIt is easy to think that Waku v2 is only for human to human messaging, since that\'s how Waku is currently primarily used in the Status app. However, the goal is to be useful for generalized messaging, which includes other type of information as well as machine to machine messaging.\\n\\nWhat is Ethereum M2M messaging? Going back to the Holy Trinity of Ethereum/Whisper/Swarm, the messaging component was seen as something that could facilitate messages between dapps and acts as a building block. This can help with things such as:\\n\\n- Reducing on-chain transactions\\n- Reduce latency for operations\\n- Decentralize centrally coordinated services (like WalletConnect)\\n- Improve UX of dapps\\n- Broadcast live information\\n- A message transport layer for state channels\\n\\nAnd so on.\\n\\n## 7. Ethereum Messaging - Why? (Cont)\\n\\nWhat are some examples of practical things Waku as used for Ethereum Messaging could solve?\\n\\n- Multisig transfers only needing one on chain transaction\\n- DAO votes only needing one one chain transaction\\n- Giving dapps ability to direct push notifications to users\\n- Giving users ability to directly respond to requests from daps\\n- Decentralized Wallet Connect\\n\\nEtc.\\n\\n## 8. What\'s needed to deliver this?\\n\\nWe can break it down into our actors:\\n\\n- Decentralized M2M messaging system (Waku)\\n- Native wallets (Argent, Metamask, Status, etc)\\n- Dapps that benefit from M2M messaging\\n- Users whose problems are being solved\\n\\nEach of these has a bunch of requirements in turn. The messaging system needs to be decentralized, scalable, robust, etc. Wallets need support for messaging layer, dapps need to integrate this, etc.\\n\\nThis is a lot! Growing adoption is a challenge. There is a catch 22 in terms of justifying development efforts for wallets, when no dapps need it, and likewise for dapps when no wallets support Waku. In addition to this, there must be proven usage of Waku before it can be relied on, etc. How can we break this up into smaller pieces of work?\\n\\n## 9. Breaking up the problem and a high level roadmap\\n\\nWe can start small. It doesn\'t and need to be used for critical features first. A more hybrid approach can be taken where it acts more as nice-to-haves.\\n\\n1. Forking Whisper and solving scalablity, spam etc issues with it.\\n This is a work in progress. What we talked about in part 1.\\n2. Expose messaging API for Dapp developers.\\n3. Implement decentralized version of WalletConnect.\\n Currently wallets connect ot dapps with centralized service. Great UX.\\n4. Solve DAO/Multi-Sig coordination problem.\\n E.g. send message to wallet-derived key when it is time to sign a transaction.\\n5. Extend dapp-to-user and user-to-dapp communication to more dapps.\\n Use lessons learned and examples to drive adoptation for wallets/dapps.\\n\\nAnd then build up from there.\\n\\n## 10. We are hiring!\\n\\nA lot of this will happen in Javascript and browsers, since that\'s the primarily environment for a lot of wallets and dapps. We are currently hiring for a Waku JS Wallet integration lead to help push this effort further.\\n\\nCome talk to me after or [apply here](https://status.im/our_team/open_positions.html?gh_jid=2385338).\\n\\nThat\'s it! You can find us on Status, Telegram, vac.dev. I\'m on twitter [here](https://twitter.com/oskarth).\\n\\nQuestions?\\n\\n---"},{"id":"waku-v2-update","metadata":{"permalink":"/rlog/waku-v2-update","source":"@site/rlog/2020-09-28-waku-v2-update.mdx","title":"Waku v2 Update","description":"A research log. Read on to find out what is going on with Waku v2, a messaging protocol. What has been happening? What is coming up next?","date":"2020-09-28T12:00:00.000Z","formattedDate":"September 28, 2020","tags":[],"readingTime":7.435,"hasTruncateMarker":true,"authors":[{"name":"Oskar","twitter":"oskarth","github":"oskarth","key":"oskarth"}],"frontMatter":{"layout":"post","name":"Waku v2 Update","title":"Waku v2 Update","date":"2020-09-28T12:00:00.000Z","authors":"oskarth","published":true,"slug":"waku-v2-update","categories":"research","discuss":"https://forum.vac.dev/t/discussion-waku-v2-update/56"},"prevItem":{"title":"[Talk] Vac, Waku v2 and Ethereum Messaging","permalink":"/rlog/waku-v2-ethereum-messaging"},"nextItem":{"title":"What\'s the Plan for Waku v2?","permalink":"/rlog/waku-v2-plan"}},"content":"A research log. Read on to find out what is going on with Waku v2, a messaging protocol. What has been happening? What is coming up next?\\n\\n\x3c!--truncate--\x3e\\n\\nIt has been a while since the last post. It is time for an update on Waku v2. Aside from getting more familiar with libp2p (specifically nim-libp2p) and some vacation, what have we been up to? In this post we\'ll talk about what we\'ve gotten done since last time, and briefly talk about immediate next steps and future. But first, a recap.\\n\\n## Recap\\n\\nIn the last post ([Waku v2 plan](https://vac.dev/waku-v2-plan)) we explained the rationale of Waku v2 - the current Waku network is fragile and doesn\'t scale. To solve this, Waku v2 aims to reduce amplification factors and get more user run nodes. We broke the work down into three separate tracks.\\n\\n1. Track 1 - Move to libp2p\\n2. Track 2 - Better routing\\n3. Track 3 - Accounting and user-run nodes\\n\\nAs well as various rough components for each track. The primary initial focus is track 1. This means things like: moving to FloodSub, simplify the protocol, core integration, topic interest behavior, historical message caching, and Waku v1<\\\\>v2 bridge.\\n\\n## Current state\\n\\nLet\'s talk about the state of specs and our main implementation nim-waku. Then we\'ll go over our recent testnet, Nangang, and finish off with a Web PoC.\\n\\n## Specs\\n\\nAfter some back and forth on how to best structure things, we ended up breaking down the specs into a few pieces. While Waku v2 is best thought of as a cohesive whole in terms of its capabilities, it is made up of several protocols. Here\'s a list of the current specs and their status:\\n\\n- [Main spec](https://rfc.vac.dev/spec/10/) (draft)\\n- [Relay protocol spec](https://rfc.vac.dev/spec/11/) (draft)\\n- [Filter protocol spec](https://rfc.vac.dev/spec/12) (raw)\\n- [Store protocol spec](https://rfc.vac.dev/spec/13) (raw)\\n- [Bridge spec](https://rfc.vac.dev/spec/15/) (raw)\\n\\nRaw means there is not yet an implementation that corresponds fully to the spec, and draft means there is an implementation that corresponds to the spec. In the interest of space, we won\'t go into too much detail on the specs here except to note a few things:\\n\\n- The relay spec is essentially a thin wrapper on top of PubSub/FloodSub/GossipSub\\n- The filter protocol corresponds to previous light client mode in Waku v1\\n- The store protocol corresponds to the previous mailserver construct in Waku v1\\n\\nThe filter and store protocol allow for adaptive nodes, i.e. nodes that have various capabilities. For example, a node being mostly offline, or having limited bandwidth capacity. The bridge spec outlines how to bridge the Waku v1 and v2 networks.\\n\\n## Implementation\\n\\nThe main implementation we are working on is [nim-waku](https://github.com/status-im/nim-waku/). This builds on top of libraries such as [nim-libp2p](https://github.com/status-im/nim-libp2p) and others that the [Nimbus team](https://nimbus.team/) have been working on as part of their Ethereum 2.0 client.\\n\\nCurrently nim-waku implements the relay protocol, and is close to implementing filter and store protocol. It also exposes a [Nim Node API](https://github.com/status-im/nim-waku/blob/master/docs/api/v2/node.md) that allows libraries such as [nim-status](https://github.com/status-im/status-nim) to use it. Additionally, there is also a rudimentary JSON RPC API for command line scripting.\\n\\n## Nangang testnet\\n\\nLast week we launched a very rudimentary internal testnet called Nangang. The goal was to test basic connectivity and make sure things work end to end. It didn\'t have things like: client integration, encryption, bridging, multiple clients, store/filter protocol, or even a real interface. What it did do is allow Waku developers to \\"chat\\" via RPC calls and looking in the log output. Doing this meant we exposed and fixed a few blockers, such as connection issues, deployment, topic subscription management, protocol and node integration, and basic scripting/API usage. After this, we felt confident enough to upgrade the main and relay spec to \\"draft\\" status.\\n\\n## Waku Web PoC\\n\\nAs a bonus, we wanted to see what it\'d take to get Waku running in a browser. This is a very powerful capability that enables a lot of use cases, and something that libp2p enables with its multiple transport support.\\n\\nUsing the current stack, with nim-waku, would require quite a lot of ground work with WASM, WebRTC, Websockets support etc. Instead, we decided to take a shortcut and hack together a JS implementation called [Waku Web Chat](https://github.com/vacp2p/waku-web-chat/). This quick hack wouldn\'t be possible without the people behind [js-libp2p-examples](https://github.com/libp2p/js-libp2p-examples/) and [js-libp2p](https://github.com/libp2p/js-libp2p) and all its libraries. These are people like Jacob Heun, Vasco Santos, and Cayman Nava. Thanks!\\n\\nIt consists of a brower implementation, a NodeJS implementation and a bootstrap server that acts as a signaling server for WebRTC. It is largely a bastardized version of GossipSub, and while it isn\'t completely to spec, it does allow messages originating from a browser to eventually end up at a nim-waku node, and vice versa. Which is pretty cool.\\n\\n## Coming up\\n\\nNow that we know what the current state is, what is still missing? what are the next steps?\\n\\n## Things that are missing\\n\\nWhile we are getting closer to closing out work for track 1, there are still a few things missing from the initial scope:\\n\\n1. Store and filter protocols need to be finished. This means basic spec, implementation, API integration and proven to work in a testnet. All of these are work in progress and expected to be done very soon. Once the store protocol is done in a basic form, it needs further improvements to make it production ready, at least on a spec/basic implementation level.\\n\\n2. Core integration was mentioned in scope for track 1 initially. This work has stalled a bit, largely due to organizational bandwidth and priorities. While there is a Nim Node API that in theory is ready to be used, having it be used in e.g. Status desktop or mobile app is a different matter. The team responsible for this at Status ([status-nim](https://github.com/status-im/status-nim) has been making progress on getting nim-waku v1 integrated, and is expected to look into nim-waku v2 integration soon. One thing that makes this a especially tricky is the difference in interface between Waku v1 and v2, which brings\\n us too...\\n\\n3. Companion spec for encryption. As part of simplifying the protocol, the routing is decoupled from the encryption in v2 ([1](https://github.com/vacp2p/specs/issues/158), [2](https://github.com/vacp2p/specs/issues/181)). There are multiple layers of encryption at play here, and we need to figure out a design that makes sense for various use cases (dapps using Waku on their own, Status app, etc).\\n\\n4. Bridge implementation. The spec is done and we know how it should work, but it needs to be implemented.\\n\\n5. General tightening up of specs and implementation.\\n\\nWhile this might seem like a lot, a lot has been done already, and the majority of the remaining tasks are more amendable to be pursued in parallel with other efforts. It is also worth mentioning that part of track 2 and 3 have been started, in the form of moving to GossipSub (amplification factors) and basics of adaptive nodes (multiple protocols). This is in addition to things like Waku Web which were not part of the initial scope.\\n\\n## Upcoming\\n\\nAside from the things mentioned above, what is coming up next? There are a few areas of interest, mentioned in no particular order. For track 2 and 3, see previous post for more details.\\n\\n1. Better routing (track 2). While we are already building on top of GossipSub, we still need to explore things like topic sharding in more detail to further reduce amplification factors.\\n\\n2. Accounting and user-run nodes (track 3). With store and filter protocol getting ready, we can start to implement accounting and light connection game for incentivization in a bottom up and iterative manner.\\n\\n3. Privacy research. Study better and more rigorous privacy guarantees. E.g. how FloodSub/GossipSub behaves for common threat models, and how custom packet\\n format can improve things like unlinkability.\\n\\n4. zkSnarks RLN for spam protection and incentivization. We studied this [last year](https://vac.dev/feasibility-semaphore-rate-limiting-zksnarks) and recent developments have made this relevant to study again. Create an [experimental spec/PoC](https://github.com/vacp2p/specs/issues/189) as an extension to the relay protocol. Kudos to Barry Whitehat and others like Kobi Gurkan and Koh Wei Jie for pushing this!\\n\\n5. Ethereum M2M messaging. Being able to run in the browser opens up a lot of doors, and there is an opportunity here to enable things like a decentralized WalletConnect, multi-sig transactions, voting and similar use cases. This was the original goal of Whisper, and we\'d like to deliver on that.\\n\\nAs you can tell, quite a lot of thing! Luckily, we have two people joining as protocol engineers soon, which will bring much needed support for the current team of ~2-2.5 people. More details to come in further updates.\\n\\n---\\n\\nIf you are feeling adventurous and want to use early stage alpha software, check out the [docs](https://github.com/status-im/nim-waku/tree/master/docs). If you want to read the specs, head over to [Waku spec](https://rfc.vac.dev/spec/10/). If you want to talk with us, join us on [Status](https://get.status.im/chat/public/vac) or on [Telegram](https://t.me/vacp2p) (they are bridged)."},{"id":"waku-v2-plan","metadata":{"permalink":"/rlog/waku-v2-plan","source":"@site/rlog/2020-07-01-waku-v2-pitch.mdx","title":"What\'s the Plan for Waku v2?","description":"Read about our plans for Waku v2, moving to libp2p, better routing, adaptive nodes and accounting!","date":"2020-07-01T12:00:00.000Z","formattedDate":"July 1, 2020","tags":[],"readingTime":13.7,"hasTruncateMarker":true,"authors":[{"name":"Oskar","twitter":"oskarth","github":"oskarth","key":"oskarth"}],"frontMatter":{"layout":"post","name":"What\'s the Plan for Waku v2?","title":"What\'s the Plan for Waku v2?","date":"2020-07-01T12:00:00.000Z","authors":"oskarth","published":true,"slug":"waku-v2-plan","categories":"research","image":"/img/status_scaling_model_fig4.png","discuss":"https://forum.vac.dev/t/waku-version-2-pitch/52"},"prevItem":{"title":"Waku v2 Update","permalink":"/rlog/waku-v2-update"},"nextItem":{"title":"Feasibility Study: Discv5","permalink":"/rlog/feasibility-discv5"}},"content":"Read about our plans for Waku v2, moving to libp2p, better routing, adaptive nodes and accounting!\\n\\n\x3c!--truncate--\x3e\\n\\n**tldr: The Waku network is fragile and doesn\'t scale. Here\'s how to solve it.**\\n\\n_NOTE: This post was originally written with Status as a primary use case in mind, which reflects how we talk about some problems here. However, Waku v2 is a general-purpose private p2p messaging protocol, especially for people running in resource restricted environments._\\n\\n## Problem\\n\\nThe Waku network is fragile and doesn\'t scale.\\n\\nAs [Status](https://status.im) is moving into a user-acquisition phase and is improving retention rates for users they need the infrastructure to keep up, specifically when it comes to messaging.\\n\\nBased on user acquisition models, the initial goal is to support 100k DAU in September, with demand growing from there.\\n\\nWith the Status Scaling Model we have studied the current bottlenecks as a function of concurrent users (CCU) and daily active users (DAU). Here are the conclusions.\\n\\n\\\\***\\\\*1. Connection limits\\\\*\\\\***. With 100 full nodes we reach ~10k CCU based on connection limits. This can primarily be addressed by increasing the number of nodes (cluster or user operated). This assumes node discovery works. It is also worth investigating the limitations of max number of connections, though this is likely to be less relevant for user-operated nodes. For a user-operated network, this means 1% of users have to run a full node. See Fig 1-2.\\n\\n\\\\***\\\\*2. Bandwidth as a bottleneck\\\\*\\\\***. We notice that memory usage appears to not be\\nthe primary bottleneck for full nodes, and the bottleneck is still bandwidth. To support 10k DAU, and full nodes with an amplification factor of 25 the required Internet speed is ~50 Mbps, which is a fast home Internet connection. For ~100k DAU only cloud-operated nodes can keep up (500 Mbps). See Fig 3-5.\\n\\n\\\\***\\\\*3. Amplification factors\\\\*\\\\***. Reducing amplification factors with better routing, would have a high impact, but it is likely we\'d need additional measures as well, such as topic sharding or similar. See Fig 8-13.\\n\\nFigure 1-5:\\n\\n![](/img/status_scaling_model_fig1.png)\\n![](/img/status_scaling_model_fig2.png)\\n![](/img/status_scaling_model_fig3.png)\\n![](/img/status_scaling_model_fig4.png)\\n![](/img/status_scaling_model_fig5.png)\\n\\nSee for the full report.\\n\\nWhat we need to do is:\\n\\n1. Reduce amplification factors\\n2. Get more user-run full nodes\\n\\nDoing this means the Waku network will be able to scale, and doing so in the right way, in a robust fashion. What would a fragile way of scaling be? Increasing our reliance on a Status Pte Ltd operated cluster which would paint us in a corner where we:\\n\\n- keep increasing requirements for Internet speed for full nodes\\n- are vulnerable to censorship and attacks\\n- have to control the topology in an artifical manner to keep up with load\\n- basically re-invent a traditional centralized client-server app with extra steps\\n- deliberately ignore most of our principles\\n- risk the network being shut down when we run out of cash\\n\\n## Appetite\\n\\nOur initial risk appetite for this is 6 weeks for a small team.\\n\\nThe idea is that we want to make tangible progress towards the goal in a limited period of time, as opposed to getting bogged down in trying to find a theoretically perfect generalized solution. Fixed time, variable scope.\\n\\nIt is likely some elements of a complete solution will be done separately. See later sections for that.\\n\\n## Solution\\n\\nThere are two main parts of the solution. One is to reduce amplification factors, and the other is incentivization to get more user run full nodes with desktop, etc.\\n\\nWhat does a full node provide? It provides connectivity to the network, can act as a bandwidth \\"barrier\\" and be high or reasonably high availability. What this means right now is essentially topic interest and storing historical messages.\\n\\nThe goal is here to improve the status quo, not get a perfect solution from the get go. All of this can be iterated on further, for stronger guarantees, as well as replaced by other new modules.\\n\\nLet\'s first look at the baseline, and then go into some of the tracks and their phases. Track 1 is best done first, after which track 2 and 3 can be executed in parallel. Track 1 gives us more options for track 2 and 3. The work in track 1 is currently more well-defined, so it is likely the specifics of track 2 and 3 will get refined at a later stage.\\n\\n## Baseline\\n\\nHere\'s where we are at now. In reality, the amplification factor are likely even worse than this (15 in the graph below), up to 20-30. Especially with an open network, where we can\'t easily control connectivity and availability of nodes. Left unchecked, with a full mesh, it could even go as high x100, though this is likely excessive and can be dialed down. See scaling model for more details.\\n\\n![](/img/waku_v1_routing_small.png)\\n\\n## Track 1 - Move to libp2p\\n\\nMoving to PubSub over libp2p wouldn\'t improve amplification per se, but it would be stepping stone. Why? It paves the way for GossipSub, and would be a checkpoint on this journey. Additionally, FloodSub and GossipSub are compatible, and very likely other future forms of PubSub such as GossipSub 1.1 (hardened/more secure), EpiSub, forwarding Kademlia / PubSub over Kademlia, etc. Not to mention security This would also give us access to the larger libp2p ecosystem (multiple protocols, better encryption, quic, running in the browser, security audits, etc, etc), as well as be a joint piece of infrastructured used for Eth2 in Nimbus. More wood behind fewer arrows.\\n\\nSee more on libp2p PubSub here: \\n\\nAs part of this move, there are a few individual pieces that are needed.\\n\\n### 1. FloodSub\\n\\nThis is essentially what Waku over libp2p would look like in its most basic form.\\n\\nOne difference that is worth noting is that the app topics would **not** be the same as Waku topics. Why? In Waku we currently don\'t use topics for routing between full nodes, but only for edge/light nodes in the form of topic interest. In FloodSub, these topics are used for routing.\\n\\nWhy can\'t we use Waku topics for routing directly? PubSub over libp2p isn\'t built for rare and ephemeral topics, and nodes have to explicitly subscribe to a topic. See topic sharding section for more on this.\\n\\n![](/img/waku_v2_routing_flood_small.png)\\n\\nMoving to FloodSub over libp2p would also be an opportunity to clean up and simplify some components that are no longer needed in the Waku v1 protocol, see point below.\\n\\nVery experimental and incomplete libp2p support can be found in the nim-waku repo under v2: \\n\\n### 2. Simplify the protocol\\n\\nDue to Waku\'s origins in Whisper, devp2p and as a standalone protocol, there are a lot of stuff that has accumulated (). Not all of it serves it purpose anymore. For example, do we still need RLP here when we have Protobuf messages? What about extremely low PoW when we have peer scoring? What about key management / encryption when have encryption at libp2p and Status protocol level?\\n\\nNot everything has to be done in one go, but being minimalist at this stage will the protocol lean and make us more adaptable.\\n\\nThe essential characteristic that has to be maintained is that we don\'t need to change the upper layers, i.e. we still deal with (Waku) topics and some envelope like data unit.\\n\\n### 3. Core integration\\n\\nAs early as possible we want to integrate with Core via Stimbus in order to mitigate risk and catch integration issues early in the process. What this looks like in practice is some set of APIs, similar to how Whisper and Waku were working in parallel, and experimental feature behind a toggle in core/desktop.\\n\\n### 4. Topic interest behavior\\n\\nWhile we target full node traffic here, we want to make sure we maintain the existing bandwidth requirements for light nodes that Waku v1 addressed (). This means implementing topic-interest in the form of Waku topics. Note that this would be separate from app topics notes above.\\n\\n### 5. Historical message caching\\n\\nBasically what mailservers are currently doing. This likely looks slightly different in a libp2p world. This is another opportunity to simplify things with a basic REQ-RESP architecture, as opposed to the roundabout way things are now. Again, not everything has to be done in one go but there\'s no reason to reimplement a poor API if we don\'t have to.\\n\\nAlso see section below on adaptive nodes and capabilities.\\n\\n### 6. Waku v1 <\\\\> Libp2p bridge\\n\\nTo make the transition complete, there has to a be bridge mode between current Waku and libp2p. This is similar to what was done for Whisper and Waku, and allows any nodes in the network to upgrade to Waku v2 at their leisure. For example, this would likely look different for Core, Desktop, Research and developers.\\n\\n## Track 2 - Better routing\\n\\nThis is where we improve the amplification factors.\\n\\n### 1. GossipSub\\n\\nThis is a subprotocol of FloodSub in the libp2p world. Moving to GossipSub would allow traffic between full nodes to go from an amplification factor of ~25 to ~6. This basically creates a mesh of stable bidirectional connections, together with some gossiping capabilities outside of this view.\\n\\nExplaining how GossipSub works is out of scope of this document. It is implemented in nim-libp2p and used by Nimbus as part of Eth2. You can read the specs here in more detail if you are interested: and \\n\\n![](/img/waku_v2_routing_gossip_small.png)\\n\\n![](/img/status_scaling_model_fig8.png)\\n![](/img/status_scaling_model_fig9.png)\\n![](/img/status_scaling_model_fig10.png)\\n![](/img/status_scaling_model_fig11.png)\\n\\nWhile we technically could implement this over existing Waku, we\'d have to re-implement it, and we\'d lose out on all the other benefits libp2p would provide, as well as the ecosystem of people and projects working on improving the scalability and security of these protocols.\\n\\n### 2. Topic sharding\\n\\nThis one is slightly more speculative in terms of its ultimate impact. The basic idea is to split the application topic into N shards, say 10, and then each full node can choose which shards to listen to. This can reduce amplification factors by another factor of 10.\\n\\n![](/img/waku_v2_routing_sharding_small.png)\\n\\n![](/img/status_scaling_model_fig12.png)\\n![](/img/status_scaling_model_fig13.png)\\n\\nNote that this means a light node that listens to several topics would have to be connected to more full nodes to get connectivity. For a more exotic version of this, see \\n\\nThis is orthogonal from the choice of FloodSub or GossipSub, but due to GossipSub\'s more dynamic nature it is likely best combined with it.\\n\\n### 3. Other factors\\n\\nNot a primary focus, but worth a look. Looking at the scaling model, there might be other easy wins to improve overall bandwidth consumption between full nodes. For example, can we reduce envelope size by a significant factor?\\n\\n## Track 3 - Accounting and user-run nodes\\n\\nThis is where we make sure the network isn\'t fragile, become a true p2p app, get our users excited and engaged, and allow us to scale the network without creating an even bigger cluster.\\n\\nTo work in practice, this has a soft dependency on node discovery such as DNS based discovery () or Discovery v5 ().\\n\\n### 1. Adaptive nodes and capabilities\\n\\nWe want to make the gradation between light nodes, full nodes, storing (partial set of) historical messages, only acting for a specific shard, etc more flexible and explicit. This is required to identify and discover the nodes you want. See \\n\\nDepending on how the other tracks come together, this design should allow for a desktop node to identify as a full relaying node for some some app topic shard, but also express waku topic interest and retrieve historical messages itself.\\n\\nE.g. Disc v5 can be used to supply node properties through ENR.\\n\\n### 2. Accounting\\n\\nThis is based on a few principles:\\n\\n1. Some nodes contribute a lot more than other nodes in the network\\n2. We can account for the difference in contribution in some fashion\\n3. We want to incentivize nodes to tell the true, and be incentivized not to lie\\n\\nAccounting here is a stepping stone, where accounting is the raw data upon which some settlement later occurs. It can have various forms of granularity. See for discussion.\\n\\nWe also note that in GossipSub, the mesh is bidrectional. Additionally, it doesn\'t appears to be a high priority issue in terms of nodes misreporting. What is an issue is having people run full nodes in the first place. There are a few points to that. It has to be possible in the end-user UX, nodes have to be discovered, and it has to be profitable/visible that you are contributing. UX and discovery are out of scope for this work, whereas visibility/accounting is part of this scope. Settlement is a stretch goal here.\\n\\nThe general shape of the solution is inspired by the Swarm model, where we do accounting separate from settlement. It doesn\'t require any specific proofs, but nodes are incentivized to tell the truth in the following way:\\n\\n1. Both full node and light node do accounting in a pairwise, local fashion\\n2. If a light node doesn\'t ultimately pay or lie about reporting, they get disconnected (e.g.)\\n3. If a full node doesn\'t provide its service the light node may pick another full node (e.g.)\\n\\nWhile accounting for individual resource usage is useful, for the ultimate end user experience we can ideally account for other things such as:\\n\\n- end to end delivery\\n- online time\\n- completeness of storage\\n\\nThis can be gradually enhanced and strengthened, for example with proofs, consistency checks, Quality of Service, reputation systems. See for one attempt to provide stronger guarantees with periodic consistency checks and a shared fund mechanism. And for using validity proofs and removing liveness requirement for settlement.\\n\\nAll of this is optional at this stage, because our goal here is to improve the status quo for user run nodes. Accounting at this stage should be visible and correspond to the net benefit a node provides to another.\\n\\nAs a concrete example: a light node has some topic interest and cares about historical messages on some topic. A full node communicates envelopes as they come in, communicates their high availability (online time) and stores/forward stored messages. Both nodes have this information, and if they agree settlement (initially just a mock message) can be sending a payment to an address at some time interval / over some defined volume. See future sections for how this can be improved upon.\\n\\nAlso see below in section 4, using constructs such as eigentrust as a local reputation mechanism.\\n\\n### 3. Relax high availability requirement\\n\\nIf we want desktop nodes to participate in the storing of historical messages, high availability is a problem. It is a problem for any node, especially if they lie about it, but assuming they are honest it is still an issue.\\n\\nBy being connected to multiple nodes, we can get an overlapping online window. Then these can be combined together to get consistency. This is obviously experimental and would need to be tested before being deployed, but if it works it\'d be very useful.\\n\\nAdditionally or alternatively, instead of putting a high requirement on message availability, focus on detection of missing information. This likely requires re-thinking how we do data sync / replication.\\n\\n### 4. Incentivize light and full nodes to tell the truth (policy, etc)\\n\\nIn accounting phase it is largely assumed nodes are honest. What happens when they lie, and how do we incentivize them to be honest? In the case of Bittorrent this is done with tit-for-tat, however this is a different kind of relationship. What follows are some examples of how this can be done.\\n\\nFor light nodes:\\n\\n- if they don\'t, they get disconnected\\n- prepayment (especially to \\"high value\\" nodes)\\n\\nFor full nodes:\\n\\n- multiple nodes reporting to agree, where truth becomes a shelling point\\n- use eigentrust\\n- staking for discovery visibility with slashing\\n\\n### 5. Settlement PoC\\n\\nCan be done after phase 2 if so desired. Basically integrate payments based on accounting and policy.\\n\\n## Out of scope\\n\\n1. We assume the Status Base model requirements are accurate.\\n2. We assume Core will improve retention rates.\\n3. We assume the Stimbus production team will enable integration of nim-waku.\\n4. We assume Discovery mechanisms such as DNS and Discovery v5 will be worked on separately.\\n5. We assume Core will, at some point, provide an UX for integrating payment of services.\\n6. We assume the desktop client is sufficiently usable.\\n7. We assume Core and Infra will investigate ways of improving MaxPeers."},{"id":"feasibility-discv5","metadata":{"permalink":"/rlog/feasibility-discv5","source":"@site/rlog/2020-04-27-feasibility-discv5.mdx","title":"Feasibility Study: Discv5","description":"Looking at discv5 and the theoretical numbers behind finding peers.","date":"2020-04-27T12:00:00.000Z","formattedDate":"April 27, 2020","tags":[],"readingTime":5.655,"hasTruncateMarker":true,"authors":[{"name":"Dean","twitter":"DeanEigenmann","github":"decanus","website":"https://dean.eigenmann.me","key":"dean"}],"frontMatter":{"layout":"post","name":"Feasibility Study: Discv5","title":"Feasibility Study: Discv5","date":"2020-04-27T12:00:00.000Z","authors":"dean","published":true,"slug":"feasibility-discv5","categories":"research","discuss":"https://discuss.status.im/t/discv5-feasibility-study/1632"},"prevItem":{"title":"What\'s the Plan for Waku v2?","permalink":"/rlog/waku-v2-plan"},"nextItem":{"title":"What Would a WeChat Replacement Need?","permalink":"/rlog/wechat-replacement-need"}},"content":"Looking at discv5 and the theoretical numbers behind finding peers.\\n\\n\x3c!--truncate--\x3e\\n\\n> Disclaimer: some of the numbers found in this write-up could be inaccurate. They are based on the current understanding of theoretical parts of the protocol itself by the author and are meant to provide a rough overview rather than bindable numbers.\\n\\nThis post serves as a more authoritative overview of the discv5 study, for a discussionary post providing more context make sure to check out the corresponding [discuss post](https://discuss.status.im/t/discv5-feasibility-study/1632). Additionally, if you are unfamiliar with discv5, check out my previous write-up: [\\"From Kademlia to Discv5\\"](https://vac.dev/kademlia-to-discv5).\\n\\n## Motivating Problem\\n\\nThe discovery method currently used by [Status](https://status.im), is made up of various components and grew over time to solve a mix of problems. We want to simplify this while maintaining some of the properties we currently have.\\n\\nNamely, we want to ensure censorship resistance to state-level adversaries. One of the issues Status had which caused us them add to their discovery method was the fact that addresses from providers like AWS and GCP were blocked both in Russia and China. Additionally, one of the main factors required is the ability to function on resource restricted devices.\\n\\nConsidering we are talking about resource restricted devices, let\'s look at the implications and what we need to consider:\\n\\n- **Battery consumption** - constant connections like websockets consume a lot of battery life.\\n- **CPU usage** - certain discovery methods may be CPU incentive, slowing an app down and making it unusable.\\n- **Bandwidth consumption** - a lot of users will be using data plans, the discovery method needs to be efficient in order to accommodate those users without using up significant portions of their data plans.\\n- **Short connection windows** - the discovery algorithm needs to be low latency, that means it needs to return results fast. This is because many users will only have the app open for a short amount of time.\\n- **Not publicly connectable** - There is a good chance that most resource restricted devices are not publicly connectable.\\n\\nFor a node to be able to participate as both a provider, and a consumer in the discovery method. Meaning a node both reads from other nodes\' stored DHTs and hosts the DHT for other nodes to read from, it needs to be publically connectable. This means another node must be able to connect to some public IP of the given node.\\n\\nWith devices that are behind a NAT, this is easier said than done. Especially mobile devices, that when connected to 4G LTE networks are often stuck behind a symmetric NAT, drastically reducing the the succeess rate of NAT traversal. Keeping this in mind, it becomes obvious that most resource restricted devices will be consumers rather than providers due to this technical limitation.\\n\\nIn order to answer our questions, we formulated the problem with a simple method for testing. The \\"needle in a haystack\\" problem was formulated to figure out how easily a specific node can be found within a given network. This issue was fully formulated in [vacp2p/research#15](https://github.com/vacp2p/research/issues/15).\\n\\n## Overview\\n\\nThe main things we wanted to investigate was the overhead on finding a peer. This means we wanted to look at both the bandwidth, latency and effectiveness of this. There are 2 methods which we can use to find a peer:\\n\\n- We can find a peer with a specific ID, using normal lookup methods as documented by Kademlia.\\n- We can find a peer that advertises a capability, this is possible using either capabilities advertised in the ENR or through [topic tables](https://github.com/ethereum/devp2p/blob/master/discv5/discv5-theory.md#topic-advertisement).\\n\\n## Feasbility\\n\\nTo be able to investigate the feasibility of discv5, we used various methods including rough calculations which can be found in the [notebook](https://vac.dev/discv5-notebook/), and a simulation isolated in [vacp2p/research#19](https://github.com/vacp2p/research/pull/19).\\n\\n### CPU & Memory Usage\\n\\nThe experimental discv5 has already been used within Status, however what was noticed was that the CPU and memory usage was rather high. It therefore should be investiaged if this is still the case, and if it is, it should be isolated where this stems from. Additionally it is worth looking at whether or not this is the case with both the go and nim implementation.\\n\\nSee details: [vacp2p/research#31](https://github.com/vacp2p/research/issues/31)\\n\\n### NAT on Cellular Data\\n\\nIf a peer is not publically connectable it can not participate in the DHT both ways. A lot of mobile phones are behind symmetric NATs which UDP hole-punching close to impossible. It should be investigated whether or not mobile phones will be able to participate both ways and if there are good methods for doing hole-punching.\\n\\nSee details: [vacp2p/research#29](https://github.com/vacp2p/research/issues/29)\\n\\n### Topic Tables\\n\\nTopic Tables allow us the ability to efficiently find nodes given a specific topic. However, they are not implemented in the [status-im/nim-eth](https://github.com/status-im/nim-eth/) implementation nor are they fully finalized in the spec. These are important if the network grows past a size where the concentration of specific nodes is relatively low making them hard to find.\\n\\nSee details: [vacp2p/research#26](https://github.com/vacp2p/research/issues/26)\\n\\n### Finding a node\\n\\nIt is important to note, that given a network is relatively small sized, eg 100-500 nodes, then finding a node given a specific address is relatively managable. Additionally, if the concentration of a specific capability in a network is reasonable, then finding a node advertising its capabilities using an ENR rather than the topic table is also managable. A reasonable concentration for example would be 10%, which would give us an 80% chance of getting a node with that capability in the first lookup request. This can be explored more using our [discv5 notebook](https://vac.dev/discv5-notebook/#Needle-in-a-haystack-with-ENR-records-indicating-capabilities).\\n\\n## Results\\n\\nResearch has shown that finding a node in the DHT has a relatively low effect on bandwidth, both inbound and outbound. For example when trying to find a node in a network of 100 nodes, it would take roughly 5668 bytes total. Additionally if we assume 100ms latency per request it would range at \u2248 300ms latency, translating to 3 requests to find a specific node.\\n\\n## General Thoughts\\n\\nOne of the main blockers right now is figuring out what the CPU and memory usage of discv5 is on mobile phones, this is a large blocker as it affects one of the core problems for us. We need to consider whether discv5 is an upgrade as it allows us to simplify our current discovery process or if it is too much of an overhead for resource restricted devices. The topic table feature could largely enhance discovery however it is not yet implemented. Given that CPU and memory isn\'t too high, discv5 could probably be used as the other issues are more \\"features\\" than large scale issues. Implementing it would already reduce the ability for state level adversaries to censor our nodes.\\n\\n## Acknowledgements\\n\\n- Oskar Thoren\\n- Dmitry Shmatko\\n- Kim De Mey\\n- Corey Petty"},{"id":"wechat-replacement-need","metadata":{"permalink":"/rlog/wechat-replacement-need","source":"@site/rlog/2020-04-16-wechat-replacement-need.mdx","title":"What Would a WeChat Replacement Need?","description":"What would a self-sovereign, private, censorship-resistant and open alternative to WeChat look like?","date":"2020-04-16T12:00:00.000Z","formattedDate":"April 16, 2020","tags":[],"readingTime":25.24,"hasTruncateMarker":true,"authors":[{"name":"Oskar","twitter":"oskarth","github":"oskarth","key":"oskarth"}],"frontMatter":{"layout":"post","name":"What Would a WeChat Replacement Need?","title":"What Would a WeChat Replacement Need?","date":"2020-04-16T12:00:00.000Z","authors":"oskarth","published":true,"slug":"wechat-replacement-need","categories":"research","image":"/img/tianstatue.jpg","discuss":"https://forum.vac.dev/t/discussion-what-would-a-wechat-replacement-need/42"},"prevItem":{"title":"Feasibility Study: Discv5","permalink":"/rlog/feasibility-discv5"},"nextItem":{"title":"From Kademlia to Discv5","permalink":"/rlog/kademlia-to-discv5"}},"content":"What would a self-sovereign, private, censorship-resistant and open alternative to WeChat look like?\\n\\n\x3c!--truncate--\x3e\\n\\nWhat would it take to replace WeChat? More specifically, what would a self-sovereign, private, censorship-resistant and open alternative look like? One that allows people to communicate, coordinate and transact freely.\\n\\n## Background\\n\\n### What WeChat provides to the end-user\\n\\nLet\'s first look at some of the things that WeChat providers. It is a lot:\\n\\n- **Messaging:** 1:1 and group chat. Text, as well as voice and video. Post gifs. Share location.\\n- **Group chat:** Limited to 500 people; above 100 people people need to verify with a bank account. Also has group video chat and QR code to join a group.\\n- **Timeline/Moments:** Post comments with attachments and have people like/comment on it.\\n- **Location Discovery:** See WeChat users that are nearby.\\n- **Profile:** Nickname and profile picture; can alias people.\\n- **\\"Broadcast\\" messages:** Send one message to many contacts, up to 200 people (spam limited).\\n- **Contacts:** Max 5000 contacts (people get around it with multiple accounts and sim cards).\\n- **App reach:** Many diferent web apps, extensions, native apps, etc. Scan QR code to access web app from phone.\\n- **Selective posting:** Decide who can view your posts and who can view your comments on other people\'s post.\\n- **Transact:** Send money gifts through red envelopes.\\n- **Transact:** Use WeChat pay to transfer money to friends and businesses; linked account with Alipay that is connected to your bank account.\\n- **Services:** Find taxis and get notifications; book flights, train tickets, hotels etc.\\n- **Mini apps:** API for all kinds of apps that allow you to provide services etc.\\n- **Picture in picture:** allowing you to have a video call while using the app.\\n\\nAnd much more. Not going to through it all in detail, and there are probably many things I don\'t know about WeChat since I\'m not a heavy user living in mainland China.\\n\\n### How WeChat works - a toy model\\n\\nThis is an overly simplistic model of how WeChat works, but it is sufficient for our purposes. This general design applies to most traditional client-server apps today.\\n\\nTo sign up for account you need a phone number or equivalent. To get access to some features you need to verify your identity further, for example with official ID and/or bank account.\\n\\nWhen you signup this creates an entry in the WeChat server, from now on treated as a black box. You authenticate with that box, and thats where you get your messages from. If you go online the app asks that box for messages you have received while you were offline. If you login from a different app your contacts and conversations are synced from that box.\\n\\nThe box gives you an account, it deals with routing to your contacts, it stores messages and attachments and gives access to mini apps that people have uploaded. For transacting money, there is a partnership with a different company that has a different box which talks to your bank account.\\n\\nThis is done in a such a way that they can support a billion users with the features above, no sweat.\\n\\nWhoever controls that box can sees who you are talking with and what the content of those messages are. There is no end to end encryption. If WeChat/Tencent disagrees with you for some reason they can ban you. This means you can\'t interact with the box under that name anymore.\\n\\n## What do we want?\\n\\nWe want something that is self-sovereign, private, censorship-resistant and open that allows individuals and groups of people to communicate and transact freely. To explore what this means in more detail, without getting lost in the weeds, we provide the following list of properties. A lot of these are tied together, and some fall out of the other requirements. Some of them stand in slight opposition to each other.\\n\\n**Self-sovereignity identity**. Exercises authority within your own sphere. If you aren\'t harming anyone, you should be able to have an account and communicate with other people.\\n\\n**Pseudonymity, and ideally total anonymity**. Not having your identity tied to your real name (e.g. through phone number, bank account, ID, etc). This allows people to act more freely without being overly worried about censorship and coercion in the real world. While total anonymity is even more desirable - especially to break multiple hops to a true-name action - real-world constraints sometimes makes this more challenging.\\n\\n**Private and secure communication**. Your communication and who you transact with should be for your eyes only. This includes transactions (transfer of value) as a form of communication.\\n\\n**Censorship-resistance**. Not being able to easily censor individuals on the platform. Both at an individual, group and collective level. Not having single points of failure that allow service to be disrupted.\\n\\n**Decentralization**. Partly falls out of censorship-resistance and other properties. If infrastructure isn\'t decentralized it means there\'s a single point of failure that can be disrupted. This is more of a tool than a goal on its own, but it is an important tool.\\n\\n**Built for mass adoption**. Includes scalabiltiy, UX (latency, reliability, bandwidth consumption, UI etc), and allowing for people to stick around. One way of doing this is to allow users to discover people they want to talk to.\\n\\n**Scalability**. Infrastructure needs to support a lot of users to be a viabile alternative. Like, a billion of them (eventually).\\n\\n**Fundamentals in place to support great user experience**. To be a viable alternative, aside from good UI and distribution, fundamentals such as latency, bandwidth usage, consistency etc must support great UX to be a viable alternative.\\n\\n**Works for resource restricted devices, including smartphones**. Most people will use a smartphone to use this. This means it has to work well on them and similar devices, without becoming a second-class citizen where we ignore properties such as censorship-resistance and privacy. Some concession to reality will be necessary due to additional constraints, which leads us to...\\n\\n**Adaptive nodes**. Nodes will have different capabilities, and perhaps at different times. To maintain a lot of the properties described here it is desirable if as many participants as possible are first-class citizens. If a phone is switching from a limited data plan to a WiFi network or from battery to AC power it can do more useful work, and so on. Likewise for a laptop with a lot of free disk space and spare compute power, etc.\\n\\n**Sustainable**. If there\'s no centralized, top down ad-driven model, this means all the infrastructure has to be sustainable somehow. Since these are individual entitites, this means it has to be paid for. While altruistic modes and similar can be used, this likely requires some form of incentivization scheme for useful services provided in the network. Related: free rider problem.\\n\\n**Spam resistant**. Relates to sustainability, scalability and built for mass adoption. Made more difficult by pseudonymous identity due to whitewashing attacks.\\n\\n**Trust-minimized**. To know that properties are provided for and aren\'t compromised, various ways of minimizing trust requirements are useful. This also related to mass adoption and social cohesion. Examples include: open and audited protocols, open source, reproducible builds, etc. This also relates to how mini apps are provided for, since we may not know their source but want to be able to use them anyway.\\n\\n**Open source**. Related to above, where we must be able to inspect the software to know that it functions as advertised and hasn\'t been compromised, e.g. by uploading private data to a third party.\\n\\nSome of these are graded and a bit subtle, i.e.:\\n\\n- Censorship resistance would ideally be able to absorb Internet shutdowns. This would require an extensive MANET/meshnet infrastructure, which while desirable, requires a lot of challenges to be overcome to be feasible.\\n- Privacy would ideally make all actions (optionally) totally anoymous, though this may incur undue costs on bandwidth and latency, which impacts user experience.\\n- Decentralization, certain topologies, such as DHTs, are efficient and quite decentralized but still have some centralized aspects, which makes it attackable in various ways. Ditto for blockchains compared with bearer instruments which requires some coordinating infrastructure, compared with naturally occuring assets such as precious metals.\\n- \\"Discover people\\" and striving for \\"total anonymity\\" might initially seem incompatible. The idea is to provide for sane defaults, and then allow people to decide how much information they want to disclose. This is the essence of privacy.\\n- Users often want _some_ form of moderation to get a good user experience, which can be seen as a form of censorship. The idea to raise the bar on the basics, the fundamental infrastructure. If individuals or specific communities want certain moderation mechanisms, that is still a compatible requirement.\\n\\n### Counterpoint 1\\n\\nWe could refute the above by saying that the design goals are undesirable. We want a system where people can censor others, and where everyone is tied to their real identity. Or we could say something like, freedom of speech is a general concept, and it doesn\'t apply to Internet companies, even if they provide a vital service. You can survive without it and you should\'ve read the terms of service. This roughly charactericizes the mainstream view.\\n\\nAdditional factor here is the idea that a group of people know more about what\'s good for you then you do, so they are protecting you.\\n\\n### Counterpoint 2\\n\\nWe could agree with all these design goals, but think they are too extreme in terms of their requirements. For example, we could operate as a non profit, take donations and volunteers, and then host the whole infrastructure ourselves. We could say we are in a friendly legislation, so we won\'t be a single point of failure. Since we are working on this and maybe even our designs are open, you can trust us and we\'ll provide service and infrastructure that gives you what you want without having to pay for it or solve all these complex decentralized computation and so on problems. If you don\'t trust us for some reason, you shouldn\'t use us regardless. Also, this is better than status quo. And we are more likely to survive by doing this, either by taking shortcuts or by being less ambituous in terms of scope.\\n\\n## Principal components\\n\\nThere are many ways to skin a cat, but this is one way of breaking down the problem. We have a general direction with the properties listed above, together with some understanding of how WeChat works for the everday user. Now the question is, what infrastructure do we need to support this? How do we achieve the above properties, or at least get closer to them? We want to figure out the necessary building blocks, and one of doing this is to map out likely necessary components.\\n\\n### Background: Ethereum and Web3 stack\\n\\nIt is worth noting that a lot of the required infrastructure has been developed, at least as concepts, in the original Ethereum / Web3 vision. In it there is Ethereum for consensus/compute/transact, storage through Swarm, and communication through Whisper. That said, the main focus has been on the Ethereum blockchain itself, and a lot of things have happened in the last 5y+ with respect to technology around privacy and scalabilty. It is worth revisiting things from a fresh point of view, with the WeChat alternative in mind as a clear use case.\\n\\n### Account - self-sovereign identity and the perils of phone numbers\\n\\nStarting from the most basic: what is an account and how do you get one? With most internet services today, WeChat and almost all popular messaging apps included, you need to signup with some centralized authority. Usually you also have to verify this with some data that ties this account to you as an individual. E.g. by requiring a phone number, which in most jurisdictions [^1] means giving out your real ID. This also means you can be banned from using the service by a somewhat arbitrary process, with no due process.\\n\\nNow, we could argue these app providers can do what they want. And they are right, in a very narrow sense. As apps like WeChat (and Google) become general-purpose platforms, they become more and more ingrained in our everyday lives. They start to provide utilities that we absolutely require to work to go about our day, such as paying for food or transportation. This means we need higher standard than this.\\n\\nJustifications for requiring phone numbers are usually centered around three claims:\\n\\n1. Avoiding spam\\n2. Tying your account to your real name, for various reasons\\n3. Using as a commonly shared identifier as a social network discovery mechanism\\n\\nOf course, many services require more than phone numbers. E.g. email, other forms of personal data such as voice recording, linking a bank account, and so on.\\n\\nIn contrast, a self-sovereign system would allow you to \\"create an account\\" completely on your own. This can easily be done with public key cryptograpy, and it also paves the way for end-to-end encryption to make your messages private.\\n\\nThe main issue with this that you need to get more creative about avoiding spam (e.g. through white washing attacks), and ideally there is some other form of social discovery mechanism.\\n\\nJust having a public key as an account isn\'t enough though. If it goes through a central server, then nothing is stopping that server from arbitrarly blocking requests related to that public key. Of course, this also depends on how transparent such requests are. Fundamentally, lest we rely completely on goodwill, there needs to be multiple actors by which you can use the service. This naturally points to decentralization as a requirement. See counterpoint.\\n\\nEven so, if the system is closed source we don\'t know what it is doing. Perhaps the app communicating is also uploading data to another place, or somehow making it possible to see who is who and act accordingly.\\n\\nYou might notice that just one simple property, self-sovereign identity, leads to a slew of other requirements and properties. You might also notice that WeChat is far from alone in this, even if their identity requirements might be a bit stringent than, say, Telegram. Their control aspects are also a bit more extreme, at least for someone with western sensibilities [^2].\\n\\nMost user facing applications have similar issues, Google Apps/FB/Twitter etc. For popular tools that have this built in, we can look at git - which is truly decentralized and have keypair at the bottom. It is for a very specific technical domain, and even then people rely on Github. Key management is fairly difficult even for technical people, and for normal people even more so. Banks are generally far behind on this tech, relying on arcane procedures and special purpose hardware for 2FA. That\'s another big issue.\\n\\nLet\'s shift gears a bit and talk about some other functional requirements.\\n\\n### Routing - packets from A to B\\n\\nIn order to get a lot of the features WeChat provides, we need the ability to do three things: communicate, store data, and transact with people. We need a bit more than that, but let\'s focus on this for now.\\n\\nTo communicate with people, in the base case, we need to go from one phone to another phone that is separated by a large distance. This requires some form of routing. The most natural platform to build this on is the existing Internet, though not the only one. Most phones are resource restricted, and are only \\"on\\" for brief periods of time. This is needed to preserve battery and bandwidth. Additionally, Internet uses IPs as endpoints, which change as a phones move through space. NAT punching etc isn\'t always perfect either. This means we need a way to get a message from one public key to another, and through some intermediate nodes. We can think of these nodes as a form of service network. Similar to how a power grid works, or phone lines, or collection of ISPs.\\n\\nOne important property here is to ensure we don\'t end up in a situation like the centralized capture scenario above, something we\'ve seen with centralized ISPs [^3] [^4] where they can choose which traffic is good and which is bad. We want to allow the use of different service nodes, just like if a restaurant gives you food poisioning you can go to the one next door and then the first one goes out of business after a while. And the circle of life continues.\\n\\nWe shouldn\'t be naive though, and think that this is something nodes are likely to do for free. They need to be adequately compensated for their services, in some of incentivization scheme. That can either be monetary, or as in the case of Bittorrent, more of a barter situation where you use game theory to coordinate with strangers [^5], and some form of reputation attached to it (for private trackers).\\n\\nThere are many ways of doing routing, and we won\'t go into too much technical detail here. Suffice to say is that you likely want both a structured and unstructured alternative, and that these comes with several trade-offs when it comes to efficiency, metadata protection, ability to incentivize, compatibility with existing topologies, and suitability for mobilephones (mostly offline, bandwidth restricted, not directly connectable). Expect more on this in a future article.\\n\\nSome of these considerations naturally leads us into the storage and transaction components.\\n\\n### Storage - available and persistant for later\\n\\nIf mobile phones are mostly offline, we need some way to store these messages so they can be retrieved when online again. The same goes for various kinds attachments as well, and for when people are switching devices. A user might control their timeline, but in the WeChat case that timeline is stored on Tencent\'s servers, and queried from there as well. This naturally needs to happen by some other service nodes. In the WeChat case, and for most IMs, the way these servers are paid for is through some indirect ad mechanism. The entity controlling these ads and so on is the same one as the one operating the servers for storage. A more direct model with different entities would see these services being compensated for their work.\\n\\nWe also need storage for attachments, mini-apps, as well as a way of understanding the current state of consensus when it comes to the compute/transact module. In the WeChat case, this state is completely handled by the bank institution or one of their partners, such as Alibaba. When it comes to bearer instruments like cash, no state needs to be kept as that\'s a direct exchange in the physical world. This isn\'t directly compatible with transfering value over a distance.\\n\\nAll of this state requires availability and persistance. It should be done in a trust minimized fashion and decentralized, which requires some form of incentivization for keeping data around. If it isn\'t, you are relying on social cohesion which breaks down at very large scales.\\n\\nSince data will be spread out across multiple nodes, you need a way to sync data and transfer it in the network. As well as being able to add and query data from it. All of this requires a routing component.\\n\\nTo make it more censorship resistant it might be better to keep it as a general-purpose store, i.e. individuals don\'t need to know what they storing. Otherwise, you naturally end up in a situation where individual nodes can be pressured to not store certain content.\\n\\n### Messaging - from me to you to all of us (not them)\\n\\nThis builds on top of routing, but it has a slightly different focus. The goal is to allow for individuals and groups to communicate in a private, secure and censorship-resistant manner.\\n\\nIt also needs to provide a decent interface to the end user, in terms of dealing seamlessly with offline messages, providing reliable and timely messaging.\\n\\nIn order to get closer to the ideal of total anonymity, it is useful to be able to hide metadata of who is talking to whom. This applies to both normal communication as well as for transactions. Ideally, no one but the parties involved can see who is taking part in a conversation. This can be achieved through various techniques such as mixnets, anonymous credentials, private information retrieval, and so on. Many of these techniques have a fundamental trade-off with latency and bandwidth, something that is a big concern for mobilephones. Being able to do some form of tuning, in an adaptive node manner, depending on your threat model and current capabilities is useful here.\\n\\nThe baseline here is pseudonymity, and having tools to allow individuals to \\"cut off\\" ties to their real world identity and transactions. People act different in different circles in the real world, and this should be mimicked online as well. Your company, family or government shouldn\'t be able to know what exactly you use your paycheck for, and who you are talking to.\\n\\n### Compute - transact, contract and settle\\n\\nThe most immediate need here is transaction from A to B. Direct exchange. There is also a more indirect need for private lawmaking and contracting.\\n\\nWe talked about routing and storage and how they likely need to be incentivized to work properly. How are they going to be compensated? While this could in theory work via existing banking system and so on, this would be rather heavy. It\'d also very likely require tying your identifier to your legal name, something that goes against what we want to achieve. What we want is something that acts more as right-to-access, similar to the way cash functions in a society [^6]. I pay for a fruit with something that is valuable to you and then I\'m on my way.\\n\\nWhile there might be other candidates, such as pre-paid debit cards and so on, this transaction mode pretty much requires a cryptocurrency component. The alternative is to do it on a reputation basis, which might work for small communities, due to social cohesion, but quickly detoriates for large ones [^7]. Ad hoc models like private Bittorrent trackers are centralized and easy to censor.\\n\\nNow, none of the existing cryptocurrency models are ideal. They also all suffer from lack of widespread use, and it is difficult to get onboarded to them in the first place. Transactions in Bitcoin are slow. Ethereum is faster and has more capabilities, but it still suffers from linking payments over time, which makes the privacy part of this more difficult. Zcash, Monero and similar are interesting, but also require more use. For Zcash, shielded transactions appear to only account for less than 2% of all transactions in 2019 [^8] [^9].\\n\\nAnother dimension is what sets general purpose cryptocurrencies like Ethereum apart. Aside from just paying from A to B, you can encode rules about when something should be paid out and not. This is very useful for doing a form of private lawmaking, contracting, for setting up service agreements with these nodes. If there\'s no trivial recourse as in the meatspace world, where you know someone\'s name and you can sue them, you need a different kind of model.\\n\\nWhat makes something like Zcash interesting is that it works more like digital cash. Instead of leaving a public trail for everyone, where someone can see where you got the initial money from and then trace you across various usage, for Zcash every hop is privacy preserving.\\n\\nTo fulfill the general goals of being censorship resistance and secure, it is also vital that the system being used stays online and can\'t be easily disrupted. That points to disintermediation, as opposed to using gateways and exchanges. This is a case where something like cash, or gold, is more direct, since no one can censor this transaction without being physically present where this direct exchange is taking place. However, like before, this doesn\'t work over distance.\\n\\n### Secure chat - just our business\\n\\nSimilar to the messaging module above. The distinction here is that we assume the network part has already taken place. Here we are interested in keeping the contents of messages private, so that means confidentiality/end-to-end encryption, integrity, authentication, as well as forward secrecy and plausible deniability. This means that even if there\'s some actor that gets some private key material, or confiscated your phone, there is some level of...ephemerality to your conversations. Another issue here in terms of scalable private group chat.\\n\\n### Extensible mini apps\\n\\nThis relates to the compute and storage module above. Essentially we want to provide mini apps as in WeChat, but to do so in a way that is compatible with what we want to achieve more generally. This allows individuals and small businesses to create small tools for various purposes, and coordinate with strangers. E.g. booking a cab or getting an insurance, and so on.\\n\\nThis has a higher dependency on the contracting/general computation aspect. I.e. often it isn\'t only a transaction, but you might want to encode some specific rules here that strangers can abide by without having too high trust requirements. As a simple example: escrows.\\n\\nThis also needs an open API that anyone can use. It should be properly secured, so using one doesn\'t compromise the rest of the system it is operating in. To be censorship resistant it requires the routing and storage component to work properly.\\n\\n## Where are we now?\\n\\nLet\'s look back at some of desirable properties we set out in the beginning and see how close we are to building out the necessary components. Is it realistic at all or just a pipe dream? We\'ll see that there are many building blocks in place, and there\'s reason for hope.\\n\\n**Self-sovereignity identity**. Public key crypto and web of trust like constructs makes this possible.\\n\\n**Pseudonymity, and ideally total anonymity**. Pseudonymity can largely be achieved with public key crypto and open systems that allow for permissionless participation. For transactions, pseudonymity exists in most cryptocurrencies. The challenge is linkage across time, especially when interfacing with other \\"legacy\\" system. There are stronger constructs that are actively being worked on and are promising here, such as mixnets (Nym), mixers (Wasabi Wallet, Tornado.Cash) and zero knowledge proofs (Zcash, Ethereum, Starkware). This area of applied research has exploded over the last few years.\\n\\n**Private and secure communication**. Signal has pioneered a lot of this, following OTR. Double Ratchet, X3DH. E2EE is minimum these days, and properties like PFS and PD are getting better. For metadata protection, you have Tor, with its faults, and more active research on mixnets and private information retrieval, etc.\\n\\n**Censorship-resistance**. This covers a lot of ground across the spectrum. You have technologies like Bittorrent, Bitcoin/Ethereum, Tor obfuscated transports, E2EE by default, partial mesh networks in production, abilit to move/replicate host machines more quickly have all made this more of a reality than it used to be. this easier. Of course, techniques such as deep packet inspection and internet shutdowns have increased.\\n\\n**Decentralization**. Cryptocurrencies, projects like libp2p and IPFS. Need to be mindful here of many projects that claim decentralization but are still vulnerable to single points of failures, such as relying on gateways.\\n\\n**Built for mass adoption**. This one is more subjective. There\'s definitely a lot of work to be done here, both when it comes to fundamental performance, key management and things like social discoverability. Directionally these things are improving and becoming easier for the average person but there is a lot ot be done here.\\n\\n**Scalability**. With projects like Ethereum 2.0 and IPFS more and more resources are a being put into this, both at the consensus/compute layer as well as networking (gossip, scalable Kademlia) layer. Also various layer 2 solutions for transactions.\\n\\n**Fundamentals in place to support great user experience**. Similar to built for mass adoption. As scalability becomes more important, more applied research is being done in the p2p area to improve things like latency, bandwidth.\\n\\n**Works for resource restricted devices, including smartphones**. Work in progress and not enough focus here, generally an after thought. Also have stateless clients etc.\\n\\n**Adaptive nodes**. See above. With subprotocols and capabilities in Ethereum and libp2p, this is getting easier.\\n\\n**Sustainable**. Token economics is a thing. While a lot of it won\'t stay around, there are many more projects working on making themselves dispensable. Being open source, having an engaged community and enabling users run their own infrastructure. Users as stakeholders.\\n\\n**Spam resistant**. Tricky problem if you want to be pseudonymous, but some signs of hope with incentivization mechanisms, zero knowledge based signaling, etc. Together with various forms of rate limiting and better controlling of topology and network amplification. And just generally being battle-tested by real world attacks, such as historical Ethereum DDoS attacks.\\n\\n**Trust minimized**. Bitcoin. Zero knowledge provable computation. Open source. Reproducible builds. Signed binaries. Incentive compatible structures. Independent audits. Still a lot of work, but getting better.\\n\\n**Open source**. Big and only getting bigger. Including mainstream companies.\\n\\n## What\'s next?\\n\\nWe\'ve look at what WeChat provides and what we\'d like an alternative to look like. We\'ve also seen a few principal modules that are necessary to achieve those goals. To achieve all of this is a daunting task, and one might call it overly ambitiuous. We\'ve also seen how far we\'ve come with some of the goals, and how a lot of the pieces are there, in one form or another. Then it is a question of putting them all together in the right mix.\\n\\nThe good news is that a lot of people are working all these building blocks and thinking about these problems. Compared to a few years ago we\'ve come quite far when it comes to p2p infrastructure, privacy, security, scalability, and general developer mass and mindshare. If you want to join us in building some of these building blocks, and assembling them, check out our forum.\\n\\nPS. We are [hiring protocol engineers](https://status.im/our_team/open_positions.html). DS\\n\\n## Acknowledgements\\n\\nCorey, Dean, Jacek.\\n\\n## References\\n\\n[^1]: Mandatory SIM card registration laws: https://privacyinternational.org/long-read/3018/timeline-sim-card-registration-laws\\n[^2]: On WeChat keyword censorship: https://citizenlab.ca/2016/11/wechat-china-censorship-one-app-two-systems/\\n[^3]: Net Neutrality: https://www.eff.org/issues/net-neutrality\\n[^4]: ISP centralization: https://ilsr.org/repealing-net-neutrality-puts-177-million-americans-at-risk/\\n[^5]: Incentives Build Robustness in BitTorrent bittorrent.org/bittorrentecon.pdf\\n[^6]: The Case for Electronic Cash: https://coincenter.org/files/2019-02/the-case-for-electronic-cash-coin-center.pdf\\n[^7]: Money, blockchains, and social scalability: http://unenumerated.blogspot.com/2017/02/money-blockchains-and-social-scalability.html\\n[^8]: Zcash private transactions (partial paywall): https://www.theblockcrypto.com/genesis/48413/an-analysis-of-zcashs-private-transactions\\n[^9]: Shielded transactions usage (stats page 404s): https://z.cash/support/faq/"},{"id":"kademlia-to-discv5","metadata":{"permalink":"/rlog/kademlia-to-discv5","source":"@site/rlog/2020-04-9-kademlia-to-discv5.mdx","title":"From Kademlia to Discv5","description":"A quick history of discovery in peer-to-peer networks, along with a look into discv4 and discv5, detailing what they are, how they work and where they differ.","date":"2020-04-09T16:00:00.000Z","formattedDate":"April 9, 2020","tags":[],"readingTime":8.045,"hasTruncateMarker":true,"authors":[{"name":"Dean","twitter":"DeanEigenmann","github":"decanus","website":"https://dean.eigenmann.me","key":"dean"}],"frontMatter":{"layout":"post","name":"From Kademlia to Discv5","title":"From Kademlia to Discv5","date":"2020-04-09T16:00:00.000Z","authors":"dean","published":true,"slug":"kademlia-to-discv5","categories":"research"},"prevItem":{"title":"What Would a WeChat Replacement Need?","permalink":"/rlog/wechat-replacement-need"},"nextItem":{"title":"Waku Update","permalink":"/rlog/waku-update"}},"content":"A quick history of discovery in peer-to-peer networks, along with a look into discv4 and discv5, detailing what they are, how they work and where they differ.\\n\\n\x3c!--truncate--\x3e\\n\\nIf you\'ve been working on Ethereum or adjacent technologies you\'ve probably heard of [discv4](https://github.com/ethereum/devp2p/blob/master/discv4.md) or [discv5](https://github.com/ethereum/devp2p/blob/master/discv5/discv5.md). But what are they actually? How do they work and what makes them different? To answer these questions, we need to start at the beginning, so this post will assume that there is little knowledge on the subject so the post should be accessible for anyone.\\n\\n## The Beginning\\n\\nLet\'s start right at the beginning: the problem of discovery and organization of nodes in peer-to-peer networks.\\n\\nEarly P2P file sharing technologies, such as Napster, would share information about who holds what file using a single server. A node would connect to the central server and give it a list of the files it owns. Another node would then connect to that central server, find a node that has the file it is looking for and contact that node. This however was a flawed system -- it was vulnerable to attacks and left a single party open to lawsuits.\\n\\nIt became clear that another solution was needed, and after years of research and experimentation, we were given the distributed hash table or DHT.\\n\\n## Distributed Hash Tables\\n\\nIn 2001 4 new protocols for such DHTs were conceived, [Tapestry](https://pdos.csail.mit.edu/~strib/docs/tapestry/tapestry_jsac03.pdf), [Chord](https://pdos.csail.mit.edu/papers/chord:sigcomm01/chord_sigcomm.pdf), [CAN](https://people.eecs.berkeley.edu/~sylvia/papers/cans.pdf) and [Pastry](http://rowstron.azurewebsites.net/PAST/pastry.pdf), all of which made various trade-offs and changes in their core functionality, giving them unique characteristics.\\n\\nBut as said, they\'re all DHTs. So what is a DHT?\\n\\nA distributed hash table (DHT) is essentially a distributed key-value list. Nodes participating in the DHT can easily retrieve the value for a key.\\n\\nIf we have a network with 9 key-value pairs and 3 nodes, ideally each node would store 3 (optimally 6 for redundancy) of those key-value pairs, meaning that if a key-value pair were to be updated, only part of the network would responsible for ensuring that it is. The idea is that any node in the network would know where to find the specific key-value pair it is looking for based on how things are distributed amongst the nodes.\\n\\n## Kademlia\\n\\nSo now that we know what DHTs are, let\'s get to Kademlia, the predecessor of discv4. Kademlia was created by Petar Maymounkov and David Mazi\xe8res in 2002. I will naively say that this is probably one of the most popular and most used DHT protocols. It\'s quite simple in how it works, so let\'s look at it.\\n\\nIn Kademlia, nodes and values are arranged by distance (in a very mathematical definition). This distance is not a geographical one, but rather based on identifiers. It is calculated how far 2 identifiers are from eachother using some distance function.\\n\\nKademlia uses an `XOR` as its distance function. An `XOR` is a function that outputs `true` only when inputs differ. Here is an example with some binary identifiers:\\n\\n```\\nXOR 10011001\\n 00110010\\n --------\\n 10101011\\n```\\n\\nThe top in decimal numbers means that the distance between `153` and `50` is `171`.\\n\\nThere are several reasons why `XOR` was taken:\\n\\n1. The distance from one ID to itself will be `0`.\\n2. Distance is symmetric, A to B is the same as B to A.\\n3. Follows triangle inequality, if `A`, `B` and `C` are points on a triangle then the distance `A` to `B` is closer or equal to that of `A` to `C` plus the one from `B` to `C`.\\n\\nIn summary, this distance function allows a node to decide what is \\"close\\" to it and make decisions based on that \\"closeness\\".\\n\\nKademlia nodes store a routing table. This table contains multiple lists. Each subsequent list contains nodes which are a little further distanced than the ones included in the previous list. Nodes maintain detailed knowledge about nodes closest to them, and the further away a node is, the less knowledge the node maintains about it.\\n\\nSo let\'s say I want to find a specific node. What I would do is go to any node which I already know and ask them for all their neighbours closest to my target. I repeat this process for the returned neighbours until I find my target.\\n\\nThe same thing happens for values. Values have a certain distance from nodes and their IDs are structured the same way so we can calculate this distance. If I want to find a value, I simply look for the neighbours closest to that value\'s key until I find the one storing said value.\\n\\nFor Kademlia nodes to support these functions, there are several messages with which the protocol communicates.\\n\\n- `PING` - Used to check whether a node is still running.\\n- `STORE` - Stores a value with a given key on a node.\\n- `FINDNODE` - Returns the closest nodes requested to a given ID.\\n- `FINDVALUE` - The same as `FINDNODE`, except if a node stores the specific value it will return it directly.\\n\\n_This is a **very** simplified explanation of Kademlia and skips various important details. For the full description, make sure to check out the [paper](https://pdos.csail.mit.edu/~petar/papers/maymounkov-kademlia-lncs.pdf) or a more in-depth [design specification](http://xlattice.sourceforge.net/components/protocol/kademlia/specs.html)_\\n\\n## Discv4\\n\\nNow after that history lesson, we finally get to discv4 (which stands for discovery v4), Ethereum\'s current node discovery protocol. The protocol itself is essentially based off of Kademlia, however it does away with certain aspects of it. For example, it does away with any usage of the value part of the DHT.\\n\\nKademlia is mainly used for the organisation of the network, so we only use the routing table to locate other nodes. Due to the fact that discv4 doesn\'t use the value portion of the DHT at all, we can throw away the `FINDVALUE` and `STORE` commands described by Kademlia.\\n\\nThe lookup method previously described by Kademlia describes how a node gets its peers. A node contacts some node and asks it for the nodes closest to itself. It does so until it can no longer find any new nodes.\\n\\nAdditionally, discv4 adds mutual endpoint verification. This is meant to ensure that a peer calling `FINDNODE` also participates in the discovery protocol.\\n\\nFinally, all discv4 nodes are expected to maintain up-to-date ENR records. These contain information about a node. They can be requested from any node using a discv4-specific packet called `ENRRequest`.\\n\\n_If you want some more details on ENRs, check out one of my posts [\\"Network Addresses in Ethereum\\"](https://dean.eigenmann.me/blog/2020/01/21/network-addresses-in-ethereum/)_\\n\\nDiscv4 comes with its own range of problems however. Let\'s look at a few of them.\\n\\nFirstly, the way discv4 works right now, there is no way to differentiate between node sub-protocols. This means for example that an Ethereum node could add an Ethereum Classic Node, Swarm or Whisper node to its DHT without realizing that it is invalid until more communication has happened. This inability to differentiate sub-protocols makes it harder to find specific nodes, such as Ethereum nodes with light-client support.\\n\\nNext, in order to prevent replay attacks, discv4 uses timestamps. This however can lead to various issues when a host\'s clock is wrong. For more details, see the [\\"Known Issues\\"](https://github.com/ethereum/devp2p/blob/master/discv4.md#known-issues-in-the-current-version) section of the discv4 specification.\\n\\nFinally, we have an issue with the way mutual endpoint verification works. Messages can get dropped and there is no way to tell if both peers have verified eachother. This means that we could consider our peer verified while it does not consider us so making them drop the `FINDNODE` packet.\\n\\n## Discv5\\n\\nFinally, let\'s look at discv5. The next iteration of discv4 and the discovery protocol which will be used by Eth 2.0. It aims at fixing various issues present in discv4.\\n\\nThe first change is the way `FINDNODE` works. In traditional Kademlia as well as in discv5, we pass an identifier. However, in discv5 we instead pass the logarithmic distance, meaning that a `FINDNODE` request gets a response containing all nodes at the specified logarithmic distance from the called node.\\n\\nLogarithmic distance means we first calculate the distance and then run it through our log base 2 function. See:\\n\\n```\\nlog2(A xor B)\\n```\\n\\nAnd the second, more important change, is that discv5 aims at solving one of the biggest issues of discv4: the differentiation of sub-protocols. It does this by adding topic tables. Topic tables are [first in first out]() lists that contain nodes which have advertised that they provide a specific service. Nodes get themselves added to this list by registering `ads` on their peers.\\n\\nAs of writing, there is still an issue with this proposal. There is currently no efficient way for a node to place `ads` on multiple peers, since it would require separate requests for every peer which is inefficient in a large-scale network.\\n\\nAdditionally, it is unclear how many peers a node should place these `ads` on and exactly which peers to place them on. For more details, check out the issue [devp2p#136](https://github.com/ethereum/devp2p/issues/136).\\n\\nThere are a bunch more smaller changes to the protocol, but they are less important hence they were ommitted from this summary.\\n\\nNevertheless, discv5 still does not resolve a couple issues present in discv4, such as unreliable endpoint verification. As of writing this post, there is currently no new method in discv5 to improve the endpoint verification process.\\n\\nAs you can see discv5 is still a work in progress and has a few large challenges to overcome. However if it does, it will most likely be a large improvement to a more naive Kademlia implementations.\\n\\n---\\n\\nHopefully this article helped explain what these discovery protocols are and how they work. If you\'re interested in their full specifications you can find them on [github](https://github.com/ethereum/devp2p)."},{"id":"waku-update","metadata":{"permalink":"/rlog/waku-update","source":"@site/rlog/2020-02-14-waku-update.mdx","title":"Waku Update","description":"A research log. What\'s the current state of Waku? How many users does it support? What are the bottlenecks? What\'s next?","date":"2020-02-14T12:00:00.000Z","formattedDate":"February 14, 2020","tags":[],"readingTime":5.63,"hasTruncateMarker":true,"authors":[{"name":"Oskar","twitter":"oskarth","github":"oskarth","key":"oskarth"}],"frontMatter":{"layout":"post","name":"Waku Update","title":"Waku Update","date":"2020-02-14T12:00:00.000Z","authors":"oskarth","published":true,"slug":"waku-update","categories":"research","image":"/img/waku_infrastructure_sky.jpg","discuss":"https://forum.vac.dev/t/waku-update-where-are-we-at/34"},"prevItem":{"title":"From Kademlia to Discv5","permalink":"/rlog/kademlia-to-discv5"},"nextItem":{"title":"DNS Based Discovery","permalink":"/rlog/dns-based-discovery"}},"content":"A research log. What\'s the current state of Waku? How many users does it support? What are the bottlenecks? What\'s next?\\n\\n\x3c!--truncate--\x3e\\n\\nWaku is our fork of Whisper where we address the shortcomings of Whisper in an iterative manner. We\'ve seen a in [previous post](https://vac.dev/fixing-whisper-with-waku) that Whisper doesn\'t scale, and why. In this post we\'ll talk about what the current state of Waku is, how many users it can support, and future plans.\\n\\n## Current state\\n\\n**Specs:**\\n\\nWe released [Waku spec v0.3](https://rfc.vac.dev/spec/6) this week! You can see the full changelog [here](https://rfc.vac.dev/spec/6/#changelog).\\n\\nThe main change from 0.2 is making the handshake more flexible. This enables us to communicate topic interest immediately without ambiguity. We also did the following:\\n\\n- added recommendation for DNS based discovery\\n- added an upgradability and compatibility policy\\n- cut the spec up into several components\\n\\nWe cut the spec up in several components to make Vac as modular as possible. The components right now are:\\n\\n- Waku (main spec), currently in [version 0.3.0](https://rfc.vac.dev/spec/6)\\n- Waku envelope data field, currently in [version 0.1.0](https://rfc.vac.dev/spec/7)\\n- Waku mailserver, currently in [version 0.2.0](https://rfc.vac.dev/spec/8)\\n\\nWe can probably factor these out further as the main spec is getting quite big, but this is good enough for now.\\n\\n**Clients:**\\n\\nThere are currently two clients that implement Waku v0.3, these are [Nimbus (Update: now nim-waku)](https://github.com/status-im/nim-waku) in Nim and [status-go](https://github.com/status-im/status-go) in Go.\\n\\nFor more details on what each client support and don\'t, you can follow the [work in progress checklist](https://github.com/vacp2p/pm/issues/7).\\n\\nWork is currently in progress to integrate it into the [Status core app](https://github.com/status-im/status-react/pull/9949). Waku is expected to be part of their upcoming 1.1 release (see [Status app roadmap (link deprecated)](https://trello.com/b/DkxQd1ww/status-app-roadmap)).\\n\\n**Simulation:**\\n\\nWe have a [simulation](https://github.com/status-im/nim-waku/blob/master/waku/v1/node/quicksim.nim) that verifies - or rather, fails to falsify - our [scalability model](https://vac.dev/fixing-whisper-with-waku). More on the simulation and what it shows below.\\n\\n## How many users does Waku support?\\n\\nThis is our current understanding of how many users a network running Waku can support. Specifically in the context of the Status chat app, since that\'s the most immediate consumer of Waku. It should generalize fairly well to most deployments.\\n\\n**tl;dr (for Status app):**\\n\\n- beta: 100 DAU\\n- v1: 1k DAU\\n- v1.1 (waku only): 10k DAU (up to x10 with deployment hotfixes)\\n- v1.2 (waku+dns): 100k DAU (can optionally be folded into v1.1)\\n\\n_Assuming 10 concurrent users = 100 DAU. Estimate uncertainty increases for each order of magnitude until real-world data is observed._\\n\\nAs far as we know right now, these are the bottlenecks we have:\\n\\n- Immediate bottleneck - Receive bandwidth for end user clients (aka \u2018Fixing Whisper with Waku\u2019)\\n- Very likely bottleneck - Nodes and cluster capacity (aka \u2018DNS based node discovery\u2019)\\n- Conjecture but not unlikely to appear- Full node traffic (aka \u2018the routing / partition problem\u2019)\\n\\nWe\'ve already seen the first bottleneck being discussed in the initial post. Dean wrote a post on [DNS based discovery](https://vac.dev/dns-based-discovery) which explains how we will address the likely second bottleneck. More on the third one in future posts.\\n\\nFor more details on these bottlenecks, see [Scalability estimate: How many users can Waku and the Status app support?](https://discuss.status.im/t/scalability-estimate-how-many-users-can-waku-and-the-status-app-support/1514).\\n\\n## Simulation\\n\\nThe ultimate test is real-world usage. Until then, we have a simulation thanks to Kim De Mey from the Nimbus team!\\n\\n![](/img/waku_simulation.jpeg)\\n\\nWe have two network topologies, Star and full mesh. Both networks have 6 full nodes, one traditional light node with bloom filter, and one Waku light node.\\n\\nOne of the full nodes sends 1 envelope over 1 of the 100 topics that the two light nodes subscribe to. After that, it sends 10000 envelopes over random topics.\\n\\nFor light node, bloom filter is set to almost 10% false positive (bloom filter: n=100, k=3, m=512). It shows the number of valid and invalid envelopes received for the different nodes.\\n\\n**Star network:**\\n\\n| Description | Peers | Valid | Invalid |\\n| --------------- | ----- | ----- | ------- |\\n| Master node | 7 | 10001 | 0 |\\n| Full node 1 | 3 | 10001 | 0 |\\n| Full node 2 | 1 | 10001 | 0 |\\n| Full node 3 | 1 | 10001 | 0 |\\n| Full node 4 | 1 | 10001 | 0 |\\n| Full node 5 | 1 | 10001 | 0 |\\n| Light node | 2 | 815 | 0 |\\n| Waku light node | 2 | 1 | 0 |\\n\\n**Full mesh:**\\n\\n| Description | Peers | Valid | Invalid |\\n| --------------- | ----- | ----- | ------- |\\n| Full node 0 | 7 | 10001 | 20676 |\\n| Full node 1 | 7 | 10001 | 9554 |\\n| Full node 2 | 5 | 10001 | 23304 |\\n| Full node 3 | 5 | 10001 | 11983 |\\n| Full node 4 | 5 | 10001 | 24425 |\\n| Full node 5 | 5 | 10001 | 23472 |\\n| Light node | 2 | 803 | 803 |\\n| Waku light node | 2 | 1 | 1 |\\n\\nThings to note:\\n\\n- Whisper light node with ~10% false positive gets ~10% of total traffic\\n- Waku light node gets ~1000x less envelopes than Whisper light node\\n- Full mesh results in a lot more duplicate messages, expect for Waku light node\\n\\nRun the simulation yourself [here](https://github.com/status-im/nim-waku/blob/master/waku/v1/node/quicksim.nim). The parameters are configurable, and it is integrated with Prometheus and Grafana.\\n\\n## Difference between Waku and Whisper\\n\\nSummary of main differences between Waku v0 spec and Whisper v6, as described in [EIP-627](https://eips.ethereum.org/EIPS/eip-627):\\n\\n- Handshake/Status message not compatible with shh/6 nodes; specifying options as association list\\n- Include topic-interest in Status handshake\\n- Upgradability policy\\n- `topic-interest` packet code\\n- RLPx subprotocol is changed from shh/6 to waku/0.\\n- Light node capability is added.\\n- Optional rate limiting is added.\\n- Status packet has following additional parameters: light-node, confirmations-enabled and rate-limits\\n- Mail Server and Mail Client functionality is now part of the specification.\\n- P2P Message packet contains a list of envelopes instead of a single envelope.\\n\\n## Next steps and future plans\\n\\nSeveral challenges remain to make Waku a robust and suitable base\\ncommunication protocol. Here we outline a few challenges that we are addressing and will continue to work on:\\n\\n- scalability of the network\\n- incentived infrastructure and spam-resistance\\n- build with resource restricted devices in mind, including nodes being mostly offline\\n\\nFor the third bottleneck, a likely candidate for fixing this is Kademlia routing. This is similar to what is done in [Swarm\'s](https://www.ethswarm.org/) PSS. We are in the early stages of experimenting with this over libp2p in [nim-libp2p](https://github.com/status-im/nim-libp2p). More on this in a future post!\\n\\n## Acknowledgements\\n\\n_Image from \\"caged sky\\" by mh.xbhd.org is licensed under CC BY 2.0 (https://ccsearch.creativecommons.org/photos/a9168311-78de-4cb7-a6ad-f92be8361d0e)_"},{"id":"dns-based-discovery","metadata":{"permalink":"/rlog/dns-based-discovery","source":"@site/rlog/2020-02-7-dns-based-discovery.mdx","title":"DNS Based Discovery","description":"A look at EIP-1459 and the benefits of DNS based discovery.","date":"2020-02-07T12:00:00.000Z","formattedDate":"February 7, 2020","tags":[],"readingTime":5.635,"hasTruncateMarker":true,"authors":[{"name":"Dean","twitter":"DeanEigenmann","github":"decanus","website":"https://dean.eigenmann.me","key":"dean"}],"frontMatter":{"layout":"post","name":"DNS Based Discovery","title":"DNS Based Discovery","date":"2020-02-07T12:00:00.000Z","authors":"dean","published":true,"slug":"dns-based-discovery","categories":"research"},"prevItem":{"title":"Waku Update","permalink":"/rlog/waku-update"},"nextItem":{"title":"Fixing Whisper with Waku","permalink":"/rlog/fixing-whisper-with-waku"}},"content":"A look at EIP-1459 and the benefits of DNS based discovery.\\n\\n\x3c!--truncate--\x3e\\n\\nDiscovery in p2p networks is the process of how nodes find each other and specific resources they are looking for. Popular discovery protocols, such as [Kademlia](https://pdos.csail.mit.edu/~petar/papers/maymounkov-kademlia-lncs.pdf) which utilizes a [distributed hash table](https://en.wikipedia.org/wiki/Distributed_hash_table) or DHT, are highly inefficient for resource restricted devices. These methods use short connection windows, and it is quite battery intensive to keep establishing connections. Additionally, we cannot expect a mobile phone for example to synchronize an entire DHT using cellular data.\\n\\nAnother issue is how we do the initial bootstrapping. In other words, how does a client find its first node to then discover the rest of the network? In most applications, including Status right now, this is done with a [static list of nodes](https://specs.status.im/spec/1#bootstrapping) that a client can connect to.\\n\\nIn summary, we have a static list that provides us with nodes we can connect to which then allows us to discover the rest of the network using something like Kademlia. But what we need is something that can easily be mutated, guarantees a certain amount of security, and is efficient for resource restricted devices. Ideally our solution would also be robust and scalable.\\n\\nHow do we do this?\\n\\n[EIP 1459: Node Discovery via DNS](https://eips.ethereum.org/EIPS/eip-1459), which is one of the strategies we are using for discovering waku nodes. [EIP-1459](https://eips.ethereum.org/EIPS/eip-1459) is a DNS-based discovery protocol that stores [merkle trees](https://en.wikipedia.org/wiki/Merkle_tree) in DNS records which contain connection information for nodes.\\n\\n_Waku is our fork of Whisper. Oskar recently wrote an [entire post](https://vac.dev/fixing-whisper-with-waku) explaining it. In short, Waku is our method of fixing the shortcomings of Whisper in a more iterative fashion. You can find the specification [here](https://rfc.vac.dev/spec/6/)_\\n\\nDNS-based methods for bootstrapping p2p networks are quite popular. Even Bitcoin uses it, but it uses a concept called DNS seeds, which are just DNS servers that are configured to return a list of randomly selected nodes from the network upon being queried. This means that although these seeds are hardcoded in the client, the IP addresses of actual nodes do not have to be.\\n\\n```console\\n> dig dnsseed.bluematt.me +short\\n129.226.73.12\\n107.180.78.111\\n169.255.56.123\\n91.216.149.28\\n85.209.240.91\\n66.232.124.232\\n207.55.53.96\\n86.149.241.168\\n193.219.38.57\\n190.198.210.139\\n74.213.232.234\\n158.181.226.33\\n176.99.2.207\\n202.55.87.45\\n37.205.10.3\\n90.133.4.73\\n176.191.182.3\\n109.207.166.232\\n45.5.117.59\\n178.211.170.2\\n160.16.0.30\\n```\\n\\nThe above displays the result of querying on of these DNS seeds. All the nodes are stored as [`A` records](https://simpledns.plus/help/a-records) for the given domain name. This is quite a simple solution which Bitcoin almost soley relies on since removing the [IRC bootstrapping method in v0.8.2](https://en.bitcoin.it/wiki/Network#IRC).\\n\\nWhat makes this DNS based discovery useful? It allows us to have a mutable list of bootstrap nodes without needing to ship a new version of the client every time a list is mutated. It also allows for a more lightweight method of discovering nodes, something very important for resource restricted devices.\\n\\nAdditionally, DNS provides us with a robust and scalable infrastructure. This is due to its hierarchical architecture. This hierarchical architecture also already makes it distributed such that the failure of one DNS server does not result in us no longer being able to resolve our name.\\n\\nAs with every solution though, there is a trade-off. By storing the list in DNS name an adversary would simply need to censor the DNS records for a specific name. This would prevent any new client trying to join the network from being able to do so.\\n\\nOne thing you notice when looking at [EIP-1459](https://eips.ethereum.org/EIPS/eip-1459) is that it is a lot more technically complex than Bitcoin\'s way of doing this. So if Bitcoin uses this simple method and has proven that it works, why did we need a new method?\\n\\nThere are multiple reasons, but the main one is **security**. In the Bitcoin example, an attacker could create a new list and no one querying would be able to tell. This is however mitigated in [EIP-1459](https://eips.ethereum.org/EIPS/eip-1459) where we can verify the integrity of the entire returned list by storing an entire merkle tree in the DNS records.\\n\\nLet\'s dive into this. Firstly, a client that is using these DNS records for discovery must know the public key corresponding to the private key controlled by the entity creating the list. This is because the entire list is signed using a secp256k1 private key, giving the client the ability to authenticate the list and know that it has not been tampered with by some external party.\\n\\nSo that already makes this a lot safer than the method Bitcoin uses. But how are these lists even stored? As previously stated they are stored using **merkle trees** as follows:\\n\\n- The root of the tree is stored in a [`TXT` record](https://simpledns.plus/help/txt-records), this record contains the tree\'s root hash, a sequence number which is incremented every time the tree is updated and a signature as stated above.\\n\\n Additionally, there is also a root hash to a second tree called a **link tree**, it contains the information to different lists. This link tree allows us to delegate trust and build a graph of multiple merkle trees stored across multiple DNS names.\\n\\n The sequence number ensures that an attacker cannot replace a tree with an older version because when a client reads the tree, they should ensure that the sequence number is greater than the last synchronized version.\\n\\n- Using the root hash for the tree, we can find the merkle tree\'s first branch, the branch is also stored in a `TXT` record. The branch record contains all the hashes of the branch\'s leafs.\\n\\n- Once a client starts reading all the leafs, they can find one of two things: either a new branch record leading them further down the tree or an Ethereum Name Records (ENR) which means they now have the address of a node to connect to! To learn more about ethereum node records you can have a look at [EIP-778](https://eips.ethereum.org/EIPS/eip-778), or read a short blog post I wrote explaining them [here](https://dean.eigenmann.me/blog/2020/01/21/network-addresses-in-ethereum/#enr).\\n\\nBelow is the zone file taken from the [EIP-1459](https://eips.ethereum.org/EIPS/eip-1459), displaying how this looks in practice.\\n\\n```\\n; name ttl class type content\\n@ 60 IN TXT enrtree-root:v1 e=JWXYDBPXYWG6FX3GMDIBFA6CJ4 l=C7HRFPF3BLGF3YR4DY5KX3SMBE seq=1 sig=o908WmNp7LibOfPsr4btQwatZJ5URBr2ZAuxvK4UWHlsB9sUOTJQaGAlLPVAhM__XJesCHxLISo94z5Z2a463gA\\nC7HRFPF3BLGF3YR4DY5KX3SMBE 86900 IN TXT enrtree://AM5FCQLWIZX2QFPNJAP7VUERCCRNGRHWZG3YYHIUV7BVDQ5FDPRT2@morenodes.example.org\\nJWXYDBPXYWG6FX3GMDIBFA6CJ4 86900 IN TXT enrtree-branch:2XS2367YHAXJFGLZHVAWLQD4ZY,H4FHT4B454P6UXFD7JCYQ5PWDY,MHTDO6TMUBRIA2XWG5LUDACK24\\n2XS2367YHAXJFGLZHVAWLQD4ZY 86900 IN TXT enr:-HW4QOFzoVLaFJnNhbgMoDXPnOvcdVuj7pDpqRvh6BRDO68aVi5ZcjB3vzQRZH2IcLBGHzo8uUN3snqmgTiE56CH3AMBgmlkgnY0iXNlY3AyNTZrMaECC2_24YYkYHEgdzxlSNKQEnHhuNAbNlMlWJxrJxbAFvA\\nH4FHT4B454P6UXFD7JCYQ5PWDY 86900 IN TXT enr:-HW4QAggRauloj2SDLtIHN1XBkvhFZ1vtf1raYQp9TBW2RD5EEawDzbtSmlXUfnaHcvwOizhVYLtr7e6vw7NAf6mTuoCgmlkgnY0iXNlY3AyNTZrMaECjrXI8TLNXU0f8cthpAMxEshUyQlK-AM0PW2wfrnacNI\\nMHTDO6TMUBRIA2XWG5LUDACK24 86900 IN TXT enr:-HW4QLAYqmrwllBEnzWWs7I5Ev2IAs7x_dZlbYdRdMUx5EyKHDXp7AV5CkuPGUPdvbv1_Ms1CPfhcGCvSElSosZmyoqAgmlkgnY0iXNlY3AyNTZrMaECriawHKWdDRk2xeZkrOXBQ0dfMFLHY4eENZwdufn1S1o\\n```\\n\\nAll of this has already been introduced into go-ethereum with the pull request [#20094](https://github.com/ethereum/go-ethereum/pull/20094), created by Felix Lange. There\'s a lot of tooling around it that already exists too which is really cool. So if your project is written in Golang and wants to use this, it\'s relatively simple! Additionally, here\'s a proof of concept that shows what this might look like with libp2p on [github](https://github.com/decanus/dns-discovery).\\n\\nI hope this was a helpful explainer into DNS based discovery, and shows [EIP-1459](https://eips.ethereum.org/EIPS/eip-1459)\'s benefits over more traditional DNS-based discovery schemes."},{"id":"fixing-whisper-with-waku","metadata":{"permalink":"/rlog/fixing-whisper-with-waku","source":"@site/rlog/2019-12-03-fixing-whisper-with-waku.mdx","title":"Fixing Whisper with Waku","description":"A research log. Why Whisper doesn\'t scale and how to fix it.","date":"2019-12-03T12:00:00.000Z","formattedDate":"December 3, 2019","tags":[],"readingTime":9.995,"hasTruncateMarker":true,"authors":[{"name":"Oskar","twitter":"oskarth","github":"oskarth","key":"oskarth"}],"frontMatter":{"layout":"post","name":"Fixing Whisper with Waku","title":"Fixing Whisper with Waku","date":"2019-12-03T12:00:00.000Z","authors":"oskarth","published":true,"slug":"fixing-whisper-with-waku","categories":"research","image":"/img/whisper_scalability.png","discuss":"https://forum.vac.dev/t/discussion-fixing-whisper-with-waku/27"},"prevItem":{"title":"DNS Based Discovery","permalink":"/rlog/dns-based-discovery"},"nextItem":{"title":"Feasibility Study: Semaphore rate limiting through zkSNARKs","permalink":"/rlog/feasibility-semaphore-rate-limiting-zksnarks"}},"content":"A research log. Why Whisper doesn\'t scale and how to fix it.\\n\\n\x3c!--truncate--\x3e\\n\\nThis post will introduce Waku. Waku is a fork of Whisper that attempts to\\naddresses some of Whisper\'s shortcomings in an iterative fashion. We will also\\nintroduce a theoretical scaling model for Whisper that shows why it doesn\'t\\nscale, and what can be done about it.\\n\\n## Introduction\\n\\nWhisper is a gossip-based communication protocol or an ephemeral key-value store\\ndepending on which way you look at it. Historically speaking, it is the\\nmessaging pilllar of [Web3](http://gavwood.com/dappsweb3.html), together with\\nEthereum for consensus and Swarm for storage.\\n\\nWhisper, being a somewhat esoteric protocol and with some fundamental issues,\\nhasn\'t seen a lot of usage. However, applications such as Status are using it,\\nand have been making minor ad hoc modifications to it to make it run on mobile\\ndevices.\\n\\nWhat are these fundamental issues? In short:\\n\\n1. scalability, most immediately when it comes to bandwidth usage\\n2. spam-resistance, proof of work is a poor mechanism for heterogeneous nodes\\n3. no incentivized infrastructure, leading to centralized choke points\\n4. lack of formal and unambiguous specification makes it hard to analyze and implement\\n5. running over devp2p, which limits where it can run and how\\n\\nIn this post, we\'ll focus on the first problem, which is scalability through bandwidth usage.\\n\\n## Whisper theoretical scalability model\\n\\n_(Feel free to skip this section if you want to get right to the results)._\\n\\nThere\'s widespread implicit knowledge that Whisper \\"doesn\'t scale\\", but it is less understood exactly why. This theoretical model attempts to encode some characteristics of it. Specifically for use case such as one by Status (see [Status Whisper usage\\nspec](https://specs.status.im/spec/3)).\\n\\n### Caveats\\n\\nFirst, some caveats: this model likely contains bugs, has wrong assumptions, or completely misses certain dimensions. However, it acts as a form of existence proof for unscalability, with clear reasons.\\n\\nIf certain assumptions are wrong, then we can challenge them and reason about them in isolation. It doesn\u2019t mean things will definitely work as the model predicts, and that there aren\u2019t unknown unknowns.\\n\\nThe model also only deals with receiving bandwidth for end nodes, uses mostly static assumptions of averages, and doesn\u2019t deal with spam resistance, privacy guarantees, accounting, intermediate node or network wide failures.\\n\\n### Goals\\n\\n1. Ensure network scales by being user or usage bound, as opposed to bandwidth growing in proportion to network size.\\n2. Staying with in a reasonable bandwidth limit for limited data plans.\\n3. Do the above without materially impacting existing nodes.\\n\\nIt proceeds through various case with clear assumptions behind them, starting from the most naive assumptions. It shows results for 100 users, 10k users and 1m users.\\n\\n### Model\\n\\n```\\nCase 1. Only receiving messages meant for you [naive case]\\n\\nAssumptions:\\n- A1. Envelope size (static): 1024kb\\n- A2. Envelopes / message (static): 10\\n- A3. Received messages / day (static): 100\\n- A4. Only receiving messages meant for you.\\n\\nFor 100 users, receiving bandwidth is 1000.0KB/day\\nFor 10k users, receiving bandwidth is 1000.0KB/day\\nFor 1m users, receiving bandwidth is 1000.0KB/day\\n\\n------------------------------------------------------------\\n\\nCase 2. Receiving messages for everyone [naive case]\\n\\nAssumptions:\\n- A1. Envelope size (static): 1024kb\\n- A2. Envelopes / message (static): 10\\n- A3. Received messages / day (static): 100\\n- A5. Received messages for everyone.\\n\\nFor 100 users, receiving bandwidth is 97.7MB/day\\nFor 10k users, receiving bandwidth is 9.5GB/day\\nFor 1m users, receiving bandwidth is 953.7GB/day\\n\\n------------------------------------------------------------\\n\\nCase 3. All private messages go over one discovery topic [naive case]\\n\\nAssumptions:\\n- A1. Envelope size (static): 1024kb\\n- A2. Envelopes / message (static): 10\\n- A3. Received messages / day (static): 100\\n- A6. Proportion of private messages (static): 0.5\\n- A7. Public messages only received by relevant recipients (static).\\n- A8. All private messages are received by everyone (same topic) (static).\\n\\nFor 100 users, receiving bandwidth is 49.3MB/day\\nFor 10k users, receiving bandwidth is 4.8GB/day\\nFor 1m users, receiving bandwidth is 476.8GB/day\\n\\n------------------------------------------------------------\\n\\nCase 4. All private messages are partitioned into shards [naive case]\\n\\nAssumptions:\\n- A1. Envelope size (static): 1024kb\\n- A2. Envelopes / message (static): 10\\n- A3. Received messages / day (static): 100\\n- A6. Proportion of private messages (static): 0.5\\n- A7. Public messages only received by relevant recipients (static).\\n- A9. Private messages partitioned across partition shards (static), n=5000\\n\\nFor 100 users, receiving bandwidth is 1000.0KB/day\\nFor 10k users, receiving bandwidth is 1.5MB/day\\nFor 1m users, receiving bandwidth is 98.1MB/day\\n\\n------------------------------------------------------------\\n\\nCase 5. 4 + Bloom filter with false positive rate\\n\\nAssumptions:\\n- A1. Envelope size (static): 1024kb\\n- A2. Envelopes / message (static): 10\\n- A3. Received messages / day (static): 100\\n- A6. Proportion of private messages (static): 0.5\\n- A7. Public messages only received by relevant recipients (static).\\n- A9. Private messages partitioned across partition shards (static), n=5000\\n- A10. Bloom filter size (m) (static): 512\\n- A11. Bloom filter hash functions (k) (static): 3\\n- A12. Bloom filter elements, i.e. topics, (n) (static): 100\\n- A13. Bloom filter assuming optimal k choice (sensitive to m, n).\\n- A14. Bloom filter false positive proportion of full traffic, p=0.1\\n\\nFor 100 users, receiving bandwidth is 10.7MB/day\\nFor 10k users, receiving bandwidth is 978.0MB/day\\nFor 1m users, receiving bandwidth is 95.5GB/day\\n\\nNOTE: Traffic extremely sensitive to bloom false positives\\nThis completely dominates network traffic at scale.\\nWith p=1% we get 10k users ~100MB/day and 1m users ~10gb/day)\\n\\n------------------------------------------------------------\\n\\nCase 6. Case 5 + Benign duplicate receives\\n\\nAssumptions:\\n- A1. Envelope size (static): 1024kb\\n- A2. Envelopes / message (static): 10\\n- A3. Received messages / day (static): 100\\n- A6. Proportion of private messages (static): 0.5\\n- A7. Public messages only received by relevant recipients (static).\\n- A9. Private messages partitioned across partition shards (static), n=5000\\n- A10. Bloom filter size (m) (static): 512\\n- A11. Bloom filter hash functions (k) (static): 3\\n- A12. Bloom filter elements, i.e. topics, (n) (static): 100\\n- A13. Bloom filter assuming optimal k choice (sensitive to m, n).\\n- A14. Bloom filter false positive proportion of full traffic, p=0.1\\n- A15. Benign duplicate receives factor (static): 2\\n- A16. No bad envelopes, bad PoW, expired, etc (static).\\n\\nFor 100 users, receiving bandwidth is 21.5MB/day\\nFor 10k users, receiving bandwidth is 1.9GB/day\\nFor 1m users, receiving bandwidth is 190.9GB/day\\n\\n------------------------------------------------------------\\n\\nCase 7. 6 + Mailserver under good conditions; small bloom fp; mostly offline\\n\\nAssumptions:\\n- A1. Envelope size (static): 1024kb\\n- A2. Envelopes / message (static): 10\\n- A3. Received messages / day (static): 100\\n- A6. Proportion of private messages (static): 0.5\\n- A7. Public messages only received by relevant recipients (static).\\n- A9. Private messages partitioned across partition shards (static), n=5000\\n- A10. Bloom filter size (m) (static): 512\\n- A11. Bloom filter hash functions (k) (static): 3\\n- A12. Bloom filter elements, i.e. topics, (n) (static): 100\\n- A13. Bloom filter assuming optimal k choice (sensitive to m, n).\\n- A14. Bloom filter false positive proportion of full traffic, p=0.1\\n- A15. Benign duplicate receives factor (static): 2\\n- A16. No bad envelopes, bad PoW, expired, etc (static).\\n- A17. User is offline p% of the time (static) p=0.9\\n- A18. No bad request, dup messages for mailservers; overlap perfect (static).\\n- A19. Mailserver requests can change false positive rate to be p=0.01\\n\\nFor 100 users, receiving bandwidth is 3.9MB/day\\nFor 10k users, receiving bandwidth is 284.8MB/day\\nFor 1m users, receiving bandwidth is 27.8GB/day\\n\\n------------------------------------------------------------\\n\\nCase 8. No metadata protection w bloom filter; 1 node connected; static shard\\n\\nAka waku mode.\\n\\nNext step up is to either only use contact code, or shard more aggressively.\\nNote that this requires change of other nodes behavior, not just local node.\\n\\nAssumptions:\\n- A1. Envelope size (static): 1024kb\\n- A2. Envelopes / message (static): 10\\n- A3. Received messages / day (static): 100\\n- A6. Proportion of private messages (static): 0.5\\n- A7. Public messages only received by relevant recipients (static).\\n- A9. Private messages partitioned across partition shards (static), n=5000\\n\\nFor 100 users, receiving bandwidth is 1000.0KB/day\\nFor 10k users, receiving bandwidth is 1.5MB/day\\nFor 1m users, receiving bandwidth is 98.1MB/day\\n\\n------------------------------------------------------------\\n```\\n\\nSee [source](https://github.com/vacp2p/research/tree/master/whisper_scalability)\\nfor more detail on the model and its assumptions.\\n\\n### Takeaways\\n\\n1. Whisper as it currently works doesn\u2019t scale, and we quickly run into unacceptable bandwidth usage.\\n2. There are a few factors of this, but largely it boils down to noisy topics usage and use of bloom filters. Duplicate (e.g. see [Whisper vs PSS](https://our.status.im/whisper-pss-comparison/)) and bad envelopes are also factors, but this depends a bit more on specific deployment configurations.\\n3. Waku mode (case 8) is an additional capability that doesn\u2019t require other nodes to change, for nodes that put a premium on performance.\\n4. The next bottleneck after this is the partitioned topics (app/network specific), which either needs to gracefully (and potentially quickly) grow, or an alternative way of consuming those messages needs to be deviced.\\n\\n![](/img/whisper_scalability.png)\\n\\nThe results are summarized in the graph above. Notice the log-log scale. The\\ncolored backgrounds correspond to the following bandwidth usage:\\n\\n- Blue: <10mb/d (<~300mb/month)\\n- Green: <30mb/d (<~1gb/month)\\n- Yellow: <100mb/d (<~3gb/month)\\n- Red: >100mb/d (>3gb/month)\\n\\nThese ranges are somewhat arbitrary, but are based on [user\\nrequirements](https://github.com/status-im/status-react/issues/9081) for users\\non a limited data plan, with comparable usage for other messaging apps.\\n\\n## Introducing Waku\\n\\n### Motivation for a new protocol\\n\\nApps such as Status will likely use something like Whisper for the forseeable\\nfuture, and we want to enable them to use it with more users on mobile devices\\nwithout bandwidth exploding with minimal changes.\\n\\nAdditionally, there\'s not a clear cut alternative that maps cleanly to the\\ndesired use cases (p2p, multicast, privacy-preserving, open, etc).\\n\\nWe are actively researching, developing and collaborating with more greenfield\\napproaches. It is likely that Waku will either converge to those, or Waku will\\nlay the groundwork (clear specs, common issues/components) necessary to make\\nswitching to another protocol easier. In this project we want to emphasize\\niterative work with results on the order of weeks.\\n\\n### Briefly on Waku mode\\n\\n- Doesn\u2019t impact existing clients, it\u2019s just a separate node and capability.\\n- Other nodes can still use Whisper as is, like a full node.\\n- Sacrifices metadata protection and incurs higher connectivity/availability requirements for scalbility\\n\\n**Requirements:**\\n\\n- Exposes API to get messages from a set of list of topics (no bloom filter)\\n- Way of being identified as a Waku node (e.g. through version string)\\n- Option to statically encode this node in app, e.g. similar to custom bootnodes/mailserver\\n- Only node that needs to be connected to, possibly as Whisper relay / mailserver hybrid\\n\\n**Provides:**\\n\\n- likely provides scalability of up to 10k users and beyond\\n- with some enhancements to partition topic logic, can possibly scale up to 1m users (app/network specific)\\n\\n**Caveats:**\\n\\n- hasn\u2019t been tested in a large-scale simulation\\n- other network and intermediate node bottlenecks might become apparent (e.g. full bloom filter and private cluster capacity; can likely be dealt with in isolation using known techniques, e.g. load balancing) (deployment specific)\\n\\n### Progress so far\\n\\nIn short, we have a [Waku version 0 spec up](https://rfc.vac.dev/spec/5) as well as a [PoC](https://github.com/status-im/nim-eth/pull/120) for backwards compatibility. In the coming weeks, we are going to solidify the specs, get a more fully featured PoC for [Waku mode](https://github.com/status-im/nim-eth/pull/114). See [rough roadmap](https://github.com/vacp2p/pm/issues/5), project board [link deprecated] and progress thread on the [Vac forum](https://forum.vac.dev/t/waku-project-and-progress/24).\\n\\nThe spec has been rewrittten for clarity, with ABNF grammar and less ambiguous language. The spec also incorporates several previously [ad hoc implemented features](https://rfc.vac.dev/spec/6/#additional-capabilities), such as light nodes and mailserver/client support. This has already caught a few incompatibilities between the `geth` (Go), `status/whisper` (Go) and `nim-eth` (Nim) versions, specifically around light node usage and the handshake.\\n\\nIf you are interested in this effort, please check out [our forum](https://forum.vac.dev/) for questions, comments and proposals. We already have some discussion for better [spam protection](https://forum.vac.dev/t/stake-priority-based-queuing/26) (see [previous post](https://vac.dev/feasibility-semaphore-rate-limiting-zksnarks) for a more complex but privacy-preserving proposal), something that is likely going to be addressed in future versions of Waku, along with many other fixes and enhancement."},{"id":"feasibility-semaphore-rate-limiting-zksnarks","metadata":{"permalink":"/rlog/feasibility-semaphore-rate-limiting-zksnarks","source":"@site/rlog/2019-11-08-feasibility-semaphore-rate-limiting-zksnarks.mdx","title":"Feasibility Study: Semaphore rate limiting through zkSNARKs","description":"A research log. Zero knowledge signaling as a rate limiting mechanism to prevent spam in p2p networks.","date":"2019-11-08T12:00:00.000Z","formattedDate":"November 8, 2019","tags":[],"readingTime":7.54,"hasTruncateMarker":true,"authors":[{"name":"Oskar","twitter":"oskarth","github":"oskarth","key":"oskarth"}],"frontMatter":{"layout":"post","name":"Feasibility Study: Semaphore rate limiting through zkSNARKs","title":"Feasibility Study: Semaphore rate limiting through zkSNARKs","date":"2019-11-08T12:00:00.000Z","authors":"oskarth","published":true,"slug":"feasibility-semaphore-rate-limiting-zksnarks","categories":"research","image":"/img/peacock-signaling.jpg","discuss":"https://forum.vac.dev/t/discussion-feasibility-study-semaphore-rate-limiting-through-zksnarks/21","toc_min_heading_level":2,"toc_max_heading_level":5},"prevItem":{"title":"Fixing Whisper with Waku","permalink":"/rlog/fixing-whisper-with-waku"},"nextItem":{"title":"P2P Data Sync with a Remote Log","permalink":"/rlog/remote-log"}},"content":"A research log. Zero knowledge signaling as a rate limiting mechanism to prevent spam in p2p networks.\\n\\n\x3c!--truncate--\x3e\\n\\n**tldr: Moon math promising for solving spam in Whisper, but to get there we need to invest more in performance work and technical upskilling.**\\n\\n## Motivating problem\\n\\nIn open p2p networks for messaging, one big problem is spam-resistance. Existing solutions, such as Whisper\'s proof of work, are insufficient, especially for heterogeneous nodes. Other reputation-based approaches might not be desirable, due to issues around arbitrary exclusion and privacy.\\n\\nOne possible solution is to use a right-to-access staking-based method, where a node is only able to send a message, signal, at a certain rate, and otherwise they can be slashed. One problem with this is in terms of privacy-preservation, where we specifically don\'t want a user to be tied to a specific payment or unique fingerprint.\\n\\n### Related problems\\n\\nIn addition to above, there are a lot of related problems that share similarities in terms of their structure and proposed solution.\\n\\n- Private transactions ([Zcash](https://z.cash/), [AZTEC](https://www.aztecprotocol.com/))\\n- Private voting ([Semaphore](https://github.com/kobigurk/semaphore))\\n- Private group membership (Semaphore)\\n- Layer 2 scaling, poss layer 1 ([ZK Rollup](https://ethresear.ch/t/on-chain-scaling-to-potentially-500-tx-sec-through-mass-tx-validation/3477); StarkWare/Eth2-3)\\n\\n## Overview\\n\\n## Basic terminology\\n\\nA _zero-knowledge proof_ allows a _prover_ to show a _verifier_ that they know something, without revealing what that something is. This means you can do trust-minimized computation that is also privacy preserving. As a basic example, instead of showing your ID when going to a bar you simply give them a proof that you are over 18, without showing the doorman your id.\\n\\n_zkSNARKs_ is a form of zero-knowledge proofs. There are many types of zero-knowledge proofs, and the field is evolving rapidly. They come with various trade-offs in terms of things such as: trusted setup, cryptographic assumptions, proof/verification key size, proof/verification time, proof size, etc. See section below for more.\\n\\n_Semaphore_ is a framework/library/construct on top of zkSNARks. It allows for zero-knowledge signaling, specifically on top of Ethereum. This means an approved user can broadcast some arbitrary string without revealing their identity, given some specific constraints. An approved user is someone who has been added to a certain merkle tree. See [current Github home](https://github.com/kobigurk/semaphore) for more.\\n\\n_Circom_ is a DSL for writing arithmetic circuits that can be used in zkSNARKs, similar to how you might write a NAND gate. See [Github](https://github.com/iden3/circom) for more.\\n\\n## Basic flow\\n\\nWe start with a private voting example, and then extend it to the slashable rate limiting example.\\n\\n1. A user registers an identity (arbitrary keypair), along with a small fee, to a smart contract. This adds them to a merkle tree and allows them to prove that they are member of that group, without revealing who they are.\\n\\n2. When a user wants to send a message, they compute a zero-knowledge proof. This ensures certain invariants, have some _public outputs_, and can be verified by anyone (including a smart contract).\\n3. Any node can verify the proof, including smart contracts on chain (as of Byzantinum HF). Additionally, a node can have rules for the public output. In the case of voting, one such rule is that a specific output hash has to be equal to some predefined value, such as \\"2020-01-01 vote on Foo Bar for president\\".\\n4. Because of how the proof is constructed, and the rules around output values, this ensures that: a user is part of the approved set of voters and that a user can only vote once.\\n5. As a consequence of above, we have a system where registered users can only vote once, no one can see who voted for what, and this can all be proven and verified.\\n\\n### Rate limiting example\\n\\nIn the case of rate limiting, we do want nodes to send multiple messages. This changes step 3-5 above somewhat.\\n\\n_NOTE: It is a bit more involved than this, and if we precompute proofs the flow might look a bit different. But the general idea is the same_.\\n\\n1. Instead of having a rule that you can only vote once, we have a rule that you can only send a message per epoch. Epoch here can be every second, as defined by UTC date time +-20s.\\n2. Additionally, if a users sends more than one message per epoch, one of the public outputs is a random share of a private key. Using Shamir\'s Secret Sharing (similar to a multisig) and 2/3 key share as an example threshold: in the normal case only 1/3 private keys is revealed, which is insufficient to have access. In the case where two messages are sent in an epoch, probabilistically 2/3 shares is sufficient to have access to the key (unless you get the same random share of the key).\\n3. This means any untrusted user who detects a spamming user, can use it to access their private key corresponding to funds in the contract, and thus slash them.\\n\\n4. As a consequence of above, we have a system where registered users can only messages X times per epoch, and no one can see who is sending what messages. Additionally, if a user is violating the above rate limit, they can be punished and any user can profit from it.\\n\\n### Briefly on scope of \'approved users\'\\n\\nIn the case of an application like Status, this construct can either be a global StatusNetwork group, or one per chat, or network, etc. It can be applied both at the network and user level. There are no specific limitations on where or who deploys this, and it is thus more of a UX consideration.\\n\\n## Technical details\\n\\nFor a fairly self-contained set of examples above, see exploration in [Vac research repo](https://github.com/vacp2p/research/blob/master/zksnarks/semaphore/src/hello.js). Note that the Shamir secret sharing is not inside the SNARK, but out-of-band for now.\\n\\nThe [current version](https://github.com/kobigurk/semaphore) of Semaphore is using NodeJS and [Circom](https://github.com/iden3/circom) from Iden3 for Snarks.\\n\\nFor more on rate limiting idea, see [ethresearch post](https://ethresear.ch/t/semaphore-rln-rate-limiting-nullifier-for-spam-prevention-in-anonymous-p2p-setting/5009/).\\n\\n## Feasibility\\n\\nThe above repo was used to exercise the basic paths and to gain intution of feasibility. Based on it and related reading we outline a few blockers and things that require further study.\\n\\n### Technical feasibility\\n\\n#### Proof time\\n\\nProve time for Semaphore () zKSNARKs using circom, groth and snarkjs is currently way too long. It takes on the order of ~10m to generate a proof. With Websnark, it is likely to take 30s, which might still be too long. We should experiment with native code on mobile here.\\n\\nSee [details](https://github.com/vacp2p/research/issues/7).\\n\\n#### Proving key size\\n\\nProver key size is ~110mb for Semaphore. Assuming this is embedded on mobile device, it bloats the APK a lot. Current APK size is ~30mb and even that might be high for people with limited bandwidth.\\n\\nSee [details](https://github.com/vacp2p/research/issues/8).\\n\\n#### Trusted setup\\n\\nUsing zkSNARKs a trusted setup is required to generate prover and verifier keys. As part of this setup, a toxic parameter lambda is generated. If a party gets access to this lambda, they can prove anything. This means people using zKSNARKs usually have an elaborate MPC ceremony to ensure this parameter doesn\'t get discovered.\\n\\nSee [details](https://github.com/vacp2p/research/issues/9).\\n\\n#### Shamir logic in SNARK\\n\\nFor [Semaphore RLN](https://ethresear.ch/t/semaphore-rln-rate-limiting-nullifier-for-spam-prevention-in-anonymous-p2p-setting/5009) we need to embed the Shamir logic inside the SNARK in order to do slashing for spam. Currently the [implementation](https://github.com/vacp2p/research/blob/master/zksnarks/semaphore/src/hello.js#L450) is trusted and very hacky.\\n\\nSee [details](https://github.com/vacp2p/research/issues/10).\\n\\n#### End to end integation\\n\\n[Currently](https://github.com/vacp2p/research/blob/master/zksnarks/semaphore/src/hello.js) is standalone and doesn\'t touch multiple users, deployed contract with merkle tree and verification, actual transactions, a mocked network, add/remove members, etc. There are bound to be edge cases and unknown unknowns here.\\n\\nSee [details](https://github.com/vacp2p/research/issues/11).\\n\\n#### Licensing issues\\n\\nCurrently Circom [uses a GPL license](https://github.com/iden3/circom/blob/master/COPYING), which can get tricky when it comes to the App Store etc.\\n\\nSee [details](https://github.com/vacp2p/research/issues/12).\\n\\n#### Alternative ZKPs?\\n\\nSome of the isolated blockers for zKSNARKs ([#7](https://github.com/vacp2p/research/issues/7), [#8](https://github.com/vacp2p/research/issues/8), [#9](https://github.com/vacp2p/research/issues/9)) might be mitigated by the use of other ZKP technology. However, they likely have their own issues.\\n\\nSee [details](https://github.com/vacp2p/research/issues/13).\\n\\n### Social feasibility\\n\\n#### Technical skill\\n\\nzkSNARKs and related technologies are quite new. To learn how they work and get an intuition for them requires individuals to dedicate a lot of time to studying them. This means we must make getting competence in these technologies if we wish to use them to our advantage.\\n\\n#### Time and resources\\n\\nIn order for this and related projects (such as private transaction) to get anywhere, it must be made an explicit area of focus for an extend period of time.\\n\\n## General thoughts\\n\\nSimilar to Whisper, and in line with moving towards protocol and infrastructure, we need to upskill and invest resources into this. This doesn\'t mean developing all of the technologies ourselves, but gaining enough competence to leverage and extend existing solutions by the growing ZKP community.\\n\\nFor example, this might also include leveraging largely ready made solutions such as AZTEC for private transaction; more fundamental research into ZK rollup and similar; using Semaphore for private group membership and private voting; Nim based wrapper aronud Bellman, etc.\\n\\n## Acknowledgement\\n\\nThanks to Barry Whitehat for patient explanation and pointers. Thanks to WJ for helping with runtime issues.\\n\\n_Peacock header image from [Tonos]().\\\\_"},{"id":"remote-log","metadata":{"permalink":"/rlog/remote-log","source":"@site/rlog/2019-10-04-remote-log.mdx","title":"P2P Data Sync with a Remote Log","description":"A research log. Asynchronous P2P messaging? Remote logs to the rescue!","date":"2019-10-04T12:00:00.000Z","formattedDate":"October 4, 2019","tags":[],"readingTime":4.515,"hasTruncateMarker":true,"authors":[{"name":"Oskar","twitter":"oskarth","github":"oskarth","key":"oskarth"}],"frontMatter":{"layout":"post","name":"P2P Data Sync with a Remote Log","title":"P2P Data Sync with a Remote Log","date":"2019-10-04T12:00:00.000Z","authors":"oskarth","published":true,"slug":"remote-log","categories":"research","summary":null,"image":"/img/remote-log.png"},"prevItem":{"title":"Feasibility Study: Semaphore rate limiting through zkSNARKs","permalink":"/rlog/feasibility-semaphore-rate-limiting-zksnarks"},"nextItem":{"title":"Vac - A Rough Overview","permalink":"/rlog/vac-overview"}},"content":"A research log. Asynchronous P2P messaging? Remote logs to the rescue!\\n\\n\x3c!--truncate--\x3e\\n\\nA big problem when doing end-to-end data sync between mobile nodes is that most devices are offline most of the time. With a naive approach, you quickly run into issues of \'ping-pong\' behavior, where messages have to be constantly retransmitted. We saw some basic calculations of what this bandwidth multiplier looks like in a [previous post](https://vac.dev/p2p-data-sync-for-mobile).\\n\\nWhile you could do some background processing, this is really battery-draining, and on iOS these capabilities are limited. A better approach instead is to loosen the constraint that two nodes need to be online at the same time. How do we do this? There are two main approaches, one is the _store and forward model_, and the other is a _remote log_.\\n\\nIn the _store and forward_ model, we use an intermediate node that forward messages on behalf of the recipient. In the _remote log_ model, you instead replicate the data onto some decentralized storage, and have a mutable reference to the latest state, similar to DNS. While both work, the latter is somewhat more elegant and \\"pure\\", as it has less strict requirements of an individual node\'s uptime. Both act as a highly-available cache to smoothen over non-overlapping connection windows between endpoints.\\n\\nIn this post we are going to describe how such a remote log schema could work. Specifically, how it enhances p2p data sync and takes care of the [following requirements](https://vac.dev/p2p-data-sync-for-mobile):\\n\\n> 3. MUST allow for mobile-friendly usage. By mobile-friendly we mean devices\\n> that are resource restricted, mostly-offline and often changing network.\\n\\n> 4. MAY use helper services in order to be more mobile-friendly. Examples of\\n> helper services are decentralized file storage solutions such as IPFS and\\n> Swarm. These help with availability and latency of data for mostly-offline\\n> devices.\\n\\n## Remote log\\n\\nA remote log is a replication of a local log. This means a node can read data from a node that is offline.\\n\\nThe spec is in an early draft stage and can be found [here](https://github.com/vacp2p/specs/pull/16). A very basic [spike]() / proof-of-concept can be found [here](https://github.com/vacp2p/research/tree/master/remote_log).\\n\\n### Definitions\\n\\n| Term | Definition |\\n| ---------- | ------------------------------------------------------------------------- |\\n| CAS | Content-addressed storage. Stores data that can be addressed by its hash. |\\n| NS | Name system. Associates mutable data to a name. |\\n| Remote log | Replication of a local log at a different location. |\\n\\n### Roles\\n\\nThere are four fundamental roles:\\n\\n1. Alice\\n2. Bob\\n3. Name system (NS)\\n4. Content-addressed storage (CAS)\\n\\nThe _remote log_ is the data format of what is stored in the name system.\\n\\n\\"Bob\\" can represent anything from 0 to N participants. Unlike Alice, Bob only needs read-only access to NS and CAS.\\n\\n### Flow\\n\\n![Figure 1: Remote log data synchronization.](/img/remote-log.png)\\n\\n### Data format\\n\\nThe remote log lets receiving nodes know what data they are missing. Depending on the specific requirements and capabilities of the nodes and name system, the information can be referred to differently. We distinguish between three rough modes:\\n\\n1. Fully replicated log\\n2. Normal sized page with CAS mapping\\n3. \\"Linked list\\" mode - minimally sized page with CAS mapping\\n\\nA remote log is simply a mapping from message identifiers to their corresponding address in a CAS:\\n\\n| Message Identifier (H1) | CAS Hash (H2) |\\n| ----------------------- | ------------- |\\n| H1_3 | H2_3 |\\n| H1_2 | H2_2 |\\n| H1_1 | H2_1 |\\n| | |\\n| _address to next page_ |\\n\\nThe numbers here corresponds to messages. Optionally, the content itself can be included, just like it normally would be sent over the wire. This bypasses the need for a dedicated CAS and additional round-trips, with a trade-off in bandwidth usage.\\n\\n| Message Identifier (H1) | Content |\\n| ----------------------- | ------- |\\n| H1_3 | C3 |\\n| H1_2 | C2 |\\n| H1_1 | C1 |\\n| | |\\n| _address to next page_ |\\n\\nBoth patterns can be used in parallel, e,g. by storing the last `k` messages directly and use CAS pointers for the rest. Together with the `next_page` page semantics, this gives users flexibility in terms of bandwidth and latency/indirection, all the way from a simple linked list to a fully replicated log. The latter is useful for things like backups on durable storage.\\n\\n### Interaction with MVDS\\n\\n[vac.mvds.Message](https://rfc.vac.dev/spec/2/#payloads) payloads are the only payloads that MUST be uploaded. Other messages types MAY be uploaded, depending on the implementation.\\n\\n## Future work\\n\\nThe spec is still in an early draft stage, so it is expected to change. Same with the proof of concept. More work is needed on getting a fully featured proof of concept with specific CAS and NAS instances. E.g. Swarm and Swarm Feeds, or IPFS and IPNS, or something else.\\n\\nFor data sync in general:\\n\\n- Make consistency guarantees more explicit for app developers with support for sequence numbers and DAGs, as well as the ability to send non-synced messages. E.g. ephemeral typing notifications, linear/sequential history and casual consistency/DAG history\\n- Better semantics and scalability for multi-user sync contexts, e.g. CRDTs and joining multiple logs together\\n- Better usability in terms of application layer usage (data sync clients) and supporting more transports\\n\\n---\\n\\nPS1. Thanks everyone who submitted great [logo proposals](https://explorer.bounties.network/bounty/3389) for Vac!\\n\\nPPS2. Next week on October 10th decanus and I will be presenting Vac at [Devcon](https://devcon.org/agenda), come say hi :)"},{"id":"vac-overview","metadata":{"permalink":"/rlog/vac-overview","source":"@site/rlog/2019-08-02-vac-overview.mdx","title":"Vac - A Rough Overview","description":"Vac is a modular peer-to-peer messaging stack, with a focus on secure messaging. Overview of terms, stack and open problems.","date":"2019-08-02T12:00:00.000Z","formattedDate":"August 2, 2019","tags":[],"readingTime":5.535,"hasTruncateMarker":true,"authors":[{"name":"Oskar","twitter":"oskarth","github":"oskarth","key":"oskarth"}],"frontMatter":{"layout":"post","name":"Vac - A Rough Overview","title":"Vac - A Rough Overview","date":"2019-08-02T12:00:00.000Z","authors":"oskarth","published":true,"slug":"vac-overview","categories":"research"},"prevItem":{"title":"P2P Data Sync with a Remote Log","permalink":"/rlog/remote-log"},"nextItem":{"title":"P2P Data Sync for Mobile","permalink":"/rlog/p2p-data-sync-for-mobile"}},"content":"Vac is a modular peer-to-peer messaging stack, with a focus on secure messaging. Overview of terms, stack and open problems.\\n\\n\x3c!--truncate--\x3e\\n\\nVac is a **modular peer-to-peer messaging stack, with a focus on secure messaging**. What does that mean? Let\'s unpack it a bit.\\n\\n## Basic terms\\n\\n_messaging stack_. While the initial focus is on [data sync](https://vac.dev/p2p-data-sync-for-mobile), we are concerned with all layers in the stack. That means all the way from underlying transports, p2p overlays and routing, to initial trust establishment and semantics for things like group chat. The ultimate goal is to give application developers the tools they need to provide secure messaging for their users, so they can focus on their domain expertise.\\n\\n_modular_. Unlike many other secure messaging applications, our goal is not to have a tightly coupled set of protocols, nor is it to reinvent the wheel. Instead, we aim to provide options at each layer in the stack, and build on the shoulders of giants, putting a premimum on interoperability. It\'s similar in philosophy to projects such as [libp2p](https://libp2p.io/) or [Substrate](https://www.parity.io/substrate/) in that regard. Each choice comes with different trade-offs, and these look different for different applications.\\n\\n_peer-to-peer_. The protocols we work on are pure p2p, and aim to minimize centralization. This too is in opposition to many initiatives in the secure messaging space.\\n\\n_messaging_. By messaging we mean messaging in a generalized sense. This includes both human to human communication, as well machine to machine communication. By messaging we also mean something more fundamental than text messages, we also include things like transactions (state channels, etc) under this moniker.\\n\\n_secure messaging_. Outside of traditional notions of secure messaging, such as ensuring end to end encryption, forward secrecy, avoiding MITM-attacks, etc, we are also concerned with two other forms of secure messaging. We call these _private messaging_ and _censorship-resistance_. Private messaging means viewing privacy as a security property, with all that entails. Censorship resistance ties into being p2p, but also in terms of allowing for transports and overlays that can\'t easily be censored by port blocking, traffic analysis, and similar.\\n\\n_V\u0101c_. Is a Vedic goddess of speech. It also hints at being a vaccine.\\n\\n## Protocol stack\\n\\nWhat does this stack look like? We take inspiration from [core](https://tools.ietf.org/html/rfc793) [internet architecture](https://www.ietf.org/rfc/rfc1122.txt), existing [survey work](https://css.csail.mit.edu/6.858/2020/readings/secure-messaging.pdf) and other [efforts](https://code.briarproject.org/briar/briar/wikis/A-Quick-Overview-of-the-Protocol-Stack) that have been done to decompose the problem into orthogonal pieces. Each layer provides their own set of properties and only interact with the layers it is adjacent to. Note that this is a rough sketch.\\n\\n| Layer / Protocol | Purpose | Examples |\\n| ------------------- | --------------------------------- | -------------------- |\\n| Application layer | End user semantics | 1:1 chat, group chat |\\n| Data Sync | Data consistency | MVDS, BSP |\\n| Secure Transport | Confidentiality, PFS, etc | Double Ratchet, MLS |\\n| Transport Privacy | Transport and metadata protection | Whisper, Tor, Mixnet |\\n| P2P Overlay | Overlay routing, NAT traversal | devp2p, libp2p |\\n| | |\\n| Trust Establishment | Establishing end-to-end trust | TOFU, web of trust |\\n\\nAs an example, end user semantics such as group chat or moderation capabilities can largely work regardless of specific choices further down the stack. Similarly, using a mesh network or Tor doesn\'t impact the use of Double Ratchet at the Secure Transport layer.\\n\\nData Sync plays a similar role to what TCP does at the transport layer in a traditional Internet architecture, and for some applications something more like UDP is likely to be desirable.\\n\\nIn terms of specific properties and trade-offs at each layer, we\'ll go deeper down into them as we study them. For now, this is best treated as a rough sketch or mental map.\\n\\n## Problems and rough priorities\\n\\nWith all the pieces involved, this is quite an undertaking. Luckily, a lot of pieces are already in place and can be either incorporated as-is or iterated on. In terms of medium and long term, here\'s a rough sketch of priorities and open problems.\\n\\n1. **Better data sync.** While the current [MVDS](https://rfc.vac.dev/spec/2/) works, it is lacking in a few areas:\\n\\n- Lack of remote log for mostly-offline offline devices\\n- Better scalability for multi-user chat contexts\\n- Better usability in terms of application layer usage and supporting more transports\\n\\n2. **Better transport layer support.** Currently MVDS runs primarily over Whisper, which has a few issues:\\n\\n- scalability, being able to run with many nodes\\n- spam-resistance, proof of work is a poor mechanism for heterogeneous devices\\n- no incentivized infrastructure, leading to centralized choke points\\n\\nIn addition to these most immediate concerns, there are other open problems. Some of these are overlapping with the above.\\n\\n3. **Adaptive nodes.** Better support for resource restricted devices and nodes of varying capabilities. Light connection strategy for resources and guarantees. Security games to outsource processing with guarantees.\\n\\n4. **Incentivized and spam-resistant messaging.** Reasons to run infrastructure and not relying on altruistic nodes. For spam resistance, in p2p multicast spam is a big attack vector due to amplification. There are a few interesting directions here, such as EigenTrust, proof of burn with micropayments, and leveraging zero-knowledge proofs.\\n\\n5. **Strong privacy guarantees at transport privacy layer**. More rigorous privacy guarantees and explicit trade-offs for metadata protection. Includes Mixnet.\\n6. **Censorship-resistant and robust P2P overlay**. NAT traversal; running in the browser; mesh networks; pluggable transports for traffic obfuscation.\\n\\n7. **Scalable and decentralized secure conversational security.** Strong security guarantees such as forward secrecy, post compromise security, for large group chats. Includes projects such MLS and extending Double Ratchet.\\n\\n8. **Better trust establishment and key handling**. Avoiding MITM attacks while still enabling a good user experience. Protecting against ghost users in group chat and providing better ways to do key handling.\\n\\nThere is also a set of more general problems, that touch multiple layers:\\n\\n9. **Ensuring modularity and interoperability**. Providing interfaces that allow for existing and new protocols to be at each layer of the stack.\\n\\n10. **Better specifications**. Machine-readable and formally verified specifications. More rigorous analysis of exact guarantees and behaviors. Exposing work in such a way that it can be analyzed by academics.\\n\\n11. **Better simulations**. Providing infrastructure and tooling to be able to test protocols in adverse environments and at scale.\\n\\n12. **Enabling excellent user experience**. A big reason for the lack of widespread adoption of secure messaging is the fact that more centralized, insecure methods provide a better user experience. Given that incentives can align better for users interested in secure messaging, providing an even better user experience should be doable.\\n\\n---\\n\\nWe got some work to do. Come help us if you want. See you in the next update!"},{"id":"p2p-data-sync-for-mobile","metadata":{"permalink":"/rlog/p2p-data-sync-for-mobile","source":"@site/rlog/2019-07-19-p2p-data-sync-for-mobile.mdx","title":"P2P Data Sync for Mobile","description":"A research log. Reliable and decentralized, pick two.","date":"2019-07-19T12:00:00.000Z","formattedDate":"July 19, 2019","tags":[],"readingTime":11.01,"hasTruncateMarker":true,"authors":[{"name":"Oskar","twitter":"oskarth","github":"oskarth","key":"oskarth"}],"frontMatter":{"title":"P2P Data Sync for Mobile","date":"2019-07-19T12:00:00.000Z","authors":"oskarth","published":true,"slug":"p2p-data-sync-for-mobile","categories":"research","image":"/img/mvds_interactive.png","toc_min_heading_level":2,"toc_max_heading_level":5},"prevItem":{"title":"Vac - A Rough Overview","permalink":"/rlog/vac-overview"}},"content":"A research log. Reliable and decentralized, pick two.\\n\\n\x3c!--truncate--\x3e\\n\\nTogether with decanus, I\'ve been working on the problem of data sync lately.\\n\\nIn building p2p messaging systems, one problem you quickly come across is the problem of reliably transmitting data. If there\'s no central server with high availability guarantees, you can\'t meaningfully guarantee that data has been transmitted. One way of solving this problem is through a synchronization protocol.\\n\\nThere are many synchronization protocols out there and I won\'t go into detail of how they differ with our approach here. Some common examples are Git and Bittorrent, but there are also projects like IPFS, Swarm, Dispersy, Matrix, Briar, SSB, etc.\\n\\n## Problem motivation\\n\\nWhy do we want to do p2p sync for mobilephones in the first place? There are three components to that question. One is on the value of decentralization and peer-to-peer, the second is on why we\'d want to reliably sync data at all, and finally why mobilephones and other resource restricted devices.\\n\\n### Why p2p?\\n\\nFor decentralization and p2p, there are both technical and social/philosophical reasons. Technically, having a user-run network means it can scale with the number of users. Data locality is also improved if you query data that\'s close to you, similar to distributed CDNs. The throughput is also improved if there are more places to get data from.\\n\\nSocially and philosophically, there are several ways to think about it. Open and decentralized networks also relate to the idea of open standards, i.e. compare the longevity of AOL with IRC or Bittorrent. One is run by a company and is shut down as soon as it stops being profitable, the others live on. Additionally increasingly control of data and infrastructure is becoming a liability. By having a network with no one in control, everyone is. It\'s ultimately a form of democratization, more similar to organic social structures pre Big Internet companies. This leads to properties such as censorship resistance and coercion resistance, where we limit the impact a 3rd party might have a voluntary interaction between individuals or a group of people. Examples of this are plentiful in the world of Facebook, Youtube, Twitter and WeChat.\\n\\n### Why reliably sync data?\\n\\nAt risk of stating the obvious, reliably syncing data is a requirement for many problem domains. You don\'t get this by default in a p2p world, as it is unreliable with nodes permissionslessly join and leave the network. In some cases you can get away with only ephemeral data, but usually you want some kind of guarantees. This is a must for reliable group chat experience, for example, where messages are expected to arrive in a timely fashion and in some reasonable order. The same is true for messages there represent financial transactions, and so on.\\n\\n### Why mobilephones?\\n\\nMost devices people use daily are mobile phones. It\'s important to provide the same or at least similar guarantees to more traditional p2p nodes that might run on a desktop computer or computer. The alternative is to rely on gateways, which shares many of the drawbacks of centralized control and prone to censorship, control and surveillence.\\n\\nMore generally, resource restricted devices can differ in their capabilities. One example is smartphones, but others are: desktop, routers, Raspberry PIs, POS systems, and so on. The number and diversity of devices are exploding, and it\'s useful to be able to leverage this for various types of infrastructure. The alternative is to centralize on big cloud providers, which also lends itself to lack of democratization and censorship, etc.\\n\\n## Minimal Requirements\\n\\nFor requirements or design goals for a solution, here\'s what we came up with.\\n\\n1. MUST sync data reliably between devices. By reliably we mean having the ability to deal with messages being out of order, dropped, duplicated, or delayed.\\n\\n2. MUST NOT rely on any centralized services for reliability. By centralized services we mean any single point of failure that isn\u2019t one of the endpoint devices.\\n\\n3. MUST allow for mobile-friendly usage. By mobile-friendly we mean devices that are resource restricted, mostly-offline and often changing network.\\n\\n4. MAY use helper services in order to be more mobile-friendly. Examples of helper services are decentralized file storage solutions such as IPFS and Swarm. These help with availability and latency of data for mostly-offline devices.\\n\\n5. MUST have the ability to provide casual consistency. By casual consistency we mean the commonly accepted definition in distributed systems literature. This means messages that are casually related can achieve a partial ordering.\\n\\n6. MUST support ephemeral messages that don\u2019t need replication. That is, allow for messages that don\u2019t need to be reliabily transmitted but still needs to be transmitted between devices.\\n\\n7. MUST allow for privacy-preserving messages and extreme data loss. By privacy-preserving we mean things such as exploding messages (self-destructing messages). By extreme data loss we mean the ability for two trusted devices to recover from a, deliberate or accidental, removal of data.\\n\\n8. MUST be agnostic to whatever transport it is running on. It should not rely on specific semantics of the transport it is running on, nor be tightly coupled with it. This means a transport can be swapped out without loss of reliability between devices.\\n\\n## MVDS - a minimium viable version\\n\\nThe first minimum viable version is in an alpha stage, and it has a [specification](https://rfc.vac.dev/spec/2), [implementation](https://github.com/vacp2p/mvds) and we have deployed it in a [console client](https://github.com/status-im/status-console-client) for end to end functionality. It\'s heavily inspired by [Bramble Sync Protocol](https://code.briarproject.org/briar/briar-spec/blob/master/protocols/BSP.md).\\n\\nThe spec is fairly minimal. You have nodes that exchange records over some secure transport. These records are of different types, such as `OFFER`, `MESSAGE`, `REQUEST`, and `ACK`. A peer keep tracks of the state of message for each node it is interacting with. There\'s also logic for message retransmission with exponential delay. The positive ACK and retransmission model is quite similar to how TCP is designed.\\n\\nThere are two different modes of syncing, interactive and batch mode. See sequence diagrams below.\\n\\nInteractive mode:\\n![Interactive mode](/img/mvds_interactive.png)\\n\\nBatch mode:\\n![Batch mode](/img/mvds_batch.png)\\n\\nWhich mode should you choose? It\'s a tradeoff of latency and bandwidth. If you want to minimize latency, batch mode is better. If you care about preserving bandwidth interactive mode is better. The choice is up to each node.\\n\\n### Basic simulation\\n\\nInitial ad hoc bandwidth and latency testing shows some issues with a naive approach. Running with the [default simulation settings](https://github.com/vacp2p/mvds/):\\n\\n- communicating nodes: 2\\n- nodes using interactive mode: 2\\n- interval between messages: 5s\\n- time node is offine: 90%\\n- nodes each node is sharing with: 2\\n\\nwe notice a [huge overhead](https://notes.status.im/7QYa4b6bTH2wMk3HfAaU0w#). More specifically, we see a ~5 minute latency overhead and a bandwidth multiplier of x100-1000, i.e. 2-3 orders of magnitude just for receiving a message with interactive mode, without acks.\\n\\nNow, that seems terrible. A moment of reflection will reveal why that is. If each node is offline uniformly 90% of the time, that means that each record will be lost 90% of the time. Since interactive mode requires offer, request, payload (and then ack), that\'s three links just for Bob to receive the actual message.\\n\\nEach failed attempt implies another retransmission. That means we have `(1/0.1)^3 = 1000` expected overhead to receive a message in interactive mode. The latency follows naturally from that, with the retransmission logic.\\n\\n### Mostly-offline devices\\n\\nThe problem above hints at the requirements 3 and 4 above. While we did get reliable syncing (requirement 1), it came at a big cost.\\n\\nThere are a few ways of getting around this issue. One is having a _store and forward_ model, where some intermediary node picks up (encrypted) messages and forwards them to the recipient. This is what we have in production right now at Status.\\n\\nAnother, arguably more pure and robust, way is having a _remote log_, where the actual data is spread over some decentralized storage layer, and you have a mutable reference to find the latest messages, similar to DNS.\\n\\nWhat they both have in common is that they act as a sort of highly-available cache to smooth over the non-overlapping connection windows between two endpoints. Neither of them are _required_ to get reliable data transmission.\\n\\n### Basic calculations for bandwidth multiplier\\n\\nWhile we do want better simulations, and this is a work in progress, we can also look at the above scenarios using some basic calculations. This allows us to build a better intuition and reason about the problem without having to write code. Let\'s start with some assumptions:\\n\\n- two nodes exchanging a single message in batch mode\\n- 10% uniformly random uptime for each node\\n- in HA cache case, 100% uptime of a piece of infrastructure C\\n- retransmission every epoch (with constant or exponential backoff)\\n- only looking at average (p50) case\\n\\n#### First case, no helper services\\n\\nA sends a message to B, and B acks it.\\n\\n```\\nA message -> B (10% chance of arrival)\\nA <- ack B (10% chance of arrival)\\n```\\n\\nWith a constant backoff, A will send messages at epoch `1, 2, 3, ...`. With exponential backoff and a multiplier of 2, this would be `1, 2, 4, 8, ...`. Let\'s assume constant backoff for now, as this is what will influence the success rate and thus the bandwidth multiplier.\\n\\nThere\'s a difference between _time to receive_ and _time to stop sending_. Assuming each send attempt is independent, it takes on average 10 epochs for A\'s message to arrive with B. Furthermore:\\n\\n1. A will send messages until it receives an ACK.\\n2. B will send ACK if it receives a message.\\n\\nTo get an average of one ack through, A needs to send 100 messages, and B send on average 10 acks. That\'s a multiplier of roughly a 100. That\'s roughly what we saw with the simulation above for receiving a message in interactive mode.\\n\\n#### Second case, high-availability caching layer\\n\\nLet\'s introduce a helper node or piece of infrastructure, C. Whenever A or B sends a message, it also sends it to C. Whenever A or B comes online, it queries for messages with C.\\n\\n```\\nA message -> B (10% chance of arrival)\\nA message -> C (100% chance of arrival)\\nB <- req/res -> C (100% chance of arrival)\\nA <- ack B (10% chance of arrival)\\nC <- ack B (100% chance of arrival)\\nA <- req/res -> C (100% chance of arrival)\\n```\\n\\nWhat\'s the probability that A\'s messages will arrive at B? Directly, it\'s still 10%. But we can assume it\'s 100% that C picks up the message. (Giving C a 90% chance success rate doesn\'t materially change the numbers).\\n\\nB will pick up A\'s message from C after an average of 10 epochs. Then B will send ack to A, which will also be picked up by C 100% of the time. Once A comes online again, it\'ll query C and receive B\'s ack.\\n\\nAssuming we use exponential backoff with a multiplier of 2, A will send a message directly to B at epoch `1, 2, 4, 8` (assuming it is online). At this point, epoch `10`, B will be online in the average case. These direct sends will likely fail, but B will pick the message up from C and send one ack, both directly to A and to be picked up by C. Once A comes online, it\'ll query C and receive the ack from B, which means it won\'t do any more retransmits.\\n\\nHow many messages have been sent? Not counting interactions with C, A sends 4 (at most) and B 1. Depending on if the interaction with C is direct or indirect (i.e. multicast), the factor for interaction with C will be ~2. This means the total bandwidth multiplier is likely to be `<10`, which is a lot more acceptable.\\n\\nSince the syncing semantics are end-to-end, this is without relying on the reliablity of C.\\n\\n#### Caveat\\n\\nNote that both of these are probabilistic argument. They are also based on heuristics. More formal analysis would be desirable, as well as better simulations to experimentally verify them. In fact, the calculations could very well be wrong!\\n\\n## Future work\\n\\nThere are many enhancements that can be made and are desirable. Let\'s outline a few.\\n\\n1. Data sync clients. Examples of actual usage of data sync, with more interesting domain semantics. This also includes usage of sequence numbers and DAGs to know what content is missing and ought to be synced.\\n\\n2. Remote log. As alluded to above, this is necessary. It needs a more clear specification and solid proof of concepts.\\n\\n3. More efficient ways of syncing with large number of nodes. When the number of nodes goes up, the algorithmic complexity doesn\'t look great. This also touches on things such as ambient content discovery.\\n\\n4. More robust simulations and real-world deployments. Exisiting simulation is ad hoc, and there are many improvements that can be made to gain more confidence and identify issues. Additionally, better formal analysis.\\n\\n5. Example usage over multiple transports. Including things like sneakernet and meshnets. The described protocol is designed to work over unstructured, structured and private p2p networks. In some cases it can leverage differences in topology, such as multicast, or direct connections."}]}')}}]); \ No newline at end of file diff --git a/assets/js/99c49682.9b6f6dd4.js b/assets/js/99c49682.9b6f6dd4.js new file mode 100644 index 00000000..814dbb8f --- /dev/null +++ b/assets/js/99c49682.9b6f6dd4.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkvac_dev=self.webpackChunkvac_dev||[]).push([[6807],{10319:e=>{e.exports=JSON.parse('{"blogPosts":[{"id":"zkVM-testing","metadata":{"permalink":"/rlog/zkVM-testing","source":"@site/rlog/2024-09-26-Zkvm-testing.mdx","title":"zkVM Testing Report: Evaluating Zero-Knowledge Virtual Machines for Nescience","description":"Following our initial exploration of zkVMs in our previous blog post [1],","date":"2024-09-26T12:00:00.000Z","formattedDate":"September 26, 2024","tags":[],"readingTime":11.625,"hasTruncateMarker":true,"authors":[{"name":"Moudy","github":"moudyellaz","key":"moudy"}],"frontMatter":{"title":"zkVM Testing Report: Evaluating Zero-Knowledge Virtual Machines for Nescience","date":"2024-09-26T12:00:00.000Z","authors":"moudy","published":true,"slug":"zkVM-testing","categories":"research","discuss":"https://forum.vac.dev/t/zkvm-testing-report-evaluating-zero-knowledge-virtual-machines-for-nescience/","toc_min_heading_level":2,"toc_max_heading_level":5},"nextItem":{"title":"Exploring zkVMs: Which Projects Truly Qualify as Zero-Knowledge Virtual Machines?","permalink":"/rlog/zkVM-explorations"}},"content":"\x3c!--truncate--\x3e\\n\\n# Introduction\\n\\nFollowing our initial exploration of zkVMs in our previous blog post [[1](https://vac.dev/rlog/zkVM-explorations/)], \\nwe have conducted a series of tests to identify the most suitable zkVM for the Nescience architecture [[2](https://vac.dev/rlog/Nescience-state-separation-architecture)]. This post outlines the testing process, results, and conclusions. Additionally, \\nthe full test suite and scripts can be found on our GitHub page [[3](https://github.com/vacp2p/nescience-zkvm-testing)], \\nallowing others to replicate the results or explore the candidates further. \\n\\nWe\'ve shortlisted the following zkVMs for testing:\\n\\n- SP1 [[4](https://blog.succinct.xyz/introducing-sp1/)]\\n- RISC0 [[5](https://www.risczero.com/zkvm)]\\n- Nexus [[6](https://docs.nexus.xyz/)]\\n- ZkMIPS [[7](https://docs.zkm.io/zkm-architecture)]\\n- ZkWASM [[8](https://delphinuslab.com/zk-wasm/)]\\n- Valida [[9](https://delendum.xyz/writings/2023-05-10-zkvm-design.html)]\\n\\n\\n# Why these candidates?\\n\\nWhen narrowing down the zkVMs, we focused on key factors:\\n\\n- True zero-knowledge functionality: The zkVMs had to demonstrate or be close to demonstrating the ability to generate and verify zero-knowledge proofs.\\n- Performance baselines: We sought zkVMs with solid benchmarks in performance, particularly in speed and efficiency.\\n- Specific functionalities: For Nescience, functionalities like lookup tables, precompiles, and recursive capabilities are critical. \\n\\nWe need a zkVM that supports these to enable robust project development.\\n\\n\\n# Preliminary information on the candidates\\n\\n1. SP1 is a performant, open-source zkVM that verifies the execution of arbitrary Rust (or any LLVM-compiled language) programs. \\nSP1 utilizes Plonky3, enabling recursive proofs and supporting a wide range of cryptographic algorithms, including ECC-based ones like Groth16. \\nWhile it supports aggregation, it appears not to support zero knowledge in a conventional manner.\\n\\n2. RISC0 zkVM allows one to prove the correct execution of arbitrary Rust code. Built on a RISC-V architecture, it is inherently adaptable \\nfor implementing standard cryptographic hash functions such as SHA-256 and ECDSA. RISC0 employs STARKs, providing a security level of 98 bits. \\nIt supports multiple programming languages, including C and Rust, thanks to its compatibility with LLVM and WASM.\\n\\n3. Nexus is a modular, extensible, open-source, highly parallelized, prover-optimized, and contributor-friendly zkVM written in Rust. \\nIt focuses on performance and security, using the Nova folding scheme, which is particularly effective for recursive proofs. \\nNexus also supports precompiles and targeted compilation, and besides Rust, it offers C++ support.\\n\\n4. ZkMIPS is a general verifiable computing infrastructure based on Plonky2 and the MIPS microarchitecture, aiming to empower Ethereum \\nas a global settlement layer. It can run arbitrary Rust code as well. Notably, zkMIPS is the only zkVM in this list that utilizes the MIPS opcode set.\\n\\n5. ZkWASM adheres to and supports the unmodified standard WASM bytecode specification. Since Rust code can be compiled to WASM bytecode, \\none could theoretically run any Rust code on a zkWASM machine, providing flexibility and broad language support.\\n\\n6. Valida is a STARK-based virtual machine aiming to improve upon the state of the art in several categories:\\n - Code reuse: The VM has a RISC-inspired instruction set, simplifying the targeting of conventional programming languages. \\n A backend compiler is being developed to compile LLVM IR to the Valida ISA, enabling the proving of programs written in Rust, \\n Go, C++, and others with minimal to no changes in source code.\\n - Prover performance: Engineered to maximize prover performance, Valida is compatible with a 31-bit field, restricted to degree 3 constraints, \\n and features minimal instruction decoding. It operates directly on memory without general-purpose registers or a dedicated stack, \\n utilizing newer lookup arguments to reduce trace overhead involved in cross-chip communication.\\n - Extensibility: Designed to be customizable, Valida can easily be extended to include an arbitrary number of user-defined instructions. \\n Procedural macros are used to construct the desired machine at compile time, avoiding any runtime penalties.\\n\\nValida appears to be in the early stages of development but already showcases respectable performance metrics.\\n\\n# Testing plan\\n\\nTo thoroughly evaluate each zkVM, we devised a two-stage testing process:\\n\\n- Stage 1: Arithmetic operations\\n\\n The first phase focused on evaluating the zkVMs\u2019 ability to handle basic arithmetic operations: addition, subtraction, multiplication, \\n division, modulus division, and square root calculations. We designed the test around heptagonal numbers, which required zkVMs to process \\n multiple arithmetic operations simultaneously. By using this method, we could measure efficiency and speed in handling complex mathematical calculations \u2013 \\n a crucial element for zkVM performance. \\n\\n- Stage 2: Memory consumption\\n\\n For the second phase, we evaluated each zkVM\u2019s ability to manage memory under heavy loads. We tested several data structures, including lists, \\n hash maps, deques, queues, BTreeMaps, hash sets, and binary heaps. Each zkVM underwent tests for the following operations:\\n\\n - Insert: How quickly can the zkVM add data to structures?\\n - Delete: Does the zkVM handle memory release effectively?\\n - Append: Can the zkVM efficiently grow data structures?\\n - Search: How fast and efficient is the zkVM when retrieving stored data?\\n\\nThe purpose of this stage was to identify any memory bottlenecks and to determine whether a zkVM could manage high-intensity tasks efficiently, \\nsomething vital for the Nescience project\u2019s complex, data-heavy processes.\\n\\n# Machine specifications\\n\\nThe tests were conducted on the following hardware configuration:\\n\\n- CPU: AMD EPYC 7713 \\"Milan\\" 64-core processor (128 threads total)\\n- RAM: 600GiB DDR4 3200MHz ECC RAM, distributed across 16 DIMMs\\n- Host OS: Proxmox 8.3\\n- Hypervisor: KVM\\n- Network layer: Open vSwitch\\n- Machine model: Supermicro AS-2024US-TRT\\n\\n# Results\\n\\n### 1. SP1\\n\\nSP1 does not provide zero-knowledge capability in its proofs but delivers respectable performance, though slightly behind its main competitor. \\nMemory leaks were minimal, staying below the 700 KB threshold. Interestingly, SP1 consumed more RAM during the basic arithmetic \\ntest than in memory allocation tests, showcasing the team\'s effective handling of memory under load. In the basic test, \\nallocations were primarily in the 9-16 B, 33-64 B, and 65-128 B ranges. For memory allocations, most fell into the 129-256 B range.\\n- Stage 1: Hept 100 test\\n - Proof size: 3.108 MB\\n - Proof time: 16.95 seconds\\n\\n| ![Image 1](/img/zkvmtest/general11.png) | ![Image 2](/img/zkvmtest/alloc11.png) | ![Image 3](/img/zkvmtest/tempalloc11.png) | ![Image 4](/img/zkvmtest/consumed11.png) | ![Image 5](/img/zkvmtest/sizes11.png) |\\n|------------------------|------------------------|------------------------|------------------------|------------------------|\\n- Stage 2: Vec 10000 test\\n - Proof size: 3.17 MB\\n - Proof time: 20.85 seconds\\n\\n| ![Image 1](/img/zkvmtest/general12.png) | ![Image 2](/img/zkvmtest/alloc12.png) | ![Image 3](/img/zkvmtest/tempalloc12.png) | ![Image 4](/img/zkvmtest/consumed12.png) | ![Image 5](/img/zkvmtest/sizes12.png) |\\n|------------------------|------------------------|------------------------|------------------------|------------------------|\\n\\n---\\n### 2. RISC0\\nRISC0 stands out with exceptional performance in proof size and generation time, ranking among the best \\n(with the exception of Valida and zkWASM\'s basic test). It also handles memory well, with minor leaks under 0.5 MB \\nand controlled RAM consumption staying below 2.2 GB. RISC0\'s memory allocations were consistent, primarily in the 17-32 B and 33-64 B ranges.\\n\\n- Stage 1: Hept 100 test\\n - Proof size: 217.4 KB\\n - Proof time: 9.73 seconds\\n\\n| ![Image 1](/img/zkvmtest/general21.png) | ![Image 2](/img/zkvmtest/alloc21.png) | ![Image 3](/img/zkvmtest/tempalloc21.png) | ![Image 4](/img/zkvmtest/consumed21.png) | ![Image 5](/img/zkvmtest/sizes21.png) |\\n|------------------------|------------------------|------------------------|------------------------|------------------------|\\n\\n- Stage 2: Vec 10000 test\\n - Proof size: 217.4 KB\\n - Proof time: 16.63 seconds\\n\\n| ![Image 1](/img/zkvmtest/general22.png) | ![Image 2](/img/zkvmtest/alloc22.png) | ![Image 3](/img/zkvmtest/tempalloc22.png) | ![Image 4](/img/zkvmtest/consumed22.png) | ![Image 5](/img/zkvmtest/sizes22.png) |\\n|------------------------|------------------------|------------------------|------------------------|------------------------|\\n\\nBased on these results, RISC0 is a solid candidate for Nescience.\\n\\n---\\n### 3. Nexus\\nNexus\' performance offers interesting insights into folding scheme-based zkVMs. Surprisingly, proof sizes remained consistent \\nregardless of workload, with no significant memory leaks (under 700 KB). However, while RAM consumption increased slightly with higher \\nworkloads (up to 1.2 GB), Nexus performed poorly during memory allocation tests, making it unsuitable for our use case.\\n\\n- Allocation details:\\n - Basic test: Most allocations concentrated in 65-128 B\\n - Memory-heavy test: Allocations in the 129-256 B range\\n\\n- Stage 1: Hept 100 test\\n - Proof size: 46 MB\\n - Proof time: 12.06 seconds\\n\\n| ![Image 1](/img/zkvmtest/general31.png) | ![Image 2](/img/zkvmtest/alloc31.png) | ![Image 3](/img/zkvmtest/tempalloc31.png) | ![Image 4](/img/zkvmtest/consumed31.png) | ![Image 5](/img/zkvmtest/sizes31.png) |\\n|------------------------|------------------------|------------------------|------------------------|------------------------|\\n\\n- Stage 2: Vec 10000 test\\n - Proof size: 46 MB\\n - Proof time: 56 minutes\\n \\n| ![Image 1](/img/zkvmtest/general32.png) | ![Image 2](/img/zkvmtest/alloc32.png) | ![Image 3](/img/zkvmtest/tempalloc32.png) | ![Image 4](/img/zkvmtest/consumed32.png) | ![Image 5](/img/zkvmtest/sizes32.png) |\\n|------------------------|------------------------|------------------------|------------------------|------------------------|\\n\\n---\\n### 4. ZkMIPS\\nZkMIPS presents an intriguing case. While it shows good results in terms of proof size and generation time during the basic test, \\nthese come at the cost of significant RAM usage and memory leaks. The memory allocation test revealed a concerning 6.7 GB memory leak, \\nwith 0.5 GB leaked during the basic test. Despite this, RAM consumption (while high at 17+ GB) remains stable under higher workloads. \\nAllocation sizes are spread across several ranges, with notable concentrations in the 17-32 B, 65-128 B, and 257-512 B slots.\\n\\n- Stage 1: Hept 100 test\\n - Proof size: 4.3 MB\\n - Proof time: 9.32 seconds\\n\\n| ![Image 1](/img/zkvmtest/general41.png) | ![Image 2](/img/zkvmtest/alloc41.png) | ![Image 3](/img/zkvmtest/tempalloc41.png) | ![Image 4](/img/zkvmtest/consumed41.png) | ![Image 5](/img/zkvmtest/sizes41.png) |\\n|------------------------|------------------------|------------------------|------------------------|------------------------|\\n\\n- Stage 2: Vec 10000 test\\n - Proof size: 4.898 MB\\n - Proof time: 42.57 seconds\\n\\n| ![Image 1](/img/zkvmtest/general42.png) | ![Image 2](/img/zkvmtest/alloc42.png) | ![Image 3](/img/zkvmtest/tempalloc42.png) | ![Image 4](/img/zkvmtest/consumed42.png) | ![Image 5](/img/zkvmtest/sizes42.png) |\\n|------------------------|------------------------|------------------------|------------------------|------------------------|\\n\\nThis zkVM provides mixed results with strong proof generation but concerning memory management issues.\\n\\n---\\n### 5. ZkWASM\\nZkWASM, unfortunately, performed poorly in both stages regarding proof size and generation time. RAM consumption was particularly high, \\nexceeding 7 GB in the basic test, and an astounding 57 GB during memory allocation tests. Despite its impressive memory usage, \\nthe proof sizes were relatively large at 18 KB and 334 KB respectively. Allocation sizes were mainly concentrated in the 33-64 B range, \\nwith neighboring slots contributing small but notable amounts.\\n\\n- Stage 1: Hept 100 test\\n - Proof size: 18 KB\\n - Proof time: 42.7 seconds\\n\\n| ![Image 1](/img/zkvmtest/general51.png) | ![Image 2](/img/zkvmtest/alloc51.png) | ![Image 3](/img/zkvmtest/tempalloc51.png) | ![Image 4](/img/zkvmtest/consumed51.png) | ![Image 5](/img/zkvmtest/sizes51.png) |\\n|------------------------|------------------------|------------------------|------------------------|------------------------|\\n\\n- Stage 2: Vec 10000 test\\n - Proof size: 334 KB\\n - Proof time: 323 seconds\\n\\n| ![Image 1](/img/zkvmtest/general52.png) | ![Image 2](/img/zkvmtest/alloc52.png) | ![Image 3](/img/zkvmtest/tempalloc52.png) | ![Image 4](/img/zkvmtest/consumed52.png) | ![Image 5](/img/zkvmtest/sizes52.png) |\\n|------------------------|------------------------|------------------------|------------------------|------------------------| \\n\\n---\\n### 6. Valida\\nValida delivered impressive results in proof generation speed and size, with a proof size of 280 KB and a proof time of < 1 second. \\nHowever, profiling was not possible due to Valida\'s limited Rust support. Valida currently compiles Rust using the LLVM backend, \\ntranspiling LLVM IR to leverage its C/C++ implementation, which leads to errors when handling Rust-specific data structures or dependencies. \\nAs a result, complex memory interactions couldn\'t be tested, and using Valida with Rust code is currently not advisable. \\nA GitHub issue has been opened to address this.\\n\\n---\\n## Summary table\\n### Stage 1\\n\\n| zkVM | Proof time | Proof size | Peak RAM consumption | Memory leaked |\\n|--------|------------|------------|----------------------|---------------|\\n| SP1 | 16.95 s | 3.108 MB | 2.1 GB | 656.8 KB |\\n| RISC0 | 9.73 s | 217.4 KB | 1.9 GB | 470.5 KB |\\n| Nexus | 12.06 s | 46 MB | 9.7 MB | 646.5 KB |\\n| ZkMIPS | 9.32 s | 4.3 MB | 17.3 GB | 453.8 MB |\\n| ZkWASM | 42.7 s | 18 KB | 8.2 GB | 259.4 KB |\\n| Valida | < 1 s | 280 KB | N/A | N/A |\\n\\n---\\n\\n### Stage 2\\n\\n| zkVM | Proof time | Proof size | Peak RAM consumption | Memory leaked |\\n|--------|------------|------------|----------------------|---------------|\\n| SP1 | 20.85 s | 3.17 MB | 1.9 GB | 616 KB |\\n| RISC0 | 16.63 s | 217.4 KB | 2.3 GB | 485.3 KB |\\n| Nexus | 56 m | 46 MB | 1.9 GB | 616 KB |\\n| ZkMIPS | 42.57 s | 4.898 MB | 18.9 GB | 6.9 GB |\\n| ZkWASM | 323 s | 334 KB | 58.8 GB | 259.4 KB |\\n| Valida | N/A | N/A | N/A | N/A |\\n\\n---\\n# Summary\\n\\n\\nAfter an extensive evaluation of six zkVM candidates for the Nescience project, RISC0 emerged as the top choice. \\nIt excels in both proof generation time and size while maintaining a reasonable memory footprint. With strong zero-knowledge \\nproof capabilities and support for multiple programming languages, it aligns well with our project\'s needs for privacy, \\nperformance, and flexibility. Its overall balance between performance and efficiency makes it the most viable zkVM at this stage.\\n\\nValida, while promising with its potential for high prover performance, is still in early development and suffers from Rust integration issues. \\nThe current LLVM IR transpilation limitations mean it cannot handle complex memory interactions, disqualifying it for now. \\nHowever, once its development matures, Valida could become a strong alternative, and we plan to revisit it as it evolves.\\n\\nSP1, though initially interesting, failed to meet the zero-knowledge proof requirement. Its performance in arithmetic operations was \\nrespectable but insufficient to justify further consideration given its lack of ZK functionality \u2013 critical for our privacy-first objectives.\\n\\nNexus demonstrated consistent proof sizes and manageable memory usage, but its lackluster performance during memory-intensive tasks and \\nits proof size (especially for larger workloads) disqualified it from being a top contender. While zkMIPS delivered solid proof times, \\nthe memory issues were too significant to ignore, making it unsuitable.\\n\\nFinally, zkWASM exhibited the poorest results, struggling both in proof size and generation time. Despite its potential for WASM bytecode support, \\nthe excessive RAM consumption (up to 57 GB in the memory test) rendered it impractical for Nescience\u2019s use case.\\n\\nIn conclusion, RISC0 is the best fit for Nescience at this stage, but Valida remains a future candidate as its development progresses.\\n\\n\\nWe\u2019d love to hear your thoughts on our zkVM testing process and results! Do you agree with our conclusions, or do you think we missed a promising zkVM? \\nWe\u2019re always open to feedback, insights, and suggestions from the community. \\n\\nJoin the discussion and share your perspectives on \\n[our forum](https://forum.vac.dev/t/zkvm-testing-report-evaluating-zero-knowledge-virtual-machines-for-nescience/) or try out the \\ntests yourself through our [GitHub page](https://github.com/vacp2p/nescience-zkvm-testing!\\n\\n\\n\\n\\n\\n\\n\\n\\n# References\\n\\n[1] Exploring zkVMs: Which Projects Truly Qualify as Zero-Knowledge Virtual Machines? Retrieved from https://vac.dev/rlog/zkVM-explorations/\\n\\n[2] Nescience: A User-Centric State-Separation Architecture. Retrieved from https://vac.dev/rlog/Nescience-state-separation-architecture\\n\\n[3] Our GitHub Page for zkVM Testing. Retrieved from https://github.com/vacp2p/nescience-zkvm-testing\\n\\n[4] Introducing SP1: A performant, 100% open-source, contributor-friendly zkVM. Retrieved from https://blog.succinct.xyz/introducing-sp1/\\n\\n[5] The first general purpose zkVM. Retrieved from https://www.risczero.com/zkvm\\n\\n[6] The Nexus 2.0 zkVM. Retrieved from https://docs.nexus.xyz/\\n\\n[7] ZKM Architecture. Retrieved from https://docs.zkm.io/zkm-architecture\\n\\n[8] ZK-WASM. Retrieved from https://delphinuslab.com/zk-wasm/\\n\\n[9] Valida zkVM Design. Retrieved from https://delendum.xyz/writings/2023-05-10-zkvm-design.html"},{"id":"zkVM-explorations","metadata":{"permalink":"/rlog/zkVM-explorations","source":"@site/rlog/2024-08-27-Zkvm.mdx","title":"Exploring zkVMs: Which Projects Truly Qualify as Zero-Knowledge Virtual Machines?","description":"The blockchain space is rapidly evolving, and with it, new technologies are emerging that promise enhanced privacy, scalability, and security.","date":"2024-08-27T12:00:00.000Z","formattedDate":"August 27, 2024","tags":[],"readingTime":23.53,"hasTruncateMarker":true,"authors":[{"name":"Moudy","github":"moudyellaz","key":"moudy"}],"frontMatter":{"title":"Exploring zkVMs: Which Projects Truly Qualify as Zero-Knowledge Virtual Machines?","date":"2024-08-27T12:00:00.000Z","authors":"moudy","published":true,"slug":"zkVM-explorations","categories":"research","discuss":"https://forum.vac.dev/t/exploring-zkvms-which-projects-truly-qualify-as-zero-knowledge-virtual-machines/317","toc_min_heading_level":2,"toc_max_heading_level":5},"prevItem":{"title":"zkVM Testing Report: Evaluating Zero-Knowledge Virtual Machines for Nescience","permalink":"/rlog/zkVM-testing"},"nextItem":{"title":"Nescience: A User-Centric State-Separation Architecture","permalink":"/rlog/Nescience-state-separation-architecture"}},"content":"\x3c!--truncate--\x3e\\n\\n\\n# Introduction\\n\\nThe blockchain space is rapidly evolving, and with it, new technologies are emerging that promise enhanced privacy, scalability, and security. \\nAs decentralized systems grow in complexity and usage, the need for secure and private computation has never been greater.\\nZero-knowledge virtual machines (zkVMs) are one such innovation, allowing for computations to be proven correct without revealing the underlying data. \\nZkVMs have enormous implications for privacy-preserving applications, decentralized finance (DeFi), and other blockchain-based use cases.\\nHowever, as the term \\"zkVM\\" becomes more widely adopted, it is critical to distinguish between projects that truly satisfy the stringent requirements of a zkVM and those that do not.\\n\\n\\n# What is a zkVM?\\nA zkVM is a virtual machine that combines the principles of cryptographic proof generation and privacy preservation with the computational model \\nof traditional virtual machines. Essentially, a zkVM enables the execution of arbitrary programs while generating cryptographic proofs\u2014specifically, zero-knowledge proofs (ZKPs)\u2014that \\ncan verify the correctness of these computations without revealing any sensitive information. This ensures that computations can be trusted while protecting the privacy of the data involved. \\nThe key characteristics of a zkVM include:\\n\\n- Proof generation: The ability to produce ZKPs that verify the correct execution of programs. There are several types of cryptographic techniques used in zkVMs to \\ngenerate these proofs, such as zk-SNARKs, zk-STARKs, and recursive proofs. A zkVM\u2019s ability to generate these proofs determines how effectively it can ensure the integrity of computations \\nin a privacy-preserving manner.\\n- Privacy preservation: The system must maintain privacy, ensuring that only the proof is revealed, not the underlying computation or data. Privacy-preserving zkVMs allow users to maintain \\nconfidentiality without compromising the security or verifiability of their operations. However, not all zkVMs achieve the same level of privacy. Some may focus more on proof generation \\nand scalability while deprioritizing privacy features, which can limit their use in certain privacy-sensitive applications.\\n- Scalability and performance: zkVMs should offer scalable and efficient computation, leveraging advanced cryptographic techniques like zk-SNARKs, zk-STARKs, or recursive proofs. \\nA zkVM\'s performance must also be measured in terms of latency (time to generate and verify a proof) and throughput (number of computations processed within a certain time frame).\\n- Verifiable computation: The zkVM should be able to prove the execution of arbitrary programs in a secure and verifiable manner. Verifiable computation ensures that zkVMs can be deployed \\nacross a wide range of applications, from DeFi to private data-sharing platforms and more.\\n\\n# Why zkVMs matter\\n\\nThe rise of zkVMs is a crucial development for the future of blockchain and decentralized technologies. As more systems require the ability to scale while maintaining privacy and trust, \\nzkVMs provide a powerful solution. They offer the potential to reshape the way decentralized applications (dapps) handle sensitive information, enabling them to be both efficient and private.\\n\\nIt is essential to distinguish between projects that fully realize the potential of zkVMs and those that do not. In the remainder of this post, we evaluate several zkVM projects, analyzing \\nwhether they satisfy the criteria for being classified as zkVMs based on our research.\\n\\n# Our methodology\\n\\nWe analyzed each project\u2019s documentation, source code, and available benchmarks to determine whether they meet the definition of a zkVM. \\nOur criteria focus on the key capabilities of zkVMs\u2014proof generation, privacy, scalability, and integration with existing systems.\\n\\n# ZkVM project analysis\\n\\n## 1. [SP1]\\n- Overview: SP1 [[1](https://blog.succinct.xyz/introducing-sp1/)] is a developer-friendly zkVM designed to enable ZKP execution for LLVM-based languages like C, C++, Rust, and others. It supports a RISC-V-like instruction set architecture (ISA), \\nwhich makes it compatible with various programming languages compiled through LLVM.\\n- Main focus: The main focus of SP1 is scalability, open-source contributions, and accessibility for developers. It prioritizes performance over privacy, \\nmaking it a good fit for environments where privacy isn\'t the primary concern.\\n- Privacy: Not explicitly mentioned, making it less suitable for privacy-preserving applications.\\n- Performance: SP1 has demonstrated up to 5.4x better performance than similar zkVMs like RISC0 for specific computations such as Fibonacci sequence generation.\\n- Integration: SP1 is highly adaptable for rollups, light client verifiers, oracles, and even web2 projects like verifying the originality of images.\\n- Conclusion: Yes, SP1 is a zkVM, but it does not prioritize zero-knowledge privacy, focusing more on scalability and performance.\\n\\n\\n## 2. [Nexus]\\n- Overview: Nexus [[2](https://docs.nexus.xyz/)] is a highly modular zkVM designed to process up to a trillion CPU cycles per second. It relies on RISC-V instructions for computation, making it extensible and scalable. \\nHowever, it currently lacks full ZKP capabilities due to its use of Spartan proofs.\\n- Main focus: Nexus focuses on high performance and scalability, aiming to create an efficient execution environment for computationally intensive tasks.\\n- Privacy: Although zero-knowledge privacy isn\'t the primary feature of Nexus, the project hints at potential privacy enhancements in the future.\\n- Performance: Nexus has a high theoretical throughput, but it has yet to demonstrate benchmarks on zero-knowledge privacy.\\n- Integration: Nexus is a good fit for high-performance environments that do not necessarily require full privacy.\\n- Conclusion: Yes, Nexus qualifies as a zkVM in terms of scalability and proof generation, but it does not yet achieve full zero-knowledge privacy.\\n\\n## 3. [RISC0]\\n- Overview: Risc0 [[3]( https://www.risczero.com/zkvm)] is a general-purpose zkVM with strong developer support. It allows for the execution of Rust and C code on a RISC-V virtual machine \\nand generates zk-SNARK and zk-STARK proofs for these computations.\\n- Main focus: Risc0 is focused on ease of use for developers by abstracting away the complexities of circuit generation, making it accessible for a wide range of use cases.\\n- Privacy: Full zero-knowledge privacy is supported via zk-SNARK and zk-STARK proofs, with Groth16 used for constant-size proof generation.\\n- Performance: Risc0 offers strong benchmarks across different hardware setups, making it one of the most versatile zkVMs in terms of performance and scalability.\\n- Integration: Risc0 integrates with several ecosystems, including Ethereum, and supports verifiable execution of Rust-based programs.\\n- Conclusion: Yes, Risc0 qualifies as a zkVM, offering a balance of developer usability, scalability, and privacy.\\n\\n## 4. [Powdr]\\n- Overview: Powdr [[4](https://docs.powdr.org/)] is a toolkit for creating custom zkVMs. It allows developers to select from various front-end and back-end components to create zkVMs tailored to specific needs.\\n- Main focus: Powdr is focused on providing a modular architecture for zkVM creation. It enables flexibility by allowing the combination of different ZK-proof backends like Halo2 or Valida.\\n- Privacy: Powdr itself does not generate ZKPs, but it facilitates the creation of zkVMs that do.\\n- Performance: The performance depends on the components chosen by the developer, as Powdr itself is more of a framework.\\n- Integration: Powdr is highly customizable and can integrate with existing zkVM frameworks to extend their capabilities.\\n- Conclusion: No, Powdr is not a zkVM itself, but it is a powerful tool for building customized zkVMs with different privacy and performance needs.\\n\\n## 5. [ZkMIPS]\\n- Overview: ZkMIPS [[5](https://docs.zkm.io/zkm-architecture)] uses zk-STARKs to ensure privacy during computation, ensuring that private inputs are preserved while still proving correctness.\\n- Performance: ZkMIPS is built for scalability, though explicit benchmarks are not widely published.\\n- Integration: ZkMIPS can be integrated into systems that rely on MIPS architecture, making it versatile for legacy codebases that require privacy.\\n- Conclusion: Yes, zkMIPS is a zkVM focused on scalability and privacy for MIPS-based architectures.\\n\\n## 6. [Valida]\\n- Overview: Valida [[6]( https://delendum.xyz/writings/2023-05-10-zkvm-design.html)] is a performance-oriented zkVM that generates proofs for programs using a custom ISA designed to optimize zkVM implementation. \\nIt uses Plonky3 for its proof system.\\n- Main focus: Valida is centered around optimizing prover performance and extensibility, making it a valuable tool for generating proofs efficiently.\\n- Privacy: While Valida is focused on performance, it does not prioritize zero-knowledge privacy as much as other zkVMs.\\n- Performance: Valida has benchmarks indicating its performance advantages in proving computations quickly, particularly through parallel processing.\\n- Integration: Valida is specialized and may not integrate as seamlessly into general-purpose systems, as it is optimized for performance over broad applicability.\\n- Conclusion: Yes, Valida qualifies as a zkVM based on proof generation, but its lack of focus on privacy makes it less suitable for privacy-first use cases.\\n\\n## 7. [Jolt]\\n- Overview: Jolt [[7](https://a16zcrypto.com/posts/article/building-jolt/)] is a zkVM built to optimize prover performance using a modified Hyrax polynomial commitment system. It relies on RISC-V instructions for computation \\nbut falls short of full zero-knowledge capabilities.\\n- Main focus: Jolt\'s main goal is to optimize the speed of proving program execution, making it suitable for high-performance applications where privacy isn\'t the primary concern.\\n- Privacy: Jolt does not fully achieve zero-knowledge privacy due to the choice of polynomial commitment schemes.\\n- Performance: Jolt offers strong performance, with benchmarks highlighting its ability to process proofs efficiently.\\n- Integration: Jolt can be integrated with systems that prioritize speed over privacy, particularly where rapid proof generation is essential.\\n- Conclusion: Yes, Jolt qualifies as a zkVM based on proof generation, though it does not provide full zero-knowledge privacy.\\n\\n## 8. [ZkWASM]\\n- Overview: ZkWASM [[8](https://delphinuslab.com/zk-wasm/)] is a zkVM designed to execute WebAssembly (WASM) code in a privacy-preserving and scalable manner. It uses zk-SNARKs to prove the correctness of WASM \\nprogram execution while ensuring privacy.\\n- Main focus: ZkWASM focuses on scalability and privacy for WebAssembly, making it ideal for dapps that require verifiable computation without compromising privacy.\\n- Privacy: Full zero-knowledge privacy is provided through zk-SNARKs, ensuring that the execution of WASM programs remains confidential.\\n- Performance: ZkWASM is optimized for running WASM programs efficiently, with offchain computation and onchain verification to enhance performance.\\n- Integration: ZkWASM is ideal for dapps, particularly those that use WebAssembly and require verifiable execution.\\n- Conclusion: Yes, zkWASM qualifies as a zkVM, providing strong privacy, scalability, and verifiable execution for WebAssembly code.\\n\\n## 9. [Aleo]\\n- Overview: Aleo\'s [[9](https://aleo.org/blog/)] snarkVM converts code into Aleo instructions, which are then compiled into bytecode executable on its zkVM. Aleo emphasizes building private, scalable dapps.\\n- Main focus: Aleo prioritizes privacy and scalability for dapps, providing a robust framework for developers building private dapps.\\n- Privacy: Aleo offers full privacy through zk-SNARK proofs, making it suitable for building fully private applications.\\n- Performance: Aleo focuses on scalability through efficient proof systems, though detailed performance benchmarks are not widely available.\\n- Integration: Aleo is built for privacy-first dapps and integrates with other zkVM-based systems.\\n- Conclusion: Yes, Aleo qualifies as a zkVM, offering a comprehensive solution for private and scalable dapps.\\n\\n## 10. [Ola]\\n- Overview: Ola [[10](https://github.com/Sin7Y/olavm-whitepaper-v2/tree/master)] is a ZK-friendly, high-performance layer-2 (L2) rollup platform that is still under development. It is designed to execute computations offchain while generating \\nvalidity proofs for these computations, ensuring that they are correctly executed without compromising security. \\n- Privacy: Ola does not specifically prioritize privacy in the same way that zkVMs do. While it leverages ZKPs for scalability, its focus is on proving the correctness of \\ntransactions and computations rather than ensuring that the data remains private.\\n- Performance: Ola is designed to achieve high performance, particularly in terms of transaction throughput.\\n- Integration: Ola is designed to be interoperable with various layer-1 blockchains. The platform supports a hybrid ZK-rollup architecture and is expected to include bridges for cross-chain \\ninteroperability, enabling assets and data to move seamlessly between the layer-1 blockchain and the Ola rollup.\\n- Conclusion: No, Ola is not a zkVM. While it leverages ZKPs (in the form of ZK-rollups) to ensure the validity of offchain computations, its primary focus is on scalability and performance \\nrather than privacy or verifiable execution of arbitrary programs. Ola is more accurately described as a ZK-rollup platform aimed at improving transaction throughput and reducing transaction costs on \\nlayer-1 blockchains. \\n\\n## 11. [Miden]\\n- Overview: Miden zkVM [[11](https://0xpolygonmiden.github.io/miden-vm/intro/main.html)] is a zk-STARK-based virtual machine that converts code into Miden VM instructions and proves the execution of these instructions with zero-knowledge privacy.\\n- Main focus: Miden focuses on scalability and privacy for ZK-rollups, offering efficient proof generation for dapps.\\n- Privacy: Miden ensures privacy for transactions and programs via zk-STARK proofs, making it suitable for private dapps.\\n- Performance: Miden is optimized for scalability, with benchmarks showing its ability to handle up to 1,000 transactions per second (TPS).\\n- Integration: Miden integrates well with ZK-rollup solutions, making it ideal for L2 scaling solutions on blockchains like Ethereum.\\n- Conclusion: Yes, Miden qualifies as a zkVM, providing strong privacy and scalability for dapps and ZK-rollups.\\n\\n## 12. [ZkOS]\\n- Overview: ZkOS [[12](https://osblog.stephenmarz.com/index.html)] is a verifiable operating system focused on running zkApps in a decentralized manner. It is built on the RISC-V architecture and aims to create \\na world computer where all untrusted executions can be verified.\\n- Main focus: ZkOS is primarily designed to offer a proof-of-concept operating system where all executions can be verified in a trustless manner. \\nHowever, its focus is more on the infrastructure for verifiable applications rather than being a traditional zkVM.\\n- Privacy: ZkOS does not focus on privacy guarantees such as those found in zkVMs that generate ZKPs.\\n- Performance: ZkOS focuses on the efficient execution of dapps, but performance benchmarks specific to ZKP generation are not provided.\\n- Integration: ZkOS supports the execution of zkApps, but it is more of a verifiable operating system rather than a zkVM, making it distinct in its functionality.\\n- Conclusion: No, zkOS is not a zkVM. It is a verifiable operating system focused on the infrastructure to support zkApps but does not directly generate ZKPs or focus on privacy preservation.\\n\\n## 13. [Triton]\\n- Overview: Triton [[13](https://triton-vm.org/spec/)] is a domain-specific language (DSL) and compiler designed primarily for high-performance GPU kernels, particularly those used in deep learning applications. \\n- Main focus: The primary goal of Triton is to optimize computation for machine learning and GPU workloads. It is focused on enhancing performance and efficiency in processing data \\nrather than on ZKPs or verifiable computation.\\n- Privacy: Triton does not provide ZKPs or privacy features typically associated with zkVMs. Its focus is on high-performance computation rather than cryptographic verifiability.\\n- Performance: Triton is highly optimized for GPU execution, offering significant improvements in performance for computationally intensive tasks such as those found in deep learning.\\n- Integration: Triton is integrated with GPU-based computation environments and is highly specialized for optimizing low-level operations on hardware rather \\nthan being a general-purpose virtual machine.\\n- Conclusion: No, Triton is not a zkVM. It is a specialized tool for optimizing GPU workloads, focusing on performance rather than privacy or ZKPs.\\n\\n## 14. [Cairo]\\n- Overview: Cairo zkVM [[14](https://github.com/lambdaclass/cairo-vm/blob/main/docs/python_vm/README.md)] uses a custom language that compiles to an optimized STARK-based proof system, ensuring verifiable computation. It is primarily used in systems like Starknet.\\n- Main focus: Cairo focuses on scalability and performance, using zk-STARK proofs to ensure the verifiable and secure execution of programs.\\n- Privacy: Cairo provides privacy through zk-STARKs, but it focuses more on scalability and performance than privacy-first use cases.\\n- Performance: Cairo is highly optimized for performance, making it well-suited for scalable applications on Starknet.\\n- Integration: Cairo integrates deeply with systems like Starknet, supporting verifiable computation in a highly scalable and efficient manner.\\n- Conclusion: Yes, Cairo qualifies as a zkVM, focusing on performance and verifiable execution while being ZK-friendly.\\n\\n## 15. [SnarkOS]\\n- Overview: SnarkOS [[15](https://aleo.org/post/aleo-completes-security-audits-of-snarkos-and-snarkvm/)] is a decentralized operating system designed to power Aleo\'s network, enabling secure and private dapps. \\nIt manages transactions and consensus, making it a critical infrastructure component for Aleo\'s zkVM-based ecosystem.\\n- Main focus: SnarkOS primarily focuses on securing Aleo\'s network through consensus mechanisms and privacy-preserving transactions rather than acting as a \\nzkVM that directly proves program execution.\\n- Privacy: SnarkOS supports zero-knowledge privacy through its integration with Aleo\'s zkVM, but the operating system itself does not generate ZKPs for arbitrary computations.\\n- Performance: SnarkOS is optimized for managing dapps on the Aleo network and handling private transactions, but its focus is more on infrastructure \\nand consensus than on proof generation.\\n- Integration: SnarkOS integrates seamlessly with Aleo\'s zkVM to support private dapps and transactions, but its primary role is as a consensus layer.\\n- Conclusion: No, SnarkOS is not a zkVM. It serves as an operating system for Aleo\'s decentralized network, focusing on privacy and consensus rather than on generating ZKPs for computations.\\n\\n## 16. [Lurk]\\n- Overview: Lurk [[16](https://github.com/lurk-lab)] is a Turing-complete programming language designed for recursive zk-SNARKs. It focuses on enabling developers to build complex, \\nrecursive ZKPs efficiently through a custom language tailored for verifiable computation.\\n- Main focus: Lurk is centered around recursive proof generation rather than serving as a traditional virtual machine. Its purpose is to facilitate the creation of complex zk-SNARK-based proofs, \\nmaking it a specialized tool for cryptographic proofs rather than general-purpose computation.\\n- Privacy: Lurk is built for generating zk-SNARKs, which inherently provide privacy. However, Lurk itself is a language and not a zkVM that executes arbitrary programs and generates ZKPs for them.\\n- Performance: Lurk is optimized for recursive zk-SNARK generation, but specific performance metrics are tied to its proof-generation capabilities rather than traditional execution environments.\\n- Integration: Lurk is specialized for zk-SNARKs and may not easily integrate with other general-purpose systems, as it focuses on specific cryptographic tasks.\\n- Conclusion: No, Lurk is not a zkVM. It is a programming language designed for recursive zk-SNARKs and focuses on proof generation rather than program execution in a virtual machine environment.\\n\\n## 17. [Piecrust]\\n- Overview: Piecrust [[17](https://docs.rs/piecrust/latest/piecrust/)] is a WASM-based zkVM designed to run on the Dusk Network. It supports concurrent execution and focuses on providing privacy and scalability for smart contracts.\\n- Main focus: Piecrust is designed to provide private and efficient execution of smart contracts through the use of ZKPs.\\n- Privacy: Piecrust supports ZK-friendly computations and enhances privacy through cryptographic primitives such as Merkle trees.\\n- Performance: Piecrust is designed to be scalable and concurrent, allowing multiple sessions to run simultaneously, which improves overall performance.\\n- Integration: Piecrust integrates with the Dusk Network and supports private smart contracts, making it ideal for dapps.\\n- Conclusion: Yes, Piecrust qualifies as a zkVM, offering scalability, privacy, and support for succinct proof generation.\\n\\n## 18. [Ceno]\\n- Overview: Ceno [[18](https://eprint.iacr.org/2024/387)] is a zkVM that provides a theoretical framework for reducing proving time by grouping common portions of code together. It uses recursive proofs to enhance prover efficiency.\\n- Main focus: Ceno aims to optimize prover performance through recursive proofs, making it a powerful tool for handling complex computations efficiently.\\n- Privacy: Ceno supports zero-knowledge privacy through recursive proofs and is designed to handle large-scale computations securely.\\n- Performance: Ceno\'s recursive proof framework ensures that it can efficiently prove the execution of programs, reducing the time required for proof generation.\\n- Integration: Ceno can be integrated into systems that require high efficiency and privacy, particularly those handling complex, repeated computations.\\n- Conclusion: Yes, Ceno qualifies as a zkVM, providing efficient and private computation through the use of recursive proofs.\\n\\n## 19. [Stellar]\\n- Overview: Stellar [[19](https://stellar.org/blog/developers/zkvm-a-new-design-for-fast-confidential-smart-contracts)] is a decentralized protocol designed to facilitate cross-border transactions between digital and fiat currencies.\\n- Main focus: Stellar\'s primary goal is to improve financial transactions by enabling decentralized, low-cost currency transfers. It does not aim to provide ZKPs or run verifiable computations \\nlike a zkVM.\\n- Privacy: Stellar focuses on confidentiality and security for financial transactions, but it does not employ ZKPs in the way zkVMs do for verifying computation without revealing data.\\n- Performance: Stellar prioritizes the performance of financial transactions, ensuring low latency and high throughput across its decentralized network. \\nHowever, this performance focus is specific to transactions rather than general-purpose program execution.\\n- Integration: Stellar is designed for integration with financial systems, enabling currency conversions and transfers, but it is not built for executing smart contracts or verifiable computations.\\n- Conclusion: No, Stellar is not a zkVM. It is a decentralized financial protocol focused on facilitating cross-border payments rather than verifiable or privacy-preserving computation.\\n\\n## 20. [NovaNet]\\n- Overview: NovaNet [[20](https://www.novanet.xyz/blog)] is an open peer-to-peer network that aims to build upon concepts of non-uniform incremental verifiable computation. \\n- Main focus: NovaNet\'s focus is on peer-to-peer networking and decentralized computing rather than on proving the execution of programs in a zero-knowledge manner.\\n- Privacy: NovaNet does not provide ZKPs or privacy features typically associated with zkVMs. Its focus is on decentralized networking and computation.\\n- Performance: NovaNet prioritizes efficient decentralized computation but does not focus on privacy or performance benchmarks related to ZKPs.\\n- Integration: NovaNet is built for decentralized networks but is not designed to integrate with systems requiring verifiable computation or ZKP generation.\\n- Conclusion: No, NovaNet is not a zkVM. It is a decentralized peer-to-peer network focused on distributed computing rather than zero-knowledge computation.\\n\\n\\n## 21. [ZkLLVM]\\n- Overview: ZkLLVM [[21](https://github.com/NilFoundation/zkLLVM)] is a compiler that transforms C++ or Rust code into circuits for use in zk-SNARK or zk-STARK systems. Its primary purpose is to bridge high-level programming \\nlanguages with ZKP systems by compiling code into arithmetic circuits that can be used to generate and verify proofs.\\n- Main focus: ZkLLVM focuses on making ZKPs accessible to developers by enabling them to write code in familiar languages (C++, Rust) and then compile that code into ZK circuits.\\n- Privacy: ZkLLVM enables the generation of ZKPs by compiling high-level code into ZK-compatible circuits. It plays a crucial role in privacy-preserving applications but does not act \\nas a zkVM itself.\\n- Performance: ZkLLVM allows for the performance of ZKPs to be closely tied to the complexity of the compiled circuits. The performance depends on the underlying \\nzk-SNARK or zk-STARK system used.\\n- Integration: ZkLLVM integrates with zk-SNARK and zk-STARK proof systems, making it useful for a variety of privacy-focused applications, but it does not serve as a zkVM \\nfor general-purpose computation.\\n- Conclusion: No, zkLLVM is not a zkVM. It is a compiler that transforms high-level code into ZK circuits, enabling ZKPs but not acting as a virtual machine for executing and proving programs.\\n\\n\\n## 22. [ZkMove]\\n- Overview: ZkMove [[22](https://www.zkmove.net/2023-06-20-zkMove-0.2.0-Achieving-Full-Bytecode-Compatibility-with-Move/)] is a zkVM designed to execute smart contracts written in the Move language. It utilizes ZKPs to ensure that the execution of these contracts remains verifiable and secure.\\n- Main focus: ZkMove focuses on privacy and verifiable execution for Move-based smart contracts, providing a framework for ZK-friendly computation.\\n- Privacy: ZkMove ensures that smart contract execution remains private through ZKPs, making it suitable for privacy-preserving applications.\\n- Performance: ZkMove is optimized for verifiable execution, ensuring that contracts can be proven correct while preserving privacy.\\n- Integration: ZkMove integrates well with systems that use the Move language, particularly in environments that require private smart contract execution.\\n- Conclusion: Yes, zkMove qualifies as a zkVM, offering ZK-friendly execution and privacy for smart contracts written in the Move language.\\n\\n## 23. [O1VM]\\n- Overview: O1VM [[23](https://github.com/o1-labs/proof-systems/tree/master/o1vm)] is a general-purpose zkVM developed by o1Labs. It is designed to prove the execution of MIPS programs efficiently through a combination of zk-SNARKs \\nand specialized techniques like folding schemes and RAMLookups.\\n- Main focus: O1VM focuses on scalability and verifiable computation for MIPS-based programs, making it a strong contender for executing and proving complex programs efficiently.\\n- Privacy: O1VM ensures privacy through zk-SNARK proofs, keeping the details of the computation private while proving its correctness.\\n- Performance: O1VM is optimized for handling long execution traces and complex computations, making it highly scalable.\\n- Integration: O1VM integrates well with MIPS-based architectures and systems that require privacy-preserving computation.\\n- Conclusion: Yes, o1VM qualifies as a zkVM, providing privacy, scalability, and strong proof generation for MIPS programs.\\n\\n\\n# Summary of findings \\n| Project name | ZkVM status | Zero knowledge | Reasoning/comments |\\n|--------------|-------------|----------------|-------------------|\\n| **SP1** | Yes | No | Proves execution of LLVM-based programs but lacks privacy features. |\\n| **Nexus** | Yes | No | Strong proof generation but lacks zero-knowledge privacy due to Spartan. |\\n| **Risc0** | Yes | Yes | Supports full ZKP generation for Rust programs. |\\n| **Powdr** | No | Yes | Toolkit for creating custom zkVMs, not a zkVM itself. |\\n| **ZkMIPS** | Yes | Yes | Supports MIPS-like architecture with full zero-knowledge and proof generation. |\\n| **Valida** | Yes | No | Performance-focused zkVM, lacks privacy guarantees. |\\n| **Jolt** | Yes | No | Performance-focused zkVM, does not achieve zero-knowledge privacy. |\\n| **ZkWASM** | Yes | Yes | Full zero-knowledge and verifiable execution of WebAssembly code. |\\n| **Aleo** | Yes | Yes | Fully private and scalable dapps. |\\n| **Ola** | No | No | Primarily a ZK-rollup platform, not a zkVM, focusing on scalability and performance rather than privacy. |\\n| **Miden** | Yes | Yes | Zk-STARK-based zkVM with strong privacy and scalability. |\\n| **ZkOS** | No | No | Verifiable operating system focused on zkApps, not a zkVM. |\\n| **Triton** | No | No | Optimizes GPU workloads but not designed for ZKPs. |\\n| **Cairo** | Yes | ZK-friendly | Custom Rust-based language with zk-STARK proof generation. |\\n| **SnarkOS** | No | Yes | Decentralized OS for Aleo\'s network, focuses on consensus rather than verifiable computation. |\\n| **Lurk** | No | No | Programming language for recursive zk-SNARKs, not a zkVM. |\\n| **Piecrust** | Yes | ZK-friendly | ZkVM with recursive SNARK capabilities, focused on succinct proof generation. |\\n| **Ceno** | Yes | Yes | Theoretical zkVM improving prover efficiency through recursive proofs. |\\n| **Stellar** | No | No | Focuses on cross-border transactions, not ZK-proof generation or verifiable computation. |\\n| **NovaNet** | No | No | Peer-to-peer network focused on distributed computing, not zero-knowledge computation. |\\n| **ZkLLVM** | No | Yes, in some cases | Compiler for generating ZK-circuits, not a zkVM. |\\n| **ZkMove** | Yes | ZK-friendly | ZkVM supporting Move language with ZKP execution. |\\n| **O1VM** | Yes | Yes | MIPS-based zkVM with strong privacy, scalability, and proof generation. |\\n\\n# Insights and conclusions\\n\\nOur analysis reveals that many of the projects labeled as zkVMs do meet the core criteria for zkVMs, offering verifiable computation and proof generation \\nas foundational features. However, a number of these projects fall short of delivering full zero-knowledge privacy. Projects like Risc0, Aleo, and Miden stand out as leading zkVM frameworks \\nthat balance proof generation, privacy, and scalability, offering strong platforms for developers seeking to build privacy-preserving applications.\\n\\nConversely, projects like SP1 and Nexus excel in generating verifiable proofs but currently lack comprehensive zero-knowledge privacy mechanisms. These platforms are excellent for \\nscenarios where proof generation and scalability are paramount, but privacy is not a primary concern.\\n\\nAs zkVM technology continues to evolve, we expect to see more projects integrating enhanced privacy-preserving mechanisms while simultaneously improving performance and scalability. \\nThis ongoing development will likely broaden the application of zkVMs across the blockchain ecosystem, particularly in privacy-sensitive sectors such as finance, data security, \\nand decentralized applications.\\n\\nWhat are your thoughts on our zkVM analysis? Do you agree with our findings, or do you know of other zkVM projects that should be on our radar? We would love to hear your insights, questions, \\nor suggestions! Feel free to join the [discussion](https://forum.vac.dev/t/exploring-zkvms-which-projects-truly-qualify-as-zero-knowledge-virtual-machines/317) on our forum.\\n\\n\\n# References\\n\\n[1] Introducing SP1: A performant, 100% open-source, contributor-friendly zkVM. Retrieved from https://blog.succinct.xyz/introducing-sp1/\\n\\n[2] The Nexus 2.0 zkVM. Retrieved from https://docs.nexus.xyz/\\n\\n[3] The first general purpose zkVM. Retrieved from https://www.risczero.com/zkvm\\n\\n[4] Powdr. Retrieved from https://docs.powdr.org/\\n\\n[5] ZKM Architecture. Retrieved from https://docs.zkm.io/zkm-architecture\\n\\n[6] Valida zkVM Design. Retrieved from https://delendum.xyz/writings/2023-05-10-zkvm-design.html\\n\\n[7] Building Jolt: A fast, easy-to-use zkVM. Retrieved from https://a16zcrypto.com/posts/article/building-jolt/\\n\\n[8] ZK-WASM. Retrieved from https://delphinuslab.com/zk-wasm/\\n\\n[9] Aleo. Retrieved from https://aleo.org/blog/\\n\\n[10] OlaVM Whitepaper V2. Retrieved from https://github.com/Sin7Y/olavm-whitepaper-v2/tree/master\\n\\n[11] Polygon Miden VM. Retrieved from https://0xpolygonmiden.github.io/miden-vm/intro/main.html\\n\\n[12] The Adventures of OS: Making a RISC-V Operating System using Rust. Retrieved from https://osblog.stephenmarz.com/index.html\\n\\n[13] Triton VM. Retrieved from https://triton-vm.org/spec/\\n\\n[14] How does the original Cairo VM work?. Retrieved from https://github.com/lambdaclass/cairo-vm/blob/main/docs/python_vm/README.md\\n\\n[15] Aleo completes security audits of snarkOS & snarkVM. Retrieved from https://aleo.org/post/aleo-completes-security-audits-of-snarkos-and-snarkvm/\\n\\n[16] Lurk zkVM. Retrieved from https://github.com/lurk-lab\\n\\n[17] Piecrust VM. Retrieved from https://docs.rs/piecrust/latest/piecrust/\\n\\n[18] Ceno: Non-uniform, Segment and Parallel Zero-knowledge Virtual Machine. Retrieved from https://eprint.iacr.org/2024/387\\n\\n[19] ZkVM: a new design for fast, confidential smart contracts. Retrieved from https://stellar.org/blog/developers/zkvm-a-new-design-for-fast-confidential-smart-contracts\\n\\n[20] Novanet. Retrieved from https://www.novanet.xyz/blog\\n\\n[21] ZKLLVM. Retrieved from https://github.com/NilFoundation/zkLLVM\\n\\n[22] zkMove 0.2.0 - Achieving Full Bytecode Compatibility with Move. Retrieved from https://www.zkmove.net/2023-06-20-zkMove-0.2.0-Achieving-Full-Bytecode-Compatibility-with-Move/\\n\\n[23] O1VM. Retrieved from https://github.com/o1-labs/proof-systems/tree/master/o1vm"},{"id":"Nescience-state-separation-architecture","metadata":{"permalink":"/rlog/Nescience-state-separation-architecture","source":"@site/rlog/2024-08-23-state-separation.mdx","title":"Nescience: A User-Centric State-Separation Architecture","description":"Nescience: A user-centric state-separation architecture.","date":"2024-08-23T12:00:00.000Z","formattedDate":"August 23, 2024","tags":[],"readingTime":86.535,"hasTruncateMarker":true,"authors":[{"name":"Moudy","github":"moudyellaz","key":"moudy"}],"frontMatter":{"title":"Nescience: A User-Centric State-Separation Architecture","date":"2024-08-23T12:00:00.000Z","authors":"moudy","published":true,"slug":"Nescience-state-separation-architecture","categories":"research","toc_min_heading_level":2,"toc_max_heading_level":5},"prevItem":{"title":"Exploring zkVMs: Which Projects Truly Qualify as Zero-Knowledge Virtual Machines?","permalink":"/rlog/zkVM-explorations"},"nextItem":{"title":"Membership with Bloom Filters and Cuckoo Filters","permalink":"/rlog/membership-with-bloom-filters-and-cuckoo-filters"}},"content":"Nescience: A user-centric state-separation architecture.\\n\\n\x3c!--truncate--\x3e\\n\\n_Disclaimer: This content is a work in progress. Some components may be updated, changed, or expanded as new research findings become available._\\n\\n# A. Introduction\\n\\nIn blockchain applications, privacy settings are typically predefined by developers, leaving users with limited control. This traditional, \\none-size-fits-all approach often leads to inefficiencies and potential privacy concerns as it fails to cater to the diverse needs of individual users. \\nThe Nescience state-separation architecture (NSSA) aims to address these issues by shifting privacy control from developers to users. NSSA introduces a flexible, \\nuser-centric approach that allows for customized privacy settings to better meet individual needs. This blog post will delve into the details of NSSA, \\nincluding its different execution types, cryptographic foundations, and unique challenges.\\n\\n## Introducing NSSA: A user-centric approach\\n\\nNSSA gives users control over their privacy settings by introducing _shielded_ (which creates a layer of privacy for the outputs, and only the necessary details are shared) \\nand _deshielded_ (which reveal private details, making them publicly visible) execution types in addition to the traditional public and private modes. This flexibility allows \\nusers to customize their privacy settings to match their unique needs, whether they require high levels of confidentiality or more transparency. In NSSA, the system is divided \\ninto two states: public and private. The public state uses an account-based model while the private state employs a UTXO-based (unspent transaction output) model. Private executions within NSSA utilize \\nUTXO exchanges, ensuring that transaction details remain confidential. The sequencer verifies these exchanges without accessing specific details, enhancing privacy by unlinking \\nsender and receiver identities. Zero-knowledge proofs (ZKPs) allow users to prove transaction validity without revealing data, maintaining the integrity and confidentiality of \\nprivate transactions. UTXOs contain assets such as balances, NFTs, or private storage data, and are stored in plaintext within Sparse Merkle trees (SMTs) in the private state and \\nas hashes in the public state. This dual-storage approach keeps UTXO details confidential while allowing public verification through hashes, achieving a balance between privacy and transparency.\\n\\n\\nImplementing NSSA introduces unique challenges, particularly in cryptographic implementation and maintaining the integrity of private executions. These challenges are addressed \\nthrough various solutions such as ZKPs, which ensure transaction validity without compromising privacy, and the dual-storage approach, which maintains confidentiality while enabling \\npublic verification. By allowing users to customize their privacy settings, NSSA enhances user experience and promotes wider adoption of private execution platforms. As we move towards \\na future where user-empowered privacy control is crucial, NSSA provides a flexible and user-centric solution that meets the diverse needs of blockchain users.\\n\\n## Why NSSA differs from other hybrid execution platforms\\n\\nIn many existing hybrid execution platforms, privacy settings are predefined by developers, often applying a one-size-fits-all approach that does not accommodate the \\ndiverse privacy needs of users. These platforms blend public and private states, but control over privacy remains with the application developers. \\nWhile this approach is straightforward for developers (who bear the responsibility for any potential privacy leaks), it leaves users with no control over their own privacy settings. \\nThis rigidity becomes problematic as user needs evolve over time, or as new regulations necessitate changes to privacy configurations. In such cases, \\nupdates to decentralized applications are required to adjust privacy settings, which can disrupt the user experience and create friction.\\n\\nNSSA addresses these limitations by introducing a groundbreaking concept: **selective privacy**. Unlike traditional platforms where privacy \\nis static and determined by developers, selective privacy empowers users to dynamically choose their own privacy levels based on their unique needs and sensitivity. \\nThis flexibility is critical in a decentralized ecosystem where the diversity of users and use cases demands a more adaptable privacy solution.\\n\\nIn the NSSA model, users have the autonomy to select how they interact with decentralized applications (dapps) by choosing from four types of transaction executions: **public**, \\n**private**, **shielded**, and **deshielded**. This model allows users to tailor their privacy settings on a per-transaction basis, selecting the most appropriate execution type for each \\nspecific interaction. For instance, a user concerned about data confidentiality might opt for a fully private transaction while another user, wary of privacy but seeking transparency, \\nmight choose a public execution.\\n\\nWhile selective privacy may appear complex, especially for users who are not technically inclined, Nescience mitigates this by allowing the community or developers to \\nestablish best practices and recommended approaches. These guidelines provide users with an informed starting point, and over time, users can adjust their privacy \\nsettings as their preferences and trust in the platform evolve. Importantly, selective privacy gives users the right to alter their privacy level at any point in the future, \\nensuring that their privacy settings remain aligned with their needs as they change.\\n\\nThis approach not only empowers users but also facilitates greater adoption of dapps. Users who are skeptical about privacy concerns can initially engage with transparent \\ntransactions and gradually shift towards more private executions as they gain confidence in the system and vice versa for users who start with privacy but later find transparency \\nbeneficial for certain transactions. In this way, selective privacy bridges the gap between privacy and transparency, allowing for an optimal balance to emerge from the community\u2019s \\ncollective preferences.\\n\\nTo liken this to open-source projects: in traditional systems, developers fix privacy rules much like immutable code\u2014users must comply with these fixed settings. \\nIn contrast, with selective privacy, the rules are malleable and shaped by the users\u2019 preferences, enabling the community to find the ideal balance between privacy and efficiency over time.\\n\\nNSSA is distinct from traditional zero-knowledge (ZK) rollups in several key ways. One of the unique features of NSSA is its **public execution type**, which does not \\nrequire ZKPs or a zero-knowledge virtual machine (zkVM). This provides a significant advantage in terms of scalability and efficiency as users can choose public executions for \\ntransactions that do not require enhanced privacy, avoiding the overhead associated with ZKP generation and verification.\\n\\nMoreover, NSSA introduces two additional execution types\u2014**shielded and deshielded**\u2014which further distinguish it from traditional privacy-preserving rollups. \\nThese execution types allow for more nuanced control over privacy, giving users the ability to shield certain aspects of a transaction while deshielding others. \\nThis flexibility sets NSSA apart as a more adaptable and user-centric platform, catering to a wide range of privacy needs without imposing a one-size-fits-all solution.\\n\\nBy combining selective privacy with a flexible execution model, NSSA offers a more robust and adaptable framework for decentralized applications, \\nensuring that users maintain control over their privacy while benefiting from the security and efficiency of blockchain technology.\\n\\n## How Nescience state-separation architecture can be used\\n\\nNSSA offers a flexible, privacy-preserving add-on that can be applied to existing dapps. \\nOne of the emerging trends in the blockchain space is that each dapp is expected to have its own rollup for efficiency, and it is estimated that Ethereum could see \\nthe deployment of different rollups in the near future. A key question arises: how many of these rollups will incorporate privacy? For dapp developers who want to offer flexible, \\nuser-centric privacy features, NSSA provides a solution through selective privacy.\\n\\n### Use case: Adding privacy to existing dapps\\n\\nConsider a dapp running on a transparent network that offers no inherent privacy to its users. Converting this dapp to a privacy-preserving architecture from scratch would \\nrequire significant effort, restructuring, and a deep understanding of cryptographic frameworks. However, with NSSA, the dapp does not need to undergo extensive changes. \\nInstead, the **Nescience state-separation model** can be deployed as an **add-on**, offering selective privacy as an option for the dapp\u2019s users.\\n\\nThis allows the dapp to retain its existing functionality while providing users with a choice between the traditional, transparent version and a new version with selective privacy features. \\nWith NSSA, the privacy settings are flexible, meaning users can tailor their level of privacy according to their individual needs while the dapp operates on its current infrastructure. \\nThis contrasts sharply with the typical approach, where dapps are either entirely transparent or fully private, with no flexibility for users to select their own privacy preferences.\\n\\n### Key advantage: Decoupling from the host chain\\n\\nA key feature of NSSA is that it operates independently of the privacy characteristics of the host blockchain. Whether the host chain is fully transparent or fully private, \\nthe Nescience state-separation architecture can be deployed on top of it, offering users the ability to choose their own privacy settings. \\nThis decoupling from the host chain\u2019s inherent privacy model is critical as it allows users to benefit from selective privacy even in environments that were not originally designed to offer it.\\n\\nIn **fully private chains**, NSSA allows users to selectively reveal transaction details when compliance with regulations or other requirements is necessary. \\nIn **fully transparent chains**, NSSA allows users to maintain privacy for specific transactions, offering flexibility that would not otherwise be possible.\\n\\n### Conclusion\\n\\nNSSA provides a powerful tool for dapp developers who want to offer **selective privacy** to their users without the need for a complete overhaul of their existing systems. \\nBy deploying NSSA as an add-on, dapps can give users the ability to choose their own privacy settings whether they are operating on \\ntransparent or private blockchains. This flexibility makes NSSA a valuable option for any dapp looking to provide enhanced privacy options while maintaining efficiency and ease of use.\\n\\n# B. Design\\nIn this section, we will delve into the core design components of the Nescience state-separation architecture, covering its key structural elements and the mechanisms \\nthat drive its functionality. We will explore the following topics:\\n\\n1. **Architecture\'s components**: An in-depth look at the foundational building blocks of NSSA, including the public and private states, UTXO structures, zkVM, and smart contracts. \\nThese components work together to facilitate secure, flexible, and scalable transactions within the architecture.\\n\\n2. **General execution overview**: We will outline the overall flow of transaction execution within NSSA, describing how users interact with the system and how the architecture \\nsupports various types of executions\u2014public, private, shielded, and deshielded\u2014while preserving privacy and efficiency.\\n\\n3. **Execution processes and UTXO management**: This section will focus on the lifecycle of UTXOs within the architecture, from their generation to consumption. \\nWe will also cover the processes involved in managing UTXOs, including proof generation, state transitions, and ensuring transaction validity.\\n\\nThese topics will provide a comprehensive understanding of how NSSA enables flexible and secure interactions within dapps.\\n\\n## 1. Architecture\'s components\\n---\\nNSSA introduces an advanced prototype execution framework designed to enhance privacy and security in blockchain applications. \\nThis framework integrates several essential components: the public state, private state, zkVM, various execution types, Nescience users, and smart contracts.\\n\\n### a) Public state\\n---\\nThe public state in the NSSA is a fundamental component designed to hold all publicly accessible information within \\nthe blockchain network. This state is organized as a single Merkle tree structure, a sophisticated data structure that ensures efficient and secure data verification. \\nThe public state includes critical information such as user balances and the public storage data of smart contracts.\\n\\nIn an account-based model, the public state operates by storing each account or smart contract\'s public data as individual leaf nodes within the Merkle tree. \\nWhen transactions occur, they directly modify the state by updating these leaf nodes. This direct modification ensures that the most current state of the network \\nis always reflected accurately.\\n\\nThe Merkle tree structure is essential for maintaining data integrity. Each leaf node contains a hash of a data block, and each non-leaf node contains the \\nhash of its child nodes. This hierarchical arrangement means that any change in the data will result in a change in the corresponding hash, making it easy to detect \\nany tampering. The root hash, or Merkle root, is stored on the blockchain, providing a cryptographic guarantee of the data\'s integrity. This root hash serves as a single, \\nconcise representation of the entire state, enabling quick and reliable verification by any network participant.\\n\\nTransparency is a key feature of the public state. All data stored within this state is openly accessible and verifiable by any participant in the network. \\nThis openness ensures that all transactions and state changes are visible and auditable, fostering trust and accountability. For example, user balances are\\npublicly viewable, which helps ensure transparency and trust in the system. Similarly, public smart contract storage can be accessed and verified by anyone, \\nmaking it suitable for applications that require public scrutiny and auditability, such as public record updates and some financial transactions.\\n\\nThe workflow of managing the public state involves several steps to ensure data integrity and transparency. When a user initiates a transaction involving public data, \\nthe relevant changes are proposed and applied to the public state tree. The transaction details, such as transferring funds between accounts or updating smart contract storage, \\nupdate the corresponding leaf nodes in the Merkle tree. Following this, the hashes of the affected nodes are recalculated up to the root, ensuring that the entire tree \\naccurately reflects the new state of the network. The updated Merkle root is then recorded on the blockchain, allowing all network participants to verify the integrity \\nof the public state. Any discrepancy in the data will result in a mismatched root hash, signaling potential tampering or errors.\\n\\nIn summary, the public state in NSSA leverages the robustness of the Merkle tree structure to provide a secure, transparent, and verifiable environment for publicly \\naccessible information. By operating on an account-based model and maintaining rigorous data integrity checks, the public state ensures that all transactions are \\ntransparent and trustworthy, laying a strong foundation for a reliable blockchain network.\\n\\n\\n### b) Private state\\n---\\nThe private state in the NSSA is a sophisticated system designed to maintain user privacy while ensuring transaction integrity. \\nEach user has their own individual Merkle tree, which holds their private information such as balances and storage data. This structure is distinct from the public state, \\nwhich uses an account-based model. Instead, the private state employs a UTXO-based model. In this model, each transaction output is a discrete \\nunit that can be independently spent in future transactions. This design provides users with granular control over their transaction outputs.\\n\\nA key aspect of maintaining privacy within the private state is the use of ZKPs. ZKPs allow transactions to be validated without revealing any \\nunderlying private data. This means that while the system can verify that a transaction is legitimate, the details of the transaction remain confidential. Only parties \\nwith the appropriate viewing key can access and reconstruct the user\u2019s list of UTXOs, ensuring that sensitive information is protected.\\n\\nThe private state also employs a dual-storage approach to balance privacy and transparency. UTXOs are stored in plaintext within SMTs in the private state, \\nproviding detailed and accessible records for the user. In contrast, the public state only holds hashes of these UTXOs. This method ensures that while the public can verify \\nthe existence and integrity of private transactions through these hashes, they cannot access the specific details.\\n\\nThe workflow for a transaction in the private state begins with the user initiating a transaction involving their private data, such as transferring a private balance or \\nupdating private smart contract storage. The transaction involves spending existing UTXOs, represented as leaves in the Merkle tree, and creating new UTXOs, \\nwhich are then appended to the user\u2019s private list. The zkVM generates a ZKP to validate the transaction without revealing \\nany private data, ensuring the transaction adheres to the system\'s rules.\\n\\nOnce the proof is generated, it is submitted to the sequencer, which verifies the transaction\u2019s validity. Upon successful verification, the nullifier is added to the nullifier set, \\npreventing double spending of the same UTXO. The use of ZKPs and nullifiers ensures that the private state maintains both security and privacy.\\n\\nIn summary, the private state in NSSA is meticulously designed to provide users with control over their private information while ensuring the security and integrity of transactions. \\nBy utilizing a UTXO-based model, individual Merkle trees, ZKPs, and a dual-storage system, NSSA achieves a balance between confidentiality and verifiability, \\nmaking it a robust solution for managing private blockchain transactions.\\n\\n### c) ZkVM (zero-knowledge virtual machine)\\n---\\nThe zkVM is a pivotal component in NSSA, designed to uphold the highest standards \\nof privacy and security in blockchain transactions. Its primary function is to generate and aggregate ZKPs, enabling users to validate the \\ncorrectness of their transactions without disclosing any underlying details. This capability is crucial for maintaining the confidentiality and integrity of sensitive \\ndata within the blockchain network.\\n\\nZKPs are sophisticated cryptographic protocols that allow one party, the prover, to convince another party, the verifier, that a certain statement is true, \\nwithout revealing any information beyond the validity of the statement itself. In the context of the zkVM, this means users can prove their transactions are valid without \\nexposing transaction specifics, such as amounts or parties involved. This process is essential for transactions within the private state, where maintaining confidentiality is paramount.\\n\\nThe generation of ZKPs involves intricate cryptographic computations. When a user initiates a transaction, the zkVM processes the transaction inputs and produces a proof \\nthat the transaction adheres to the protocol\'s rules. This proof must be robust enough to convince the verifier of the transaction\'s validity while preserving the privacy \\nof the transaction details.\\n\\nPerformance optimization is another critical function of the zkVM. In a typical blockchain scenario, verifying multiple individual proofs can be computationally intensive \\nand time consuming, potentially leading to network congestion and delays. To address this, the zkVM can aggregate multiple ZKPs into a single, consolidated proof. \\nThis aggregation significantly reduces the verification overhead as the verifier needs to check only one comprehensive proof rather than multiple individual ones. \\nThis efficiency is vital for maintaining high throughput and low latency in the blockchain network, ensuring that the system can handle a large volume of transactions swiftly and securely.\\n\\nFurthermore, the zkVM\'s role extends beyond mere proof generation and aggregation. It also ensures that all transactions meet the required privacy and security standards \\nbefore they are recorded on the blockchain. By interacting seamlessly with other components such as the public and private states, the zkVM ensures that any transaction, \\nwhether it involves public data, private data, or a mix of both, is thoroughly validated and secured.\\n\\nIn summary, the zkVM is essential for the NSSA, providing the cryptographic backbone necessary to support secure and private transactions. Its ability to generate and \\naggregate ZKPs not only preserves the confidentiality of user data but also enhances the overall efficiency and scalability of the blockchain network. \\nBy ensuring that all transactions are validated without revealing sensitive information, the zkVM upholds the integrity and trustworthiness of the Nescience blockchain system.\\n\\n\\n### d) Execution types in NSSA\\n---\\nNSSA incorporates multiple execution types to cater to varying levels of privacy and security requirements. \\nThese execution types\u2014public, private, shielded, and deshielded\u2014are designed to provide users with flexible options for managing their transactions based on their specific privacy needs.\\n\\n#### 1. Public executions\\n\\nPublic executions are straightforward transactions that involve reading from and writing to the public state. In this model, data is openly accessible and verifiable \\nby all participants in the network. Public executions do not require ZKPs since transparency is the primary goal. This execution type is ideal \\nfor non-sensitive transactions where public visibility is beneficial, such as updating public records, performing open financial transactions, or interacting with public smart contracts.\\n\\nThe workflow for a public execution starts with a user initiating a transaction that modifies public data. The transaction details are then used to update the relevant \\nleaf nodes in the Merkle tree. As changes are made, the hashes of affected nodes are recalculated up to the root, ensuring that the entire tree reflects the most recent state. \\nFinally, the updated Merkle root is recorded on the blockchain, making the new state publicly verifiable.\\n\\n#### 2. Private executions\\n\\nPrivate executions are designed for confidential transactions, reading from and writing to the private state. These transactions require ZKPs to ensure that while the \\ntransaction details are validated, the actual data remains private. This execution type is suitable for scenarios where privacy is crucial, such as private financial \\ntransactions or sensitive data management within smart contracts.\\n\\nIn a private execution, the user initiates a transaction involving private data. The transaction spends existing UTXOs and creates new ones, all of which are represented as \\nleaves in the Merkle tree. The zkVM generates a ZKP to validate the transaction without revealing private data. This proof is submitted to the sequencer, \\nwhich verifies the proof to ensure the transaction\'s validity. Upon successful verification, the nullifier is added to the nullifier set, and the private state is updated \\nwith the new Merkle root.\\n\\n#### 3. Shielded executions\\n\\nShielded executions create a layer of privacy for the outputs by allowing interactions between the public and private states. When a transaction occurs in a shielded execution, \\ndetails of the transaction are processed within the private state, ensuring that sensitive information remains confidential. Only the necessary details are shared with the public state, \\noften in a masked or encrypted form. This approach allows for the validation of the transaction without revealing critical data, thus preserving the privacy of the involved parties.\\n\\nThe workflow for shielded executions begins with the user initiating a transaction that reads from the public state and prepares to write to the private state. Public data is accessed, \\nand the private state is prepared to receive new data. The zkVM generates a ZKP to hide the receiver\u2019s identity. This proof is submitted to the sequencer, which verifies \\nthe proof to ensure the transaction\'s validity. If valid, the private state is updated with the new data while the public state reflects the change without revealing private details. \\nThis type of execution is particularly useful for scenarios where the receiver\u2019s identity needs to be hidden, such as in anonymous donation systems or confidential data storage.\\n\\n#### 4. Deshielded executions\\n\\nDeshielded executions operate in the opposite manner of shielded executions, where data is read from the private state and written to the public state. This execution type is useful \\nin situations where the sender\'s identity needs to be kept confidential while making the transaction results publicly visible.\\n\\nIn a deshielded execution, the user initiates a transaction that reads from the private state and prepares to write to the public state. Private data is accessed, \\nand the transaction details are prepared. The zkVM generates a ZKP to hide the sender\u2019s identity. This proof is then submitted to the sequencer, \\nwhich verifies the proof to ensure the transaction\'s validity. Once verified, the public state is updated with the new data, reflecting the change while keeping the sender\u2019s \\ndetails confidential. This can be useful when transparency is needed, such as when auditing or proving certain aspects of a transaction to a wider audience. \\nBy selectively deshielding certain transactions, users can control what information is shared publicly, thus maintaining a balance between privacy and transparency \\nas required by their specific use case.\\n\\n\\n#### Table of execution types\\n\\n| Type | Read from | Write to | ZKP required | Use case | Description |\\n|------------|--------------|-------------|--------------|------------------------------------------------------------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|\\n| Public | Public state | Public state| No | Non-sensitive transactions requiring transparency. | Ideal for transactions that do not require privacy, ensuring full transparency. |\\n| Private | Private state| Private state| Yes | Confidential transactions needing privacy. | Suitable for transactions that require confidentiality. Ensures that transaction details remain private through the use of ZKPs. |\\n| Shielded | Public state | Private state| Yes | Transactions where the receiver\u2019s identity needs to be hidden. | Hides the identity of the receiver while keeping the transaction details private. Suitable for anonymous donations or confidential data storage. |\\n| Deshielded | Private state| Public state| Yes | Transactions where the sender\u2019s identity needs to be hidden. | Ensures the sender\u2019s identity remains confidential while making the transaction results public. Suitable for confidential disbursements or anonymized data publication. |\\n---\\n\\n\\nBy supporting a range of execution types, NSSA provides a flexible and robust framework for managing privacy and security in blockchain transactions. \\nWhether the need is for complete transparency, total privacy, or a balanced approach, NSSA\'s execution types allow users to select the level of confidentiality \\nthat best fits their requirements. This flexibility enhances the overall utility of the blockchain, making it suitable for a wide array of applications and use cases.\\n\\n### e) Nescience users\\n---\\nNescience users are integral to the architecture, managing balances and assets within the blockchain network and invoking smart contracts with various privacy options. \\nThey can choose the appropriate execution type\u2014public, private, shielded, or deshielded\u2014based on their specific privacy and security needs.\\n\\nUsers handle both public and private balances. Public balances are visible to all network participants and suitable for non-sensitive transactions, \\nwhile private balances are confidential and used for transactions requiring privacy. Digital wallets provide a user-friendly interface for managing \\nthese balances, assets, and transactions, allowing users to select the desired execution type seamlessly.\\n\\nSecurity is ensured through the use of cryptographic keys, which authenticate and verify transactions. ZKPs maintain privacy \\nby validating transaction correctness without revealing underlying data, ensuring sensitive information remains confidential even during verification.\\n\\nThe workflow for users involves initiating a transaction, preparing inputs, interacting with smart contracts, generating proofs if needed, \\nand submitting the transaction to the sequencer for verification and state update. This flexible approach supports various use cases, \\nfrom financial transactions and decentralized applications to data privacy management, allowing users to maintain control over their privacy settings.\\n\\nBy offering this high degree of flexibility and security, Nescience enables users to tailor their privacy settings to their specific needs, \\nensuring sensitive transactions remain confidential while non-sensitive ones are transparent. This integration of cryptographic keys and ZKPs \\nprovides a robust framework for a wide range of blockchain applications, enhancing both utility and trust within the network.\\n\\n\\n### f) Smart contracts in NSSA\\n---\\nSmart contracts are a core feature of NSSA, providing a way to automate and execute predefined actions based on coded rules. \\nOnce deployed on the blockchain, these contracts become immutable, meaning their behavior cannot be altered. This ensures that they perform exactly as \\nintended without the risk of tampering. Because the state and data of the contract are stored permanently on the blockchain, all interactions are fully \\ntransparent and auditable, creating a reliable and trustworthy environment.\\n\\nOne of the key strengths of smart contracts is their ability to automate processes. They are designed to automatically execute when specific conditions are met, \\nreducing the need for manual oversight or intermediaries. For example, a smart contract might transfer funds when a certain deadline is reached or update a record \\nonce a task is completed. This self-executing nature makes them efficient and minimizes human error.\\n\\nSmart contracts operate deterministically, meaning they will always produce the same result given the same inputs. This predictability is crucial for ensuring reliability, \\nespecially in complex systems. Additionally, they run in isolated environments on the blockchain, which enhances security by preventing unintended interactions with other processes.\\n\\nSecurity is another critical feature of smart contracts. They leverage the underlying cryptographic protections of the blockchain, ensuring that every interaction \\nis secure and authenticated. Before deployment, the contract code can be audited and verified to ensure it functions correctly. Once on the blockchain, \\nthe immutable nature of the code prevents unauthorized modifications, further ensuring the integrity of the system.\\n\\nRunning smart contracts requires computational resources, which are compensated through gas fees. These fees vary depending on the complexity of the operations within the contract. \\nMore resource-intensive contracts incur higher fees, which helps manage the computational load on the blockchain network.\\n\\nThe workflow of a smart contract begins with its development, where developers code the contract using languages like Rust. Once the code is compiled and deployed to the blockchain, \\nit becomes a permanent part of the network. Users can then interact with the contract by sending transactions that invoke specific functions. The contract checks whether the \\nrequired conditions are met, and if so, it automatically executes the specified actions, such as transferring tokens or updating data on the blockchain.\\n\\nThe benefits of smart contracts are numerous. They eliminate the need for intermediaries by providing a system where trust is built into the code itself. \\nThis not only reduces costs but also increases efficiency by automating repetitive processes. The inherent security of smart contracts, combined with their \\ntransparency\u2014where every action is recorded and visible on the blockchain\u2014makes them a powerful tool for ensuring accountability and trust in decentralized systems. \\nThey can be ideal for managing decentralized autonomous organizations (DAOs), where governance decisions are automated through coded rules.\\n\\nBy integrating smart contracts, NSSA offers a highly versatile, secure, and transparent framework that can support a wide range of applications \\nacross various industries, from finance to governance, supply chains, and more.\\n\\n## 2. General execution overview\\n---\\nThis section explains the execution process within NSSA, providing an overview of how it works from start to finish. \\nIt outlines the steps involved in each execution type, guiding the reader through the entire process from user interaction to completion.\\n\\nThe process begins when a user initiates a transaction by invoking a smart contract. This invocation involves selecting at least one of \\nthe four execution types: public, private, shielded, or deshielded. The choice of execution type determines how data will be read from and written to the blockchain, \\naffecting the transaction\'s privacy and security levels. Each execution type caters to different privacy needs, allowing the user to tailor the transaction according \\nto their specific requirements, whether it be full transparency or complete confidentiality.\\n\\n![general](/img/general.png)\\n\\n\\n### User actions\\n---\\n**Step 1**: **Smart contract selection and input creation**\\n- **Smart contract selection**: The user selects a smart contract they wish to invoke.\\n- **Input creation**: The user creates a set of inputs required for the invocation by reading the necessary data from both the public and private states. This includes:\\n - Public data such as current account balances, public keys, and smart contract states.\\n - Private data such as private account balances and UTXOs.\\n\\n**Step 2**: **Choosing execution type**\\n- **Execution type selection**: The user selects the type of execution based on their privacy needs. The options include:\\n - **Public execution**: Suitable for transactions where transparency is desired.\\n - **Private execution**: Used when transaction details need to be confidential.\\n - **Shielded execution**: Hides the receiver\'s identity.\\n - **Deshielded execution**: Hides the sender\'s identity.\\n- **ZkVM requirement**: If the execution involves private, shielded, or deshielded types, the user must call the zkVM to handle these confidential transactions. \\nFor purely public executions, the zkVM is not needed, and the user can directly transmit the transaction code to the sequencer.\\n\\n**Step 3**: **Calling zkVM for proof generation**\\n- **ZkVM compilation**: The user calls the zkVM to compile the smart contract with both public and private inputs.\\n - **Kernel circuit proofs**: The zkVM generates individual proofs for each execution type through kernel circuits.\\n - **Proof aggregation**: The zkVM aggregates these individual proofs into a single comprehensive proof, combining both private and public inputs.\\n\\n**Step 4**: **Transmitting public inputs and retaining private inputs**\\n- **Retaining private inputs**: The user keeps the private inputs secure and does not transmit them.\\n- **Revealing public inputs**: The user transmits the following public inputs to the sequencer:\\n - Public inputs of the recursive proof\\n - Hashes of UTXOs\\n - Updates to the public state\\n - Transaction signature\\n - Nullifiers (to prevent double spending)\\n\\nAfter completing these steps, the user\'s part of the execution is done, and the sequencer takes over the process.\\n\\n### Sequencer actions\\n---\\n**Step 5**: **Proof verification**\\n- **Proof and data reception**: The sequencer receives the proof and public inputs from the user.\\n- **Verification process**:\\n - For private, shielded, and deshielded executions, the sequencer verifies the proof using the provided public data.\\n - For public executions, the sequencer reruns the smart contract code with the provided inputs to check the results.\\n- **Validation**: If both the zkVM proofs and public execution results are verified successfully, the sequencer collects the proof and public data to proceed. \\nIf verification fails, the process is aborted, and the transaction is rejected.\\n\\n**Step 6**: **Aggregating proofs and finalizing the block**\\n- **Proof aggregation**: The sequencer calls the zkVM again to aggregate all received proofs into one comprehensive proof to finalize the block.\\n- **Finalizing the block**:\\n - **Public state update**: The sequencer updates the public state with the new transaction data.\\n - **Nullifier tree update**: Updates the nullifier tree to reflect the new state and prevent double spending.\\n - **Synchronization mechanism**: Runs synchronization mechanisms to ensure fairness and consistency across the network.\\n - **UTXO validation**: Validates the exchanged UTXOs to complete the transaction process.\\n\\nThis comprehensive process ensures that transactions are executed securely, with the appropriate level of privacy and state updates synchronized across the network.\\n\\nBelow, we outline the execution process of the four different execution types within NSSA:\\n- **Public execution**:\\n\\n![public](/img/public.png)\\n\\n- **Private execution**:\\n\\n![private](/img/private.png)\\n\\n- **Shielded execution**:\\n\\n![shielded](/img/se.png)\\n\\n- **Deshielded execution**:\\n\\n![deshielded](/img/de.png)\\n\\n\\n## 3. Execution processes and UTXO management\\n---\\nIn Nescience state-separation architecture, UTXOs are key components for managing private data and assets. They serve as private entities that hold both storage and assets, \\nfacilitating secure and confidential transactions. UTXOs are utilized in three of the four execution types within NSSA: private, shielded, \\nand deshielded executions. This section explores the lifecycle of UTXOs, detailing their generation, transfer, encryption, and eventual consumption within the private execution framework.\\n\\n### a) Components of a Nescience UTXO\\n---\\nA Nescience UTXO is a critical and versatile component of the private state in the Nescience state-separation architecture. \\nIt carries essential information that ensures its proper functionality within private execution, such as the owner, value, private storage slot, non-fungibles, \\nand other cryptographic components. Below is a detailed breakdown of each component and its role in maintaining the integrity, security, and privacy of the system:\\n\\n* **Owner:**\\nThe owner component represents the public key of the entity that controls the UTXO. Only the owner can spend this UTXO, ensuring its security and privacy through public key cryptography. \\nThis means that the UTXO remains secure as only the rightful owner, using their private key, can generate valid signatures to authorize the transaction. For example, \\nif Alice owns a UTXO linked to her public key, she must sign any transaction to spend it using her private key. This cryptographic protection ensures that only Alice can authorize \\nspending the UTXO and transfer it to someone else, such as Bob.\\n\\n* **Value:**\\nThe value in a UTXO represents the balance or asset contained within it. This could be cryptocurrency, tokens, or other digital assets. The value ensures accurate accounting, \\npreventing double spending and maintaining the overall integrity of the system. For instance, if Alice\'s UTXO has a value of 10 tokens, this represents her ownership of that amount \\nwithin the network, and when spent, this value will be deducted from her UTXO and transferred accordingly.\\n\\n* **Private storage slot:**\\nThe private storage slot is an arbitrary and flexible storage space within the UTXO for Nescience applications. It allows users and smart contracts to store additional private data \\nthat is only accessible by the owner. This could be used to hold metadata, smart contract states, or user-specific information. For example, if a smart contract is holding private user data, \\nthis information is securely stored in the private storage slot and can only be accessed or modified by the owner, ensuring privacy and security.\\n\\n* **Non-fungibles:**\\nNon-fungibles within the UTXO represent unique assets, such as NFTs (Non-Fungible Tokens). Each non-fungible asset is assigned a unique serial number or identifier within the UTXO, \\nensuring its distinctiveness and traceability. For example, if Alice owns a digital artwork represented as an NFT, the non-fungible component of the UTXO will store the unique identifier \\nfor this NFT, preventing duplication or forgery of the digital asset.\\n\\n* **Random commitment key:**\\nThe random commitment key (RCK) is a randomly generated number used to create a cryptographic commitment to the contents of the UTXO. This commitment ensures the integrity of the data \\nwithout revealing any private information. By generating a random key for the commitment, the system ensures that even if someone observes the commitment, they cannot infer any details \\nabout the underlying UTXO. For example, RCK helps maintain confidentiality in the system while still allowing the verification of transactions.\\n\\n* **Nullifier key:**\\nThe Nullifier key is another randomly generated number, used to ensure that a UTXO is only spent once. When a UTXO is spent, its nullifier key is recorded in a nullifier set to prevent \\ndouble spending. This key guarantees that once a UTXO is spent, it cannot be reused in another transaction, effectively nullifying it from future use. This mechanism is crucial for \\nmaintaining the security and integrity of the system, as it ensures that no UTXO can be spent more than once.\\n\\n\\n### b) UTXO lifecycle: From generation to consumption\\n---\\nUTXOs in NSSA are created when a transaction outputs a specific value, asset, or data intended for future use. Once generated, these UTXOs become private entities \\nowned by specific users, containing sensitive information such as balances, private data, or unique assets like NFTs.\\n\\nTo maintain the required level of confidentiality, UTXOs are encrypted and transferred anonymously across the network. This encryption process ensures that the data within each UTXO \\nremains hidden from network participants, including the sequencer, while still allowing for verification and validation through ZKPs. These proofs enable the network \\nto ensure that UTXOs are valid, prevent double spending, and maintain security, all without revealing any sensitive information.\\n\\nWhen a user wishes to spend or transfer a UTXO, the lifecycle progresses towards its consumption. The user must prove ownership and validity of the UTXO through a ZKP, \\nwhich is then verified by the sequencer. This process occurs in private, shielded, and deshielded executions, where confidentiality is a priority. Once the proof is validated, \\nthe UTXO is consumed, meaning it is marked as spent and cannot be reused, ensuring the integrity of the transaction and preventing double spending. \\n\\nUTXOs are central to the private, shielded, and deshielded execution types in Nescience. In private executions, UTXOs are transferred securely between parties without revealing any \\ndetails to the public state. In shielded executions, UTXOs are used to receive assets from the public state while keeping the recipient\'s identity confidential. Finally, \\nin deshielded executions, UTXOs are used to send assets from the private state to the public state, while preserving the sender\'s anonymity.\\n\\nSince UTXOs are not exchanged in public executions, this lifecycle analysis is focused solely on private, shielded, and deshielded executions, where privacy and confidentiality are essential. \\nIn these contexts, the careful management and transfer of UTXOs ensure that the users\' private data and assets remain secure, while still allowing for seamless and confidential transactions \\nwithin the network.\\n\\nAt this point, it\'s crucial to introduce two key components that will play a significant role in the next section: the ephemeral key and the nillifier.\\n\\n* **Ephemeral key:** The ephemeral key is embedded in the transaction message and plays a crucial role in maintaining privacy. It is used by the sender, alongside the receiver\'s public key, \\nin a key agreement protocol to derive a shared secret. This shared secret is then employed to encrypt the transaction details, ensuring that only those with the receiver\'s viewing key can \\ndecrypt the transaction. By using the ephemeral key, the receiver can regenerate the shared secret, granting access to the transaction\'s contents. The sender generates the ephemeral key \\nusing their spending key and the UTXO\'s nullifier, reinforcing the security of the transaction. (more details in [key management and addresses section](#key))\\n\\n* **Nullifier:** A nullifier is a unique value tied to a specific UTXO, ensuring that it has not been spent before. Its uniqueness is essential, as a nullifier must never correspond to more \\nthan one UTXO\u2014otherwise, even if both UTXOs are valid, only one could be spent. This would undermine the integrity of the system. To spend a UTXO, a proof must be provided showing that \\nthe nullifier does not already exist in the Nullifier Tree. Once the transaction is confirmed and included in the blockchain, the nullifier is added to the Nullifier Tree, preventing any \\nfuture reuse of the same UTXO. A UTXO\'s nullifier is generated by combining the receiver\'s nullifier key with the transaction note\'s commitment, further ensuring its distinctiveness \\nand security. (More details in [nullifier tree section](#nul).)\\n\\n#### I) UTXOs in private executions\\n---\\nIn private executions within NSSA, transactions are handled ensuring maximum privacy by concealing all transaction details from the public state. \\nThis approach is particularly useful for confidential payments, where the identities of the sender and receiver, as well as the transaction amounts, must remain hidden. \\nThe process is powered by ZKPs, ensuring that only the involved parties have access to the transaction details while maintaining the integrity of the network.\\n\\n* **Stages of private execution**: Private executions operate in two key stages: UTXO consumption and UTXO creation. In the first stage, UTXOs from the private state are used \\nas inputs for the transaction. In the second stage, new UTXOs are generated as outputs and stored back in the private state. Throughout this process, the details of the \\ntransaction are kept confidential and only shared between the sender and receiver.\\n\\n* **Private transaction workflow (transaction initialization)**: The user initiates a private transaction by selecting the input UTXOs that will be spent and determining the \\noutput UTXOs to be created. This involves specifying the amounts to be transferred and the recipient\u2019s private address (a divestified address that hides the recipient\'s public \\naddress from the network). The nullifier key and random number for commitments (RCK) are also generated at this stage to define how these UTXOs can be spent or nullified in the \\nfuture by the receiver.\\n\\n* **Proof generation and verification**: Next, the zkVM generates a ZKP to validate the transaction. This proof includes both a membership proof for the input UTXOs, \\nconfirming their presence in the hashed UTXO tree, and a non-membership proof to ensure that the input UTXOs have not already been spent (i.e., they are not in the nullifier tree). \\nThe proof also confirms that the total input value matches the total output value, ensuring no discrepancies. The user then submits the proof, along with the necessary metadata, to the sequencer.\\n\\n* **Shared secret and encryption**: To maintain confidentiality, the sender uses the receiver\u2019s divestified address to generate an ephemeral public key. \\nThis allows the creation of a shared secret between the sender and receiver. Using a key derivation function, a symmetric encryption key is generated from the shared secret. \\nThe input and output UTXOs are then encrypted using this symmetric key, ensuring that only the intended recipient can decrypt the data.\\n\\n* **Broadcasting the transaction**: The user broadcasts the encrypted UTXOs to the network, along with a commitment to the output UTXOs using Pedersen hashes. \\nThese committed UTXOs are sent to the sequencer, which updates the hashed UTXO tree without knowing the transaction details.\\n\\n* **Decryption by the receiver**: After the broadcast, the receiver attempts to decrypt the broadcast UTXOs using their symmetric key, derived from the ephemeral public key. \\nIf the receiver successfully decrypts a UTXO, it confirms ownership of that UTXO. The receiver then computes the nullifier for the UTXO and verifies its presence in the hashed \\nUTXO tree and its absence from the nullifier tree, ensuring it has not been spent. Finally, the new UTXO is added to the receiver\u2019s locally stored UTXO tree for future transactions.\\n\\nThroughout the private execution process, the identities of both the sender and receiver, as well as all transaction details, remain hidden from the public. \\nThe use of ZKPs ensures that the integrity of the transaction is verified without revealing any sensitive information. At the end of the process, \\nthe network guarantees that no participant, aside from the sender and receiver, can deduce any details about the transaction or the involved parties.\\n\\n#### II) UTXOs in shielded executions\\n---\\nIn shielded executions, the interaction between public and private states provides a hybrid privacy model that balances transparency and confidentiality. \\nThis model is suitable for scenarios where the initial step, such as a public transaction, requires visibility, while subsequent actions, such as private asset management, \\nneed to remain confidential. One common use case is asset conversion\u2014where a public token is converted into a private token. The conversion is visible on the public ledger, \\nbut subsequent transactions remain private.\\n\\n##### a) How shielded executions work\\nShielded executions operate in two distinct stages: first, there is a modification of the public state, and then new UTXOs are created and stored in the private state. \\nImportantly, shielded executions do not consume UTXOs but instead mint them, as new UTXOs are created to reflect the changes in the private state. This structure demands \\nZKPs to ensure that the newly minted UTXOs are consistent with the modifications in the public state. Here\u2019s a step-by-step breakdown of how the shielded \\nexecution process unfolds:\\n\\n1. **Transaction initiation:** The user initiates a transaction that modifies the public state, such as converting a public token to a private token.\\n The transaction alters the public state (e.g., balances or smart contract storage) while simultaneously preparing to mint new UTXOs in the private state.\\n\\n2. **Generating UTXOs:** After modifying the public state, the system mints new UTXOs in the private state. These UTXOs must be securely created, ensuring their integrity \\nand consistency with the initial public state modification. A ZKP is generated by the user to prove that these new UTXOs align with the changes made in the public state.\\n\\n3. **Key setup for privacy**: The sender retrieves the receiver\'s address and uses it to create a shared secret through an ephemeral public key. This shared secret is then used \\nto derive a symmetric key, which encrypts the output UTXOs. This encryption ensures that only the intended receiver can decrypt and access the UTXOs.\\n\\n4. **Broadcasting and verifying UTXOs**: After encrypting the UTXOs, the sender broadcasts them to the network. The new hashed UTXOs are sent to the sequencer, \\nwhich verifies the validity of the UTXOs and attaches them to the hashed UTXO tree within the private state. The public inputs for the ZKP circuits consist of the \\nPedersen-hashed UTXOs and the modifications in the public state.\\n\\n5. **Receiver\'s role**: Once the UTXOs are broadcast, the receiver attempts to decrypt each UTXO using the symmetric key derived from the shared secret. If the decryption is successful, \\nthe UTXO belongs to the receiver. The receiver then verifies the UTXO\u2019s validity by checking its inclusion in the hashed UTXO tree and ensuring that its nullifier has not yet been used.\\n\\n6. **Nullifier check and integration**: To prevent double spending, the receiver computes the nullifier for the received UTXO and verifies that it is not already present in the nullifier tree. \\nOnce verified, the receiver adds the UTXO to their locally stored UTXO tree for future use in private transactions.\\n\\n\\nWhile shielded executions offer privacy, certain information is still exposed to the public state, such as the sender\'s identity. To further enhance privacy, \\nthe sender can create empty UTXOs\u2014UTXOs that don\u2019t belong to anyone but are included in the transaction to obfuscate the true details of the transaction. \\nThough this approach increases the size of the data, it adds a layer of privacy by complicating the identification of meaningful transactions.\\n\\n##### b) Summary of shielded execution flow\\n* **Stage 1 (public modification):** The user modifies public state data, such as converting tokens from public to private. This stage is visible to the public.\\n* **Stage 2 (UTXO minting and privacy):** New UTXOs are minted in the private state, encrypted, and broadcast to the network. The transaction remains private from this point forward, \\nsecured by ZKPs and cryptographic keys.\\n* **Receiver\u2019s role:** The receiver decrypts the UTXOs and verifies their validity, ensuring the UTXOs are not double spent and are ready for future transactions.\\n\\nIn summary, shielded executions enable a hybrid privacy model in Nescience, balancing public transparency and private confidentiality. They are well-suited for \\ntransactions requiring initial public visibility, such as asset conversions, while ensuring that subsequent actions remain secure and private within the network.\\n\\n#### III) UTXOs in deshielded executions\\n---\\nIn NSSA, deshielded executions offer a unique way to move data and assets from the private state to the public state, revealing previously private \\ninformation in a controlled and verifiable manner. This type of execution allows for selective disclosure, ensuring transparency when needed while still maintaining \\nthe security and privacy of critical details through cryptographic techniques like ZKPs. Deshielded executions are particularly valuable for use cases \\nsuch as regulatory compliance reporting, where specific transaction details must be revealed to meet legal requirements, while other sensitive transactions remain private.\\n\\n##### a) Stages of deshielded executions\\n\\n* **Stage 1 (UTXO consumption):** The process begins in the private state, where UTXOs are consumed as inputs for the transaction. This involves gathering all necessary \\nUTXOs that contain the assets or balances to be made public, as well as any associated private data stored in memory slots.\\n\\n* **Stage 2 (public state modification):** After the UTXOs are consumed, the transaction details are made public by modifying the public state. This update includes changes \\nto the public balances, storage data, and any necessary public records. While the public state is updated, the sender\u2019s identity and other sensitive information remain hidden, \\nthanks to the privacy-preserving properties of ZKPs.\\n\\nThis model ensures that private data can be selectively revealed when needed, offering both flexibility and transparency. It is particularly useful for scenarios requiring \\nauditing or compliance reporting, where specific details must be made publicly verifiable without exposing the entire history or contents of private transactions.\\n\\n##### b) How deshielded executions work\\nThe deshielded execution process starts when a user initiates a transaction using private UTXOs. The Nescience zkVM is called to generate a ZKP, \\nwhich validates the transaction without revealing sensitive details such as the sender\'s identity or the specifics of the Nescience application being executed.\\n\\nDuring the transaction, the UTXOs from the private state are consumed, meaning they are used up as inputs and will no longer be available for future transactions. \\nInstead of generating new UTXOs, the transaction modifies the public state, updating the necessary balances or memory slots related to the transaction. \\nHere\u2019s a step-by-step breakdown of how the deshielded execution process unfolds:\\n\\n1. **Get receiver\'s public address:** The sender first identifies the public address of the receiver, to which the information or assets will be made public.\\n\\n2. **Determine input UTXOs and public state modifications:** The sender gathers all the input UTXOs needed for the transaction and determines the public state modifications \\nnecessary for the Nescience applications and token transfers involved.\\n\\n3. **Calculate nullifiers:** Nullifiers are generated for each input UTXO, ensuring that these UTXOs cannot be reused or double spent. The nullifiers are derived from the\\n corresponding UTXO commitments.\\n\\n4. **Call zkVM with deshielded circuits:** The sender invokes the zkVM with deshielded kernel circuits, which generates the proof. The proof ensures that all input UTXOs \\nare valid by verifying their membership in the UTXO tree and their non-membership in the nullifier tree, ensuring they haven\u2019t been spent.\\n\\n5. **Generate and submit proof:** The zkVM generates a ZKP that verifies the correctness of the transaction without revealing private details. \\nThe proof includes the nullifiers and the planned modifications to the public state.\\n\\n6. **Send proof to sequencer:** The sender then sends the proof and any relevant public information to the sequencer. The sequencer is responsible for verifying the proof, \\nupdating the public state accordingly, and adding the nullifiers to the nullifier tree.\\n\\nOnce the proof and public information have been broadcast to the network, the receiver does not need to take any further action. \\nThe sequencer manages the public state updates and ensures that the transaction is properly executed. By the end of the deshielded execution, \\nspecific transaction details become publicly visible, such as the identity of the receiver and the outcome of the transaction. \\nThis allows participants in the public state to extract information about the transaction, including the receiver\'s identity and some details about the execution. \\nWhile the receiver\'s identity is revealed, the sender\'s identity and sensitive transaction details remain hidden, thanks to the use of ZKPs. \\nThis makes deshielded executions ideal for cases where transparency is needed, but complete privacy is still a priority for certain elements of the transaction.\\n\\n### Summary of UTXO consumption in NSSA\\n---\\nIn NSSA, consuming UTXOs is a critical step in maintaining the security and integrity of the blockchain by preventing double spending. \\nWhen a UTXO is consumed, it is used as an input in a transaction, effectively marking it as spent. This ensures that the UTXO cannot be reused, preserving the integrity of the blockchain.\\n\\n1. **The process of consuming UTXOs:** The process of consuming a UTXO begins when a user selects a UTXO from their private state. The user verifies the UTXO\u2019s existence and \\nownership using their viewing key, ensuring that they are the legitimate owner of the UTXO. Once verified, the user generates two key cryptographic proofs:\\n * **Membership proof:** This proof confirms that the UTXO exists within the hashed UTXO tree, ensuring its validity within the system.\\n * **Non-membership proof:** This proof ensures that the UTXO has not been previously consumed by checking its absence in the nullifier tree, which tracks spent UTXOs.\\n\\nTo mark the UTXO as spent, a **nullifier** is generated. This nullifier is a unique cryptographic hash derived from the UTXO, which is then added to the nullifier tree in the public state. \\nAdding the nullifier to the tree prevents the UTXO from being reused in future transactions, thus preventing double spending.\\n\\nAfter generating the membership and non-membership proofs, the user compiles the transaction using the zkVM. The zkVM is responsible for generating the necessary ZKPs,\\n which validate the transaction without revealing sensitive details. The compiled transaction, along with the proofs, is then submitted to the sequencer for verification.\\n\\n2. **The role of the sequencer:** Once the transaction is submitted, the sequencer verifies the ZKPs to confirm that the transaction is valid. If the proofs are verified \\nsuccessfully, the sequencer updates both the private and public states to reflect the transaction. This includes updating the nullifier tree with the newly generated nullifier, \\nensuring that the UTXO is marked as spent and cannot be reused.\\n\\n#### Example: Alice sending tokens to Bob\\n---\\nConsider an example where Alice wants to send 5 Nescience tokens to Bob using a private execution. Alice selects a UTXO from her private state that contains 5 Nescience tokens. \\nShe generates the necessary membership and non-membership proofs, ensuring that her UTXO exists in the system and has not been previously spent. Alice then creates a nullifier by \\nhashing the UTXO and compiles the transaction with the zkVM.\\n\\nOnce Alice submits the transaction, the sequencer verifies the proofs and updates the blockchain by adding the nullifier to the nullifier tree and recording the transaction details. \\nThis ensures that Alice\u2019s UTXO is marked as spent and cannot be used again, while Bob receives the 5 tokens.\\n\\n#### The importance of nullifiers\\n---\\nNullifiers are a key mechanism in preventing double spending. By marking consumed UTXOs as spent and tracking them in the nullifier tree, NSSA ensures that \\nonce a UTXO is used in a transaction, it cannot be reused in any future transactions. This process is fundamental to maintaining the integrity and security of the blockchain, \\nas it guarantees that assets are only spent once and prevents potential attacks on the system.\\n\\nIn conclusion, the process of consuming UTXOs in NSSA combines cryptographic proofs, nullifiers, and ZKPs to ensure that transactions \\nare secure, confidential, and free from the risks of double spending.\\n\\n\\n# C. Cryptographic primitives in NSSA\\n\\nIn the NSSA, cryptographic primitives are the foundational elements that ensure the security, privacy, and efficiency of the state separation model.\\n These cryptographic tools enable private transactions, secure data management, and robust verification processes across both public and private states. \\n The architecture leverages a wide range of cryptographic mechanisms, including advanced hash functions, key management systems, tree structures, and ZKPs, \\n to safeguard user data and maintain the integrity of transactions.\\n\\nCryptographic hash functions play a pivotal role in concealing UTXO details, generating nullifiers, and constructing sparse Merkle trees, which organize and verify \\ndata efficiently within the network. Key management and address generation further enhance the security of user assets and identity, ensuring that only authorized \\nusers can access and control their holdings.\\n\\nThe architecture also relies on specialized tree structures for organizing data, verifying the existence of UTXOs, and tracking nullifiers, which prevent double spending. \\nAdditionally, Nescience features a privacy-preserving zero-knowledge virtual machine (zk-zkVM), which allows users to prove the correctness of an execution without \\ndisclosing sensitive information. This enables private transactions and maintains confidentiality across the network.\\n\\nAs Nescience evolves, optional cryptographic mechanisms such as multi-party computation (MPC) may be integrated to enhance synchronization across privacy levels. \\nThis MPC-based synchronization mechanism is still under development and under review for potential inclusion in the system. Together, these cryptographic primitives \\nform the backbone of Nescience\u2019s security architecture, ensuring that users can transact and interact privately, securely, and efficiently.\\n\\nIn the following sections, we will explore each of these cryptographic components in detail, beginning with the role of hash functions.\\n\\n## a) Hash functions in Nescience\\n---\\nHash functions are a foundational element of Nescience\u2019s cryptographic framework, serving multiple critical roles that ensure the security, privacy, and efficiency of the system. \\nOne of the primary uses of hash functions in Nescience is to conceal sensitive details of UTXOs by converting them into fixed-size hashes. This process allows UTXO details \\nto remain private, ensuring that sensitive information is not directly exposed on the blockchain, while still enabling their existence and integrity to be verified. Hashing \\nthe UTXO details allows the actual data to remain confidential, with the hashes stored in a global tree structure for efficient management and retrieval.\\n\\nAdditionally, hash functions are essential for generating **nullifiers**, which play a crucial role in preventing double spending. Nullifiers are created by hashing UTXOs \\nand are used to mark them as spent, ensuring that they cannot be reused in subsequent transactions. These nullifiers are stored in a nullifier tree, and each transaction \\nmust prove that its UTXO\u2019s nullifier is not already present in the tree before it can be processed. This ensures that the UTXO has not been spent before, maintaining the \\nintegrity of the transaction process.\\n\\nHash functions are also vital in the construction of **sparse Merkle trees**, which provide an efficient and secure method for verifying data within the blockchain. \\nSparse Merkle trees enable quick and reliable proofs of membership and non-membership, making them essential for verifying both UTXOs and nullifiers. By using hash functions \\nto build these trees, Nescience can ensure the integrity of the data, as any tampering with the data would result in a change in the hash, making the manipulation detectable.\\n\\nAnother critical consideration in Nescience is the compatibility of hash functions with **ZKPs**. ZK-friendly hash functions are optimized for efficient \\ncomputation within the constraints of ZK circuits, ensuring that they do not become a bottleneck in the proof generation or verification process. These hash functions \\nmaintain strong cryptographic security properties while enabling efficient computations in ZKP systems, which is essential for maintaining privacy and \\nintegrity within the ZK framework.\\n\\nThe primary advantage of using hash functions in Nescience is their ability to ensure that transaction details remain private while still allowing for verification \\nof their validity. Furthermore, by integrating hash functions into Merkle trees, the blockchain data becomes tamper-proof, enabling quick and efficient verification \\nprocesses that uphold the system\u2019s security and privacy standards.\\n\\n### Use case: How to use the Pedersen hash to create the UTXO commitment\\n---\\nAs mentioned in the [UTXOs in private exections section](#pe), the user broadcasts the encrypted UTXOs to the network, along with a commitment to the output UTXOs \\nusing **Pedersen hashes**. The Pedersen hash is used to create the UTXO commitment. The Pedersen hash is a homomorphic commitment scheme that allows secure commitments\\nwhile maintaining privacy and enabling proofs of correctness in transactions. The commitment formula is as follows:\\n\\n$$Commitment = C(UTXO,RCK) =g^{UTXO}\u22c5h^{RCK}$$\\n\\n\\nIn this formula, $g$ and $h$ are two generators of a cryptographic group where no known relationship exists between them. This ensures that the commitment is secure \\nand computationally infeasible to reverse or manipulate without knowing the original UTXO components. The random number $RCK$ adds an additional layer of security \\nby blinding the UTXO\'s contents, ensuring that the commitment doesn\'t leak any information about the underlying data.\\n\\n**Importance of homomorphic commitments**\\n\\nIt is essential to use a homomorphic commitment like the Pedersen commitment for UTXOs because it allows for the verification of important properties in transactions, \\nsuch as ensuring that the total input value of a transaction equals the total output value. This balance is crucial for preventing the unauthorized creation of funds or d\\ndiscrepancies in transactions. A homomorphic commitment enables these proofs because of its additive properties. Specifically, the exponents in the commitment formula are additive, \\nmeaning that commitments can be combined and verified without revealing the individual components. For instance, if you have two UTXOs with commitments $C(UTXO_1,RCK_1)$ \\nand $C(UTXO_2,RCK_2)$, you can combine them and verify that the resulting commitment is valid without exposing the actual amounts.\\n\\nThis capability is leveraged through a modified version of the Schnorr protocol, which is used in conjunction with the Pedersen hash to verify the correctness of transactions. \\nThe Schnorr protocol allows users to prove, without revealing the actual values, that the sum of inputs equals the sum of outputs, ensuring that no funds are created or lost in the transaction.\\n\\n**Limitations of standard cryptographic hashes**\\n\\nStandard cryptographic hash functions, such as SHA-256, are not suitable for this purpose because they lack the algebraic structure needed for homomorphic properties. \\nIn particular, while SHA-256 provides strong security for general hashing purposes, it does not allow the additive properties that are required to perform the type of \\nZKPs used in Nescience for UTXO commitments. This is why the Pedersen hash is preferred, as it enables the secure and private execution of transactions\\nwhile allowing for balance verification and other critical proofs.\\n\\n**Conclusion**\\n\\nBy using homomorphic commitments like the Pedersen hash, NSSA ensures that UTXOs can be securely committed and validated without exposing sensitive information. \\nThe random component (RCK) adds an additional layer of security, and the additive properties of the Pedersen commitment enable powerful ZKPs that maintain the \\nintegrity of the system.\\n\\n\\n## b) Key management and addresses in Nescience\\n---\\nNSSA utilizes different cryptographic schemes, such as public key encryption and digital signatures, to ensure secure private executions through \\nthe exchange of UTXOs. These schemes rely on a structured set of cryptographic keys, each serving a specific purpose in maintaining privacy, security, and control over assets. \\nHere\'s a breakdown of the keys used in Nescience:\\n\\n### I. Spending key\\nThe spending key is the fundamental secret key in NSSA, acting as the primary control mechanism for a user\u2019s UTXOs and other digital assets. \\nIt plays a critical role in the cryptographic security of the system, ensuring that only the rightful owner can authorize and spend their assets.\\n\\n- **Role of the spending key**: The spending key is responsible for generating the user\u2019s private keys, which are used in various cryptographic operations such as \\nsigning transactions and creating commitments. This hierarchical relationship means that the spending key sits at the root of a user\u2019s key structure, safeguarding \\naccess to all associated private keys and, consequently, to the user\u2019s assets. In Nescience\u2019s privacy-focused model, the spending key is never exposed or shared outside \\nthe user\u2019s control. Unlike other keys, it does not interact with the public state, kernel circuits, or even the ZKP system. This isolation ensures that \\nthe spending key remains completely private and inaccessible to external entities. By keeping the spending key separate from the operational aspects of the network, \\nNescience minimizes the risk of key leakage or compromise.\\n\\n- **Generation and security of the spending key**: The spending key is generated randomly from the scalar field, a large mathematical space that ensures uniqueness \\nand cryptographic strength. This randomness is crucial because it prevents attackers from predicting or replicating the key, thereby safeguarding the user\u2019s assets \\nfrom unauthorized access: it is computationally infeasible for an attacker to guess or brute-force the key. Once the spending key is generated, it is securely stored \\nby the user, typically in a hardware wallet or another secure storage mechanism that prevents unauthorized access.\\n\\n- **Spending UTXOs with the spending key**: The spending key\u2019s primary function is to authorize the spending of UTXOs in private transactions. When a user initiates \\na transaction, the spending key is used to generate the necessary cryptographic proofs and signatures, ensuring that the transaction is valid and originates from \\nthe rightful owner. However, even though the spending key generates these proofs, it is never directly exposed during the transaction process. Instead, derived \\nprivate keys handle the operational aspects while the spending key remains secure in the background. For example, when Alice decides to spend a UTXO in a \\nprivate execution, her spending key generates the required private keys that will sign the transaction and ensure its validity. However, the spending key itself \\nnever appears in any public state or transaction data, preserving its confidentiality.\\n\\n- **Ensuring security through isolation**: One of the key security principles of the spending key is its isolation from the network. Since it never interacts with \\npublic-facing elements, such as the public state or kernel circuits, the risk of exposure is significantly reduced. This isolation ensures that even if other parts \\nof the cryptographic infrastructure are compromised, the spending key remains protected, preventing unauthorized spending of UTXOs.\\n\\nIn summary, the spending key in Nescience is a powerful and carefully guarded element of the cryptographic system. It is the root key from which other private keys\\nare derived, allowing users to spend their UTXOs securely and privately. Its isolation from the public state and its random generation from a secure scalar field ensures \\nthat the spending key remains protected, making it a cornerstone of security in NSSA.\\n\\n### II. Private keys\\nIn Nescience, the private key is an essential cryptographic element responsible for facilitating various secure operations, such as generating commitments and signing \\ntransactions. While the spending key plays a foundational role in safeguarding access to UTXOs and assets, the private keys handle the operational aspects of transactions \\nand cryptographic proofs. The private key consists of three critical components: ${private}_{key}.rsd$, ${private}_{key}.rcm$, and ${private}_{key}.sig$, each serving a \\ndistinct purpose within the Nescience cryptographic framework.\\n\\n1. **${private}_{key}.rsd$ (random seed)**: The random seed (${private}_{key}.rsd$) is the first and foundational component of the private key. It is a value randomly chosen from the scalar field, which ensures \\nits cryptographic security and unpredictability. This seed is generated using a random number generator, making it virtually impossible to predict or replicate. \\nThe random seed is essential because it is used to derive the other two components of the private key. By leveraging a secure random seed, Nescience ensures that \\nthe entire private key structure is rooted in randomness, preventing external entities from guessing or deriving the key through brute-force attacks. \\nThe strength of the random seed ensures the overall security of the private key and, consequently, the integrity of the user\'s transactions and commitments.\\n\\n2. **${private}_{key}.rcm$ (random commitment)**: The random commitment component (${private}_{key}.rcm$) is a crucial part of the private key used specifically in the commitment scheme. It acts as a blinding factor, \\nadding a layer of security to commitments made by the user. The ${private}_{key}.rcm$ value is also drawn from the scalar field and is used to ensure that the commitment \\nto any UTXO or other sensitive data remains confidential. The commitment scheme in Nescience requires the use of ${private}_{key}.rcm$ to create cryptographic commitments \\nthat bind the user to specific data (such as UTXO details) without revealing the actual data. The role of ${private}_{key}.rcm$ is to ensure that these commitments are \\nnon-malleable and secure, preventing anyone from modifying the committed data without detection. For instance, when Alice commits to a UTXO, ${private}_{key}.rcm$ is used \\nto generate a Pedersen commitment that ensures the UTXO details are hidden but can still be verified cryptographically. This means that even though the actual UTXO details \\nare concealed, their existence and integrity can be proven.\\n\\n3. **${private}_{key}.sig$ (signing key for transactions)**: The signing key (${private}_{key}.sig$) is the third and final component of the private key, used primarily for signing transactions. One possible approach is that \\nNescience employs Schnorr signatures, a cryptographic protocol known for its efficiency and security. In this case, the ${private}_{key}.sig$ component would generate \\nSchnorr signatures that are used to authenticate transactions, ensuring that only the rightful owner of the private key can authorize the spending of UTXOs. Schnorr \\nsignatures are important as they provide a secure and non-repudiable method of verifying that a transaction was initiated by the legitimate owner of the assets. \\nWhen Alice signs a transaction using her ${private}_{key}.sig$, the corresponding public key allows others to verify that the transaction was indeed signed by Alice, \\nwithout revealing her private key. This verification process ensures that all transactions are legitimate and prevents unauthorized entities from forging transactions \\nor spending assets they do not control. Even if an attacker gains access to the signed transaction, they cannot reverse engineer the ${private}_{key}.sig$, ensuring \\nthe security of Alice\'s future transactions.\\n\\n**Robustness of private keys in Nescience**\\n\\nDespite the critical role of the private key in the operation of NSSA, the system is designed to maintain security even in the event that the \\nprivate key is compromised. This resilience is achieved through the integrity of the spending key, which is never exposed in the process of signing or committing. \\nThe spending key acts as the ultimate safeguard, ensuring that even if a private key component is compromised, the attacker cannot access or spend the user\'s assets \\nwithout control over the spending key.\\n\\nThe architecture\u2019s design, where private keys handle operational tasks but rely on the spending key for ultimate control, ensures a layered approach to security. \\nThis way, the system can mitigate the damage of a compromised private key by maintaining the inviolability of the user\'s assets.\\n\\n**Conclusion**\\n\\nIn summary, the private key in Nescience consists of three interrelated components that together ensure secure transaction signing, commitment creation, and the \\nprotection of user data. The ${private}_{key}.rsd$ serves as the root from which the other key components are derived, ensuring randomness and security. \\nThe ${private}_{key}.rcm$ plays a crucial role in generating commitments, while ${private}_{key}.sig$ provides the signing capability needed for transaction authentication. \\nTogether, these components enable users to engage in private, secure transactions while preserving the integrity of their assets, even in the face of potential key compromise.\\n\\n### III. Public keys\\nPublic keys in Nescience serve as the user\'s interface with the network, allowing for secure interaction and verification without exposing the user\'s private keys. \\nDerived directly from the user\'s private keys, public keys play a crucial role in enabling cryptographic operations such as transaction verification, commitment schemes, \\nand deterministic computations. The public key components correspond to their private key counterparts and ensure that transactions and commitments are securely processed \\nand validated across the network.\\n\\n1. **${public}_{key}.sig$ (verifying Schnorr signatures)**:\\n\\nThe ${public}_{key}.sig$ is derived from the signing component of the private key (${private}_{key}.sig$) and is used for verifying **Schnorr signatures**. \\nSchnorr signatures are used to authenticate transactions, ensuring that they have been signed by the legitimate owner of the private key. This public key is \\nessentially a verification key, allowing others in the network to confirm that a specific transaction was indeed authorized by the user. When a transaction is \\nbroadcast to the network, ${public}_{key}.sig$ enables any participant to verify that the transaction\u2019s signature matches the user\u2019s private key without \\nneeding access to the private key itself. This mechanism prevents forgeries as only the legitimate owner with access to the private key can generate a valid Schnorr signature.\\nFor example, if Alice sends a transaction, she signs it with her private key (${private}_{key}.sig$). Bob, or any other network participant, can use Alice\u2019s ${public}_{key}.sig$ \\nto verify the signature. If the signature is valid, Bob can be confident that the transaction was authorized by Alice and not by an imposter.\\n\\n2. **${public}_{key}.rcm$ (commitment schemes)**\\n\\nThe ${public}_{key}.rcm$ is derived from the commitment component of the private key (${private}_{key}.rcm$). It is used in the **commitment schemes** \\nthat underpin Nescience\u2019s privacy-preserving architecture. Commitments are a crucial cryptographic technique that allows users to commit to a piece of data (such as a UTXO)\\n without revealing the actual data, while still enabling proof of its integrity and existence. In Nescience, the ${public}_{key}.rcm$ is used as part of the Pedersen commitment scheme, \\n where it functions as a public commitment to certain transaction details. Even though the actual values are hidden (thanks to the private key component), the commitment can \\n still be verified by other network participants using ${public}_{key}.rcm$. This enables secure and private transactions while maintaining the ability to verify that commitments \\n are consistent with the original data. For instance, when Alice commits to a UTXO, she uses her private key to generate the commitment, and the ${public}_{key}.rcm$ is available \\n to others to verify the commitment\u2019s validity without revealing the underlying details.\\n\\n3. **${public}_{key}.sk(prf)$ (pseudorandom function)**\\n\\nThe ${public}_{key}.sk(prf)$ is derived from a random field element within the private key and is used to generate the **pseudorandom function (PRF)** associated with the user\'s account. \\nThis PRF is essential for producing deterministic outputs based on the user\u2019s keys and transaction data while ensuring that these outputs are unique to the user and cannot be \\npredicted or replicated by others. The PRF is crucial in scenarios where the user needs to derive unique identifiers or values that are tied to their specific account, \\nensuring that these values remain consistent across different transactions or interactions without revealing sensitive information. For example, ${public}_{key}.sk(prf)$ may be \\nused in generating deterministic yet secure addresses or transaction references, which can be linked to the user\u2019s activity in a controlled manner. By using ${public}_{key}.sk(prf)$, \\nNescience ensures that certain operations, like generating addresses or computing deterministic transaction outcomes, remain both private and cryptographically secure. The public key\u2019s \\nrole in this process is to maintain consistency in these outputs while preventing unauthorized parties from reverse engineering the associated private keys or transaction data.\\n\\n**Summary**\\n\\nPublic keys in Nescience are essential for secure interactions within the network. \\"${public}_{key}.sig$\\" allows others to verify that transactions were signed by the legitimate owner, \\nensuring the authenticity of every operation. \\"${public}_{key}.rcm$\\" enables secure and private commitment schemes, allowing participants to commit to transaction details without \\nrevealing sensitive information. Finally, \\"${public}_{key}.sk(prf)$\\" powers deterministic outputs through a pseudorandom function, ensuring that user-specific data remains consistent \\nand secure throughout various transactions. Together, these public key components facilitate privacy, security, and trust within NSSA, enabling seamless interactions while safeguarding user data.\\n\\n### IV. Viewing key\\nThe **viewing key** in NSSA is a specialized cryptographic key that allows a user to decrypt both incoming and outgoing transactions associated with their account. \\nThis key is designed to offer a degree of transparency to the user, enabling them to view the details of their transactions without compromising the security of their assets or granting \\ncontrol over those assets.\\n\\n- **Role of the viewing key**: The primary function of the viewing key is to provide visibility into transaction details while maintaining the integrity of private, shielded, \\nor deshielded transactions. It enables the user to see the specifics of the transactions they are involved in\u2014such as amounts transferred, asset types, and metadata\u2014without \\nexposing the sensitive transaction data to the broader network. For instance, if Alice has executed a private transaction with Bob, her viewing key allows her to decrypt and \\nreview the details of the transaction, ensuring that everything was processed correctly. This ability to audit her own transactions helps Alice maintain confidence in the integrity \\nof her private interactions on the blockchain.\\n\\n- **Security considerations**: Despite its utility, the viewing key must be handled with care as its exposure could potentially compromise the user\u2019s privacy. \\nAlthough possessing the viewing key does **not** provide the ability to spend or sign transactions (that authority remains strictly with the spending key and private keys), \\nit does allow anyone with access to the viewing key to decrypt the details of the user\u2019s private transactions. This means that if the viewing key is leaked or stolen, \\nthe privacy guarantees of Nescience\u2019s private, shielded, and deshielded executions could be undermined. Specifically, the viewing key could be used to link various transactions, \\nbreaking the unlinkability of private transactions. For example, an attacker with access to the viewing key could decrypt past and future transactions, exposing the relationships \\nbetween different parties and transaction flows. To mitigate this risk, Nescience recommends that users treat their viewing key with the same level of protection as their private keys. \\nIt should be stored securely in encrypted hardware wallets or other secure storage solutions to prevent unauthorized access. \\n\\n- **Balancing privacy and transparency**: The viewing key provides an essential balance between privacy and transparency in NSSA. While it ensures that users \\ncan monitor their transaction history and verify the details of their private transactions, it does so without compromising the control of their funds. This allows users to maintain \\na transparent view of their interactions while keeping their assets secure. For example, if Alice is using shielded execution to transfer assets, her viewing key enables her to \\naudit the transaction without allowing anyone else, including Bob or external observers, to see the specific details unless they also have access to the viewing key. Moreover, \\nsince the viewing key does not grant signing or spending authority, even if it were exposed, an attacker would still not be able to manipulate the user\u2019s assets. However, \\nto maintain the unlinkability and confidentiality of private transactions, the viewing key must be kept secure at all times.\\n\\n- **Protecting transaction unlinkability**: In private transactions, unlinkability is one of the core privacy guarantees. This property ensures that individual \\ntransactions cannot be correlated with each other or linked to the same user unless that user chooses to reveal the connection. The viewing key must be carefully \\nprotected to preserve this unlinkability, as its compromise could allow someone to map out a user\u2019s private transaction history. For instance, in deshielded transactions, \\nthe viewing key allows the user to see which private UTXOs were consumed and how the public state was modified. If the viewing key is compromised, an attacker could potentially \\nlink private UTXOs across multiple transactions, unraveling the user\u2019s privacy.\\n\\n**Conclusion**\\n\\nThe viewing key in Nescience is a powerful tool for providing insight into both incoming and outgoing transactions without granting control over assets. It allows users \\nto decrypt and verify their transaction details, maintaining transparency in their interactions. However, due to its potential to compromise privacy if exposed, the viewing \\nkey must be handled with great care. Proper security measures are necessary to protect the viewing key, ensuring that the unlinkability of private, shielded, and deshielded \\ntransactions remains intact. In this way, the viewing key offers a crucial balance between privacy and transparency within the Nescience ecosystem.\\n\\n### V. Ephemeral key\\nThe ephemeral key is generated using a combination of the sender\u2019s spending key and the UTXO\'s nullifier, ensuring that the key is unique to each transaction. \\nThe process can be informally described as follows:\\n\\n1. **Ephemeral key generation** \\n Let $\\\\rho$ denote the nullifier of the UTXO being consumed in the transaction. The sender uses the receiver\u2019s public key component ${public}_{key}.sk(prf)$, \\n which is derived from the receiver\u2019s private key, to compute an **ephemeral secret key ($esk$)**. The computation is based on the nullifier $\\\\rho$ and a base value:\\n \\n $$esk = {public}_{key}.sk(prf((0,0,0,0) || \\\\rho)$$\\n This formula binds the secret key to the specific transaction, leveraging the receiver\u2019s cryptographic identity and the unique properties of the UTXO being spent.\\n\\n2. **Deriving the ephemeral public key** \\n After computing the ephemeral secret key ($esk$), the next step is to derive the corresponding **ephemeral public key (epk)**. This is done using the Key Agreement \\n Protocol\'s **DerivePublic algorithm**, which generates the public key associated with the shared secret key. The ephemeral public key is computed as:\\n \\n $$epk = KA.DerivePublic(esk, gd)$$\\n \\nHere, ($gd$) is the **diversifier address** associated with the receiver\u2019s account. The diversifier address is computed from the receiver\u2019s \\naccount using the **DiversifierHash** function:\\n \\n $$gd = receiver.DiversifierHash(d)$$\\n\\nThe diversifier ($d$) is a random value selected by the sender to add randomness to the process. This diversifier ensures that even if a single receiver is involved \\nin multiple transactions, the derived keys remain distinct for each transaction. The value ($d$) is included in the transaction note for transparency and reproducibility.\\n\\n3. **Establishing the shared secret** \\nThe shared secret, used to encrypt the transaction details, is derived from the key agreement between the sender\u2019s ephemeral key and the receiver\u2019s viewing key. \\nAny party possessing the receiver\u2019s viewing key can use it in conjunction with the ephemeral key to compute the shared secret, which is then used to decrypt the transaction. \\nThis ensures that only the intended recipient (or anyone with their viewing key) can access the transaction details.\\n\\n**Key components and protocol**\\n\\nThe formal protocol for generating ephemeral keys closely follows this informal description but involves additional intermediate steps for converting values to \\nbinary sequences to fit implementation requirements. These steps are essential for ensuring compatibility with cryptographic algorithms used in NSSA. \\nThe protocol uses the following key components:\\n- **Nullifier ($\\\\rho$):** Ensures that the ephemeral key is tied to the specific UTXO being consumed, preventing reuse of the key in future transactions.\\n- **Receiver\u2019s public key (${public}_{key}.sk(prf)$:** Establishes the receiver\'s identity in the key generation process, ensuring that the shared secret can \\nonly be derived by the intended party.\\n- **Diversifier ($d$):** Adds randomness to the transaction, ensuring that keys remain unique across different transactions involving the same receiver.\\n\\nThe end result is an ephemeral key system that provides strong cryptographic guarantees for transaction privacy, leveraging key agreement protocols and secure \\ncryptographic primitives to prevent unauthorized access to sensitive transaction data.\\n\\n**Conclusion**\\n\\nThe ephemeral key in Nescience is a critical element for maintaining transaction confidentiality. It facilitates a secure key agreement between the sender and the receiver, \\nallowing for the encryption of transaction details with a shared secret that can only be derived by the intended recipient. By incorporating the nullifier, receiver\'s public key, \\nand diversifier address, the ephemeral key ensures that transaction privacy is preserved while preventing unauthorized access to transaction information, even in a complex, \\nmulti-party blockchain environment.\\n\\n### VI. Nescience addresses\\nNescience\u2019s dual address system is a core component of its privacy-focused architecture, designed to balance transparency and confidentiality across different types of transactions. \\nThe architecture provides each user or smart contract with both public addresses and private addresses, allowing them to participate in both open and confidential activities on the blockchain.\\n\\n#### a) Public addresses\\nPublic addresses in Nescience are visible to all participants on the network and reside within the public state. These addresses are essential for engaging in \\ntransparent and verifiable interactions, such as sending tokens or invoking smart contracts that are meant to be publicly auditable. Public addresses serve as \\nthe interface for users who need to engage with the transparent elements of the system, including public transactions or smart contracts that require public access.\\n\\nThey are analogous to traditional blockchain addresses seen in systems like Ethereum or Bitcoin, where every participant can see the address and the transactions associated with it. \\nFor example, when Alice wants to receive tokens from Bob in a public transaction, she can provide her public address, allowing Bob to send the tokens transparently. \\nAnyone on the network can verify the transaction, providing accountability and trust in the public state.\\n\\nBecause public addresses are visible and auditable, they are typically used for interactions where privacy is not a concern or where transparency is desirable. \\nThis could include simple token transfers, public contract calls, or interactions with dapps that require public accountability, \\nsuch as voting or governance systems.\\n\\n#### b) Private addresses\\nIn contrast, private addresses are designed for confidentiality and are not visible onchain. These addresses are used exclusively for private transactions and executions, \\nensuring that sensitive details\u2014such as the sender, receiver, or amount transferred\u2014remain hidden from the public state. Private addresses are a key feature of \\nNescience\u2019s private, shielded, and deshielded execution models, where preserving the confidentiality of participants is crucial.\\n\\nUsers can generate an unlimited number of private addresses using their private keys. This flexibility allows users to compartmentalize their interactions, \\ngiving them the ability to provide different private addresses to different parties. For instance, Alice could create a unique private address for each entity \\nshe interacts with, thereby ensuring that her transactions remain isolated and difficult to trace. This feature enhances privacy by preventing any direct linkage \\nbetween different transactions or activities associated with a single user.\\n\\nPrivate addresses are not tied to the public state and are only accessible through the user\u2019s private key infrastructure. Transactions involving private addresses \\nare conducted within the confines of the private state and are only decrypted by the intended participants. For example, when Alice sends tokens to Bob using \\na private address, the details of that transaction remain confidential, accessible only to Alice and Bob, unless they choose to reveal it.\\n\\n**Role of the viewing key in private addresses**: A key feature of Nescience\u2019s private address system is the viewing key, which allows users to decrypt any transaction \\ninvolving their private addresses. This capability provides oversight and transparency into the user\u2019s private transactions, ensuring that they can monitor their own \\nactivity without exposing the details to the public. The viewing key does not compromise the security of the user\'s assets as it does not grant spending or signing authority. \\nHowever, it does allow the user to audit and verify the accuracy of their private transactions, ensuring that everything proceeds as expected. For instance, Alice can use her \\nviewing key to review the details of a private transaction she conducted with Bob, ensuring that the correct amount was transferred and that the transaction was properly processed. \\nThis functionality is critical for users who want to maintain control over their private interactions while still benefiting from transparency into their transaction history. \\nThe ability to generate multiple private addresses and decrypt them with the viewing key ensures that users can maintain compartmentalized privacy without sacrificing oversight.\\n\\n**Summary**\\n\\nNescience\u2019s dual address system\u2014comprising public and private addresses\u2014provides users with the flexibility to engage in both transparent and confidential transactions. \\nPublic addresses are visible onchain and are used for open, public interactions that require accountability and auditability. In contrast, private addresses are \\ninvisible onchain and are used for confidential transactions, enhancing privacy and security.\\n\\nBy allowing users to generate multiple private addresses, Nescience gives individuals control over the visibility of their transactions. Combined with the viewing \\nkey\u2019s ability to decrypt transactions involving private addresses, the system ensures that users can maintain transparency over their private transactions without \\nexposing sensitive information to the public state. This dual-address approach enables users to seamlessly switch between public and private interactions depending on their needs, \\nproviding a robust framework for both privacy and transparency in NSSA.\\n\\n### VII. Conclusion\\nKey management in NSSA is a carefully designed system that strikes an optimal balance between security, privacy, and flexibility. \\nThe architecture\u2019s hierarchical structure, with distinct roles for the spending key, private keys, and public keys, ensures that users retain full control \\nover their assets while maintaining the integrity of their transactions. The spending key, as the root of security, provides unassailable control over the \\nuser\'s UTXOs and assets, ensuring that only the rightful owner can authorize spending. Private keys, derived from the spending key, enable users to engage \\nin cryptographic operations such as signing transactions and generating commitments without exposing sensitive information to the network.\\n\\nThe viewing key adds another layer of transparency, allowing users to decrypt and review their transactions without compromising their authority over their assets. \\nWhile it provides a window into transaction history, the viewing key does not grant spending power, preserving the critical separation between visibility and control.\\n\\nThe dual system of public and private addresses gives users the flexibility to navigate between open, transparent transactions and confidential, privacy-protected activities. \\nPublic addresses allow users to engage in verifiable, public interactions while private addresses enable compartmentalized, secure transactions that remain hidden \\nfrom the public eye. This dual-address framework ensures that users can seamlessly adapt to different privacy requirements, whether they are participating in public \\ndapps or conducting sensitive financial operations.\\n\\nOverall, Nescience\u2019s cryptographic infrastructure is designed to empower users to engage confidently in both transparent and confidential activities. \\nBy providing flexible, secure key management and address systems, Nescience ensures that users can fully participate in the blockchain ecosystem without \\ncompromising their privacy or control. The architecture supports the nuanced needs of modern blockchain users, who require both the transparency of public \\ninteractions and the security of private transactions, all while maintaining the integrity and confidentiality of their assets.\\n\\n\\n## c) Trees in NSSA\\nTrees in NSSA serve as verifiable databases, essential for maintaining privacy and security. Different types of trees are used for various purposes:\\n\\n1. **Global state tree:** The global state tree is a single, public tree that holds all public assets and storage information. It acts as a central repository for all \\npublicly accessible data on the blockchain. By organizing this data in a Merkle tree structure, the Global State Tree allows for efficient and secure verification of public information.\\n\\n2. **Hashed UTXO tree:** The hashed UTXO tree is a public tree that contains hashes of all created UTXOs. When users wish to consume a UTXO, they provide a membership \\nproof to demonstrate that the UTXO exists within this tree. This process ensures that only valid and existing UTXOs can be spent, maintaining the integrity of transactions. \\nIn fact, users generate membership proofs that verify the presence of specific UTXOs in the tree without revealing their actual data. The benefit here is that the Merkle \\ntree structure allows for quick and efficient verification of UTXO existence.\\n\\n3. **UTXO trees (private states):** Each user or smart contract has its private state stored in UTXO trees. These trees are kept as plaintext on the client\u2019s \\nlocal system (off-chain), ensuring privacy as sensitive information remains confidential. The private state includes all UTXOs owned by the user or the smart contract, and these \\nare not directly exposed to the public blockchain. For instance, users have full control over their private state, which is not visible to other participants in the network.\\n\\nIn conclusion, the tree structures enable efficient verification of transaction validity without compromising privacy. By using Merkle trees, \\nNescience ensures that any tampering with the data can be easily detected. The efficient structure of these trees supports the scalability of the architecture, \\nallowing it to handle a large number of transactions and data entries. By leveraging different types of trees, Nescience ensures efficient and secure management \\nof both public and private states.\\n\\n## d) Nullifier tree in Nescience\\n\\nThe **nullifier tree** is a fundamental component of NSSA, designed to prevent double spending by securely tracking all consumed UTXOs. \\nThis tree acts as a public ledger of spent UTXOs, ensuring that once a UTXO is consumed in a transaction, it cannot be reused in future transactions. \\n\\nThe primary function of the nullifier Tree is to store the **nullifiers** of all consumed UTXOs. By recording the nullifiers in a public tree, \\nthe system ensures that each UTXO is spent only once, thereby safeguarding the integrity of the entire network.\\n\\n- **Ensuring non-membership and preventing double spending**\\nBefore a user can consume a UTXO in a transaction, they must provide a **non-membership proof**. This proof demonstrates that the UTXO\u2019s nullifier \\ndoes not already exist in the Nullifier Tree, proving that the UTXO has not been spent before. If the UTXO\u2019s nullifier is found in the tree, \\nthe system will reject the transaction, preventing double spending. The non-membership proof ensures that users cannot attempt to spend the \\nsame UTXO in multiple transactions. This mechanism is critical for maintaining the security and reliability of NSSA. \\nThe tree structure, which is typically built using a cryptographic tree like a Merkle tree, allows for efficient verification of nullifiers. \\nVerifiers can quickly check whether a nullifier is present or absent in the tree, ensuring that each UTXO is only spent once.\\n\\n- **Nullifier tree structure and operation**\\nThe nullifier tree is likely structured as a **Merkle tree**, which is a cryptographic binary tree where each node represents the hash of its child nodes. \\nThis structure allows for efficient storage and verification of large sets of nullifiers as only the root hash of the tree needs to be stored on the blockchain. \\nWhen a new nullifier is added to the tree, the tree is recalculated, and the root hash is updated. This process ensures that all consumed UTXOs are securely recorded. \\nEach time a transaction consumes a UTXO, the nullifier is added to the Nullifier Tree, and the tree is updated to reflect this new entry. To verify that a \\nUTXO has not been double spent, verifiers can use the tree\u2019s root hash and a proof of inclusion or exclusion (membership or non-membership proof) to check whether the \\nnullifier is present in the tree. For example, if Alice wants to spend a UTXO, she must prove that the nullifier associated with that UTXO is not already in the Nullifier Tree. \\nShe generates a non-membership proof that shows her nullifier is not recorded in the tree, and the transaction is allowed to proceed. Once the transaction is completed, \\nthe nullifier is added to the tree, ensuring that the UTXO cannot be used again.\\n\\n**Conclusion**\\nThe Nullifier Tree is a crucial element of Nescience\'s security. By recording all consumed UTXOs and ensuring that nullifiers are unique, the tree prevents double spending \\nand maintains the integrity of the blockchain. The non-membership proof mechanism guarantees that every transaction is validated against the tree. This structure supports \\nthe scalability and security of NSSA, providing a reliable method for verifying the validity of transactions while preventing malicious behavior.\\n\\n## e) Recursive-friendly privacy-preserving zk-zkVM\\nThe development of the zk-zkVM in Nescience is a work in progress, as the architecture continues to evolve to support privacy-preserving transactions \\nand efficient ZKP generation. The goal of the zk-zkVM is to seamlessly integrate with the Nescience state-separation architecture, \\nensuring that private transactions remain confidential while allowing the network to verify their validity without compromising privacy.\\n\\nCurrently, we are exploring and testing several existing zkVMs to identify the most suitable platform for our needs. Our focus is on finding a zkVM \\nthat not only supports the core features of Nescience, such as state separation and privacy, but also provides the efficiency and scalability required \\nfor a decentralized system. Once a suitable zkVM is chosen, we will begin implementing advanced privacy features on top of it, including support for \\nconfidential transactions, selective disclosure, and recursive proof aggregation.\\n\\nThe integration of these privacy-preserving features with an existing zkVM will enable Nescience to fully employ its state-separation architecture, \\nensuring that users can conduct private transactions with robust security and scalability. This approach will allow us to leverage the strengths of \\nproven zkVM technologies while enhancing them with the unique privacy and state-separation capabilities that Nescience requires.\\n\\n\\n- **Privacy-preserving features**: At its core, the zk-zkVM is designed with privacy in mind. One of the zk-zkVM\u2019s standout privacy features is **selective disclosure**, \\nwhich allows users to reveal only specific details of a transaction as needed. For example, a user could disclose the transaction amount while concealing the identities \\nof the participants. The zk-zkVM employs advanced encryption techniques to protect this sensitive data. All transaction data is encrypted before being stored on the blockchain, \\nso even if the data is intercepted, it cannot be deciphered without the appropriate decryption keys. Another of the crucial privacy-preserving features is the support \\nfor **confidential transactions**. Only the parties involved in the transaction can access the encrypted data. Furthermore, the zk-zkVM supports **verifiable encryption**, \\na powerful capability that allows encrypted data to be included in ZKPs without needing to decrypt it. This ensures that transaction details remain private \\nwhile their correctness can still be proven.\\n\\n\\n- **Lightweight design for accessibility**: The zk-zkVM is being designed to be lightweight and efficient, enabling it to run on standard consumer-grade hardware. \\nThis makes it accessible to a wide range of users without requiring specialized equipment or significant computational resources.\\n\\n- **Faster proving time**: To maintain a seamless user experience, especially during high transaction volumes, the zk-zkVM is being optimized for **fast proving times**. \\nFast proof generation is particularly important for ensuring that the system remains usable during periods of peak activity, preventing bottlenecks and maintaining the fluidity of the network.\\n\\n- **Recursive-friendly operations**: One of the most advanced features of the zk-zkVM will be its support for **recursive operations**. Recursion enables the aggregation \\nof multiple proofs into a single proof, improving efficiency on both the client and sequencer sides of the network.\\n\\n- **Client-side recursion (batch processing):** When a single transaction involves multiple executions, each requiring its own ZKP, these individual \\nproofs can be recursively aggregated before being sent to the sequencer. This reduces the overall data transmitted, enhancing the efficiency of the transaction process \\nby compressing multiple proofs into a single package.\\n \\n- **Sequencer-side recursion (reduced redundancy):** The sequencer, which is responsible for processing transactions and creating verifiable blocks, collects transactions \\ncontaining aggregated proofs. These proofs are further merged into a single comprehensive proof, ensuring that all transactions within a block are validated collectively. \\nThis process reduces redundancy and optimizes the blockchain\u2019s efficiency by minimizing the size and complexity of the proofs required for verification.\\n\\n- **Developer-friendly language**: To foster widespread adoption and innovation within the Nescience ecosystem, the zk-zkVM would include a **developer-friendly language**. \\nThis high-level language simplifies the process of building applications that leverage state separation and privacy-preserving transactions. The language should offer extensive \\nsupport for modular design, APIs, and SDKs, enabling developers to integrate their applications with the zk-zkVM more easily. By lowering the barrier to entry, Nescience encourages \\ninnovation and helps expand the range of privacy-preserving applications that can be built on its platform.\\n\\n**Conclusion**\\n\\nThe zk-zkVM in Nescience is a powerful and versatile virtual machine that embodies the principles of privacy, efficiency, and scalability. By supporting ZKPs \\nand integrating with advanced privacy technologies like homomorphic encryption. Its lightweight design allows it to run efficiently on standard hardware, promoting decentralization, \\nand its recursive operations further enhance the system\'s scalability. With its developer-friendly language and fast proving times, the zk-zkVM is positioned as a key component in \\nfostering the growth and adoption of privacy-preserving blockchain applications.\\n\\n## f) MPC-based synchronization mechanism (under review)\\n\\nNescience is developing an **MPC-based** synchronization mechanism to balance privacy and fairness between public and private execution types. \\nThis mechanism extracts common information from encrypted UTXOs without revealing private details, ensuring privacy and preventing UTXO linkage to users or specific transactions. \\nIt guarantees that public and private executions remain equitable, with the total input equaling the public output.\\n\\nThe mechanism employs **MPC protocols** to perform computations privately, **ZKPs** to verify correctness, and **cryptographic protocols** \\nto secure data during synchronization. This ensures a consistent and fair environment for all users, regardless of their chosen privacy level. Currently, \\nthis feature is under development and review for potential inclusion depending on the research output and compability.\\n\\n\\n\\n\\n\\n# D. Future plans for Nescience\\n\\nNescience is committed to continuously evolving its architecture to ensure scalability, privacy, and security in a growing blockchain landscape. \\nOne of the primary goals is to integrate the **zk-zkVM** and the **Nescience state-separation architecture** into a fully functioning node, \\nenabling efficient private transactions while maintaining network integrity.\\n\\n- **Addressing scalability challenges**: A key challenge facing Nescience is the increasing size of nullifier and hashed UTXO trees, which could impact \\nnetwork performance and scalability over time. To mitigate this, Nescience plans to adopt state-of-the-art scalable privacy techniques such as:\\n - **Mutator sets:** Dynamically adjusting data structures to manage the growth of the nullifier set efficiently.\\n - **SNARK-based accumulators:** Compressing data in a verifiable way to ensure that only relevant information is stored while maintaining cryptographic security.\\n - **Pruning techniques:** Periodically trimming unnecessary data from trees to maintain optimal size and performance, ensuring that the network scales logarithmically \\n rather than exponentially as more transactions occur.\\n\\nBy implementing these approaches, Nescience aims to keep the size of its data structures manageable, ensuring that scalability does not come at the cost of performance or privacy.\\n\\n- **Enhanced key management**: Another critical focus for Nescience is improving key management to streamline operations and enhance security. \\nThe plan is to integrate the different keys used for signatures, addresses, UTXO encryption, and SNARK verification into a unified system. \\nThis integration will simplify key management for users while reducing the risk of security breaches caused by complex, disparate key systems. \\nNescience also plans to implement **Hierarchical Deterministic (HD) keys**, which allow users to derive multiple keys from a single seed, \\nenhancing both security and usability. This approach reduces the complexity of managing multiple keys across various functions and provides an additional \\nlayer of protection for private transactions. Additionally, **multi-signature schemes** will be introduced, requiring multiple parties to authorize transactions. \\nThis feature increases security by reducing the likelihood of unauthorized access, ensuring that a single compromised key cannot lead to malicious transactions.\\n\\n- **Integrating advanced cryptographic techniques**: Nescience will integrate advanced cryptographic techniques, enhancing both privacy and scalability. Among these are:\\n - **Homomorphic encryption:** Allowing computations to be performed on encrypted data without the need to decrypt it, preserving privacy while enabling secure, complex data processing.\\n - **Zero-knowledge rollups:** Bundling multiple transactions into a single proof to reduce the amount of data processed and stored on the blockchain, \\n significantly improving scalability without sacrificing security.\\n\\nThese cryptographic enhancements will ensure that Nescience can support a growing network while continuing to protect user privacy and maintaining high transaction throughput.\\n\\n- **Long-term vision**\\n\\nThe ultimate goal for Nescience is to deploy a fully operational **node powered by zk-zkVM** and the **Nescience state-separation architecture**. \\nThis node will handle complex, private transactions at scale while integrating all of the advanced cryptographic techniques outlined in the roadmap. \\nNescience aims to provide users with an infrastructure that balances privacy, security, and efficiency, ensuring the network remains resilient and capable of handling future demands.\\n\\nBy pursuing these future plans, Nescience is poised to not only address current challenges around scalability and key management but also lead the way in \\napplying advanced cryptography to decentralized systems. This vision will help secure the long-term integrity and performance of the Nescience state-separation \\nmodel as the blockchain grows and evolves.\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n# References\\n\\n[1] Nakamoto, S. (2008). Bitcoin: A Peer-to-Peer Electronic Cash System. Retrieved from https://bitcoin.org/bitcoin.pdf\\n\\n[2] Sanchez, F. (2021). Cardano\u2019s Extended UTXO accounting model. Retrived from https://iohk.io/en/blog/posts/2021/03/11/cardanos-extended-utxo-accounting-model/\\n\\n[3] Morgan, D. (2020). HD Wallets Explained: From High Level to Nuts and Bolts. Retrieved from https://medium.com/mycrypto/the-journey-from-mnemonic-phrase-to-address-6c5e86e11e14\\n\\n[4] Wuille, P. (2012). Bitcoin Improvement Proposal (BIP) 32. Retrieved from https://github.com/bitcoin/bips/blob/master/bip-0032.mediawiki\\n\\n[5] Sin7y Tech Review (29): Design Principles of Private Transactions in Aleo & Zcash. Retrieved from https://hackmd.io/@sin7y/rkxFXLkgs\\n\\n[6] Sin7y Tech Review (33): Principles of private transactions and regulatory compliance issues. Retrieved from https://hackmd.io/@sin7y/S16RyFzZn\\n\\n[7] Zcash Protocol Specification. Retrieved from https://zips.z.cash/protocol/protocol.pdf\\n\\n[8] Anatomy of a Zcash Transaction. Retrieved from https://electriccoin.co/blog/anatomy-of-zcash\\n\\n[9] The Penumbra Protocol: Notes, Nullifiers, and Trees. Retrieved from https://protocol.penumbra.zone/main/concepts/notes_nullifiers_trees.html\\n\\n[10] Zero-knowledge Virtual Machine (ZKVM). Retrieved from https://medium.com/@abhilashkrish/zero-knowledge-virtual-machine-zkvm-95adc2082cfd\\n\\n[11] What\'s a Sparse Merkle tree?. Retrieved from https://medium.com/@kelvinfichter/whats-a-sparse-merkle-tree-acda70aeb837\\n\\n[12] Lecture 10: Accounts Model and Merkle Trees. Retrieved from https://web.stanford.edu/class/ee374/lec_notes/lec10.pdf\\n\\n[13] The UTXO vs Account Model. Retrieved from https://www.horizen.io/academy/utxo-vs-account-model/\\n\\n[14] Addresses and Value Pools in Zcash. Retrieved from https://zcash.readthedocs.io/en/latest/rtd_pages/addresses.html"},{"id":"membership-with-bloom-filters-and-cuckoo-filters","metadata":{"permalink":"/rlog/membership-with-bloom-filters-and-cuckoo-filters","source":"@site/rlog/2024-07-19-bloomfilter.mdx","title":"Membership with Bloom Filters and Cuckoo Filters","description":"We examine two data structures: Bloom filters and Cuckoo filters.","date":"2024-07-19T12:00:00.000Z","formattedDate":"July 19, 2024","tags":[],"readingTime":12.62,"hasTruncateMarker":true,"authors":[{"name":"Marvin","github":"jonesmarvin8","key":"marvin"}],"frontMatter":{"title":"Membership with Bloom Filters and Cuckoo Filters","date":"2024-07-19T12:00:00.000Z","authors":"marvin","published":false,"slug":"membership-with-bloom-filters-and-cuckoo-filters","categories":"research","toc_min_heading_level":2,"toc_max_heading_level":4},"prevItem":{"title":"Nescience: A User-Centric State-Separation Architecture","permalink":"/rlog/Nescience-state-separation-architecture"},"nextItem":{"title":"RLN-v3: Towards a Flexible and Cost-Efficient Implementation","permalink":"/rlog/rln-v3"}},"content":"We examine two data structures: Bloom filters and Cuckoo filters.\\n\\n\x3c!--truncate--\x3e\\n\\n## Membership with Bloom Filters and Cuckoo Filters\\n\\nThe ability to efficiently query the membership of an element in a given data set is crucial.\\nIn certain applications, it is more important to output a result quickly than to have a \'perfect\' result.\\nIn particular, false positives may be an acceptable tradeoff for speed.\\nIn this blog, we examine [Bloom](https://dl.acm.org/doi/10.1145/362686.362692) and [Cuckoo](https://www.cs.cmu.edu/~dga/papers/cuckoo-conext2014.pdf) data filters.\\nBoth of these filters are data structures that can be used for membership proofs.\\n\\nEveryone is familiar with the process of creating a new account for various websites, whether it is an e-mail account or a social media account.\\nConsider when you enter your desired username.\\nMany sites provide real-time feedback, as you type, on the availability of a given string.\\nIn this scenario, it is necessary that the result is seemingly instant, regardless of the number of existing accounts.\\nHowever, it is not important that the usernames that are flagged as unavailable are, in fact, in use.\\nThat is, it is sufficient to have a probabilistic check for membership.\\n\\n**Bloom filters** and **Cuckoo filters** are data structures that can be used to accumulate data with a fixed amount of space.\\nThe associated filter $F$ for a digest of data $D$ can be queried to determine whether an element is (possibly) a member of $D$:\\n\\n- **0:** The queried element is definitely not a member of digest $D$.\\n- **1:** The entry is possibly a member of the digest $D$.\\n\\nThe algorithms associated with Bloom filters and Cuckoo filters, which we will discuss shortly, are deterministic.\\nThe possibility of false positives arises from the query algorithm.\\n\\n\\n## Bloom filters\\nA **Bloom filter** is a data structure that can be used to accumulate an arbitrary amount of data with a fixed amount of space.\\nBloom filters have been a popular data structure for proof of non-membership due to their small storage size.\\nSpecifically, a Bloom filter consists of a binary string ${\\\\bf{v}} \\\\in \\\\{0,1\\\\}^n$ and $k$ hash functions $\\\\{h_i: \\\\{0,1\\\\}^* \\\\rightarrow \\\\{0,\\\\dots,n-1\\\\}\\\\}_{i=0}^{k-1}$.\\nWe note that each hash function $h_i$ is used to determine an index of our binary string ${\\\\bf{v}}$ to flip the associated bit to 1.\\nThe binary string ${\\\\bf{v}}$ is initialized with every entry as 0.\\nThe hash functions do not need to be cryptographic hash functions.\\n\\n\\n- **Append:** Suppose that we wish to add the element $x$ to the Bloom filter.\\n - Define the vector ${\\\\bf{b}} \\\\in \\\\{0,\\\\dots,n-1\\\\}^k$ so that ${\\\\bf{b}}[i] := h_i(x)$ for each $i \\\\in \\\\{0,\\\\dots,k-1\\\\}$.\\n - Update the binary string ${\\\\bf{v}}[{\\\\bf{b}}[i]] \\\\leftarrow 1$ for each $i \\\\in \\\\{0,\\\\dots,k-1\\\\}$.\\n \\n- **Query:** Suppose that we wish to query the Bloom filter for element $y$.\\n - Return 1 provided ${\\\\bf{v}}[h_i(y)] = 1$ for every $i \\\\in \\\\{0,\\\\dots,k-1\\\\}$. Otherwise, return 0.\\n \\nThe algorithm **Query** will output 1 for every element $y$ that has been added to the Bloom filter.\\nThis is a consequence of the **Append** algorithm.\\nHowever, due to potential collisions over a set of hash functions, it is possible for false positives to occur.\\nMoreover, the possibility of collisions makes it impossible to remove elements from the Bloom filter.\\n\\n### Complexity\\nThe storage of a Bloom filter requires constant space.\\nSpecifically, the Bloom filter uses $n$ bits regardless of the size of the digest.\\nSo, regardless of the number of elements that we append, the Bloom filter will use $n$ bits.\\nFurther, if we assume that each of the $k$ hash functions runs in constant time, then we can append/query an entry in $O(k)$.\\n\\n### Example\\nSuppose that $k = 3$ and $n = 10$. \\nOur Bloom filter is initialized as $\\\\bf{v} = \\\\begin{pmatrix}0&0&0&0&0&0&0&0&0&0\\\\end{pmatrix}.$\\nNow, we will append the words $add$, $sum$, and $equal$.\\nSuppose that\\n\\n$\\\\begin{matrix}\\nh_0(add) = 1 & h_1(add) = 4 & h_2(add) = 7\\\\\\\\\\nh_0(sum) = 9 & h_1(sum) = 2 & h_2(sum) = 1\\\\\\\\\\nh_0(equal) = 5 & h_1(equal) = 8 & h_2(equal) = 0.\\n\\\\end{matrix}$\\n\\nAfter appending these words, the Bloom filter is $\\\\bf{v} = \\\\begin{pmatrix}1&1&1&0&1&1&0&1&1&1\\\\end{pmatrix}.$\\n\\nNow, suppose that we query the words $subtract$ and $multiple$ so that\\n\\n$\\\\begin{matrix} h_0(subtract) = 3 & h_1(subtract) = 5 & h_2(subtract) = 1\\\\\\\\ h_0(multiple) = 7 & h_1(multiple) = 1 & h_2(multiple) = 4\\\\\\\\\\n\\\\end{matrix}$.\\n\\nThe query for $subtract$ returns 0 since ${\\\\bf{v}}[3]=0$.\\nOn the other hand, the query for $multiple$ returns 1 since ${\\\\bf{v}}[1]=1, {\\\\bf{v}}[4] = 1$, and ${\\\\bf{v}}[7]=1$.\\nEven though $multiple$ was not used to generate the Bloom filter ${\\\\bf{v}}$, our query returns the false positive.\\n\\n\\n### Probability of false positives\\nFor our analysis, we will assume that the probabilities that arise in our analysis are independent. \\nHowever, this assumption can be removed to gain the same approximation.\\n\\nWe note that for a single hash function, the probability that a specific bit is flipped to 1 is $1/n$.\\nSo, the probability that the specific bit is not flipped by the hash function is $1-1/n$.\\nApplying our assumption that the $k$ hash functions are \'independent,\'\\nthe probability that the specific bit is not flipped by any of the hash functions is\\n$(1-1/n)^k$.\\n\\nRecall the calculus fact $\\\\lim_{\\\\infty} (1-1/n)^n = e^{-1}$.\\nThat is, as we increase the number of bits that our Bloom filter uses, the approximate probability that a given bit is not flipped by any of the $k$ hash functions is $e^{-k/n}$.\\n\\nSuppose that $\\\\ell$ entries have been added to the Bloom filter.\\nThe probability that a specific bit is still 0 after the $\\\\ell$ entries have been added is approximately $e^{-\\\\ell k/n}$.\\nThe probability that a queried element is erroneously claimed as a member of the digest is approximately\\n$(1-e^{-\\\\ell k/n})^k$.\\n\\nThe following table provides concrete values for these approximations.\\n\\n| $n$ | $k$ | $\\\\ell$ | $(1-e^{-\\\\ell k/n})^k$|\\n| -------- | -------- | -------- | --- |\\n| 32 | 3 | 3 | 0.01474 |\\n| 32 | 3 | 7 | 0.11143 |\\n| 32 | 3 | 12 |0.30802 |\\n| 32 | 3 | 17 |0.50595 |\\n| 32 | 3 | 28 |0.79804 |\\n\\nNotice that the probability of false positives increases as the number of elements ($\\\\ell$) that have been added to the digest increases.\\n\\n### Sliding-Window Bloom filter\\nOur toy example and table illustrated an issue concerning Bloom filters.\\nThe number of entries that can be added to a Bloom filter is restricted by our choice of $k$ and $n$.\\nNot only does the probability that false positives will occur increase,\\nbut it is possible that our vector ${\\\\bf{v}}$ can be a string of all 1s.\\n[Szepieniec and V\xe6rge](https://eprint.iacr.org/2023/1208.pdf) proposed a modification to Bloom filters to handle this.\\n\\nInstead of having a fixed number of bits for our Bloom filter, we dynamically allot memory based on the number of entries that have been added to the filter.\\nGiven a predetermined threshold ($b$) for the number of entries, we shift our \'window\' of flipping bits by $s$ bits.\\nNote that this means that it is necessary to keep track of when a given entry is added to the digest.\\nThis means that querying the Sliding-Window Bloom filter will yield different results when different timestamps are used.\\n\\nThis can be done with $k$ hash functions as we used earlier.\\nAlternatively, Szepieniec and V\xe6rge proposed using the same hash function but to produce $k$ entries in the current window.\\nSpecifically, we obtain the bits we wish to flip to 1s by computing $h(X || i)$ for each $i \\\\in \\\\{0,\\\\dots, k-1\\\\}$ and $X$ as we will define next.\\nFor Sliding-Window Bloom filters, $X$ is more than just the element we wish to append to the filter.\\nInstead, $X$ consists of the element $x$ and a timestamp $t$. \\nThe timestamp $t$ is used to locate the correct window for bits, as we see below:\\n\\n- **Append:** Suppose that we wish to add the element $x$ with timestamp $t$ to the Sliding-Window Bloom filter.\\n - Define the vector ${\\\\bf{b}} \\\\in \\\\{0,\\\\dots,n-1\\\\}^k$ so that ${\\\\bf{b}}[i] := h(x||t||i)$ for each $i \\\\in \\\\{0,\\\\dots,k-1\\\\}$.\\n - Update the binary string ${\\\\bf{v}}[{\\\\bf{b}}[i]+\\\\lfloor t/b \\\\rfloor s] \\\\leftarrow 1$ for each $i \\\\in \\\\{0,\\\\dots,k-1\\\\}$.\\n \\n- **Query:** Suppose that we wish to query the Bloom filter for element $y$ with timestamp $t$.\\n - Return 1 provided ${\\\\bf{v}}[h(y||t||i) + \\\\lfloor t/b \\\\rfloor s] = 1$ for every $i \\\\in \\\\{0,\\\\dots,k-1\\\\}$. Otherwise, return 0.\\n \\n\\nBy incorporating a shifting window, we maintain efficient querying and appending at the cost of constant space.\\nHowever, by losing constant space, we gain \'infinite\' scalability.\\n\\n## Cuckoo filters\\nA Cuckoo filter is a data structure for probabilistic membership proofs based on Cuckoo hash tables.\\nThe specific design goal for Cuckoo filters is to address the inability to remove elements from a Bloom Filter.\\nThis is done by replacing a list of bits with a list of \'fingerprints.\'\\nA fingerprint can be thought of as the hash value for an entry in the digest.\\nA Cuckoo filter is a fixed-length list of \'fingerprints.\'\\nIf the maximum number of entries that a Cuckoo filter can hold is $n$ and a fingerprint occupies $f$ bits,\\nthen the Cuckoo filter occupies $nf$ bits.\\n\\nNow, we describe the algorithms associated with the Cuckoo filter $C$ with hash function $hash(X)$ and fingerprint function $fingerprint(X)$.\\n\\n- **Append:** Suppose that we wish to add the element $x$ to the Cuckoo filter.\\n - If either position $i_x := hash(x)$ or $j_x := i \\\\otimes hash(fingerprint(x))$ of $C$ is empty,\\n then $fingerprint(x)$ is inserted into an empty position.\\n - If both $i_x$ and $j_x$ are occupied with a fingerprint that is distinct from $fingerprint(x)$,\\n then we select either $i_x$ or $j_x$ to insert $fingerprint(x)$.\\n The fingerprint that had previously occupied this position cannot be discarried.\\n Instead, we insert this fingerprint into its alternate location.\\n This reshuffling process either ends with fingerprints all having their own bucket or one that cannot be inserted.\\n In the case that we have a fingerprint that cannot be inserted, then the Cuckoo filter is overfilled.\\n\\n- **Query:** Suppose that we wish to query the Cuckoo filter for element $y$.\\n - Return 1 provided $fingerprint(y)$ is either in position $i_y$ or $j_y$.\\n\\n- **Delete:** Suppose that we wish to delete the element $y$ from the Cuckoo filter.\\n - If $y$ has been added to the Cuckoo filter, then $fingerprint(y)$ is either in position $i_y$ or $j_y$.\\n We remove $fingerprint(y)$ from the appropriate position.\\n\\nWe note that false positives in Cuckoo filters only occur when an element shares a fingerprint and hash with a value that has already been added to the Cuckoo filter.\\n\\n### Example\\nIn this example, we will append the words $add$, $sum$, and $equal$ to a Cuckoo filter with 8 slots.\\n\\nFor each word $x$, we compute two indices:\\n$i_x := hash(x) \\\\text{ and } j_x := hash(x) \\\\otimes hash(fingerprint(x)).$\\nSuppose that we have the following values for\\nour words:\\n\\n| word | $i_x$ | $j_x$|\\n|---|---|---|\\n|$add$| $(0,1,0)$ | $(1,0,0)$ |\\n|$sum$| $(1,0,1)$ | $(1,1,0)$ |\\n|$equal$| $(0,1,0)$ | $(1,0,1)$ |\\n\\nFor clarity of the example, we append the words directly to the buckets instead of fingerprints of our data.\\n\\n| |0 | 1 | 2 | 3 | 4| 5| 6| 7|\\n|---|---|---|---|---|---|---|---|---|\\n|append $add$| ||$add$||||| |\\n|append $sum$| ||$add$|||$sum$|| |\\n\\nNotice that both of the buckets (2 and 5) that $equal$ can map to are occupied.\\nSo, we select one of these buckets (say 2) to insert $equal$ into.\\nThen, we have to insert $add$ to its possible bucket (1).\\nThis leaves us with the Cuckoo filter:\\n\\n|0 | 1 | 2 | 3 | 4| 5| 6| 7|\\n|---|---|---|---|---|---|---|---|\\n| |$add$|$equal$|||$sum$|| |\\n\\n### Complexity\\nNotice that deletions and queries to Cuckoo filters are done in constant time.\\nSpecifically, only two locations need to be checked for any data $x$.\\nAppends may require shuffling previously added elements to their alternate locations.\\nAs such, the append does not run in constant time.\\n\\n## Bloom filters vs Cuckoo filters\\nThe design of Bloom filters is focused on space efficiency and quick query time.\\nEven though they occupy constant space,\\nCuckoo filters require significantly more space for $n$ items than Bloom filters.\\nThe worst-case append in a Cuckoo filter is slower than the append in a Bloom filter.\\nHowever, an append that does not require any shuffling in a Cuckoo filter can be quicker than appends in Bloom filters.\\nCuckoo filters make up for these disadvantages with quicker query time and the ability to delete entries.\\nFurther, the probability of false positives in Cuckoo filters is lower than the probability of false positives in Bloom filters.\\n\\n\\n## Combining Filters with RLN\\nIn a series of posts ([1](https://vac.dev/rlog/rln-anonymous-dos-prevention),[2](https://vac.dev/rlog/rln-v3/),[3](https://vac.dev/rlog/rln-light-verifiers)),\\nvarious versons of rate limiting nullifiers (RLN) that are used by Waku has been discussed.\\nRLN uses a sparse Merkle tree for the membership set.\\nThe computational power required to construct the Merkle tree prevent light clients from participating in verifying membership proofs.\\nIn [Verifying RLN Proofs in Light Clients with Subtrees](https://vac.dev/rlog/rln-light-verifiers),\\nit was proposed to move the membership set on-chain so that it would not be necessary for a light client to construct the entire Merkle tree locally.\\nUnfortunately, the naive approach is not practical as the gas limit for a single call is too restrictive for an appropriately sized tree.\\nInstead, it was proposed to make utilize of subtrees.\\nIn this section, we provide a discussion of an alternate solution for light clients by using filters for the membership set.\\nThe two [parts of RLN](https://rate-limiting-nullifier.github.io/rln-docs/rln_in_details.html) that we will focus on are user registration and deletion.\\n\\nBoth Bloom and Cuckoo filters support user registration as this is can be done as an append.\\nThe fixed size of these filters would restrict the total number of users that can register.\\nThis can be migitated by using Sliding-Window Bloom filter as this supports system growth.\\nThe Sliding-Window can be adapted to Cuckoo filters as well.\\nIn the case of a Sliding-Window filter, an user would maintain the epoch of when they registered.\\nThe registration of new users to Bloom filters can be done in constant time which is a significant improvement over appending to subtrees.\\nUnfortunately, the complexity of registration to Cuckoo filters cannot be as easily computed.\\n\\nA user could be slashed from the RLN by sending too many messages in a given epoch.\\nUnfortunately, Bloom filters do not support the deletion of members.\\nLuckily, Cuckoo filters allow for deletions that can performed in constant time.\\n\\nCuckoo filter that use Sliding-Window could be used so that light clients are able to verify proofs of membership in the RLN.\\nThese proofs are not a substitute to the usual proofs that a heavy client can verify due to the allowance of false positives.\\nHowever, with the allowance of false positives, a light client can participate in verification RLN proofs in an efficient manner.\\n\\n\\n### References\\n- [Space/Time Trade-offs in Hash Coding with Allowable Errors](https://dl.acm.org/doi/10.1145/362686.362692)\\n- [David Wagner\'s Lecture Notes on Bloom filters](https://people.eecs.berkeley.edu/~daw/teaching/cs170-s03/Notes/lecture10.pdf)\\n- [Mutator Sets and their Application to Scalable Privacy](https://eprint.iacr.org/2023/1208)\\n- [Cuckoo Filter: Practically Better than Bloom](https://www.cs.cmu.edu/~dga/papers/cuckoo-conext2014.pdf)\\n- [Strengthening Anonymous DoS Prevention with Rate Limiting Nullifiers in Waku](https://vac.dev/rlog/rln-anonymous-dos-prevention)\\n- [RLN-v3: Towards a Flexible and Cost-Efficient Implementation](https://vac.dev/rlog/rln-v3/)\\n- [Verifying RLN Proofs in Light Clients with Subtrees](https://vac.dev/rlog/rln-light-verifiers)\\n- [RLN in details](https://rate-limiting-nullifier.github.io/rln-docs/rln_in_details.html)"},{"id":"rln-v3","metadata":{"permalink":"/rlog/rln-v3","source":"@site/rlog/2024-05-13-rln-v3.mdx","title":"RLN-v3: Towards a Flexible and Cost-Efficient Implementation","description":"Improving on the previous version of RLN by allowing dynamic epoch sizes.","date":"2024-05-13T12:00:00.000Z","formattedDate":"May 13, 2024","tags":[],"readingTime":6.31,"hasTruncateMarker":true,"authors":[{"name":"Aaryamann","twitter":"p1ge0nh8er","github":"rymnc","key":"p1ge0nh8er"}],"frontMatter":{"title":"RLN-v3: Towards a Flexible and Cost-Efficient Implementation","date":"2024-05-13T12:00:00.000Z","authors":"p1ge0nh8er","published":true,"slug":"rln-v3","categories":"research","toc_min_heading_level":2,"toc_max_heading_level":4},"prevItem":{"title":"Membership with Bloom Filters and Cuckoo Filters","permalink":"/rlog/membership-with-bloom-filters-and-cuckoo-filters"},"nextItem":{"title":"Verifying RLN Proofs in Light Clients with Subtrees","permalink":"/rlog/rln-light-verifiers"}},"content":"Improving on the previous version of RLN by allowing dynamic epoch sizes.\\n\\n\x3c!--truncate--\x3e\\n\\n## Introduction\\n\\nRecommended previous reading: [Strengthening Anonymous DoS Prevention with Rate Limiting Nullifiers in Waku](https://vac.dev/rlog/rln-anonymous-dos-prevention).\\n\\nThe premise of RLN-v3 is to have a variable message rate per variable epoch,\\nwhich can be explained in the following way:\\n\\n- **RLN-v1:** \u201cAlice can send 1 message per global epoch\u201d\\n\\n Practically, this is `1 msg/second`\\n\\n- **RLN-v2:** \u201cAlice can send `x` messages per global epoch\u201d\\n\\n Practically, this is `x msg/second`\\n\\n- **RLN-v3:** \u201cAlice can send `x` messages within a time interval `y` chosen by herself.\\n The funds she has to pay are affected by both the number of messages and the chosen time interval.\\n Other participants can choose different time intervals fitting their specific needs.\\n\\n Practically, this is `x msg/y seconds`\\n\\nRLN-v3 allows higher flexibility and ease of payment/stake for users who have more predictable usage patterns and therefore,\\nmore predictable bandwidth usage on a p2p network (Waku, etc.).\\n\\nFor example:\\n\\n- An AMM that broadcasts bids, asks, and fills over Waku may require a lot of throughput in the smallest epoch possible and hence may register an RLN-v3 membership of `10000 msg/1 second`.\\n They could do this with RLN-v2, too.\\n- Alice, a casual user of a messaging app built on Waku, who messages maybe 3-4 people infrequently during the day, may register an RLN-v3 membership of `100 msg/hour`,\\n which would not be possible in RLN-v2 considering the `global epoch` was set to `1 second`.\\n With RLN-v2, Alice would have to register with a membership of `1 msg/sec`,\\n which would translate to `3600 msg/hour`. This is much higher than her usage and would\\n result in her overpaying to stake into the membership set.\\n- A sync service built over Waku,\\n whose spec defines that it MUST broadcast a set of public keys every hour,\\n may register an RLN-v3 membership of `1 msg/hour`,\\n cutting down the costs to enter the membership set earlier.\\n\\n## Theory\\n\\n### Modification to leaves set in the membership Merkle tree\\n\\nTo ensure that a user\u2019s epoch size (`user_epoch_limit`) is included within their membership we must modify the user\u2019s commitment/leaf in the tree to contain it.\\nA user\u2019s commitment/leaf in the tree is referred to as a `rate_commitment`,\\nwhich was previously derived from their public key (`identity_commitment`)\\nand their variable message rate (`user_message_limit`).\\n\\nIn **RLN-v2:**\\n\\n$$\\nrate\\\\_commitment = poseidon([identity\\\\_commitment, user\\\\_message\\\\_limit])\\n$$\\n\\nIn **RLN-v3:**\\n\\n$$\\nrate\\\\_commitment = poseidon([identity\\\\_commitment, user\\\\_message\\\\_limit, user\\\\_epoch\\\\_limit])\\n$$\\n\\n### Modification to circuit inputs\\n\\nTo detect double signaling,\\nwe make use of a circuit output `nullifier`,\\nwhich remains the same if a user generates a proof with the same `message_id` and `external_nullifier`,\\nwhere the `external_nullifier` and `nullifier` are defined as:\\n\\n$$\\nexternal\\\\_nullifier = poseidon([epoch, rln\\\\_identifier]) \\\\\\\\\\nnullifier = poseidon([identity\\\\_secret, external\\\\_nullifier, message\\\\_id])\\n$$\\n\\nWhere:\\n\\n- `epoch` is defined as the Unix epoch timestamp with seconds precision.\\n- `rln_identifier` uniquely identifies an application for which a user submits a proof.\\n- `identity_secret` is the private key of the user.\\n- `message_id` is the sequence number of the user\u2019s message within `user_message_limit` in an epoch.\\n\\nIn RLN-v2, the global epoch was 1 second,\\nhence we did not need to perform any assertions to the epoch\u2019s value inside the circuit,\\nand the validation of the epoch was handled off-circuit (i.e., too old, too large, bad values, etc.).\\n\\nIn RLN-v3, we propose that the `epoch` that is passed into the circuit\\nmust be a valid multiple of `user_epoch_limit`\\nsince the user may pass in values of the `epoch` which do not directly correlate with the `user_epoch_limit`.\\n\\nFor example:\\n\\n- A user with `user_epoch_limit` of 120\\n passes in an epoch of `237`\\n generates `user_message_limit` proofs with it,\\n can increment the epoch by `1`,\\n and generate `user_message_limit` proofs with it,\\n thereby allowing them to bypass the message per epoch restriction.\\n\\nOne could say that we could perform this validation outside of the circuit,\\nbut we maintain the `user_epoch_limit` as a private input to the circuit so that the user is not deanonymized by the anonymity set connected to that `user_epoch_limit`.\\nSince `user_epoch_limit` is kept private,\\nthe verifier does not have access to that value and cannot perform validation on it.\\n\\nIf we ensure that the `epoch` is a multiple of `user_epoch_limit`,\\nwe have the following scenarios:\\n\\n- A user with `user_epoch_limit` of 120\\n passes in an epoch of `237`.\\n Proof generation fails since the epoch is not a multiple of `user_epoch_limit`.\\n- A user with `user_epoch_limit` of 120\\n passes in an epoch of `240` and\\n can generate `user_message_limit` proofs without being slashed.\\n\\nSince we perform operations on the `epoch`, we must include it as a circuit input (previously, it was removed from the circuit inputs to RLN-v2).\\n\\nTherefore, the new circuit inputs are as follows:\\n\\n```c\\n// unchanged\\nprivate identity_secret\\nprivate user_message_limit\\nprivate message_id\\nprivate pathElements[]\\nprivate pathIndices[]\\npublic x // messageHash\\n\\n// new/changed\\nprivate user_epoch_limit\\nprivate user_epoch_quotient // epoch/user_epoch_limit to assert within circuit\\npublic epoch\\npublic rln_identifier\\n```\\n\\nThe circuit outputs remain the same.\\n\\n### Additional circuit constraints\\n\\n1. Since we accept the `epoch`, `user_epoch_quotient`, and `user_epoch_limit`,\\n we must ensure that the relation between these 3 values is preserved. I.e.:\\n\\n $$\\n epoch == user\\\\_epoch\\\\_limit * user\\\\_epoch\\\\_quotient\\n $$\\n\\n2. To ensure no overflows/underflows occur in the above multiplication,\\n we must constrain the inputs of `epoch`, `user_epoch_quotient`, and `user_epoch_limit`.\\n We have assumed `3600` to be the maximum valid size of the `user_epoch_quotient`.\\n\\n$$\\nsize(epoch) \\\\leq 64\\\\ bits \\\\\\\\\\nsize(user\\\\_epoch\\\\_limit) \\\\leq 12\\\\ bits \\\\\\\\\\nuser\\\\_epoch\\\\_limit \\\\leq 3600 \\\\\\\\\\nuser\\\\_epoch\\\\_limit \\\\leq epoch \\\\\\\\\\nuser\\\\_epoch\\\\_quotient < user\\\\_epoch\\\\_limit\\n$$\\n\\n### Modifications to external epoch validation (Waku, etc.)\\n\\nFor receivers of an RLN-v3 proof\\nto detect if a message is too old, we must use the higher bound of the `user_epoch_limit`, which has been set to `3600`.\\nThe **trade-off** here is that we allow hour-old messages to propagate within the network.\\n\\n### Modifications to double signaling detection scheme (Waku, etc.)\\n\\nFor verifiers of RLN-v1/v2 proofs,\\na log of nullifiers seen in the last epoch is maintained,\\nand if there is a match with a pre-existing nullifier,\\ndouble signaling has been detected and the verifier MAY proceed to slash the spamming user.\\n\\nWith the RLN-v3 scheme,\\nwe need to increase the size of the nullifier log used,\\nwhich previously cleared itself every second to the higher bound of the `user_epoch_limit`, which is `3600`.\\nNow, the RLN proof verifier must clear the nullifier log every `3600` seconds to satisfactorily detect double signaling.\\n\\n## The implementation\\n\\nAn implementation of the RLN-v3 scheme in [gnark](https://docs.gnark.consensys.io/) can be found [here](https://github.com/vacp2p/gnark-rln/blob/9b05eddc89901a06d8f41b093ce8ce12fd0bb4e0/rln/rln.go).\\n\\n## Comments on performance\\n\\n- Hardware: Macbook Air M2, 16GB RAM\\n- Circuit: [RLN-v3](https://github.com/vacp2p/gnark-rln/blob/9b05eddc89901a06d8f41b093ce8ce12fd0bb4e0/rln/rln.go)\\n- Proving system: [`Groth16`](https://eprint.iacr.org/2016/260.pdf)\\n- Framework: [`gnark`](https://docs.gnark.consensys.io/)\\n- Elliptic curve: [`bn254`](https://eprint.iacr.org/2013/879.pdf) (aka bn128) (not to be confused with the 254-bit Weierstrass curve)\\n- Finite field: Prime-order subgroup of the group of points on the `bn254` curve\\n- Default Merkle tree height: `20`\\n- Hashing algorithm: [`Poseidon`](https://eprint.iacr.org/2019/458.pdf)\\n- Merkle tree: [`Sparse Indexed Merkle Tree`](https://github.com/rate-limiting-nullifier/pmtree)\\n\\n### Proving\\n\\nThe proving time for the RLN-v3 circuit is `90ms` for a single proof.\\n\\n### Verification\\n\\nThe verification time for the RLN-v3 circuit is `1.7ms` for a single proof.\\n\\n## Conclusion\\n\\nThe RLN-v3 scheme introduces a new epoch-based message rate-limiting scheme to the RLN protocol.\\nIt enhances the user\'s flexibility in setting their message limits and cost-optimizes their stake.\\n\\n## Future work\\n\\n- Implementing the RLN-v3 scheme in [Zerokit](https://github.com/vacp2p/zerokit)\\n- Implementing the RLN-v3 scheme in [Waku](https://github.com/waku-org/nwaku)\\n- Formal security analysis of the RLN-v3 scheme\\n\\n## References\\n\\n- [Strengthening Anonymous DoS Prevention with Rate Limiting Nullifiers in Waku](https://vac.dev/rlog/rln-anonymous-dos-prevention)\\n- [RLN Circuits](https://github.com/rate-limiting-nullifier/circom-rln)\\n- [Groth16](https://eprint.iacr.org/2016/260.pdf)\\n- [Gnark](https://docs.gnark.consensys.io/)\\n- [Poseidon Hash](https://eprint.iacr.org/2019/458.pdf)\\n- [Zerokit](https://github.com/vacp2p/zerokit)\\n- [RLN-v1 RFC](https://rfc.vac.dev/spec/32/)\\n- [RLN-v2 RFC](https://rfc.vac.dev/spec/58/)\\n- [Waku](https://waku.org)"},{"id":"rln-light-verifiers","metadata":{"permalink":"/rlog/rln-light-verifiers","source":"@site/rlog/2024-05-03-rln-light-verifiers.mdx","title":"Verifying RLN Proofs in Light Clients with Subtrees","description":"How resource-restricted devices can verify RLN proofs fast and efficiently.","date":"2024-05-03T12:00:00.000Z","formattedDate":"May 3, 2024","tags":[],"readingTime":4.81,"hasTruncateMarker":true,"authors":[{"name":"Aaryamann","twitter":"p1ge0nh8er","github":"rymnc","key":"p1ge0nh8er"}],"frontMatter":{"title":"Verifying RLN Proofs in Light Clients with Subtrees","date":"2024-05-03T12:00:00.000Z","authors":"p1ge0nh8er","published":true,"slug":"rln-light-verifiers","categories":"research","toc_min_heading_level":2,"toc_max_heading_level":4},"prevItem":{"title":"RLN-v3: Towards a Flexible and Cost-Efficient Implementation","permalink":"/rlog/rln-v3"},"nextItem":{"title":"Strengthening Anonymous DoS Prevention with Rate Limiting Nullifiers in Waku","permalink":"/rlog/rln-anonymous-dos-prevention"}},"content":"How resource-restricted devices can verify RLN proofs fast and efficiently.\\n\\n\x3c!--truncate--\x3e\\n\\n## Introduction\\n\\nRecommended previous reading: [Strengthening Anonymous DoS Prevention with Rate Limiting Nullifiers in Waku](https://vac.dev/rlog/rln-anonymous-dos-prevention).\\n\\nThis post expands upon ideas described in the previous post,\\nfocusing on how resource-restricted devices can verify RLN proofs fast and efficiently.\\n\\nPreviously, it was required to fetch all the memberships from the smart contract,\\nconstruct the merkle tree locally,\\nand derive the merkle root,\\nwhich is subsequently used to verify RLN proofs.\\n\\nThis process is not feasible for resource-restricted devices since it involves a lot of RPC calls, computation and fault tolerance.\\nOne cannot expect a mobile phone to fetch all the memberships from the smart contract and construct the merkle tree locally.\\n\\n## Constraints and requirements\\n\\nAn alternative solution to the one proposed in this post is to construct the merkle tree on-chain,\\nand have the root accessible with a single RPC call.\\nHowever, this approach increases gas costs for inserting new memberships and _may_ not be feasible until it is optimized further with batching mechanisms, etc.\\n\\nThe other methods have been explored in more depth [here](https://hackmd.io/@rymnc/rln-tree-storages).\\n\\nFollowing are the requirements and constraints for the solution proposed in this post:\\n\\n1. Cheap membership insertions.\\n2. As few RPC calls as possible to reduce startup time.\\n3. Merkle root of the tree is available on-chain.\\n4. No centralized services to sequence membership insertions.\\n5. Map inserted commitments to the block in which they were inserted.\\n\\n## Metrics on sync time for a tree with 2,653 leaves\\n\\nThe following metrics are based on the current implementation of RLN in the Waku gen0 network.\\n\\n### Test bench\\n\\n- Hardware: Macbook Air M2, 16GB RAM\\n- Network: 120 Megabits/sec\\n- Nwaku commit: [e61e4ff](https://github.com/waku-org/nwaku/tree/e61e4ff90a235657a7dc4248f5be41b6e031e98c)\\n- RLN membership set contract: [0xF471d71E9b1455bBF4b85d475afb9BB0954A29c4](https://sepolia.etherscan.io/address/0xF471d71E9b1455bBF4b85d475afb9BB0954A29c4#code)\\n- Deployed block number: 4,230,716\\n- RLN Membership set depth: 20\\n- Hash function: PoseidonT3 (which is a gas guzzler)\\n- Max size of the membership set: 2^20 = 1,048,576 leaves\\n\\n### Metrics\\n\\n- Time to sync the whole tree: 4 minutes\\n- RPC calls: 702\\n- Number of leaves: 2,653\\n\\nOne can argue that the time to sync the tree at the current state is not _that_ bad.\\nHowever, the number of RPC calls is a concern,\\nwhich scales linearly with the number of blocks since the contract was deployed\\nThis is because the implementation fetches all events from the contract,\\nchunking 2,000 blocks at a time.\\nThis is done to avoid hitting the block limit of 10,000 events per call,\\nwhich is a limitation of popular RPC providers.\\n\\n## Proposed solution\\n\\nFrom a theoretical perspective,\\none could construct the merkle tree on-chain,\\nin a view call, in-memory.\\nHowever, this is not feasible due to the gas costs associated with it.\\n\\nTo compute the root of a Merkle tree with $2^{20}$ leaves it costs approximately 2 billion gas.\\nWith Infura and Alchemy capping the gas limit to 350M and 550M gas respectively,\\nit is not possible to compute the root of the tree in a single call.\\n\\nAcknowledging that [Polygon Miden](https://polygon.technology/blog/polygon-miden-state-model) and [Penumbra](https://penumbra.zone/blog/tiered-commitment-tree/) both make use of a tiered commitment tree,\\nwe propose a similar approach for RLN.\\n\\nA tiered commitment tree is a tree which is sharded into multiple smaller subtrees,\\neach of which is a tree in itself.\\nThis allows scaling in terms of the number of leaves,\\nas well as reducing state bloat by just storing the root of a subtree when it is full instead of all its leaves.\\n\\nHere, the question arises:\\nWhat is the maximum number of leaves in a subtree with which the root can be computed in a single call?\\n\\nIt costs approximately 217M gas to compute the root of a Merkle tree with $2^{10}$ leaves.\\n\\nThis is a feasible number for a single call,\\nand hence we propose a tiered commitment tree with a maximum of $2^{10}$ leaves in a subtree and the number of subtrees is $2^{10}$.\\nTherefore, the maximum number of leaves in the tree is $2^{20}$ (the same as the current implementation).\\n\\n![img](/img/light-rln-verifiers.png)\\n\\n### Insertion\\n\\nWhen a commitment is inserted into the tree it is first inserted into the first subtree.\\nWhen the first subtree is full the next insertions go into the second subtree and so on.\\n\\n### Syncing\\n\\nWhen syncing the tree,\\none only needs to fetch the roots of the subtrees.\\nThe root of the full tree can be computed in-memory or on-chain.\\n\\nThis allows us to derive the following relation:\\n\\n$$\\nnumber\\\\_of\\\\_rpc\\\\_calls = number\\\\_of\\\\_filled\\\\_subtrees + 1\\n$$\\n\\nThis is a significant improvement over the current implementation,\\nwhich requires fetching all the memberships from the smart contract.\\n\\n### Gas costs\\n\\nThe gas costs for inserting a commitment into the tree are the same as the current implementation except it consists of an extra SSTORE operation to store the `shardIndex` of the commitment.\\n\\n### Events\\n\\nThe events emitted by the contract are the same as the current implementation,\\nappending the `shardIndex` of the commitment.\\n\\n### Proof of concept\\n\\nA proof of concept implementation of the tiered commitment tree is available [here](https://github.com/vacp2p/rln-contract/pull/37),\\nand is deployed on Sepolia at [0xE7987c70B54Ff32f0D5CBbAA8c8Fc1cAf632b9A5](https://sepolia.etherscan.io/address/0xE7987c70B54Ff32f0D5CBbAA8c8Fc1cAf632b9A5).\\n\\nIt is compatible with the current implementation of the RLN verifier.\\n\\n## Future work\\n\\n1. Optimize the gas costs of the tiered commitment tree.\\n2. Explore using different number of leaves under a given node in the tree (currently set to 2).\\n\\n## Conclusion\\n\\nThe tiered commitment tree is a promising approach to reduce the number of RPC calls required to sync the tree and reduce the gas costs associated with computing the root of the tree.\\nConsequently, it allows for a more scalable and efficient RLN verifier.\\n\\n## References\\n\\n- [RLN Circuits](https://github.com/rate-limiting-nullifier/circom-rln)\\n- [Zerokit](https://github.com/vacp2p/zerokit)\\n- [RLN-V1 RFC](https://rfc.vac.dev/spec/32/)\\n- [RLN-V2 RFC](https://rfc.vac.dev/spec/58/)\\n- [RLN Implementers guide](https://hackmd.io/7cBCMU5hS5OYv8PTaW2wAQ?view)\\n- [Strengthening Anonymous DoS Prevention with Rate Limiting Nullifiers in Waku](https://vac.dev/rlog/rln-anonymous-dos-prevention)"},{"id":"rln-anonymous-dos-prevention","metadata":{"permalink":"/rlog/rln-anonymous-dos-prevention","source":"@site/rlog/2023-11-07-rln-relay.mdx","title":"Strengthening Anonymous DoS Prevention with Rate Limiting Nullifiers in Waku","description":"Rate Limiting Nullifiers in practice, applied to an anonymous p2p network, like Waku.","date":"2023-11-07T12:00:00.000Z","formattedDate":"November 7, 2023","tags":[],"readingTime":6.77,"hasTruncateMarker":true,"authors":[{"name":"Aaryamann","twitter":"p1ge0nh8er","github":"rymnc","key":"p1ge0nh8er"}],"frontMatter":{"title":"Strengthening Anonymous DoS Prevention with Rate Limiting Nullifiers in Waku","date":"2023-11-07T12:00:00.000Z","authors":"p1ge0nh8er","published":true,"slug":"rln-anonymous-dos-prevention","categories":"research","toc_min_heading_level":2,"toc_max_heading_level":4},"prevItem":{"title":"Verifying RLN Proofs in Light Clients with Subtrees","permalink":"/rlog/rln-light-verifiers"},"nextItem":{"title":"GossipSub Improvements: Evolution of Overlay Design and Message Dissemination in Unstructured P2P Networks","permalink":"/rlog/GossipSub Improvements"}},"content":"Rate Limiting Nullifiers in practice, applied to an anonymous p2p network, like Waku.\\n\\n\x3c!--truncate--\x3e\\n\\n## Introduction\\n\\nRate Limiting Nullifier (RLN) is a zero-knowledge gadget that allows users to prove 2 pieces of information,\\n1. They belong to a permissioned membership set\\n2. Their rate of signaling abides by a fixed number that has been previously declared\\n\\nThe \\"membership set\\" introduced above, is in the form of a sparse, indexed merkle tree.\\nThis membership set can be maintained on-chain, off-chain or as a hybrid depending on the network\'s storage costs.\\nWaku makes use of a hybrid membership set, \\nwhere insertions are tracked in a smart contract.\\nIn addition, each Waku node maintains a local copy of the tree, \\nwhich is updated upon each insertion.\\n\\nUsers register themselves with a hash of a locally generated secret, \\nwhich is then inserted into the tree at the next available index.\\nAfter having registered, users can prove their membership by proving their knowledge of the pre-image of the respective leaf in the tree.\\nThe leaf hashes are also referred to as commitments of the respective users.\\nThe actual proof is done by a [Merkle Inclusion Proof](https://ethereum.org/en/developers/tutorials/merkle-proofs-for-offline-data-integrity/), which is a type of ZK proof.\\n\\nThe circuit ensures that the user\'s secret does indeed hash to a leaf in the tree,\\nand that the provided Merkle proof is valid.\\n\\nAfter a User generates this Merkle proof, \\nthey can transmit it to other users, \\nwho can verify the proof.\\nIncluding a message\'s hash within the proof generation, \\nadditionally guarantees integrity of that message.\\n\\nA malicious user could generate multiple proofs per epoch.\\nthey generate multiple proofs per epoch.\\nHowever, when multiple proofs are generated per epoch, \\nthe malicious user\'s secret is exposed, which strongly disincentivizes this attack.\\nThis mechanism is further described in [malicious User secret interpolation mechanism](#malicious-user-secret-interpolation-mechanism)\\n\\nNote: This blog post describes rln-v1, which excludes the range check in favor of a global rate limit for all users,\\nwhich is once per time window. This version is currently in use in waku-rln-relay.\\n\\n## RLN Protocol parameters\\n\\nGiven below is the set of cryptographic primitives, \\nand constants that are used in the RLN protocol. \\n\\n1. Proving System: [`groth16`](https://eprint.iacr.org/2016/260.pdf)\\n2. Elliptic Curve: [`bn254`](https://eprint.iacr.org/2013/879.pdf) (aka bn128) (not to be confused with the 254 bit Weierstrass curve)\\n3. Finite Field: Prime-order subgroup of the group of points on the `bn254` curve\\n4. Default Merkle Tree Height: `20`\\n5. Hashing algorithm: [`Poseidon`](https://eprint.iacr.org/2019/458.pdf)\\n6. Merkle Tree: [`Sparse Indexed Merkle Tree`](https://github.com/rate-limiting-nullifier/pmtree)\\n7. Messages per epoch: `1`\\n8. Epoch duration: `10 seconds`\\n\\n## Malicious User secret interpolation mechanism\\n\\n> note: all the parameters mentioned below are elements in the finite field mentioned above.\\n\\nThe private inputs to the circuit are as follows: -\\n```\\nidentitySecret: the randomly generated secret of the user\\nidentityPathIndex: the index of the commitment derived from the secret\\npathElements: elements included in the path to the index of the commitment\\n```\\n\\nFollowing are the public inputs to the circuit -\\n```\\nx: hash of the signal to the finite field\\nrlnIdentifier: application-specific identifier which this proof is being generated for\\nepoch: the timestamp which this proof is being generated for\\n```\\n\\nThe outputs of the circuit are as follows: -\\n```\\ny: result of Shamir\'s secret sharing calculation\\nroot: root of the Merkle tree obtained after applying the inclusion proof\\nnullifier: uniquely identifies a message, derived from rlnIdentifier, epoch, and the user\'s secret\\n```\\n\\nWith the above data in mind, following is the circuit pseudocode -\\n\\n```\\nidentityCommitment = Poseidon([identitySecret])\\nroot = MerkleInclusionProof(identityCommitment, identityPathIndex, pathElements)\\nexternalNullifier = Poseidon([epoch, rlnIdentifier])\\na1 = Poseidon([identitySecret, externalNullifier])\\ny = identitySecret + a1 * x\\nnullifier = Poseidon([a1])\\n```\\n\\nTo interpolate the secret of a user who has sent multiple signals during the same epoch to the same rln-based application, we may make use of the following formula -\\n\\n$$a_1 = {(y_1 - y_2) \\\\over (x_1 - x_2)}$$\\n\\nwhere $x_1$, $y_1$ and $x_2$, $y_2$ are shares from different messages\\n\\nsubsequently, we may use one pair of the shares, $x_1$ and $y_1$ to obtain the `identitySecret`\\n\\n$$identitySecret = y_1 - a_1 * x$$\\n\\nThis enables RLN to be used for rate limiting with a *global* limit. For arbitrary limits,\\nplease refer to an article written by @curryrasul, [rln-v2](https://mirror.xyz/privacy-scaling-explorations.eth/iCLmH1JVb7fDqp6Mms2NR001m2_n5OOSHsLF2QrxDnQ).\\n\\n\\n## Waku\'s problem with DoS\\n\\nIn a decentralized, privacy focused messaging system like [Waku](https://waku.org),\\nDenial of Service (DoS) vulnerabilities are very common, and must be addressed to promote network scale and optimal bandwidth utilization.\\n\\n### DoS prevention with user metadata\\n\\nThere are a couple of ways a user can be rate-limited, either -\\n1. IP Logging\\n2. KYC Logging\\n\\nBoth IP and KYC logging prevent systems from being truly anonymous, and hence, cannot be used as a valid DoS prevention mechanism for Waku.\\n\\nRLN can be used as an alternative, which provides the best of both worlds, i.e a permissioned membership set, as well as anonymous signaling.\\nHowever, we are bound by k-anonymity rules of the membership set.\\n\\n[Waku-RLN-Relay](https://rfc.vac.dev/spec/17/) is a [libp2p](https://libp2p.io) pubsub validator that verifies if a proof attached to a given message is valid.\\nIn case the proof is valid, the message is relayed.\\n\\n## Performance analysis\\n\\n> Test bench specs: AMD EPYC 7502P 32-Core, 4x32GB DDR4 Reg.ECC Memory \\n\\nThis simulation was conducted by @alrevuelta, and is described in more detail [here](https://github.com/waku-org/research/issues/23).\\n\\nThe simulation included 100 waku nodes running in parallel.\\n\\nProof generation times - \\n![img](/img/rln-relay-2023-update//proof_generation_time.png)\\n\\nProof verification times -\\n![img](/img/rln-relay-2023-update/proof_verification_time.png)\\n\\nA spammer node publishes 3000 msg/epoch, which is detected by all connected nodes, and subsequently disconnect to prevent further spam -\\n![img](/img/rln-relay-2023-update/spam_prevention_in_action.png)\\n\\n\\n## Security analysis\\n\\n[Barbulescu and Duquesne](https://doi.org/10.1007/s00145-018-9280-5)\\nconclude that that the `bn254` curve has only 100 bits of security.\\nSince the bn254 curve has a small embedding degree,\\nit is vulnerable to the [MOV attack](https://en.wikipedia.org/wiki/MOV_attack).\\nHowever, the MOV attack is only applicable to pairings,\\nand not to the elliptic curve itself.\\nIt is acceptable to use the bn254 curve for RLN,\\nsince the circuit does not make use of pairings.\\n\\n[An analysis](https://github.com/vacp2p/research/issues/155) on the number of rounds in the Poseidon hash function was done,\\nwhich concluded that the hashing rounds should *not* be reduced, \\n\\nThe [smart contracts](https://github.com/vacp2p/rln-contract) have *not* been audited, and are not recommended for real world deployments *yet*.\\n\\n\\n## Storage analysis\\n\\n$$\\ncommitment\\\\_size = 32\\\\ bytes \\\\\\\\\\ntree\\\\_height =20 \\\\\\\\\\ntotal\\\\_leaves = 2^{20} \\\\\\\\ \\nmax\\\\_tree\\\\_size = total\\\\_leaves * commitment\\\\_size \\\\\\\\\\nmax\\\\_tree\\\\_size = 2^{20} * 32 = 33,554,432 \\\\\\\\\\n\u2234max\\\\_tree\\\\_size = 33.55\\\\ megabytes\\n$$\\nThe storage overhead introduced by RLN is minimal.\\nRLN only requires 34 megabytes of storage, which poses no problem on most end-user hardware, with the exception of IoT/microcontrollers.\\nStill, we are working on further optimizations allowing proof generation without having to store the full tree.\\n\\n## The bare minimum requirements to run RLN\\n\\nWith proof generation time in sub-second latency, along with low storage overhead for the tree,\\nit is possible for end users to generate and verify RLN proofs on a modern smartphone.\\n\\nFollowing is a demo provided by @rramos that demonstrates\\n[waku-rln-relay used in react native](https://drive.google.com/file/d/1ITLYrDOQrHQX2_3Q6O5EqKPYJN8Ye2gF/view?usp=sharing).\\n\\n> Warning: The react native sdk will be deprecated soon, and the above demo should serve as a PoC for RLN on mobiles\\n\\n## RLN usage guide\\n\\n[Zerokit](https://github.com/vacp2p/zerokit) implements api\'s that allow users to handle operations to the tree, \\nas well as generate/verify RLN proofs.\\n\\nOur main implementation of RLN can be accessed via this Rust [crate](https://crates.io/crates/rln),\\nwhich is documented [here](https://docs.rs/rln/0.4.1/rln/public/struct.RLN.html).\\nIt can used in other langugages via the FFI API, which is documented [here](https://docs.rs/rln/0.4.1/rln/ffi/index.html).\\nThe usage of RLN in Waku is detailed in our [RLN Implementers guide](https://hackmd.io/7cBCMU5hS5OYv8PTaW2wAQ?view),\\nwhich provides step-by-step instructions on how to run Waku-RLN-Relay.\\n\\nFollowing is a diagram that will help understand the dependency tree -\\n\\n![rln-dep-tree](/img/rln-relay-2023-update/rln_dep_tree.jpg)\\n\\n## Future work\\n\\n- Optimizations to zerokit for proof generation time.\\n- Incrementing tree depth from 20 to 32, to allow more memberships.\\n- Optimizations to the smart contract.\\n- An ability to signal validity of a message in different time windows.\\n- Usage of proving systems other than Groth16.\\n\\n## References\\n\\n* [RLN Circuits](https://github.com/rate-limiting-nullifier/circom-rln)\\n* [Zerokit](https://github.com/vacp2p/zerokit)\\n* [RLN-V1 RFC](https://rfc.vac.dev/spec/32/)\\n* [RLN-V2 RFC](https://rfc.vac.dev/spec/58/)\\n* [RLN Implementers guide](https://hackmd.io/7cBCMU5hS5OYv8PTaW2wAQ?view)\\n* [groth16](https://eprint.iacr.org/2016/260.pdf)\\n* [bn254](https://eprint.iacr.org/2013/879.pdf)\\n* [Poseidon Hash](https://eprint.iacr.org/2019/458.pdf)\\n* [Sparse Indexed Merkle Tree](https://github.com/rate-limiting-nullifier/pmtree)\\n* [Updating key size estimations for pairings](https://doi.org/10.1007/s00145-018-9280-5)"},{"id":"GossipSub Improvements","metadata":{"permalink":"/rlog/GossipSub Improvements","source":"@site/rlog/2023-09-27-gossipimprovements.mdx","title":"GossipSub Improvements: Evolution of Overlay Design and Message Dissemination in Unstructured P2P Networks","description":"GossipSub Improvements: Evolution of Overlay Design and Message Dissemination in Unstructured P2P Networks","date":"2023-11-06T12:00:00.000Z","formattedDate":"November 6, 2023","tags":[],"readingTime":13.815,"hasTruncateMarker":true,"authors":[{"name":"Umar Farooq","github":"ufarooqstatus","key":"farooq"}],"frontMatter":{"title":"GossipSub Improvements: Evolution of Overlay Design and Message Dissemination in Unstructured P2P Networks","date":"2023-11-06T12:00:00.000Z","authors":"farooq","published":true,"slug":"GossipSub Improvements","categories":"research","toc_min_heading_level":2,"toc_max_heading_level":5},"prevItem":{"title":"Strengthening Anonymous DoS Prevention with Rate Limiting Nullifiers in Waku","permalink":"/rlog/rln-anonymous-dos-prevention"},"nextItem":{"title":"Nescience - A zkVM leveraging hiding properties","permalink":"/rlog/Nescience-A-zkVM-leveraging-hiding-properties"}},"content":"GossipSub Improvements: Evolution of Overlay Design and Message Dissemination in Unstructured P2P Networks \\r\\n\\r\\n\x3c!--truncate--\x3e\\r\\n\\r\\n## Motivitation\\r\\nWe have been recently working on analyzing and improving the performance of the GossipSub protocol for large messages, \\r\\nas in the case of Ethereum Improvement Proposal [EIP-4844](https://eips.ethereum.org/EIPS/eip-4844).\\r\\nThis work led to a comprehensive study of unstructured P2P networks. \\r\\nThe intention was to identify the best practices that can serve as guidelines for performance improvement and scalability of P2P networks.\\r\\n\\r\\n## Introduction\\r\\n\\r\\nNodes in an unstructured p2p network form self-organizing overlay(s) on top of the IP infrastructure to facilitate different services like information dissemination,\\r\\nquery propagation, file sharing, etc. The overlay(s) can be as optimal as a tree-like structure or as enforcing as a fully connected mesh. \\r\\n\\r\\nDue to peer autonomy and a trustless computing environment, some peers may deviate from the expected operation or even leave the network.\\r\\nAt the same time, the underlying IP layer is unreliable. \\r\\n\\r\\nTherefore, tree-like overlays are not best suited for reliable information propagation.\\r\\nMoreover, tree-based solutions usually result in significantly higher message dissemination latency due to suboptimal branches. \\r\\n\\r\\nFlooding-based solutions, on the other hand, result in maximum resilience against adversaries and achieve minimal message dissemination latency because the message propagates through all (including the optimal) paths. \\r\\nRedundant transmissions help maintain the integrity and security of the network in the presence of adversaries and high node failure but significantly increase network-wide bandwidth utilization, cramming the bottleneck links. \\r\\n\\r\\nAn efficient alternative is to lower the number of redundant transmissions by D-regular broadcasting, where a peer will likely receive (or relay) a message from up to $D$ random peers.\\r\\nPublishing through a D-regular overlay triggers approximately $N \\\\times D$ transmissions.\\r\\nReducing $D$ reduces the redundant transmissions but compromises reachability and latency. \\r\\nSharing metadata through a K-regular overlay (where $K > D$) allows nodes to pull missing messages. \\r\\n\\r\\nGossipSub [[1](https://arxiv.org/pdf/2007.02754.pdf)] benefits from full-message (D-regular) and metadata-only (k-regular) overlays.\\r\\nAlternatively, a metadata-only overlay can be used, requiring a pull-based operation that significantly minimizes bandwidth utilization at the cost of increased latency. \\r\\n\\r\\nStriking the right balance between parameters like $D, K$, pull-based operation, etc., can yield application-specific performance tuning, but scalability remains a problem.\\r\\n\\r\\nAt the same time, many other aspects can significantly contribute to the network\'s performance and scalability.\\r\\nOne option is to realize peers\' suitability and continuously changing capabilities while forming overlays. \\r\\n\\r\\nFor instance, a low-bandwidth link near a publisher can significantly demean the entire network\'s performance.\\r\\nReshuffling of peering links according to the changing network conditions can lead to superior performance. \\r\\n\\r\\nLaying off additional responsibilities to more capable nodes (super nodes) can alleviate peer cramming, but it makes the network susceptible to adversaries/peer churn.\\r\\nGrouping multiple super nodes to form virtual node(s) can solve this problem. \\r\\n\\r\\n\\r\\nSimilarly, flat (single-tier) overlays cannot address the routing needs in large (geographically dispersed) networks.\\r\\n\\r\\nHierarchical (Multi-tier) overlays with different intra/inter-overlay routing solutions can better address these needs.\\r\\nMoreover, using message aggregation schemes for grouping multiple messages can save bandwidth and provide better resilience against adversaries/peer churn.\\r\\n\\r\\n\\r\\nThis article\'s primary objective is to investigate the possible choices that can empower an unstructured P2P network to achieve superior performance for the broadest set of applications. \\r\\nWe look into different constraints imposed by application-specific needs (performance goals) and investigate various choices that can augment the network\'s performance. \\r\\nWe explore overlay designs/freshness, peer selection approaches, message-relaying mechanisms, and resilience against adversaries/peer churn. \\r\\nWe consider GossipSub a baseline protocol to explore various possibilities and decisively commit to the ones demonstrating superior performance.\\r\\nWe also discuss the current state and, where applicable, propose a strategic plan for embedding new features to the GossipSub protocol. \\r\\n\\r\\n\\r\\n## GOAL1: Low Latency Operation\\r\\nDifferent applications, like blockchain, streaming, etc., impose strict time bounds on network-wide message dissemination latency. \\r\\nA message delivered after the imposed time bounds is considered as dropped. \\r\\nAn early message delivery in applications like live streaming can further enhance the viewing quality.\\r\\n\\r\\nThe properties and nature of the overlay network topology significantly impact the performance of services and applications executed on top of them. \\r\\nStudying and devising mechanisms for better overlay design and message dissemination is paramount to achieving superior performance.\\r\\n\\r\\nInterestingly, shortest-path message delivery trees have many limitations: \\r\\n\\r\\n1) Changing network dynamics requires a quicker and continuous readjustment of the multicast tree. \\r\\n2) The presence of resource-constrained (bandwidth/compute, etc.) nodes in the overlay can result in congestion. \\r\\n3) Node failure can result in partitions, making many segments unreachable. \\r\\n4) Assuring a shortest-path tree-like structure requires a detailed view of the underlying (and continuously changing) network topology. \\r\\n\\r\\n\\r\\nSolutions involve creating multiple random trees to add redundancy [[2](https://ieeexplore.ieee.org/abstract/document/6267905)].\\r\\nAlternatives involve building an overlay mesh and forwarding messages through the multicast delivery tree (eager push). \\r\\n\\r\\nMetadata is shared through the overlay links so that the nodes can ask for missing messages (lazy push or pull-based operation) through the overlay links. \\r\\nNew nodes are added from the overlay on node failure, but it requires non-faulty node selection.\\r\\n\\r\\nGossipSub uses eager push (through overlay mesh) and lazy push (through IWANT messages). \\r\\n\\r\\nThe mesh degree $D_{Low} \\\\leq D \\\\leq D_{High}$ is crucial in deciding message dissemination latency. \\r\\nA smaller value for $D$ results in higher latency due to increased rounds, whereas a higher $D$ reduces latency on the cost of increased bandwidth. \\r\\nAt the same time, keeping $D$ independent of the growing network size ($N$) may increase network-wide message dissemination latency.\\r\\nAdjusting $D$ with $N$ maintains similar latency on the cost of increased workload for peers. \\r\\nAuthors in [[3](https://infoscience.epfl.ch/record/83478/files/EugGueKerMas04IEEEComp.pdf)] suggest only a logarithmic increase in $D$ to maintain a manageable workload for peers.\\r\\nIn [[4](https://inria.hal.science/tel-02375909/document)], it is reported that the average mesh degree should not exceed $D_{avg} = \\\\ln(N) + C$ for an optimal operation, \\r\\nwhere $C$ is a small constant.\\r\\n\\r\\nMoreover, quicker shuffling of peers results in better performance in the presence of resource-constrained nodes or node failure [[4](https://inria.hal.science/tel-02375909/document)].\\r\\n\\r\\n## GOAL2: Considering Heterogeneity In Overlay Design\\r\\nRandom peering connections in P2P overlays represent a stochastic process. It is inherently difficult to precisely model the performance of such systems. \\r\\nMost of the research on P2P networks provides simulation results assuming nodes with similar capabilities. \\r\\nThe aspect of dissimilar capabilities and resource-constrained nodes is less explored.\\r\\n\\r\\nIt is discussed in GOAL1 that overlay mesh results in better performance if $D_{avg}$ does not exceed $\\\\ln(N) + C$. \\r\\nEnforcing all the nodes to have approximately $\\\\ln(N) + C$ peers makes resource-rich nodes under-utilized, while resource-constrained nodes are overloaded. \\r\\nAt the same time, connecting high-bandwidth nodes through a low-bandwidth node undermines the network\'s performance.\\r\\nIdeally, the workload on any node should not exceed its available resources.\\r\\nA better solution involves a two-phased operation:\\r\\n\\r\\n\\r\\n1. Every node computes its available bandwidth and selects a node degree $D$ proportional to its available bandwidth [[4](https://inria.hal.science/tel-02375909/document)].\\r\\n Different bandwidth estimation approaches are suggested in literature [[5](https://ieeexplore.ieee.org/abstract/document/1224454),[6](https://ieeexplore.ieee.org/abstract/document/1248658)]. \\r\\n Simple bandwidth estimation approaches like variable packet size probing [[6](https://ieeexplore.ieee.org/abstract/document/1248658)] yield similar results with less complexity.\\r\\n It is also worth mentioning that many nodes may want to allocate only a capped share of their bandwidth to the network. \\r\\n Lowering $D$ according to the available bandwidth can still prove helpful. \\r\\n Additionally, bandwidth preservation at the transport layer through approaches like \xb5TP can be useful.\\r\\n To further conform to the suggested mesh-degree average $D_{avg}$, every node tries achieving this average within its neighborhood, resulting in an overall similar $D_{avg}$.\\r\\n\\r\\n2. From the available local view, every node tries connecting peers with the lowest latency until $D$ connections are made.\\r\\n We suggest referring to the peering solution discussed in GOAL5 to avoid network partitioning.\\r\\n\\r\\nThe current GossipSub design considers homogeneous peers, and every node tries maintaining $D_{Low} \\\\leq D \\\\leq D_{High}$ connections. \\r\\n\\r\\n\\r\\n## GOAL3: Bandwidth Optimization\\r\\nRedundant message transmissions are essential for handling adversaries/node failure. However, these transmissions result in traffic bursts, cramming many overlay links. \\r\\nThis not only adds to the network-wide message dissemination latency but a significant share of the network\'s bandwidth is wasted on (usually) unnecessary transmissions. \\r\\nIt is essential to explore solutions that can minimize the number of redundant transmissions while assuring resilience against node failures. \\r\\n\\r\\nMany efforts have been made to minimize the impact of redundant transmissions. \\r\\nThese solutions include multicast delivery trees, metadata sharing to enable pull-based operation, in-network information caching, etc. [[7](https://dl.acm.org/doi/abs/10.1145/945445.945473),[8](https://link.springer.com/chapter/10.1007/11558989_12)]. \\r\\nGossipSub employs a hybrid of eager push (message dissemination through the overlay) and lazy push (a pull-based operation by the nodes requiring information through IWANT messages). \\r\\n\\r\\nA better alternative to simple redundant transmission is to use message aggregation [[9](https://ieeexplore.ieee.org/abstract/document/8737576),[10](https://dl.acm.org/doi/abs/10.1145/1993636.1993676),[11](https://ieeexplore.ieee.org/abstract/document/4276446)] for the GossipSub protocol. \\r\\nAs a result, redundant message transmissions can serve as a critical advantage of the GossipSub protocol. \\r\\nSuppose that we have three equal-length messages $x1, x2, x3$. Assuming an XOR coding function,\\r\\nwe know two trivial properties: $x1 \\\\oplus x2 \\\\oplus x2 = x1$ and $\\\\vert x1 \\\\vert = \\\\vert x1 \\\\oplus x2 \\\\oplus x2 \\\\vert$. \\r\\n\\r\\nThis implies that instead of sending messages individually, we can encode and transmit composite message(s) to the network. \\r\\nThe receiver can reconstruct the original message from encoded segments. \\r\\nAs a result, fewer transmissions are sufficient for sending more messages to the network. \\r\\n\\r\\nHowever, sharing linear combinations of messages requires organizing messages in intervals, \\r\\nand devising techniques to identify all messages belonging to each interval.\\r\\nIn addition, combining messages from different publishers requires more complex arrangements, \\r\\ninvolving embedding publisher/message IDs, delayed forwarding (to accommodate more messages), and mechanisms to ensure the decoding of messages at all peers.\\r\\nCareful application-specific need analysis can help decide the benefits against the added complexity. \\r\\n\\r\\n## GOAL4: Handling Large Messages\\r\\nMany applications require transferring large messages for their successful operation. For instance, database/blockchain transactions [[12](https://eips.ethereum.org/EIPS/eip-4844)]. \\r\\nThis introduces two challenges: \\r\\n\\r\\n1) Redundant large message transmissions result in severe network congestion. \\r\\n2) Message transmissions follow a store/forward process at all peers, which is inefficient in the case of large messages. \\r\\n\\r\\nThe above-mentioned challenges result in a noticeable increase in message dissemination latency and bandwidth wastage. \\r\\nMost of the work done for handling large messages involves curtailing redundant transmissions using multicast delivery trees,\\r\\nreducing the number of fanout nodes, employing in-network message caching, pull-based operation, etc.\\r\\n\\r\\nApproaches like message aggregation also prove helpful in minimizing bandwidth wastage.\\r\\n\\r\\nOur recent work on GossipSub improvements (still a work in progress) suggests the following solutions to deal with large message transmissions: \\r\\n\\r\\n1. Using IDontWant message proposal [[13](https://github.com/libp2p/specs/pull/413)] and staggered sending. \\r\\n\\r\\n IDontWant message helps curtail redundant transmissions by letting other peers know we have already received the message.\\r\\n Staggered sending enables relaying the message to a short subset of peers in each round.\\r\\n We argue that simultaneously relaying a message to all peers hampers the effectiveness of the IDontWant message.\\r\\n Therefore, using the IDontWant message with staggered sending can yield better results by allowing timely reception and processing of IDontWant messages.\\r\\n\\r\\n2. Message transmissions follow a store/forward process at all peers that is inefficient in the case of large messages.\\r\\n We can parallelize message transmission by partitioning large messages into smaller fragments, letting intermediate peers relay these fragments as soon as they receive them.\\r\\n\\r\\n\\r\\n## GOAL5: Scalability\\r\\nP2P networks are inherently scalable because every incoming node brings in bandwidth and compute resources.\\r\\nIn other words, we can keep adding nodes to the network as long as every incoming node brings at-least $R \\\\times D$ bandwidth, \\r\\nwhere $R$ is average data arrival rate. \\r\\nIt is worth mentioning that network-wide message dissemination requires at-least $\\\\lceil \\\\log_D (N) \\\\rceil$ hops. \\r\\nTherefore, increasing network size increases message dissemination latency, assuming D is independent of the network size.\\r\\n\\r\\nAdditionally, problems like peer churn, adversaries, heterogeneity, distributed operation, etc., significantly hamper the network\'s performance.\\r\\nMost efforts for bringing scalability to the P2P systems have focused on curtailing redundant transmissions and flat overlay adjustments.\\r\\nHierarchical overlay designs, on the other hand, are less explored.\\r\\n\\r\\nPlacing a logical structure in unstructured P2P systems can help scale P2P networks. \\r\\n\\r\\nOne possible solution is to use a hierarchical overlay inspired by the approaches [[14](https://link.springer.com/article/10.1007/s12083-016-0460-5),[15](https://link.springer.com/chapter/10.1007/978-3-030-19223-5_16),[16](https://ieeexplore.ieee.org/abstract/document/9826458)]. \\r\\nAn abstract operation of such overlay design is provided below:\\r\\n\\r\\n1. Clustering nodes based on locality, assuming that such peers will have relatively lower intra-cluster latency and higher bandwidth. \\r\\n For this purpose, every node tries connecting peers with the lowest latency until $D$ connections are made or the cluster limit is reached.\\r\\n\\r\\n2. A small subset of nodes having the highest bandwidth and compute resources is selected from each cluster. \\r\\n These super nodes form a fully connected mesh and jointly act as a virtual node, \\r\\n mitigating the problem of peer churn among super nodes.\\r\\n \\r\\n3. Virtual nodes form a fully connected mesh to construct a hierarchical overlay. \\r\\n Each virtual node is essentially a collection of super nodes; \\r\\n a link to any of the constituent super nodes represents a link to the virtual node.\\r\\n\\r\\n4. One possible idea is to use GossipSub for intra-cluster message dissemination and FloodSub for inter-cluster message dissemination.\\r\\n\\r\\n## Summary\\r\\nOverlay acts as a virtual backbone for a P2P network. A flat overlay is more straightforward and allows effortless readjustment to application needs. \\r\\nOn the other hand, a hierarchical overlay can bring scalability at the cost of increased complexity. \\r\\nRegardless of the overlay design, a continuous readjustment to appropriate peering links is essential for superior performance. \\r\\nAt the same time, bandwidth preservation (through message aggregation, caching at strategic locations, metadata sharing, pull-based operation, etc.) can help minimize latency.\\r\\nHowever, problems like peer churn and in-network adversaries can be best alleviated through balanced redundant coverage, and frequent reshuffling of the peering links.\\r\\n\\r\\n# References\\r\\n\\r\\n* [1] D. Vyzovitis, Y. Napora, D. McCormick, D. Dias, and Y. Psaras, \u201cGossipsub: Attack-resilient message propagation in the filecoin and eth2. 0 networks,\u201d arXiv preprint arXiv:2007.02754, 2020. Retrieved from https://arxiv.org/pdf/2007.02754.pdf\\r\\n* [2] M. Matos, V. Schiavoni, P. Felber, R. Oliveira, and E. Riviere, \u201cBrisa: Combining efficiency and reliability in epidemic data dissemination,\u201d in 2012 IEEE 26th International Parallel and Distributed Processing Symposium. IEEE, 2012, pp. 983\u2013994. Retrieved from https://ieeexplore.ieee.org/abstract/document/6267905\\r\\n* [3] P. T. Eugster, R. Guerraoui, A. M. Kermarrec, and L. Massouli, \u201cEpidemic information dissemination in distributed systems,\u201d IEEE Computer, vol. 37, no. 5, 2004. Retrieved from https://infoscience.epfl.ch/record/83478/files/EugGueKerMas04IEEEComp.pdf\\r\\n* [4] D. Frey, \u201cEpidemic protocols: From large scale to big data,\u201d Ph.D. dissertation, Universite De Rennes 1, 2019. Retrieved from https://inria.hal.science/tel-02375909/document\\r\\n* [5] M. Jain and C. Dovrolis, \u201cEnd-to-end available bandwidth: measurement methodology, dynamics, and relation with tcp throughput,\u201d IEEE/ACM Transactions on networking, vol. 11, no. 4, pp. 537\u2013549, 2003. Retrieved from https://ieeexplore.ieee.org/abstract/document/1224454\\r\\n* [6] R. Prasad, C. Dovrolis, M. Murray, and K. Claffy, \u201cBandwidth estimation: metrics, measurement techniques, and tools,\u201d IEEE network, vol. 17, no. 6, pp. 27\u201335, 2003. Retrieved from https://ieeexplore.ieee.org/abstract/document/1248658\\r\\n* [7] D. Kostic, A. Rodriguez, J. Albrecht, and A. Vahdat, \u201cBullet: High bandwidth data dissemination using an overlay mesh,\u201d in Proceedings of the nineteenth ACM symposium on Operating systems principles, 2003, pp. 282\u2013297. Retrieved from https://dl.acm.org/doi/abs/10.1145/945445.945473\\r\\n* [8] V. Pai, K. Kumar, K. Tamilmani, V. Sambamurthy, and A. E. Mohr, \u201cChainsaw: Eliminating trees from overlay multicast,\u201d in Peer-to-Peer Systems IV: 4th International Workshop, IPTPS 2005, Ithaca, NY, USA, February 24-25, 2005. Revised Selected Papers 4. Springer, 2005, pp. 127\u2013140. Retrieved from https://link.springer.com/chapter/10.1007/11558989_12\\r\\n* [9] Y.-D. Bromberg, Q. Dufour, and D. Frey, \u201cMultisource rumor spreading with network coding,\u201d in IEEE INFOCOM 2019-IEEE Conference on Computer Communications. IEEE, 2019, pp. 2359\u20132367. Retrieved from https://ieeexplore.ieee.org/abstract/document/8737576\\r\\n* [10] B. Haeupler, \u201cAnalyzing network coding gossip made easy,\u201d in Proceedings of the forty-third annual ACM symposium on Theory of computing, 2011, pp. 293\u2013302. Retrieved from https://dl.acm.org/doi/abs/10.1145/1993636.1993676\\r\\n* [11] S. Yu and Z. Li, \u201cMassive data delivery in unstructured peer-to-peer networks with network coding,\u201d in 6th IEEE/ACIS International Conference on Computer and Information Science (ICIS 2007). IEEE, 2007, pp. 592\u2013597. Retrieved from https://ieeexplore.ieee.org/abstract/document/4276446\\r\\n* [12] V. Buterin, D. Feist, D. Loerakker, G. Kadianakis, M. Garnett, M. Taiwo, and A. Dietrichs, \u201cEip-4844: Shard blob transactions scale data-availability of ethereum in a simple, forwards-compatible manner,\u201d 2022. Retrieved from https://eips.ethereum.org/EIPS/eip-4844\\r\\n* [13] A. Manning, \u201cGossipsub extension for epidemic meshes (v1.2.0),\u201d 2022. Retrieved from https://github.com/libp2p/specs/pull/413\\r\\n* [14] Z. Duan, C. Tian, M. Zhou, X. Wang, N. Zhang, H. Du, and L. Wang, \u201cTwo-layer hybrid peer-to-peer networks,\u201d Peer-to-Peer Networking and Applications, vol. 10, pp. 1304\u20131322, 2017. Retrieved from https://link.springer.com/article/10.1007/s12083-016-0460-5\\r\\n* [15] W. Hao, J. Zeng, X. Dai, J. Xiao, Q. Hua, H. Chen, K.-C. Li, and H. Jin, \u201cBlockp2p: Enabling fast blockchain broadcast with scalable peer-to-peer network topology,\u201d in Green, Pervasive, and Cloud Computing: 14th International Conference, GPC 2019, Uberlandia, Brazil, May 26\u201328, 2019, Proceedings 14. Springer, 2019, pp. 223\u2013237. Retrieved from https://link.springer.com/chapter/10.1007/978-3-030-19223-5_16\\r\\n* [16] H. Qiu, T. Ji, S. Zhao, X. Chen, J. Qi, H. Cui, and S. Wang, \u201cA geography-based p2p overlay network for fast and robust blockchain systems,\u201d IEEE Transactions on Services Computing, 2022. Retrieved from https://ieeexplore.ieee.org/abstract/document/9826458"},{"id":"Nescience-A-zkVM-leveraging-hiding-properties","metadata":{"permalink":"/rlog/Nescience-A-zkVM-leveraging-hiding-properties","source":"@site/rlog/2023-08-28-Nescience.mdx","title":"Nescience - A zkVM leveraging hiding properties","description":"Nescience, a privacy-first blockchain zkVM.","date":"2023-08-28T12:00:00.000Z","formattedDate":"August 28, 2023","tags":[],"readingTime":31.34,"hasTruncateMarker":true,"authors":[{"name":"Moudy","github":"moudyellaz","key":"moudy"}],"frontMatter":{"title":"Nescience - A zkVM leveraging hiding properties","date":"2023-08-28T12:00:00.000Z","authors":"moudy","published":true,"slug":"Nescience-A-zkVM-leveraging-hiding-properties","categories":"research","toc_min_heading_level":2,"toc_max_heading_level":5},"prevItem":{"title":"GossipSub Improvements: Evolution of Overlay Design and Message Dissemination in Unstructured P2P Networks","permalink":"/rlog/GossipSub Improvements"},"nextItem":{"title":"Device Pairing in Js-waku and Go-waku","permalink":"/rlog/device-pairing-in-js-waku-and-go-waku"}},"content":"Nescience, a privacy-first blockchain zkVM. \\n\\n\x3c!--truncate--\x3e\\n\\n## Introduction\\n\\nNescience is a privacy-first blockchain project that aims to enable private transactions and provide a general-purpose execution environment for classical applications. \\nThe goals include creating a state separation architecture for public/private computation, \\ndesigning a versatile virtual machine based on mainstream instruction sets, \\ncreating proofs for private state updates, implementing a kernel-based architecture for correct execution of private functions, \\nand implementing core DeFi protocols such as AMMs and staking from a privacy perspective. \\n\\nIt intends to create a user experience that is similar to public blockchains, but with additional privacy features that users can leverage at will. \\nTo achieve this goal, Nescience will implement a versatile virtual machine that can be used to implement existing blockchain applications, \\nwhile also enabling the development of privacy-centric protocols such as private staking and private DEXs.\\n\\nTo ensure minimal trust assumptions and prevent information leakage, Nescience proposes a proof system that allows users to create proofs for private state updates, \\nwhile the verification of the proofs and the execution of the public functions inside the virtual machine can be delegated to an external incentivised prover. \\n\\nIt also aims to implement a seamless interaction between public and private state, enabling composability between contracts, and private and public functions. \\nFinally, Nescience intends to implement permissive licensing, which means that the source code will be open-source, \\nand developers will be able to use and modify the code without any restriction.\\n\\nOur primary objective is the construction of the Zero-Knowledge Virtual Machine (zkVM). This document serves as a detailed exploration of the multifaceted challenges, \\npotential solutions, and alternatives that lay ahead. Each step is a testament to our commitment to thoroughness; \\nwe systematically test various possibilities and decisively commit to the one that demonstrates paramount performance and utility. \\nFor instance, as we progress towards achieving Goal 2, we are undertaking a rigorous benchmarking of the Nova proof system against its contemporaries. \\nShould Nova showcase superior performance metrics, we stand ready to integrate it as our proof system of choice. Through such meticulous approaches, \\nwe not only reinforce the foundation of our project but also ensure its scalability and robustness in the ever-evolving landscape of blockchain technology.\\n\\n\\n## Goal 1: Create a State Separation Architecture\\n\\nThe initial goal revolves around crafting a distinctive architecture that segregates public and private computations, \\nemploying an account-based framework for the public state and a UTXO-based structure for the private state. \\n\\nThe UTXO model [[1]( https://bitcoin.org/bitcoin.pdf),[2](https://iohk.io/en/blog/posts/2021/03/11/cardanos-extended-utxo-accounting-model/)], notably utilized in Bitcoin, generates new UTXOs to serve future transactions, \\nwhile the account-based paradigm assigns balances to accounts that transactions can modify. \\nAlthough the UTXO model bolsters privacy by concealing comprehensive balances, \\nthe pursuit of a dual architecture mandates a meticulous synchronization of these state models, \\nensuring that private transactions remain inconspicuous in the wider public network state. \\n\\nThis task is further complicated by the divergent transaction processing methods intrinsic to each model, \\nnecessitating a thoughtful and innovative approach to harmonize their functionality. \\nTo seamlessly bring together the dual architecture, harmonizing the account-based model for public state with the UTXO-based model for private state, \\na comprehensive strategy is essential.\\n\\nThe concept of blending an account-based structure with a UTXO-based model for differentiating between public and private states is intriguing. \\nIt seeks to leverage the strengths of both models: the simplicity and directness of the account-based model with the privacy enhancements of the UTXO model.\\n\\nHere\'s a breakdown and a potential strategy for harmonizing these models:\\n\\n### Rationale Behind the Dual Architecture: \\n\\n* **Account-Based Model:** This model is intuitive and easy to work with. Every participant has an account, \\nand transactions directly modify the balances of these accounts. It\'s conducive for smart contracts and a broad range of applications.\\n\\n* **UTXO-Based Model:** This model treats every transaction as a new output, which can then be used as an input for future transactions. \\nBy not explicitly associating transaction outputs with user identities, it offers a degree of privacy.\\n\\n### Harmonizing the Two Systems: \\n\\n1. Translation Layer\\n\\n * Role: Interface between UTXO and account-based states.\\n\\n * _UTXO-to-Account Adapter:_ When UTXOs are spent, the adapter can translate these into the corresponding account balance modifications. \\n This could involve creating a temporary \'pseudo-account\' that mirrors the \\n UTXO\'s attributes.\\n\\n * _Account-to-UTXO Adapter:_ When an account wishes to make a private transaction, \\n it would initiate a process converting a part of its balance to a UTXO, facilitating a privacy transaction.\\n\\n2. Unified Identity Management\\n\\n * Role: Maintain a unified identity (or address) system that works across both state models, \\n allowing users to easily manage their public and private states without requiring separate identities.\\n\\n * _Deterministic Wallets:_ Use Hierarchical Deterministic (HD) wallets [[3](https://medium.com/mycrypto/the-journey-from-mnemonic-phrase-to-address-6c5e86e11e14),[4](https://github.com/bitcoin/bips/blob/master/bip-0032.mediawiki)], enabling users to generate multiple addresses (both UTXO and account-based) from a single seed. \\n This ensures privacy while keeping management centralized for the user.\\n\\n\\n3. State Commitments\\n\\n * Role: Use cryptographic commitments to commit to the state of both models. This can help in efficiently validating cross-model transactions.\\n \\n * _Verkle Trees:_ Verkle Trees combine Vector Commitment and the KZG polynomial commitment scheme to produce a structure that\'s efficient in terms of both proofs and verification.\\n Verkle proofs are considerably small in size (less data to store and transmit), where Transaction and state verifications can be faster due to the smaller proof sizes and computational efficiencies.\\n\\n * _Mimblewimble-style Aggregation_ [[5](https://github.com/mimblewimble/grin/blob/master/doc/intro.md)]: For UTXOs, techniques similar to those used in Mimblewimble can be used to aggregate transactions, keeping the state compact and enhancing privacy.\\n\\n\\n4. Batch Processing & Anonymity Sets\\n\\n * Role: Group several UTXO-based private transactions into a single public account-based transaction. \\n This can provide a level of obfuscation and can make synchronization between the two models more efficient.\\n\\n * _CoinJoin Technique_ [[6](https://en.bitcoin.it/wiki/CoinJoin)]: As seen in Bitcoin, multiple users can combine their UTXO transactions into one, enhancing privacy.\\n\\n * _Tornado Cash Principle_ [[7](https://github.com/tornadocash/tornado-classic-ui)]: For account-based systems wanting to achieve privacy, methods like those used in Tornado Cash can be implemented, \\n providing zk-SNARKs-based private transactions.\\n\\n5. Event Hooks & Smart Contracts\\n\\n * Role: Implement event-driven mechanisms that trigger specific actions in one model based on events in the other. \\n For instance, a private transaction (UTXO-based) can trigger a corresponding public notification or event in the account-based model.\\n\\n * _Conditional Execution:_ Smart contracts could be set to execute based on events in the UTXO system. For instance, \\n a smart contract might release funds (account-based) once a specific UTXO is spent.\\n\\n * _Privacy Smart Contracts:_ Using zk-SNARKs or zk-STARKs to bring privacy to the smart contract layer, \\n allowing for private logic execution.\\n\\n\\n### Challenges and Solutions \\n\\n1. Synchronization Overhead\\n\\n * Challenge: Combining two distinct transaction models creates an inherent synchronization challenge.\\n\\n * State Channels: By allowing transactions to be conducted off-chain between participants, state channels can alleviate synchronization stresses. \\n Only the final state needs to be settled on-chain, drastically reducing the amount of data and frequency of updates required.\\n\\n * Sidechains: These act as auxiliary chains to the main blockchain. Transactions can be processed on the sidechain and then periodically synced with the main chain. \\n This structure helps reduce the immediate load on the primary system.\\n\\n * Checkpointing: Introduce periodic checkpoints where the two systems\' states are verified and harmonized. \\n This can ensure consistency without constant synchronization.\\n\\n2. Double Spending\\n\\n * Challenge: With two models operating in tandem, there\'s an increased risk of double-spending attacks.\\n\\n * Multi-Signature Transactions: Implementing transactions that require signatures from both systems can prevent unauthorized movements.\\n\\n * Cross-Verification Mechanisms: Before finalizing a transaction, it undergoes verification in both UTXO and account-based systems. \\n If discrepancies arise, the transaction can be halted.\\n\\n * Timestamping: By attaching a timestamp to each transaction, it\'s possible to order them sequentially, making it easier to spot and prevent double spending.\\n\\n3. Complexity in User Experience\\n\\n * Challenge: The dual model, while powerful, is inherently complex.\\n\\n * Abstracted User Interfaces: Design UIs that handle the complexity behind the scenes, \\n allowing users to make transactions without needing to understand the nuances of the dual model.\\n\\n * Guided Tutorials: Offer onboarding tutorials to acquaint users with the system\'s features, \\n especially emphasizing when and why they might choose one transaction type over the other.\\n\\n * Feedback Systems: Implement systems where users can provide feedback on any complexities or challenges they encounter. \\n This real-time feedback can be invaluable for iterative design improvements.\\n\\n4. Security\\n\\n * Challenge: Merging two systems can introduce unforeseen vulnerabilities.\\n\\n * Threat Modeling: Regularly conduct threat modeling exercises to anticipate potential attack vectors, \\n especially those that might exploit the interaction between the two systems.\\n\\n * Layered Security Protocols: Beyond regular audits, introduce multiple layers of security checks. \\n Each layer can act as a fail-safe if a potential threat bypasses another.\\n\\n * Decentralized Watchtowers: These are third-party services that monitor the network for malicious activities. \\n If any suspicious activity is detected, they can take corrective measures or raise alerts.\\n\\n5. Gas & Fee Management:\\n\\n * Challenge: A dual model can lead to convoluted fee structures.\\n\\n * Dynamic Fee Adjustment: Implement algorithms that adjust fees based on network congestion and transaction type. \\n This can ensure fairness and prevent network abuse.\\n\\n * Fee Estimation Tools: Provide tools that can estimate fees before a transaction is initiated. \\n This helps users understand potential costs upfront.\\n\\n * Unified Gas Stations: Design platforms where users can purchase or allocate gas for both transaction types simultaneously, \\n simplifying the gas acquisition process.\\n\\n\\nBy addressing these challenges head-on with a detailed and systematic approach, it\'s possible to unlock the full potential of a dual-architecture system, \\ncombining the strengths of both UTXO and account-based models without their standalone limitations.\\n\\n\\n| Aspect \\t| Details \\t|\\n|------------------------\\t|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------\\t|\\n| **Harmony** \\t| - **Advanced VM Development:** Design tailored for private smart contracts. - **Leverage Established Architectures:** Use WASM or RISC-V to harness their versatile and encompassing nature suitable for zero-knowledge applications. - **Support for UTXO & Account-Based Models:** Enhance adaptability across various blockchain structures. \\t|\\n| **Challenges** \\t| - **Adaptation Concerns:** WASM and RISC-V weren\'t designed with zero-knowledge proofs as a primary focus, posing integration challenges. - **Complexities with Newer Systems:** Systems like (Super)Nova, STARKs, and Sangria are relatively nascent, adding another layer of intricacy to the integration. - **Optimization Concerns:** Ensuring that these systems are optimized for zero-knowledge proofs. \\t|\\n| **Proposed Solutions** \\t| - **Integration of Nova:** Consider Nova\'s proof system for its potential alignment with project goals. - **Comprehensive Testing:** Rigorously test and benchmark against alternatives like Halo2, Plonky, and Starky to validate choices. - **Poseidon Recursion Technique:** To conduct exhaustive performance tests, providing insights into each system\'s efficiency and scalability. \\t|\\n\\n\\n## Goal 2: Virtual Machine Creation\\n\\nThe second goal entails the creation of an advanced virtual machine by leveraging established mainstream instruction sets like WASM or RISC-V. \\nAlternatively, the objective involves pioneering a new, specialized instruction set meticulously optimized for Zero-Knowledge applications.\\n\\nThis initiative seeks to foster a versatile and efficient environment for executing computations within the privacy-focused context of the project. \\nBoth WASM and RISC-V exhibit adaptability to both UTXO and account-based models due to their encompassing nature as general-purpose instruction set architectures.\\n\\n _WASM_, operating as a low-level virtual machine, possesses the capacity to execute code derived from a myriad of high-level programming languages, \\n and boasts seamless integration across diverse blockchain platforms. \\n \\n Meanwhile, _RISC-V_ emerges as a versatile option, accommodating both models, and can be seamlessly integrated with secure enclaves like SGX or TEE, \\n elevating the levels of security and privacy. However, it is crucial to acknowledge that employing WASM or RISC-V might present challenges, \\n given their original design without specific emphasis on optimizing for Zero-Knowledge Proofs (ZKPs). \\n \\n Further complexity arises with the consideration of more potent proof systems like (Super)Nova, STARKs, and Sangria, which, \\n while potentially addressing optimization concerns, necessitate extensive research and testing due to their relatively nascent status within the field. \\n This accentuates the need for a judicious balance between established options and innovative solutions in pursuit of an architecture harmoniously amalgamating privacy, security, and performance.\\n\\nThe ambition to build a powerful virtual machine tailored to zero-knowledge (ZK) applications is both commendable and intricate. \\nThe combination of two renowned instruction sets, WASM and RISC-V, in tandem with ZK, is an innovation that could redefine privacy standards in blockchain. \\nLet\'s dissect the challenges and possibilities inherent in this goal:\\n\\n1. Established Mainstream Instruction Sets - WASM and RISC-V\\n\\n * Strengths:\\n\\n * _WASM_: Rooted in its ability to execute diverse high-level language codes, its potential for cross-chain compatibility makes it a formidable contender. \\n Serving as a low-level virtual machine, its role in the blockchain realm is analogous to that of the Java Virtual Machine in the traditional computing landscape.\\n\\n * _RISC-V_: This open-standard instruction set architecture has made waves due to its customizable nature. \\n Its adaptability to both UTXO and account-based structures coupled with its compatibility with trusted execution environments like SGX and TEE augments its appeal, \\n especially in domains that prioritize security and privacy.\\n\\n * Challenges: Neither WASM nor RISC-V was primarily designed with ZKPs in mind. While they offer flexibility, \\n they might lack the necessary optimizations for ZK-centric tasks. Adjustments to these architectures might demand intensive R&D efforts.\\n\\n\\n\\n2. Pioneering a New, Specialized Instruction Set\\n\\n * Strengths: A bespoke instruction set can be meticulously designed from the ground up with ZK in focus, \\n potentially offering unmatched performance and optimizations tailored to the project\'s requirements.\\n \\n * Challenges: Crafting a new instruction set is a monumental task requiring vast resources, including expertise, time, and capital.\\n It would also need to garner community trust and support over time.\\n\\n\\n\\n3. Contemporary Proof Systems - (Super)Nova, STARKs, Sangria\\n\\n * Strengths: These cutting-edge systems, being relatively new, might offer breakthrough cryptographic efficiencies that older systems lack: designed with modern challenges in mind, \\n they could potentially bridge the gap where WASM and RISC-V might falter in terms of ZKP optimization.\\n\\n * Challenges: Their nascent nature implies a dearth of exhaustive testing, peer reviews, and potentially limited community support. \\n The unknowns associated with these systems could introduce unforeseen vulnerabilities or complexities. \\n While they could offer optimizations that address challenges presented by WASM and RISC-V, their young status demands rigorous vetting and testing.\\n\\n\\n
\\n\\n| | Mainstream (WASM, RISC-V) | ZK-optimized (New Instruction Set) |\\n|:------------------:|:-------------------------:|:----------------------------------:|\\n| Existing Tooling | YES | NO |\\n| Blockchain-focused | NO | YES |\\n| Performant | DEPENDS | YES |\\n\\n
\\n\\n### Optimization Concerns for WASM and RISC-V: \\n\\n* _Cryptography Libraries_: ZKP applications rely heavily on specific cryptographic primitives. Neither WASM nor RISC-V natively supports all of these primitives. \\nThus, a comprehensive library of cryptographic functions, optimized for these platforms, needs to be developed.\\n\\n* _Parallel Execution_: Given the heavy computational demands of ZKPs, leveraging parallel processing capabilities can optimize the time taken. \\nBoth WASM and RISC-V would need modifications to handle parallel execution of ZKP processes efficiently.\\n\\n* _Memory Management_: ZKP computations can sometimes require significant amounts of memory, especially during the proof generation phase. \\nFine-tuned memory management mechanisms are essential to prevent bottlenecks.\\n\\n\\n### Emerging ZKP Optimized Systems Considerations: \\n\\n* _Proof Size_: Different systems generate proofs of varying sizes. A smaller proof size is preferable for blockchain applications to save on storage and bandwidth. \\nThe trade-offs between proof size, computational efficiency, and security need to be balanced.\\n\\n* _Universality_: Some systems can support any computational statement (universal), while others might be tailored to specific tasks. \\nA universal system can be more versatile for diverse applications on the blockchain.\\n\\n* _Setup Requirements_: Certain ZKP systems, like zk-SNARKs, require a trusted setup, which can be a security concern. \\nAlternatives like zk-STARKs don\'t have this requirement but come with other trade-offs.\\n\\n\\n### Strategies for Integration: \\n\\n* _Iterative Development_: Given the complexities, an iterative development approach can be beneficial. \\nStart with a basic integration of WASM or RISC-V for general tasks and gradually introduce specialized ZKP functionalities.\\n\\n* _Benchmarking_: Establish benchmark tests specifically for ZKP operations. This will provide continuous feedback on the performance of the system as modifications are made, ensuring optimization.\\n\\n* _External Audits & Research_: Regular checks from cryptographic experts and collaboration with academic researchers can help in staying updated and ensuring secure implementations.\\n\\n\\n## Goal 3: Proofs Creation and Verification\\n\\nThe process of generating proofs for private state updates is vested in the hands of the user, aligning with our commitment to minimizing trust assumptions and enhancing privacy. \\nConcurrently, the responsibility of verifying these proofs and executing public functions within the virtual machine can be effectively delegated to an external prover, \\na role that is incentivized to operate with utmost honesty and integrity. This intricate balance seeks to safeguard against information leakage, \\npreserving the confidentiality of private transactions. Integral to this mechanism is the establishment of a robust incentivization framework.\\n\\nTo ensure the prover\u2019s steadfast commitment to performing tasks with honesty, we should introduce a mechanism that facilitates both rewards for sincere behavior and penalties for any deviation from the expected standards. \\nThis two-pronged approach serves as a compelling deterrent against dishonest behavior and fosters an environment of accountability. \\nIn addition to incentivization, a crucial consideration is the economic aspect of verification and execution. \\nThe verification process has been intentionally designed to be more cost-effective than execution. \\n\\nThis strategic approach prevents potential malicious actors from exploiting the system by flooding it with spurious proofs, a scenario that could arise when the costs align favorably. \\nBy maintaining a cost balance that favors verification, we bolster the system\u2019s resilience against fraudulent activities while ensuring its efficiency. \\nIn sum, our multifaceted approach endeavors to strike an intricate equilibrium between user-initiated proof creation, external verification, and incentivization. \\nThis delicate interplay of mechanisms ensures a level of trustworthiness that hinges on transparency, accountability, and economic viability.\\n\\nAs a result, we are poised to cultivate an ecosystem where users\u2019 privacy is preserved, incentives are aligned, \\nand the overall integrity of the system is fortified against potential adversarial actions. To achieve the goals of user-initiated proof creation, \\nexternal verification, incentivization, and cost-effective verification over execution, several options and mechanisms can be employed:\\n\\n1. **User-Initiated Proof Creation:** Users are entrusted with the generation of proofs for private state updates, thus ensuring greater privacy and reducing trust dependencies.\\n\\n * Challenges:\\n\\n * Maintaining the quality and integrity of the proofs generated by users.\\n\\n * Ensuring that users have the tools and knowledge to produce valid proofs.\\n\\n * Solutions:\\n\\n * Offer extensive documentation, tutorials, and user-friendly tools to streamline the proof-generation process.\\n\\n * Implement checks at the verifier\'s end to ensure the quality of proofs.\\n\\n\\n2. **External Verification by Provers:** An external prover verifies the proofs and executes public functions within the virtual machine.\\n\\n * Challenges:\\n\\n * Ensuring that the external prover acts honestly.\\n\\n * Avoiding centralized points of failure.\\n \\n * Solutions:\\n\\n * Adopt a decentralized verification approach, with multiple provers cross-verifying each other\u2019s work.\\n\\n * Use reputation systems to rank provers based on their past performances, creating a trust hierarchy.\\n\\n3. ** Incentivization Framework:** A system that rewards honesty and penalizes dishonest actions, ensuring provers\' commitment to the task.\\n\\n * Challenges:\\n\\n * Determining the right balance of rewards and penalties.\\n\\n * Ensuring that the system cannot be gamed for undue advantage.\\n\\n * Solutions[^1]: \\n\\n * Implement a dynamic reward system that adjusts based on network metrics and provers\' performance.\\n\\n * Use a staking mechanism where provers need to lock up a certain amount of assets. \\n Honest behavior earns rewards, while dishonest behavior could lead to loss of staked assets.\\n\\n4. **Economic Viability through Cost Dynamics:** Making verification more cost-effective than execution to deter spamming and malicious attacks.\\n\\n * Challenges: \\n\\n * Setting the right cost metrics for both verification and execution.\\n\\n * Ensuring that genuine users aren\u2019t priced out of the system.\\n\\n * Solutions:\\n\\n * Use a dynamic pricing model, adjusting costs in real-time based on network demand.\\n\\n * Implement gas-like mechanisms to differentiate operation costs and ensure fairness.\\n\\n5. ** Maintaining Trustworthiness:** Create a system that\'s transparent, holds all actors accountable, and is economically sound.\\n\\n * Challenges: \\n\\n * Keeping the balance where users feel their privacy is intact, while provers feel incentivized.\\n\\n * Ensuring the system remains resilient against adversarial attacks.\\n\\n * Solutions:\\n\\n * Implement layered checks and balances.\\n\\n * Foster community involvement, allowing them to participate in decision-making, potentially through a decentralized autonomous organization (DAO).\\n\\nEach of these options can be combined or customized to suit the specific requirements of your project, striking a balance between user incentives, \\ncost dynamics, and verification integrity. A thoughtful combination of these mechanisms ensures that the system remains robust, resilient, \\nand conducive to the objectives of user-initiated proof creation, incentivized verification, and cost- effective validation.\\n\\n
\\n\\n| Aspect \\t| Details \\t|\\n|-------------------------------\\t|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------\\t|\\n| **Design Principle** \\t| - **User Responsibility:** Generating proofs for private state updates. - **External Prover:** Delegated the task of verifying proofs and executing public VM functions. \\t|\\n| **Trust & Privacy** \\t| - **Minimized Trust Assumptions:** Place proof generation in users\' hands. - **Enhanced Privacy:** Ensure confidentiality of private transactions and prevent information leakage. \\t|\\n| **Incentivization Framework** \\t| - **Rewards:** Compensate honest behavior. - **Penalties:** Deter and penalize dishonest behavior. \\t|\\n| **Economic Considerations** \\t| - **Verification vs. Execution:** Make verification more cost-effective than execution to prevent spurious proofs flooding. - **Cost Balance:** Strengthen resilience against fraudulent activities and maintain efficiency. \\t|\\n| **Outcome** \\t| An ecosystem where: - Users\' privacy is paramount. - Incentives are appropriately aligned. - The system is robust against adversarial actions. \\t|\\n\\n
\\n\\n[^1]: Incentive Mechanisms:\\n * Token Rewards: Design a token-based reward system where honest provers are compensated with tokens for their verification services. \\n This incentivizes participation and encourages integrity.\\n \\n * Staking and Slashing: Introduce a staking mechanism where provers deposit tokens as collateral. \\n Dishonest behavior results in slashing (partial or complete loss) of the staked tokens, while honest actions are rewarded.\\n \\n * Proof of Work/Proof of Stake: Implement a proof-of-work or proof-of- stake consensus mechanism for verification, \\n aligning incentives with the blockchain\u2019s broader consensus mechanism.\\n\\n\\n## Goal 4: Kernel-based Architecture Implementation\\n\\nThis goal centers on the establishment of a kernel-based architecture, akin to the model observed in ZEXE, to facilitate the attestation of accurate private function executions. \\nThis innovative approach employs recursion to construct a call stack, which is then validated through iterative recursive computations. \\nAt its core, this technique harnesses a recursive Succinct Non-Interactive Argument of Knowledge (SNARK) mechanism, where each function call\u2019s proof accumulates within the call stack.\\n\\nThe subsequent verification of this stack\u2019s authenticity leverages recursive SNARK validation. \\nWhile this method offers robust verification of private function executions, it\u2019s essential to acknowledge its associated intricacies.\\n\\nThe generation of SNARK proofs necessitates a substantial computational effort, which, in turn, may lead to elevated gas fees for users. \\nMoreover, the iterative recursive computations could potentially exhibit computational expansion as the depth of recursion increases. \\nThis calls for a meticulous balance between the benefits of recursive verification and the resource implications it may entail.\\n\\nIn essence, Goal 4 embodies a pursuit of enhanced verification accuracy through a kernel-based architecture. \\nBy weaving recursion and iterative recursive computations into the fabric of our system, we aim to establish a mechanism that accentuates the trustworthiness of private function executions, \\nwhile conscientiously navigating the computational demands that ensue.\\n\\nTo accomplish the goal of implementing a kernel-based architecture for recursive verification of private function executions, \\nseveral strategic steps and considerations can be undertaken: recursion handling and depth management.\\n\\n Recursion Handling \\n\\n* _Call Stack Management:_ \\n\\n * Implement a data structure to manage the call stack, recording each recursive function call\u2019s details, parameters, and state.\\n\\n* _Proof Accumulation: _\\n\\n * Design a mechanism to accumulate proof data for each function call within the call stack. \\n This includes cryptographic commitments, intermediate results, and cryptographic challenges.\\n\\n * Ensure that the accumulated proof data remains secure and tamper-resistant throughout the recursion process.\\n\\n* _Intermediary SNARK Proofs:_\\n\\n * Develop an intermediary SNARK proof for each function call\u2019s correctness within the call stack. \\n This proof should demonstrate that the function executed correctly and produced expected outputs.\\n\\n * Ensure that the intermediary SNARK proof for each recursive call can be aggregated and verified together, maintaining the integrity of the entire call stack.\\n\\n Depth management \\n\\n* _Depth Limitation:_\\n\\n * Define a threshold for the maximum allowable recursion depth based on the system\u2019s computational capacity, gas limitations, and performance considerations.\\n\\n * Implement a mechanism to prevent further recursion beyond the defined depth limit, safeguarding against excessive computational growth.\\n\\n* _Graceful Degradation:_\\n\\n * Design a strategy for graceful degradation when the recursion depth approaches or reaches the defined limit. \\n This may involve transitioning to alternative execution modes or optimization techniques.\\n\\n * Communicate the degradation strategy to users and ensure that the system gracefully handles scenarios where recursion must be curtailed.\\n\\n* _Resource Monitoring:_\\n\\n * Develop tools to monitor resource consumption (such as gas usage and computational time) as recursion progresses. \\n Provide real-time feedback to users about the cost and impact of recursive execution.\\n\\n* _Dynamic Depth Adjustment:_\\n\\n * Consider implementing adaptive depth management that dynamically adjusts the recursion depth based on network conditions, transaction fees, and available resources.\\n\\n * Utilize algorithms to assess the optimal recursion depth for efficient execution while adhering to gas cost constraints.\\n\\n* _Fallback Mechanisms:_\\n\\n * Create fallback mechanisms that activate if the recursion depth limit is reached or if the system encounters resource constraints. \\n These mechanisms could involve alternative verification methods or delayed execution.\\n\\n* _User Notifications:_\\n\\n * Notify users when the recursion depth limit is approaching, enabling them to make informed decisions about the complexity of their transactions and potential resource usage.\\n\\n\\nGoal 4 underscores the project\'s ambition to integrate the merits of a kernel-based architecture with recursive verifications to bolster the reliability of private function executions. \\nWhile the approach promises robust outcomes, it\'s pivotal to maneuver through its intricacies with astute strategies, ensuring computational efficiency and economic viability. \\nBy striking this balance, the architecture can realize its full potential in ensuring trustworthy and efficient private function executions.\\n\\n\\n## Goal 5: Seamless Interaction Design\\n\\nGoal 5 revolves around the meticulous design of a seamless interaction between public and private states within the blockchain ecosystem. \\nThis objective envisions achieving not only composability between contracts but also the harmonious integration of private and public functions.\\n\\nA notable challenge in this endeavor lies in the intricate interplay between public and private states, \\nwherein the potential linkage of a private transaction to a public one raises concerns about unintended information leakage.\\n\\nThe essence of this goal entails crafting an architecture that facilitates the dynamic interaction of different states while ensuring that the privacy and confidentiality of private transactions remain unbreached. \\nThis involves the formulation of mechanisms that enable secure composability between contracts, guaranteeing the integrity of interactions across different layers of functionality.\\n\\nA key focus of this goal is to surmount the challenge of information leakage by implementing robust safeguards. \\nThe solution involves devising strategies to mitigate the risk of revealing private transaction details when connected to corresponding public actions. \\nBy creating a nuanced framework that com- partmentalizes private and public interactions, the architecture aims to uphold privacy while facilitating seamless interoperability.\\n\\nGoal 5 encapsulates a multifaceted undertaking, calling for the creation of an intricate yet transparent framework that empowers users to confidently engage in both public and private functions, \\nwithout compromising the confidentiality of private transactions. The successful realization of this vision hinges on a delicate blend of architectural ingenuity, cryptographic sophistication, and user-centric design.\\n\\nTo achieve seamless interaction between public and private states, composability, and privacy preservation, a combination of solutions and approaches can be employed. \\nIn the table below, a comprehensive list of solutions that address these objectives:\\n\\n
\\n\\n| **Solution Category** \\t| **Description** \\t|\\n|:-----------------------------------------:\\t|:--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------:\\t|\\n| **Layer 2 Solutions** \\t| Employ zk-Rollups, Optimistic Rollups, and state channels to handle private interactions off-chain and settle them on-chain periodically. Boost scalability and cut transaction costs. \\t|\\n| **Intermediary Smart Contracts** \\t| Craft smart contracts as intermediaries for secure public-private interactions. Use these to manage data exchange confidentially. \\t|\\n| **Decentralized Identity & Pseudonymity** \\t| Implement decentralized identity systems for pseudonymous interactions. Validate identity using cryptographic proofs. \\t|\\n| **Confidential Sidechains & Cross-Chain** \\t| Set up confidential sidechains and employ cross-chain protocols to ensure private and composability across blockchains. \\t|\\n| **Temporal Data Structures** \\t| Create chronological data structures for secure interactions. Utilize cryptographic methods for data integrity and privacy. \\t|\\n| **Homomorphic Encryption & MPC** \\t| Apply homomorphic encryption and MPC for computations on encrypted data and interactions between state layers. \\t|\\n| **Commit-Reveal Schemes** \\t| Introduce commit-reveal mechanisms for private transactions, revealing data only post necessary public actions. \\t|\\n| **Auditability & Verifiability** \\t| Use on-chain tools for auditing and verifying interactions. Utilize cryptographic commitments for third-party validation. \\t|\\n| **Data Fragmentation & Sharding** \\t| Fragment data across shards for private interactions and curtailed data exposure. Bridge shards securely with cryptography. \\t|\\n| **Ring Signatures & CoinJoin** \\t| Incorporate ring signatures and CoinJoin protocols to mask transaction details and mix transactions collaboratively. \\t|\\n\\n
\\n\\n## Goal 6: Integration of DeFi Protocols with a Privacy-Preserving Framework\\n\\nThe primary aim of Goal 6 is to weave key DeFi protocols, such as AMMs and staking, into a user-centric environment that accentuates privacy. \\nThis endeavor comes with inherent challenges, especially considering the heterogeneity of existing DeFi protocols, predominantly built on Ethereum. \\nThese variations in programming languages and VMs exacerbate the quest for interoperability. Furthermore, the success and functionality of DeFi protocols is closely tied to liquidity, \\nwhich in turn is influenced by user engagement and the amount of funds locked into the system.\\n\\n## Strategic Roadmap for Goal 6 \\n\\n1. _** Pioneering Privacy-Centric DeFi Models: **_ Initiate the development of AMMs and staking solutions that are inherently protective of users\' transactional privacy and identity.\\n\\n2. _** Specialized Smart Contracts with Privacy: **_ Architect distinct smart contracts infused with privacy elements, setting the stage for secure user interactions within this new, confidential DeFi landscape.\\n\\n3. _** Optimized User Interfaces: **_ Craft interfaces that resonate with user needs, simplifying the journey through the private DeFi space without compromising on security.\\n\\n4. _** Tackling Interoperability: **_ \\n\\n * Deploy advanced bridge technologies and middleware tools to foster efficient data exchanges and guarantee operational harmony across a spectrum of programming paradigms and virtual environments.\\n \\n * Design and enforce universal communication guidelines that bridge the privacy-centric DeFi entities with the larger DeFi world seamlessly.\\n\\n\\n5. _** Enhancing and Sustaining Liquidity: **_\\n\\n * Unveil innovative liquidity stimuli and yield farming incentives, compelling users to infuse liquidity into the private DeFi space.\\n \\n * Incorporate adaptive liquidity frameworks that continually adjust based on the evolving market demands, ensuring consistent liquidity.\\n\\n * Forge robust alliances with other DeFi stalwarts, jointly maximizing liquidity stores and honing sustainable token distribution strategies.\\n\\n\\n6. _** Amplifying Community Engagement:**_ Design and roll out enticing incentive schemes to rally users behind privacy-focused AMMs and staking systems, \\nthereby nurturing a vibrant, privacy-advocating DeFi community.\\n\\n\\nThrough the integration of these approaches, we aim to achieve Goal 6, providing users with a privacy-focused platform for engaging effortlessly in core DeFi functions such as AMMs and staking, \\nall while effectively overcoming the obstacles related to interoperability and liquidity concerns.\\n\\n\\n## Summary of the Architecture\\n\\nIn our quest to optimize privacy, we\'re proposing a Zero-Knowledge Virtual Machine (Zkvm) that harnesses the power of Zero-Knowledge Proofs (ZKPs).\\nThese proofs ensure that while private state data remains undisclosed, public state transitions can still be carried out and subsequently verified by third parties. \\nThis blend of public and private state is envisaged to be achieved through a state tree representing the public state, while the encrypted state leaves stand for the private state. \\nEach user\'s private state indicates validity through the absence of a corresponding nullifier.\\nA nullifier is a unique cryptographic value generated in privacy-preserving blockchain transactions to prevent double-spending, \\nensuring that each private transaction is spent only once without revealing its details.\\n\\nPrivate functions\' execution mandates users to offer a proof underscoring the accurate execution of all encapsulated private calls. \\nFor validating a singular private function call, we\'re leaning into the kernel-based model inspired by the ZEXE protocol. \\nDefined as kernel circuits, these functions validate the correct execution of each private function call. \\nDue to their recursive circuit structure, a succession of private function calls can be executed by calculating proofs in an iterative manner. \\nExecution-relevant data, like private and public call stacks and additions to the state tree, are incorporated as public inputs.\\n\\nOur method integrates the verification keys for these functions within a merkle tree. Here\'s the innovation: a user\'s ZKP showcases the existence of the verification key in this tree, yet keeps the executed function concealed. \\nThe unique function identifier can be presented as the verification key, with all contracts merkleized for hiding functionalities.\\n\\nWe suggest a nuanced shift from the ZEXE protocol\'s identity function, which crafts an identity for smart contracts delineating its behavior, access timeframes, and other functionalities. \\nInstead of the ZEXE protocol\'s structure, our approach pivots to a method anchored in the \\nsecurity of a secret combined with the uniqueness from hashing with the contract address. \\nThe underlying rationale is straightforward: the sender, equipped with a unique nonce and salt for the transaction, hashes the secret, payload, nonce, and salt. \\nThis result is then hashed with the contract address for the final value. The hash function\'s unidirectional nature ensures that the input cannot be deduced easily from its output. \\nA specific concern, however, is the potential repetition of secret and payload values across transactions, which could jeopardize privacy. \\nYet, by embedding the function\'s hash within the hash of the contract address, users can validate a specific function\'s execution without divulging the function, navigating this limitation.\\n\\nAlternative routes do exist: We could employ signature schemes like ECDSA, focusing on uniqueness and authenticity, albeit at the cost of complex key management. \\nFully Homomorphic Encryption (FHE) offers another pathway, enabling function execution on encrypted data, or Multi-Party Computation (MPC) which guarantees non-disclosure of function or inputs. \\nYet, integrating ZKPs with either FHE or MPC presents a challenge. Combining cryptographic functions like SHA-3 and BLAKE2 can also bolster security and uniqueness. \\nIt\'s imperative to entertain these alternatives, especially when hashing might not serve large input/output functions effectively or might fall short in guaranteeing uniqueness.\\n\\n## Current State\\n\\nOur aim is to revolutionize the privacy and security paradigms through Nescience.\\nAs we strive to set milestones and achieve groundbreaking advancements, \\nour current focus narrows onto the realization of Goal 2 and Goal 3.\\n\\nOur endeavors to build a powerful virtual machine tailored for Zero-Knowledge applications have led us down the path of rigorous exploration and testing. \\nWe believe that integrating the right proof system is pivotal to our project\'s success, which brings us to Nova [[8](https://eprint.iacr.org/2021/370)].\\nIn our project journey, we have opted to integrate the Nova proof system, recognizing its potential alignment with our overarching goals. \\nHowever, as part of our meticulous approach to innovation and optimization, we acknowledge the need to thoroughly examine Nova\u2019s performance capabilities, \\nparticularly due to its status as a pioneering and relatively unexplored proof system.\\n\\nThis critical evaluation entails a comprehensive process of benchmarking and comparative analysis [[9]](https://github.com/vacp2p/zk-explorations), \\npitting Nova against other prominent proof systems in the field, including Halo2 [[10](https://electriccoin.co/blog/explaining-halo-2/)], \\nPlonky2 [[11](https://polygon.technology/blog/introducing-plonky2)], and Starky [[12](https://eprint.iacr.org/2021/582)]. \\nThis ongoing and methodical initiative is designed to ensure a fair and impartial assessment, enabling us to draw meaningful conclusions about Nova\u2019s strengths and limitations in relation to its counterparts. \\nBy leveraging the Poseidon recursion technique, we are poised to conduct an exhaustive performance test that delves into intricate details. \\nThrough this testing framework, we aim to discern whether Nova possesses the potential to outshine its contemporaries in terms of efficiency, scalability, and overall performance. \\nThe outcome of this rigorous evaluation will be pivotal in shaping our strategic decisions moving forward. \\nArmed with a comprehensive understanding of Nova\u2019s performance metrics vis-\xe0-vis other proof systems, \\nwe can confidently chart a course that maximizes the benefits of our project\u2019s optimization efforts.\\n\\nMoreover, as we ambitiously pursue the establishment of a robust mechanism for proof creation and verification, our focus remains resolute on preserving user privacy, \\nincentivizing honest behaviour, and ensuring the cost-effective verification of transactions. \\nAt the heart of this endeavor is our drive to empower users by allowing them the autonomy of generating proofs for private state updates, \\nthereby reducing dependencies and enhancing privacy.\\nWe would like to actively work on providing comprehensive documentation, user-friendly tools, \\nand tutorials to aid users in this intricate process.\\n\\nParallelly, we\'re looking into decentralized verification processes, harnessing the strength of multiple external provers that cross-verify each other\'s work. \\nOur commitment is further cemented by our efforts to introduce a dynamic reward system that adjusts based on network metrics and prover performance. \\nThis intricate balance, while challenging, aims to fortify our system against potential adversarial actions, aligning incentives, and preserving the overall integrity of the project.\\n\\n\\n# References\\n\\n[1] Nakamoto, S. (2008). Bitcoin: A Peer-to-Peer Electronic Cash System. Retrieved from https://bitcoin.org/bitcoin.pdf\\n\\n[2] Sanchez, F. (2021). Cardano\u2019s Extended UTXO accounting model. Retrived from https://iohk.io/en/blog/posts/2021/03/11/cardanos-extended-utxo-accounting-model/\\n\\n[3] Morgan, D. (2020). HD Wallets Explained: From High Level to Nuts and Bolts. Retrieved from https://medium.com/mycrypto/the-journey-from-mnemonic-phrase-to-address-6c5e86e11e14\\n\\n[4] Wuille, P. (012). Bitcoin Improvement Proposal (BIP) 44. Retrieved from https://github.com/bitcoin/bips/blob/master/bip-0032.mediawiki\\n\\n[5] Jedusor, T. (2020). Introduction to Mimblewimble and Grin. Retrieved from https://github.com/mimblewimble/grin/blob/master/doc/intro.md\\n\\n[6] Bitcoin\'s official wiki overview of the CoinJoin method. Retrieved from https://en.bitcoin.it/wiki/CoinJoin\\n\\n[7] TornadoCash official Github page. Retrieved from https://github.com/tornadocash/tornado-classic-ui\\n\\n[8] Kothapalli, A., Setty, S., Tzialla, I. (2021). Nova: Recursive Zero-Knowledge Arguments from Folding Schemes. Retrieved from https://eprint.iacr.org/2021/370\\n\\n[9] ZKvm Github page. Retrieved from https://github.com/vacp2p/zk-explorations\\n\\n[10] Electric Coin Company (2020). Explaining Halo 2. Retrieved from https://electriccoin.co/blog/explaining-halo-2/\\n\\n[11] Polygon Labs (2022). Introducing Plonky2. Retrieved from https://polygon.technology/blog/introducing-plonky2\\n\\n[12] StarkWare (2021). ethSTARK Documentation. Retrieved from https://eprint.iacr.org/2021/582"},{"id":"device-pairing-in-js-waku-and-go-waku","metadata":{"permalink":"/rlog/device-pairing-in-js-waku-and-go-waku","source":"@site/rlog/2023-04-24-device-pairing-in-js-waku-and-go-waku.mdx","title":"Device Pairing in Js-waku and Go-waku","description":"Device pairing and secure message exchange using Waku and noise protocol.","date":"2023-04-24T12:00:00.000Z","formattedDate":"April 24, 2023","tags":[],"readingTime":4.09,"hasTruncateMarker":true,"authors":[{"name":"Richard","twitter":"richardramos_me","github":"richard-ramos","website":"https://richard-ramos.github.io/","key":"rramos"}],"frontMatter":{"layout":"post","name":"Device Pairing in Js-waku and Go-waku","title":"Device Pairing in Js-waku and Go-waku","date":"2023-04-24T12:00:00.000Z","authors":"rramos","published":true,"slug":"device-pairing-in-js-waku-and-go-waku","categories":"platform"},"prevItem":{"title":"Nescience - A zkVM leveraging hiding properties","permalink":"/rlog/Nescience-A-zkVM-leveraging-hiding-properties"},"nextItem":{"title":"The Future of Waku Network: Scaling, Incentivization, and Heterogeneity","permalink":"/rlog/future-of-waku-network"}},"content":"Device pairing and secure message exchange using Waku and noise protocol.\\n\\n\x3c!--truncate--\x3e\\n\\nAs the world becomes increasingly connected through the internet, the need for secure and reliable communication becomes paramount. In [this article](https://vac.dev/wakuv2-noise) it is described how the Noise protocol can be used as a key-exchange mechanism for Waku.\\n\\nRecently, this feature was introduced in [js-waku](https://github.com/waku-org/js-noise) and [go-waku](https://github.com/waku-org/go-waku), providing a simple API for developers to implement secure communication protocols using the Noise Protocol framework. These open-source libraries provide a solid foundation for building secure and decentralized applications that prioritize data privacy and security.\\n\\nThis functionality is designed to be simple and easy to use, even for developers who are not experts in cryptography. The library offers a clear and concise API that abstracts away the complexity of the Noise Protocol framework and provides an straightforward interface for developers to use. Using this, developers can effortlessly implement secure communication protocols on top of their JavaScript and Go applications, without having to worry about the low-level details of cryptography.\\n\\nOne of the key benefits of using Noise is that it provides end-to-end encryption, which means that the communication between two parties is encrypted from start to finish. This is essential for ensuring the security and privacy of sensitive information\\n\\n### Device Pairing\\n\\nIn today\'s digital world, device pairing has become an integral part of our lives. Whether it\'s connecting our smartphones with other computers or web applications, the need for secure device pairing has become more crucial than ever. With the increasing threat of cyber-attacks and data breaches, it\'s essential to implement secure protocols for device pairing to ensure data privacy and prevent unauthorized access.\\n\\nTo demonstrate how device pairing can be achieved using Waku and Noise, we have examples available at https://examples.waku.org/noise-js/. You can try pairing different devices, such as mobile and desktop, via a web application. This can be done by scanning a QR code or opening a URL that contains the necessary data for a secure handshake.\\n\\nThe process works as follows:\\n\\nActors:\\n\\n- Alice the initiator\\n- Bob the responder\\n\\n1. The first step in achieving secure device pairing using Noise and Waku is for Bob generate the pairing information which could be transmitted out-of-band. For this, Bob opens https://examples.waku.org/noise-js/ and a QR code is generated, containing the data required to do the handshake. This pairing QR code is timeboxed, meaning that after 2 minutes, it will become invalid and a new QR code must be generated\\n2. Alice scans the QR code using a mobile phone. This will open the app with the QR code parameters initiating the handshake process which is described in [43/WAKU2-DEVICE-PAIRING](https://rfc.vac.dev/spec/43/#protocol-flow). These messages are exchanged between two devices over Waku to establish a secure connection. The handshake messages consist of three main parts: the initiator\'s message, the responder\'s message, and the final message, which are exchanged to establish a secure connection. While using js-noise, the developer is abstracted of this process, since the messaging happens automatically depending on the actions performed by the actors in the pairing process.\\n3. Both Alice and Bob will be asked to verify each other\'s identity. This is done by confirming if an 8-digits authorization code match in both devices. If both actors confirm that the authorization code is valid, the handshake concludes succesfully\\n4. Alice and Bob receive a set of shared keys that can be used to start exchanging encrypted messages. The shared secret keys generated during the handshake process are used to encrypt and decrypt messages sent between the devices. This ensures that the messages exchanged between the devices are secure and cannot be intercepted or modified by an attacker.\\n\\nThe above example demonstrates device pairing using js-waku. Additionally, You can also try building and experimenting with other noise implementations like nwaku, or go-waku, with an example available at https://github.com/waku-org/go-waku/tree/master/examples/noise in which the same flow described before is done with Bob (the receiver) using go-waku instead of js-waku.\\n\\n### Conclusion\\n\\nWith its easy to use API built on top of the Noise Protocol framework and the LibP2P networking stack, if you are a developer looking to implement secure messaging in their applications that are both decentralized and censorship resistant, Waku is definitely an excellent choice worth checking out!\\n\\nWaku is also Open source with a MIT and APACHEv2 licenses, which means that developers are encouraged to contribute code, report bugs, and suggest improvements to make it even better.\\n\\nDon\'t hesitate to try the live example at https://examples.waku.org/noise-js and build your own webapp using https://github.com/waku-org/js-noise, https://github.com/waku-org/js-waku and https://github.com/waku-org/go-waku. This will give you a hands-on experience of implementing secure communication protocols using the Noise Protocol framework in a practical setting. Happy coding!\\n\\n### References\\n\\n- [Noise handshakes as key-exchange mechanism for Waku](https://vac.dev/wakuv2-noise)\\n- [Noise Protocols for Waku Payload Encryption](https://rfc.vac.dev/spec/35/)\\n- [Session Management for Waku Noise](https://rfc.vac.dev/spec/37/)\\n- [Device pairing and secure transfers with Noise](https://rfc.vac.dev/spec/43/)\\n- [go-waku Noise\'s example](https://github.com/waku-org/go-waku/tree/master/examples/noise)\\n- [js-waku Noise\'s example](https://github.com/waku-org/js-waku-examples/tree/master/examples/noise-js)\\n- [js-noise](https://github.com/waku-org/js-noise/)\\n- [go-noise](https://github.com/waku-org/js-noise/)"},{"id":"future-of-waku-network","metadata":{"permalink":"/rlog/future-of-waku-network","source":"@site/rlog/2023-04-03-waku-as-a-network.mdx","title":"The Future of Waku Network: Scaling, Incentivization, and Heterogeneity","description":"Learn how the Waku Network is evolving through scaling, incentivization, and diverse ecosystem development and what the future might look like.","date":"2023-04-03T00:00:00.000Z","formattedDate":"April 3, 2023","tags":[],"readingTime":5.745,"hasTruncateMarker":true,"authors":[{"name":"Franck","twitter":"fryorcraken","github":"fryorcraken","key":"franck"}],"frontMatter":{"layout":"post","name":"The Future of Waku Network: Scaling, Incentivization, and Heterogeneity","title":"The Future of Waku Network: Scaling, Incentivization, and Heterogeneity","date":"2023-04-03T00:00:00.000Z","authors":"franck","published":true,"slug":"future-of-waku-network","categories":"platform, operator, network","image":"/img/black-waku-logo-with-name.png","discuss":"https://forum.vac.dev/t/discussion-the-future-of-waku-network-scaling-incentivization-and-heterogeneity/173","hide_table_of_contents":false},"prevItem":{"title":"Device Pairing in Js-waku and Go-waku","permalink":"/rlog/device-pairing-in-js-waku-and-go-waku"},"nextItem":{"title":"Waku for All Decentralized Applications and Infrastructures","permalink":"/rlog/waku-for-all"}},"content":"Learn how the Waku Network is evolving through scaling, incentivization, and diverse ecosystem development and what the future might look like.\\n\\n\x3c!--truncate--\x3e\\n\\nWaku is preparing for production with a focus on the Status Communities use case. In this blog post, we will provide an\\noverview of recent discussions and research outputs, aiming to give you a better understanding of how the Waku network\\nmay look like in terms of scaling and incentivization.\\n\\n## DOS Mitigation for Status Communities\\n\\nWaku is actively exploring DOS mitigation mechanisms suitable for Status Communities. While RLN\\n(Rate Limiting Nullifiers) remains the go-to DOS protection solution due to its privacy-preserving and\\ncensorship-resistant properties, there is still more work to be done. We are excited to collaborate with PSE\\n(Privacy & Scaling Explorations) in this endeavor. Learn more about their latest progress in this [tweet](https://twitter.com/CPerezz19/status/1640373940634939394?s=20).\\n\\n## A Heterogeneous Waku Network\\n\\nAs we noted in a previous [forum post](https://forum.vac.dev/t/waku-payment-models/166/3), Waku\'s protocol\\nincentivization model needs to be flexible to accommodate various business models. Flexibility ensures that projects\\ncan choose how they want to use Waku based on their specific needs.\\n\\n### Reversing the Incentivization Question\\n\\nTraditionally, the question of incentivization revolves around how to incentivize operators to run nodes. We\'d like to\\nreframe the question and instead ask, \\"How do we pay for the infrastructure?\\"\\n\\nWaku does not intend to offer a free lunch.\\nEthereum\'s infrastructure is supported by transaction fees and inflation, with validators receiving rewards from both sources.\\nHowever, this model does not suit a communication network like Waku.\\nUsers and platforms would not want to pay for every single message they send. Additionally, Waku aims to support instant\\nephemeral messages that do not require consensus or long-term storage.\\n\\nProjects that use Waku to enable user interactions, whether for chat messages, gaming, private DeFi, notifications, or\\ninter-wallet communication, may have different value extraction models. Some users might provide services for the\\nproject and expect to receive value by running nodes, while others may pay for the product or run infrastructure to\\ncontribute back. Waku aims to support each of these use cases, which means there will be various ways to \\"pay for the\\ninfrastructure.\\"\\n\\nIn [his talk](https://vac.dev/building-privacy-protecting-infrastructure), Oskar addressed two strategies: RLN and service credentials.\\n\\n### RLN and Service Credentials\\n\\nRLN enables DOS protection across the network in a privacy-preserving and permission-less manner: stake in a contract,\\nand you can send messages.\\n\\nService credentials establish a customer-provider relationship. Users might pay to have messages they are interested in\\nstored and served by a provider. Alternatively, a community owner could pay a service provider to host their community.\\n\\nProviders could offer trial or limited free services to Waku users, similar to Slack or Discord. Once a trial is expired or outgrown,\\na community owner could pay for more storage or bandwidth, similar to Slack\'s model.\\nAlternatively, individual users could contribute financially, akin to Discord\'s Server Boost, or by sharing their own\\nresources with their community.\\n\\nWe anticipate witnessing various scenarios across the spectrum: from users sharing resources to users paying for access to the network and everything in between.\\n\\n## Waku Network: Ethereum or Cosmos?\\n\\nAnother perspective is to consider whether the Waku network will resemble Ethereum or Cosmos.\\n\\nFor those not familiar with the difference between both, in a very concise manner:\\n\\n- Ethereum is a set of protocols and software that are designed to operate on one common network and infrastructure\\n- Cosmos is a set of protocols and software (SDKs) designed to be deployed in separate yet interoperable networks and infrastructures by third parties\\n\\nWe want Waku to be decentralized to provide censorship resistance and privacy-preserving communication.\\nIf each application has to deploy its own network, we will not achieve this goal.\\nTherefore, we aim Waku to be not only an open source set of protocols, but also a shared infrastructure that anyone can leverage to build applications on top, with some guarantees in terms of decentralization and anonymity.\\nThis approach is closer in spirit to Ethereum than Cosmos.\\nDo note that, similarly to Ethereum, anyone is free to take Waku software and protocols and deploy their own network.\\n\\nYet, because of the difference in the fee model, the Waku Network is unlikely to be as unified as Ethereum\'s.\\nWe currently assume that there will be separate gossipsub networks with different funding models.\\nSince there is no consensus on Waku, each individual operator can decide which network to support, enabling Waku to maintain its permission-less property.\\n\\nMost likely, the Waku network will be heterogeneous, and node operators will choose the incentivization model they prefer.\\n\\n## Scalability and Discovery Protocols\\n\\nTo enable scalability, the flow of messages in the Waku network will be divided in shards,\\nso that not every node has to forward every message of the whole network.\\nDiscovery protocols will facilitate users connecting to the right nodes to receive the messages they are interested in.\\n\\nDifferent shards could be subject to a variety of rate limiting techniques (globally, targeted to that shard or something in-between).\\n\\nMarketplace protocols may also be developed to help operators understand how they can best support the network and where\\ntheir resources are most needed. However, we are still far from establishing or even assert that such a marketplace will be needed.\\n\\n## Open Problems\\n\\nSplitting traffic between shards reduces bandwidth consumption for every Waku Relay node.\\nThis improvement increases the likelihood that users with home connections can participate and contribute to the gossipsub network without encountering issues.\\n\\nHowever, it does not cap traffic.\\nThere are still open problems regarding how to guarantee that someone can use Waku with lower Internet bandwidth or run critical services, such as a validation node, on the same connection.\\n\\nWe have several ongoing initiatives:\\n\\n- Analyzing the Status Community protocol to confirm efficient usage of Waku [[4]](https://github.com/vacp2p/research/issues/177)\\n- Simulating the Waku Network to measure actual bandwidth usage [[5]](https://github.com/waku-org/pm/issues/2)\\n- Segregating chat messages from control and media messages [[6]](https://rfc.vac.dev/spec/57/#control-message-shards)\\n\\nThe final solution will likely be a combination of protocols that reduce bandwidth usage or mitigate the risk of DOS attacks, providing flexibility for users and platforms to enable the best experience.\\n\\n## The Evolving Waku Network\\n\\nThe definition of the \\"Waku Network\\" will likely change over time. In the near future, it will transition from a single\\ngossipsub network to a sharded set of networks unified by a common discovery layer. This change will promote scalability\\nand allow various payment models to coexist within the Waku ecosystem.\\n\\nIn conclusion, the future of Waku Network entails growth, incentivization, and heterogeneity while steadfastly\\nmaintaining its core principles. As Waku continues to evolve, we expect it to accommodate a diverse range of use cases\\nand business models, all while preserving privacy, resisting censorship, avoiding surveillance, and remaining accessible\\nto devices with limited resources.\\n\\n## References\\n\\n1. [51/WAKU2-RELAY-SHARDING](https://rfc.vac.dev/spec/51/)\\n2. [57/STATUS-Simple-Scaling](https://rfc.vac.dev/spec/57/)\\n3. [58/RLN-V2](https://rfc.vac.dev/spec/58/)\\n4. [Scaling Status Communities: Potential Problems](https://github.com/vacp2p/research/issues/177)\\n5. [Waku Network Testing](https://github.com/waku-org/pm/issues/2)\\n6. [51/WAKU2-RELAY-SHARDING: Control Message Shards](https://rfc.vac.dev/spec/57/#control-message-shards)"},{"id":"waku-for-all","metadata":{"permalink":"/rlog/waku-for-all","source":"@site/rlog/2022-11-08-waku-for-all-decentralize-applications.mdx","title":"Waku for All Decentralized Applications and Infrastructures","description":"Waku is an open communication protocol and network. Decentralized apps and infrastructure can use Waku for their","date":"2022-11-08T00:00:00.000Z","formattedDate":"November 8, 2022","tags":[],"readingTime":6.145,"hasTruncateMarker":true,"authors":[{"name":"Franck","twitter":"fryorcraken","github":"fryorcraken","key":"franck"}],"frontMatter":{"layout":"post","name":"Waku for All Decentralized Applications and Infrastructures","title":"Waku for All Decentralized Applications and Infrastructures","date":"2022-11-08T00:00:00.000Z","authors":"franck","published":true,"slug":"waku-for-all","categories":"waku, dapp, infrastructure, public good, platform, operator","image":"/img/black-waku-logo-with-name.png","discuss":"https://forum.vac.dev/t/discussion-waku-for-all-decentralized-applications-and-infrastructures/163"},"prevItem":{"title":"The Future of Waku Network: Scaling, Incentivization, and Heterogeneity","permalink":"/rlog/future-of-waku-network"},"nextItem":{"title":"Building Privacy-Protecting Infrastructure","permalink":"/rlog/building-privacy-protecting-infrastructure"}},"content":"Waku is an open communication protocol and network. Decentralized apps and infrastructure can use Waku for their\\ncommunication needs. It is designed to enable dApps and decentralized infrastructure projects to have secure, private,\\nscalable communication. Waku is available in several languages and platforms, from Web to mobile to desktop to cloud.\\nInitially, We pushed Waku adoption to the Web ecosystem, we learned that Waku is usable in a variety of complex applications\\nand infrastructure projects. We have prioritized our effort to make Waku usable on various platforms and environments.\\n\\n\x3c!--truncate--\x3e\\n\\n## Background\\n\\nWe have built Waku to be the communication layer for Web3. Waku is a collection of protocols to chose from for your\\nmessaging needs. It enables secure, censorship-resistant, privacy-preserving, spam-protected communication for its user.\\nIt is designed to run on any device, from mobile to the cloud.\\n\\nWaku is available on many systems and environments and used by several applications and SDKs for decentralized communications.\\n\\nThis involved research efforts in various domains: conversational security, protocol incentivization, zero-knowledge,\\netc.\\n\\nWaku uses novel technologies. Hence, we knew that early dogfooding of Waku was necessary. Even if research\\nwas still _in progress_ [[1]](#references). Thus, as soon as Waku protocols and software were usable, we started to push\\nfor the adoption of Waku. This started back in 2021.\\n\\nWaku is the communication component of the Web3 trifecta. This trifecta was Ethereum (contracts), Swarm\\n(storage) and Whisper (communication). Hence, it made sense to first target dApps which already uses one of the pillars:\\nEthereum.\\n\\nAs most dApps are web apps, we started the development of [js-waku for the browser](https://vac.dev/presenting-js-waku).\\n\\nOnce ready, we reached out to dApps to integrate Waku, added [prizes to hackathons](https://twitter.com/waku_org/status/1451400128791605254?s=20&t=Zhc0BEz6RVLkE_SeE6UyFA)\\nand gave [talks](https://docs.wakuconnect.dev/docs/presentations/).\\n\\nWe also assumed we would see patterns in the usage of Waku, that we would facilitate with the help of\\n[SDKs](https://github.com/status-im/wakuconnect-vote-poll-sdk).\\n\\nFinally, we created several web apps:\\n[examples](https://docs.wakuconnect.dev/docs/examples/)\\nand [PoCs](https://github.com/status-iM/gnosis-safe-waku).\\n\\nBy discussing with Waku users and watching it being used, we learned a few facts:\\n\\n1. The potential use cases for Waku are varied and many:\\n\\n- Wallet <> dApp communication: [WalletConnect](https://medium.com/walletconnect/walletconnect-v2-0-protocol-whats-new-3243fa80d312), [XMTP](https://xmtp.org/docs/dev-concepts/architectural-overview/)\\n- Off-chain (and private) marketplace:\\n [RAILGUN](https://twitter.com/RAILGUN_Project/status/1556780629848727552?s=20&t=NEKQJiJAfg5WJqvuF-Ym_Q) &\\n [Decentralized Uber](https://twitter.com/TheBojda/status/1455557282318721026)\\n- Signature exchange for a multi-sign wallet: [Gnosis Safe x Waku](https://github.com/status-im/gnosis-safe-waku)\\n- Off-chain Game moves/actions: [Super Card Game (EthOnline 2021)](https://showcase.ethglobal.com/ethonline2021/super-card-game)\\n- Decentralized Pastebin: [Debin](https://debin.io/)\\n\\n2. Many projects are interested in having an embedded chat in their dApp,\\n3. There are complex applications that need Waku as a solution. Taking RAILGUN as an example:\\n\\n- Web wallet\\n- \\\\+ React Native mobile wallet\\n- \\\\+ NodeJS node/backend.\\n\\n(1) means that it is not that easy to create SDKs for common use cases.\\n\\n(2) was a clear candidate for an SDK. Yet, building a chat app is a complex task. Hence, the Status app team tackled\\nthis in the form of [Status Web](https://github.com/status-im/status-web/).\\n\\nFinally, (3) was the most important lesson. We learned that multi-tier applications need Waku for decentralized and\\ncensorship-resistant communications. For these projects, js-waku is simply not enough. They need Waku to work in their\\nGolang backend, Unity desktop game and React Native mobile app.\\n\\nWe understood that we should see the whole Waku software suite\\n([js-waku](https://github.com/waku-org/js-waku),\\n[nwaku](https://github.com/status-im/nwaku),\\n[go-waku](https://github.com/status-im/go-waku),\\n[waku-react-native](https://github.com/waku-org/waku-react-native),\\n[etc](https://github.com/waku-org)) as an asset for its success.\\nThat we should not limit outreach, marketing, documentation efforts to the web, but target all platforms.\\n\\nFrom a market perspective, we identified several actors:\\n\\n- platforms: Projects that uses Waku to handle communication,\\n- operators: Operators run Waku nodes and are incentivized to do so,\\n- developers: Developers are usually part of a platforms or solo hackers learning Web3,\\n- contributors: Developers and researchers with interests in decentralization, privacy, censorship-resistance,\\n zero-knowledge, etc.\\n\\n## Waku for All Decentralized Applications and Infrastructures\\n\\nIn 2022, we shifted our focus to make the various Waku implementations **usable and used**.\\n\\nWe made Waku [multi-plaform](https://github.com/status-im/go-waku/tree/master/examples).\\n\\nWe shifted Waku positioning to leverage all Waku implementations and better serve the user\'s needs:\\n\\n- Running a node for your projects and want to use Waku? Use [nwaku](https://github.com/status-im/nwaku).\\n- Going mobile? Use [Waku React Native](https://github.com/status-im/waku-react-native).\\n- C++ Desktop Game? Use [go-waku\'s C-Bindings](https://github.com/status-im/go-waku/tree/master/examples/c-bindings).\\n- Web app? Use [js-waku](https://github.com/status-im/js-waku).\\n\\nWe are consolidating the documentation for all implementations on a single website ([work in progress](https://github.com/waku-org/waku.org/issues/15))\\nto improve developer experience.\\n\\nThis year, we also started the _operator outreach_ effort to push for users to run their own Waku nodes. We have\\nrecently concluded our [first operator trial run](https://github.com/status-im/nwaku/issues/828).\\n[Nwaku](https://vac.dev/introducing-nwaku)\'s documentation, stability and performance has improved. It is now easier to\\nrun your [own Waku node](https://github.com/status-im/nwaku/tree/master/docs/operators).\\n\\nToday, operator wannabes most likely run their own nodes to support or use the Waku network.\\nWe are [dogfooding](https://twitter.com/oskarth/status/1582027828295790593?s=20&t=DPEP6fXK6KWbBjV5EBCBMA)\\n[Waku RLN](https://github.com/status-im/nwaku/issues/827), our novel economic spam protection protocol,\\nand looking at [incentivizing the Waku Store protocol](https://github.com/vacp2p/research/issues/99).\\nThis way, we are adding reasons to run your own Waku node.\\n\\nFor those who were following us in 2021, know that we are retiring the _Waku Connect_ branding in favour of the _Waku_\\nbranding.\\n\\n## Waku for Your Project\\n\\nAs discussed, Waku is now available on various platforms. The question remains: How can Waku benefit **your** project?\\n\\nHere are a couple of use cases we recently investigated:\\n\\n## Layer-2 Decentralization\\n\\nMost ([[2] [3]](#references) roll-ups use a centralized sequencer or equivalent. Running several sequencers is not as straightforward as running several execution nodes.\\nWaku can help:\\n\\n- Provide a neutral marketplace for a mempool: If sequencers compete for L2 tx fees, they may not be incentivized to\\n share transactions with other sequencers. Waku nodes can act as a neutral network to enable all sequences to access\\n transactions.\\n- Enable censorship-resistant wallet<>L2 communication,\\n- Provide rate limiting mechanism for spam protection: Using [RLN](https://rfc.vac.dev/spec/32/) to prevent DDOS.\\n\\n## Device pairing and communication\\n\\nWith [Waku Device Pairing](https://rfc.vac.dev/spec/43/), a user can setup a secure encrypted communication channel\\nbetween their devices. As this channel would operate over Waku, it would be censorship-resistant and privacy preserving.\\nThese two devices could be:\\n\\n- Ethereum node and mobile phone to access a remote admin panel,\\n- Alice\'s phone and Bob\'s phone for any kind of secure communication,\\n- Mobile wallet and desktop/browser dApp for transaction and signature exchange.\\n\\nCheck [js-waku#950](https://github.com/waku-org/js-waku/issues/950) for the latest update on this.\\n\\n## Get Involved\\n\\nDeveloper? Grab any of the Waku implementations and integrate it in your app: https://waku.org/platform.\\n\\nResearcher? See https://vac.dev/contribute to participate in Waku research.\\n\\nTech-savvy? Try to run your own node: https://waku.org/operator.\\n\\nOtherwise, play around with the various [web examples](https://github.com/waku-org/js-waku-examples#readme).\\n\\nIf you want to help, we are [hiring](https://jobs.status.im/)!\\n\\n## Moving Forward\\n\\nWhat you can expect next:\\n\\n- [Scalability and performance studies](https://forum.vac.dev/t/waku-v2-scalability-studies/142/9) and improvement across Waku software,\\n- [New websites](https://github.com/waku-org/waku.org/issues/15) to easily find documentation about Waku and its implementations,\\n- New Waku protocols implemented in all code bases and cross client PoCs\\n ([noise](https://rfc.vac.dev/spec/35/), [noise-sessions](https://rfc.vac.dev/spec/37/),\\n [waku-rln-relay](https://rfc.vac.dev/spec/17/), etc),\\n- Easier to [run your own waku node](https://github.com/status-im/nwaku/issues/828), more operator trials,\\n- Dogfooding and Improvement of existing protocols (e.g. [Waku Filter](https://github.com/vacp2p/rfc/issues?q=is%3Aissue+is%3Aopen+sort%3Aupdated-desc++12%2FWAKU2-FILTER)),\\n- Continue our focus Waku portability: Browser,\\n [Raspberry Pi Zero](https://twitter.com/richardramos_me/status/1574405469912932355?s=20&t=DPEP6fXK6KWbBjV5EBCBMA) and other restricted-resource environments,\\n- More communication & marketing effort around Waku and the Waku developer community.\\n\\n---\\n\\n## References\\n\\n- \\\\[1\\\\] Waku is modular; it is a suite of protocols; hence some Waku protocols may be mature, while\\n new protocols are still being designed. Which means that research continues to be _ongoing_ while\\n Waku is already used in production.\\n- [[2]](https://community.optimism.io/docs/how-optimism-works/#block-production) The Optimism Foundation runs the only block produce on the Optimism network.\\n- [[3]](https://l2beat.com/) Top 10 L2s are documented has having a centralized operator."},{"id":"building-privacy-protecting-infrastructure","metadata":{"permalink":"/rlog/building-privacy-protecting-infrastructure","source":"@site/rlog/2022-11-04-building-privacy-protecting-infrastructure.mdx","title":"Building Privacy-Protecting Infrastructure","description":"What is privacy-protecting infrastructure? Why do we need it and how we can build it? We\'ll look at Waku, the communication layer for Web3. We\'ll see how it uses ZKPs to incentivize and protect the Waku network. We\'ll also look at Zerokit, a library that makes it easier to use ZKPs in different environments. After reading this, I hope you\'ll better understand the importance of privacy-protecting infrastructure and how we can build it.","date":"2022-11-04T12:00:00.000Z","formattedDate":"November 4, 2022","tags":[],"readingTime":18.595,"hasTruncateMarker":true,"authors":[{"name":"Oskar","twitter":"oskarth","github":"oskarth","key":"oskarth"}],"frontMatter":{"layout":"post","name":"Building Privacy-Protecting Infrastructure","title":"Building Privacy-Protecting Infrastructure","date":"2022-11-04T12:00:00.000Z","authors":"oskarth","published":true,"slug":"building-privacy-protecting-infrastructure","categories":"research","image":"/img/building_private_infra_intro.png","discuss":"https://forum.vac.dev/t/discussion-building-privacy-protecting-infrastructure/161"},"prevItem":{"title":"Waku for All Decentralized Applications and Infrastructures","permalink":"/rlog/waku-for-all"},"nextItem":{"title":"Waku Privacy and Anonymity Analysis Part I: Definitions and Waku Relay","permalink":"/rlog/wakuv2-relay-anon"}},"content":"What is privacy-protecting infrastructure? Why do we need it and how we can build it? We\'ll look at Waku, the communication layer for Web3. We\'ll see how it uses ZKPs to incentivize and protect the Waku network. We\'ll also look at Zerokit, a library that makes it easier to use ZKPs in different environments. After reading this, I hope you\'ll better understand the importance of privacy-protecting infrastructure and how we can build it.\\n\\n\x3c!--truncate--\x3e\\n\\n_This write-up is based on a talk given at DevCon 6 in Bogota, a video can be found [here](https://www.youtube.com/watch?v=CW1DYJifdhs)_\\n\\n### Intro\\n\\nIn this write-up, we are going to talk about building privacy-protecting\\ninfrastructure. What is it, why do we need it and how can we build it?\\n\\nWe\'ll look at Waku, the communication layer for Web3. We\'ll look at how we are\\nusing Zero Knowledge (ZK) technology to incentivize and protect the Waku\\nnetwork. We\'ll also look at Zerokit, a library we are writing to make ZKP easier\\nto use in different environments.\\n\\nAt the end of this write-up, I hope you\'ll come away with an understanding of\\nthe importance of privacy-protecting infrastructure and how we can build it.\\n\\n### About\\n\\nFirst, briefly about Vac. We build public good protocols for the decentralized\\nweb, with a focus on privacy and communication. We do applied research based on\\nwhich we build protocols, libraries and publications. We are also the custodians\\nof protocols that reflect a set of principles.\\n\\n![Principles](/img/building_private_infra_principles.png)\\n\\nIt has its origins in the [Status app](https://status.im/) and trying to improve\\nthe underlying protocols and infrastructure. We build [Waku](https://waku.org/),\\namong other things.\\n\\n### Why build privacy-protecting infrastructure?\\n\\nPrivacy is the power to selectively reveal yourself. It is a requirement for\\nfreedom and self-determination.\\n\\nJust like you need decentralization in order to get censorship-resistance, you\\nneed privacy to enable freedom of expression.\\n\\nTo build applications that are decentralized and privacy-protecting, you need\\nthe base layer, the infrastructure itself, to have those properties.\\n\\nWe see this a lot. It is easier to make trade-offs at the application layer than\\ndoing them at the base layer. You can build custodial solutions on top of a\\ndecentralized and non-custodial network where participants control their own\\nkeys, but you can\'t do the opposite.\\n\\nIf you think about it, buildings can be seen as a form of privacy-protecting\\ninfrastructure. It is completely normal and obvious in many ways, but when it\\ncomes to the digital realm our mental models and way of speaking about it hasn\'t\\ncaught up yet for most people.\\n\\nI\'m not going too much more into the need for privacy or what happens when you\\ndon\'t have it, but suffice to say it is an important property for any open\\nsociety.\\n\\nWhen we have conversations, true peer-to-peer offline conversations, we can talk\\nprivately. If we use cash to buy things we can do commerce privately.\\n\\nOn the Internet, great as it is, there are a lot of forces that makes this\\nnatural state of things not the default. Big Tech has turned users into a\\ncommodity, a product, and monetized user\'s attention for advertising. To\\noptimize for your attention they need to surveil your habits and activities, and\\nhence breach your privacy. As opposed to more old-fashioned models, where\\nsomeone is buying a useful service from a company and the incentives are more\\naligned.\\n\\nWe need to build credibly neutral infrastructure that protects your privacy at\\nthe base layer, in order to truly enable applications that are\\ncensorship-resistant and encourage meaningful freedom of expression.\\n\\n### Web3 infrastructure\\n\\nInfrastructure is what lies underneath. Many ways of looking at this but I\'ll\\nkeep it simple as per the original Web3 vision. You had Ethereum for\\ncompute/consensus, Swarm for storage, and Whisper for messaging. Waku has taken\\nover the mantle from Whisper and is a lot more\\n[usable](https://vac.dev/fixing-whisper-with-waku) today than Whisper ever was,\\nfor many reasons.\\n\\n![Web3 Infrastructure](/img/web3_holy_trinity.png)\\n\\nOn the privacy-front, we see how Ethereum is struggling. It is a big UX problem,\\nespecially when you try to add privacy back \\"on top\\". It takes a lot of effort\\nand it is easier to censor. We see this with recent action around Tornado Cash.\\nCompare this with something like Zcash or Monero, where privacy is there by\\ndefault.\\n\\nThere are also problems when it comes to the p2p networking side of things, for\\nexample with Ethereum validator privacy and hostile actors and jurisdictions. If\\nsomeone can easily find out where a certain validator is physically located,\\nthat\'s a problem in many parts of the world. Being able to have stronger\\nprivacy-protection guarantees would be very useful for high-value targets.\\n\\nThis doesn\'t begin to touch on the so called \\"dapps\\" that make a lot of\\nsacrifices in how they function, from the way domains work, to how websites are\\nhosted and the reliance on centralized services for communication. We see this\\ntime and time again, where centralized, single points of failure systems work\\nfor a while, but then eventually fail.\\n\\nIn many cases an individual user might not care enough though, and for platforms\\nthe lure to take shortcuts is strong. That is why it is important to be\\nprincipled, but also pragmatic in terms of the trade-offs that you allow on top.\\nWe\'ll touch more on this in the design goals around modularity that Waku has.\\n\\n### ZK for privacy-protecting infrastructure\\n\\nZKPs are a wonderful new tool. Just like smart contracts enables programmable\\nmoney, ZKPs allow us to express fundamentally new things. In line with the great\\ntradition of trust-minimization, we can prove statement while revealing the\\nabsolute minimum information necessary. This fits the definition of privacy, the\\npower to selectively reveal yourself, perfectly. I\'m sure I don\'t need to tell\\nanyone reading this but this is truly revolutionary. The technology is advancing\\nextremely fast and often it is our imagination that is the limit.\\n\\n![Zero knowledge](/img/building_private_infra_zk.png)\\n\\n### Waku\\n\\nWhat is Waku? It is a set of modular protocols for p2p communication. It has a\\nfocus on privacy, security and being able to run anywhere. It is the spiritual\\nsuccess to Whisper.\\n\\nBy modular we mean that you can pick and choose protocols and how you use them\\ndepending on constraints and trade-offs. For example, bandwidth usage vs\\nprivacy.\\n\\nIt is designed to work in resource restricted environments, such as mobile\\nphones and in web browsers. It is important that infrastructure meets users\\nwhere they are and supports their real-world use cases. Just like you don\'t need\\nyour own army and a castle to have your own private bathroom, you shouldn\'t need\\nto have a powerful always-on node to get reasonable privacy and\\ncensorship-resistance. We might call this self-sovereignty.\\n\\n### Waku - adaptive nodes\\n\\nOne way of looking at Waku is as an open service network. There are nodes with\\nvarying degrees of capabilities and requirements. For example when it comes to\\nbandwidth usage, storage, uptime, privacy requirements, latency requirements,\\nand connectivity restrictions.\\n\\nWe have a concept of adaptive nodes that can run a variety of protocols. A node\\noperator can choose which protocols they want to run. Naturally, there\'ll be\\nsome nodes that do more consumption and other nodes that do more provisioning.\\nThis gives rise to the idea of a service network, where services are provided\\nfor and consumed.\\n\\n![Adaptive Nodes](/img/building_private_infra_adaptive.png)\\n\\n### Waku - protocol interactions\\n\\nThere are many protocols that interact. Waku Relay protocol is based on libp2p\\nGossipSub for p2p messaging. We have filter for bandwidth-restricted nodes to\\nonly receive subset of messages. Lightpush for nodes with short connection\\nwindows to push messages into network. Store for nodes that want to retrieve\\nhistorical messages.\\n\\nOn the payload layer, we provide support for Noise handshakes/key-exchanges.\\nThis means that as a developers, you can get end-to-end encryption and expected\\nguarantees out of the box. We have support for setting up a secure channel from\\nscratch, and all of this paves the way for providing Signal\'s Double Ratchet at\\nthe protocol level much easier. We also have experimental support for\\nmulti-device usage. Similar features have existed in for example the Status app\\nfor a while, but with this we make it easier for any platform using Waku to use\\nit.\\n\\nThere are other protocols too, related to peer discovery, topic usage, etc. See\\n[specs](https://rfc.vac.dev/) for more details.\\n\\n![Protocol Interactions](/img/building_private_infra_interactions.png)\\n\\n### Waku - Network\\n\\nFor the Waku network, there are a few problems. For example, when it comes to\\nnetwork spam and incentivizing service nodes. We want to address these while\\nkeeping privacy-guarantees of the base layer. I\'m going to go into both of\\nthese.\\n\\nThe spam problem arises on the gossip layer when anyone can overwhelm the\\nnetwork with messages. The service incentivization is a problem when nodes don\'t\\ndirectly benefit from the provisioning of a certain service. This can happen if\\nthey are not using the protocol directly themselves as part of normal operation,\\nor if they aren\'t socially inclined to provide a certain service. This depends a\\nlot on how an individual platform decides to use the network.\\n\\n![Waku Network](/img/building_private_infra_network.png)\\n\\n### Dealing with network spam and RLN Relay\\n\\nSince the p2p relay network is open to anyone, there is a problem with spam. If\\nwe look at existing solutions for dealing with spam in traditional messaging\\nsystems, a lot of entities like Google, Facebook, Twitter, Telegram, Discord use\\nphone number verification. While this is largely sybil-resistant, it is\\ncentralized and not private at all.\\n\\nHistorically, Whisper used PoW which isn\'t good for heterogenerous networks.\\nPeer scoring is open to sybil attacks and doesn\'t directly address spam\\nprotection in an anonymous p2p network.\\n\\nThe key idea here is to use RLN for private economic spam protection using\\nzkSNARKs.\\n\\nI\'m not going to go into too much detail of RLN here. If you are interested, I\\ngave a [talk](https://www.youtube.com/watch?v=g41nHQ0mLoA) in Amsterdam at\\nDevconnect about this. We have some write-ups on RLN\\n[here](https://vac.dev/rln-relay) by Sanaz who has been pushing a lot of this\\nfrom our side. There\'s also another talk at Devcon by Tyler going into RLN in\\nmore detail. Finally, here\'s the [RLN spec](https://rfc.vac.dev/spec/32/).\\n\\nI\'ll briefly go over what it is, the interface and circuit and then talk about\\nhow it is used in Waku.\\n\\n### RLN - Overview and Flow\\n\\nRLN stands for Rate Limiting Nullifier. It is an anonyomous rate limiting\\nmechanism based on zkSNARKs. By rate limiting we mean you can only send N\\nmessages in a given period. By anonymity we mean that you can\'t link message to\\na publisher. We can think of it as a voting booth, where you are only allowed to\\nvote once every election.\\n\\n![Voting Booth](/img/building_private_infra_vote.png)\\n\\nIt can be used for spam protection in p2p messaging systems, and also rate\\nlimiting in general, such as for a decentralized captcha.\\n\\nThere are three parts to it. You register somewhere, then you can signal and\\nfinally there\'s a verification/slashing phase. You put some capital at risk,\\neither economic or social, and if you double signal you get slashed.\\n\\n### RLN - Circuit\\n\\nHere\'s what the private and public inputs to the circuit look like. The identity\\nsecret is generated locally, and we create an identity commitment that is\\ninserted into a Merkle tree. We then use Merkle proofs to prove membership.\\nRegistered member can only signal once for a given epoch or external nullifier,\\nfor example every ten seconds in Unix time. RLN identifer is for a specific RLN\\napp.\\n\\nWe also see what the circuit output looks like. This is calculated locally. `y`\\nis a share of the secret equation, and the (internal) nullifier acts as a unique\\nfingerprint for a given app/user/epoch combination. How do we calculate `y` and\\nthe internal nullifier?\\n\\n```\\n// Private input\\nsignal input identity_secret;\\nsignal input path_elements[n_levels][1];\\nsignal input identity_path_index[n_levels];\\n\\n// Public input\\nsignal input x; // signal_hash\\nsignal input epoch; // external_nullifier\\nsignal input rln_identifier;\\n\\n// Circuit output\\nsignal output y;\\nsignal output root;\\nsignal output nullifier;\\n```\\n\\n### RLN - Shamir\'s secret sharing\\n\\nThis is done using [Shamir\'s secret\\nsharing](https://en.wikipedia.org/wiki/Shamir%27s_Secret_Sharing). Shamir\u2019s\\nsecret sharing is based on idea of splitting a secret into shares. This is how\\nwe enable slashing of funds.\\n\\nIn this case, we have two shares. If a given identity `a0` signals twice in\\nepoch/external nullifier, `a1` is the same. For a given RLN app,\\n`internal_nullifier` then stays the same. `x` is signal hash which is different,\\nand `y` is public, so we can reconstruct `identity_secret`. With the identity\\nsecret revealed, this gives access to e.g. financial stake.\\n\\n```\\na_0 = identity_secret // secret S\\na_1 = poseidonHash([a0, external_nullifier])\\n\\ny = a_0 + x * a_1\\n\\ninternal_nullifier = poseidonHash([a_1, rln_identifier])\\n```\\n\\n![Shamir\'s secret sharing](/img/building_private_infra_shamir.png)\\n\\n### RLN Relay\\n\\nThis is how RLN is used with Relay/GossipSub protocol. A node registers and\\nlocks up funds, and after that it can send messages. It publishes a message\\ncontaining the Zero Knowledge proof and some other details.\\n\\nEach relayer node listens to the membership contract for new members, and it\\nalso keeps track of relevant metadata and merkle tree. Metadata is needed to be\\nable to detect double signaling and perform slashing.\\n\\nBefore forwarding a message, it does some verification checks to ensure there\\nare no duplicate messages, ZKP is valid and no double signaling has occured. It\\nis worth noting that this can be combined with peer scoring, for example for\\nduplicate messages or invalid ZK proofs.\\n\\nIn line of Waku\'s goals of modularity, RLN Relay is applied on a specific subset\\nof pubsub and content topics. You can think of it as an extra secure channel.\\n\\n![RLN Relay](/img/building_private_infra_rlnrelay.png)\\n\\n### RLN Relay cross-client testnet\\n\\nWhere are we with RLN Relay deployment? We\'ve recently launched our second\\ntestnet. This is using RLN Relay with a smart contract on Goerli. It integrates\\nwith our example p2p chat application, and it does so through three different\\nclients, nwaku, go-waku and js-waku for browsers. This is our first p2p\\ncross-client testnet for RLN Relay.\\n\\nHere\'s a [video](https://www.youtube.com/watch?v=-vVrJWW0fls) that shows a user\\nregistering in a browser, signaling through JS-Waku. It then gets relayed to a\\nnwaku node, that verifies the proof. The second\\n[video](https://www.youtube.com/watch?v=Xz5q2ZhkFYs) shows what happens in the\\nspam case. when more than one message is sent in a given epoch, it detects it as\\nspam and discards it. Slashing hasn\'t been implemented fully yet in the client\\nand is a work in progress.\\n\\nIf you are curious and want to participate, you can join the effort on our [Vac\\nDiscord](https://discord.gg/PQFdubGt6d). We also have\\n[tutorials](https://github.com/status-im/nwaku/blob/master/docs/tutorial/rln-chat-cross-client.md)\\nsetup for all clients so you can play around with it.\\n\\nAs part of this, and to make it work in multiple different environments, we\'ve\\nalso been developing a new library called Zerokit. I\'ll talk about this a bit\\nlater.\\n\\n### Private settlement / Service credentials\\n\\nGoing back to the service network idea, let\'s talk about service credentials.\\nThe idea behind service credentials and private settlement is to enable two\\nactors to pay for and provide services without compromising their privacy. We do\\nnot want the payment to create a direct public link between the service provider\\nand requester.\\n\\nRecall the Waku service network illustration with adaptive nodes that choose\\nwhich protocols they want to run. Many of these protocols aren\'t very heavy and\\njust work by default. For example the relay protocol is enabled by default.\\nOther protocols are much heavier to provide, such as storing historical\\nmessages.\\n\\nIt is desirable to have additional incentives for this, especially for platforms\\nthat aren\'t community-based where some level of altruism can be assumed (e.g.\\nStatus Communities, or WalletConnect cloud infrastructure).\\n\\nYou have a node Alice that is often offline and wants to consume historical\\nmessages on some specific content topics. You have another node Bob that runs a\\nserver at home where they store historical messages for the last several weeks.\\nBob is happy to provide this service for free because he\'s excited about running\\nprivacy-preserving infrastructure and he\'s using it himself, but his node is\\ngetting overwhelmed by freeloaders and he feels like he should be paid something\\nfor continuing to provide this service.\\n\\nAlice deposits some funds in a smart contract which registers it in a tree,\\nsimilar to certain other private settlement mechanisms. A fee is taken or\\nburned. In exchange, she gets a set of tokens or service credentials. When she\\nwants to do a query with some criteria, she sends this to Bob. Bob responds with\\nsize of response, cost, and receiver address. Alice then sends a proof of\\ndelegation of a service token as a payment. Bob verifies the proof and resolves\\nthe query.\\n\\nThe end result is that Alice has consumed some service from Bob, and Bob has\\nreceived payment for this. There\'s no direct transaction link between Alice and\\nBob, and gas fees can be minimized by extending the period before settling on\\nchain.\\n\\nThis can be complemented with altruistic service provisioning, for example by\\nsplitting the peer pool into two slots, or only providing a few cheap queries\\nfor free.\\n\\nThe service provisioning is general, and can be generalized for any kind of\\nrequest/response service provisoning that we want to keep private.\\n\\nThis isn\'t a perfect solution, but it is an incremental improvement on top of\\nthe status quo. It can be augmented with more advanced techniques such as better\\nnon-repudiable node reputation, proof of correct service provisioning, etc.\\n\\nWe are currently in the raw spec / proof of concept stage of this. We expect to\\nlaunch a testnet of this later this year or early next year.\\n\\n![Service credentials flow](/img/building_private_infra_servicecred.png)\\n\\n### Zerokit\\n\\n[Zerokit](https://github.com/vacp2p/zerokit) is a set of Zero Knowledge modules,\\nwritten in Rust and designed to be used in many different environments. The\\ninitial goal is to get the best of both worlds with Circom/Solidity/JS and\\nRust/ZK ecosystem. This enables people to leverage Circom-based constructs from\\nnon-JS environments.\\n\\nFor the RLN module, it is using Circom circuits via ark-circom and Rust for\\nscaffolding. It exposes a C FFI API that can be used through other system\\nprogramming environments, like Nim and Go. It also exposes an experimental WASM\\nAPI that can be used through web browsers.\\n\\nWaku is p2p infrastructure running in many different environments, such as\\nNim/JS/Go/Rust, so this a requirement for us.\\n\\nCircom and JS strengths are access to Dapp developers, tooling, generating\\nverification code, circuits etc. Rust strengths is that it is systems-based and\\neasy to interface with other language runtime such as Nim, Go, Rust, C. It also\\ngives access to other Rust ZK ecosystems such as arkworks. This opens door for\\nusing other constructs, such as Halo2. This becomes especially relevant for\\nconstructs where you don\'t want to do a trusted setup or where circuits are more\\ncomplex/custom and performance requirements are higher.\\n\\nIn general with Zerokit, we want to make it easy to build and use ZKP in a\\nmultitude of environments, such as mobile phones and web browsers. Currently it\\nis too complex to write privacy-protecting infrastructure with ZKPs considering\\nall the languages and tools you have to learn, from JS, Solidity and Circom to\\nRust, WASM and FFI. And that isn\'t even touching on things like secure key\\nstorage or mobile dev. Luckily more and more projects are working on this,\\nincluding writing DSLs etc. It\'d also be exciting if we can make a useful\\ntoolstack for JS-less ZK dev to reduce cognitive overhead, similar to what we\\nhave with something like Foundry.\\n\\n### Other research\\n\\nI also want to mention a few other things we are doing. One thing is\\n[protocol specifications](https://rfc.vac.dev/). We think this is very important\\nfor p2p infra, and we see a lot of other projects that claim to do it p2p\\ninfrastructure but they aren\'t clear about guarantees or how stable something\\nis. That makes it hard to have multiple implementations, to collaborate across\\ndifferent projects, and to analyze things objectively.\\n\\nRelated to that is publishing [papers](https://vac.dev/publications). We\'ve put\\nout three so far, related to Waku and RLN-Relay. This makes it easier to\\ninterface with academia. There\'s a lot of good researchers out there and we want\\nto build a better bridge between academia and industry.\\n\\nAnother thing is [network](https://vac.dev/wakuv2-relay-anon)\\n[privacy](https://github.com/vacp2p/research/issues/107). Waku is modular with\\nrespect to privacy guarantees, and there are a lot of knobs to turn here\\ndepending on specific deployments. For example, if you are running the full\\nrelay protocol you currently have much stronger receiver anonymity than if you\\nare running filter protocol from a bandwidth or connectivity-restricted node.\\n\\nWe aim to make this pluggable depending on user needs. E.g. mixnets such as Nym\\ncome with some trade-offs but are a useful tool in the arsenal. A good mental\\nmodel to keep in mind is the anonymity trilemma, where you can only pick 2/3 out\\nof low latency, low bandwidth usage and strong anonymity.\\n\\nWe are currently exploring [Dandelion-like\\nadditions](https://github.com/vacp2p/research/issues/119) to the relay/gossip\\nprotocol, which would provide for stronger sender anonymity, especially in a\\nmulti-node/botnet attacker model. As part of this we are looking into different\\nparameters choices and general possibilities for lower latency usage. This could\\nmake it more amenable for latency sensitive environments, such as validator\\nprivacy, for specific threat models. The general theme here is we want to be\\nrigorous with the guarantees we provide, under what conditions and for what\\nthreat models.\\n\\nAnother thing mentioned earlier is [Noise payload\\nencryption](https://vac.dev/wakuv2-noise), and specifically things like allowing\\nfor pairing different devices with e.g. QR codes. This makes it easier for\\ndevelopers to provide secure messaging in many realistic scenarios in a\\nmulti-device world.\\n\\n![Other research](/img/building_private_infra_misc.png)\\n\\n### Summary\\n\\nWe\'ve gone over what privacy-protecting infrastructure is, why we want it and\\nhow we can build it. We\'ve seen how ZK is a fundamental building block for this.\\nWe\'ve looked at Waku, the communication layer for Web3, and how it uses Zero\\nKnowledge proofs to stay private and function better. We\'ve also looked at\\nZerokit and how we can make it easier to do ZKP in different environments.\\n\\nFinally we also looked at some other research we\'ve been doing. All of the\\nthings mentioned in this article, and more, is available as\\n[write-ups](https://vac.dev/research), [specs](https://rfc.vac.dev/), or\\ndiscussions on our [forum](forum.vac.dev/) or [Github](github.com/vacp2p/).\\n\\nIf you find any of this exciting to work on, feel free to reach out on our\\nDiscord. We are also [hiring](https://jobs.status.im/), and we have started\\nexpanding into other privacy infrastructure tech like private and provable\\ncomputation with ZK-WASM."},{"id":"wakuv2-relay-anon","metadata":{"permalink":"/rlog/wakuv2-relay-anon","source":"@site/rlog/2022-07-22-relay-anonymity.mdx","title":"Waku Privacy and Anonymity Analysis Part I: Definitions and Waku Relay","description":"Introducing a basic threat model and privacy/anonymity analysis for the Waku v2 relay protocol.","date":"2022-07-22T10:00:00.000Z","formattedDate":"July 22, 2022","tags":[],"readingTime":16.78,"hasTruncateMarker":true,"authors":[{"name":"Daniel","github":"kaiserd","key":"kaiserd"}],"frontMatter":{"layout":"post","name":"Waku Privacy and Anonymity Analysis Part I: Definitions and Waku Relay","title":"Waku Privacy and Anonymity Analysis Part I: Definitions and Waku Relay","date":"2022-07-22T10:00:00.000Z","authors":"kaiserd","published":true,"slug":"wakuv2-relay-anon","categories":"research","image":"/img/anonymity_trilemma.svg","discuss":"https://forum.vac.dev/t/discussion-waku-privacy-and-anonymity-analysis/149","_includes":["math"],"toc_min_heading_level":2,"toc_max_heading_level":5},"prevItem":{"title":"Building Privacy-Protecting Infrastructure","permalink":"/rlog/building-privacy-protecting-infrastructure"},"nextItem":{"title":"Noise handshakes as key-exchange mechanism for Waku","permalink":"/rlog/wakuv2-noise"}},"content":"Introducing a basic threat model and privacy/anonymity analysis for the Waku v2 relay protocol.\\n\\n\x3c!--truncate--\x3e\\n\\n[Waku v2](https://rfc.vac.dev/spec/10/) enables secure, privacy preserving communication using a set of modular P2P protocols.\\nWaku v2 also aims at protecting the user\'s anonymity.\\nThis post is the first in a series about Waku v2 security, privacy, and anonymity.\\nThe goal is to eventually have a full privacy and anonymity analysis for each of the Waku v2 protocols, as well as covering the interactions of various Waku v2 protocols.\\nThis provides transparency with respect to Waku\'s current privacy and anonymity guarantees, and also identifies weak points that we have to address.\\n\\nIn this post, we first give an informal description of security, privacy and anonymity in the context of Waku v2.\\nFor each definition, we summarize Waku\'s current guarantees regarding the respective property.\\nWe also provide attacker models, an attack-based threat model, and a first anonymity analysis of [Waku v2 relay](https://rfc.vac.dev/spec/11/) within the respective models.\\n\\nWaku comprises many protocols that can be combined in a modular way.\\nFor our privacy and anonymity analysis, we start with the relay protocol because it is at the core of Waku v2 enabling Waku\'s publish subscribe approach to P2P messaging.\\nIn its current form, Waku relay is a minor extension of [libp2p GossipSub](https://github.com/libp2p/specs/blob/master/pubsub/gossipsub/README.md).\\n\\n![Figure 1: The Waku v2 relay mesh is based on the [GossipSub mesh](https://docs.libp2p.io/concepts/publish-subscribe#types-of-peering)](/img/libp2p_gossipsub_types_of_peering.png)\\n\\n## Informal Definitions: Security, Privacy, and Anonymity\\n\\nThe concepts of security, privacy, and anonymity are linked and have quite a bit of overlap.\\n\\n### Security\\n\\nOf the three, [Security](https://en.wikipedia.org/wiki/Information_security) has the clearest agreed upon definition,\\nat least regarding its key concepts: _confidentiality_, _integrity_, and _availability_.\\n\\n- confidentiality: data is not disclosed to unauthorized entities.\\n- integrity: data is not modified by unauthorized entities.\\n- availability: data is available, i.e. accessible by authorized entities.\\n\\nWhile these are the key concepts, the definition of information security has been extended over time including further concepts,\\ne.g. [authentication](https://en.wikipedia.org/wiki/Authentication) and [non-repudiation](https://en.wikipedia.org/wiki/Non-repudiation).\\nWe might cover these in future posts.\\n\\n### Privacy\\n\\nPrivacy allows users to choose which data and information\\n\\n- they want to share\\n- and with whom they want to share it.\\n\\nThis includes data and information that is associated with and/or generated by users.\\nProtected data also comprises metadata that might be generated without users being aware of it.\\nThis means, no further information about the sender or the message is leaked.\\nMetadata that is protected as part of the privacy-preserving property does not cover protecting the identities of sender and receiver.\\nIdentities are protected by the [anonymity property](#anonymity).\\n\\nOften privacy is realized by the confidentiality property of security.\\nThis neither makes privacy and security the same, nor the one a sub category of the other.\\nWhile security is abstract itself (its properties can be realized in various ways), privacy lives on a more abstract level using security properties.\\nPrivacy typically does not use integrity and availability.\\nAn adversary who has no access to the private data, because the message has been encrypted, could still alter the message.\\n\\nWaku offers confidentiality via secure channels set up with the help of the [Noise Protocol Framework](https://noiseprotocol.org/).\\nUsing these secure channels, message content is only disclosed to the intended receivers.\\nThey also provide good metadata protection properties.\\nHowever, we do not have a metadata protection analysis as of yet,\\nwhich is part of our privacy/anonymity roadmap.\\n\\n### Anonymity\\n\\nPrivacy and anonymity are closely linked.\\nBoth the identity of a user and data that allows inferring a user\'s identity should be part of the privacy policy.\\nFor the purpose of analysis, we want to have a clearer separation between these concepts.\\n\\nWe define anonymity as _unlinkablity of users\' identities and their shared data and/or actions_.\\n\\nWe subdivide anonymity into _receiver anonymity_ and _sender anonymity_.\\n\\n#### Receiver Anonymity\\n\\nWe define receiver anonymity as _unlinkability of users\' identities and the data they receive and/or related actions_.\\nThe data transmitted via Waku relay must be a [Waku message](https://rfc.vac.dev/spec/14/), which contains a content topic field.\\nBecause each message is associated with a content topic, and each receiver is interested in messages with specific content topics,\\nreceiver anonymity in the context of Waku corresponds to _subscriber-topic unlinkability_.\\nAn example for the \\"action\\" part of our receiver anonymity definition is subscribing to a specific topic.\\n\\nThe Waku message\'s content topic is not related to the libp2p pubsub topic.\\nFor now, Waku uses a single libp2p pubsub topic, which means messages are propagated via a single mesh of peers.\\nWith this, the receiver discloses its participation in Waku on the gossipsub layer.\\nWe will leave the analysis of libp2p gossipsub to a future article within this series, and only provide a few hints and pointers here.\\n\\nWaku offers k-anonymity regarding content topic interest in the global adversary model.\\n[K-anonymity](https://en.wikipedia.org/wiki/K-anonymity) in the context of Waku means an attacker can link receivers to content topics with a maximum certainty of $1/k$.\\nThe larger $k$, the less certainty the attacker gains.\\nReceivers basically hide in a pool of $k$ content topics, any subset of which could be topics they subscribed to.\\nThe attacker does not know which of those the receiver actually subscribed to,\\nand the receiver enjoys [plausible deniability](https://en.wikipedia.org/wiki/Plausible_deniability#Use_in_cryptography) regarding content topic subscription.\\nAssuming there are $n$ Waku content topics, a receiver has $n$-anonymity with respect to association to a specific content topic.\\n\\nTechnically, Waku allows distributing messages over several libp2p pubsub topics.\\nThis yields $k$-anonymity, assuming $k$ content topics share the same pubsub topic.\\nHowever, if done wrongly, such sharding of pubsub topics can breach anonymity.\\nA formal specification of anonymity-preserving topic sharding building on the concepts of [partitioned topics](https://specs.status.im/spec/10#partitioned-topic) is part of our roadmap.\\n\\nAlso, Waku is not directly concerned with 1:1 communication, so for this post, 1:1 communication is out of scope.\\nChannels for 1:1 communication can be implemented on top of Waku relay.\\nIn the future, a 1:1 communication protocol might be added to Waku.\\nSimilar to topic sharding, it would maintain receiver anonymity leveraging [partitioned topics](https://specs.status.im/spec/10#partitioned-topic).\\n\\n#### Sender Anonymity\\n\\nWe define sender anonymity as _unlinkability of users\' identities and the data they send and/or related actions_.\\nBecause the data in the context of Waku is Waku messages, sender anonymity corresponds to _sender-message unlinkability_.\\n\\nIn summary, Waku offers weak sender anonymity because of [Waku\'s strict no sign policy](https://rfc.vac.dev/spec/11/#signature-policy),\\nwhich has its origins in the [Ethereum consensus specs](https://github.com/ethereum/consensus-specs/blob/dev/specs/phase0/p2p-interface.md#why-are-we-using-the-strictnosign-signature-policy).\\n[17/WAKU-RLN-RELAY](https://rfc.vac.dev/spec/17/) and [18/WAKU2-SWAP](https://rfc.vac.dev/spec/18/) mitigate replay and injection attacks.\\n\\nWaku currently does not offer sender anonymity in stronger attacker models, as well as cannot protect against targeted attacks in weaker attacker models like the single or multi node attacker.\\nWe will cover this in more detail in later sections.\\n\\n### Anonymity Trilemma\\n\\n[The Anonymity trilemma](https://freedom.cs.purdue.edu/projects/trilemma.html) states that only two out of _strong anonymity_, _low bandwidth_, and _low latency_ can be guaranteed in the global on-net attacker model.\\nWaku\'s goal, being a modular set of protocols, is to offer any combination of two out of these three properties, as well as blends.\\nAn example for blending is an adjustable number of pubsub topics and peers in the respective pubsub topic mesh; this allows tuning the trade-off between anonymity and bandwidth.\\n\\n![Figure 2: Anonymity Trilemma: pick two. ](/img/anonymity_trilemma.svg)\\n\\nA fourth factor that influences [the anonymity trilemma](https://freedom.cs.purdue.edu/projects/trilemma.html) is _frequency and patterns_ of messages.\\nThe more messages there are, and the more randomly distributed they are, the better the anonymity protection offered by a given anonymous communication protocol.\\nSo, incentivising users to use the protocol, for instance by lowering entry barriers, helps protecting the anonymity of all users.\\nThe frequency/patterns factor is also related to the above described k-anonymity.\\n\\n### Censorship Resistance\\n\\nAnother security related property that Waku aims to offer is censorship resistance.\\nCensorship resistance guarantees that users can participate even if an attacker tries to deny them access.\\nSo, censorship resistance ties into the availability aspect of security.\\nIn the context of Waku that means users should be able to send messages as well as receive all messages they are interested in,\\neven if an attacker tries to prevent them from disseminating messages or tries to deny them access to messages.\\n\\nCurrently, Waku only guarantees censorship resistance in the weak single node attacker model.\\nWhile currently employed secure channels mitigate targeted censorship, e.g. blocking specific content topics,\\ngeneral censorship resistance in strong attacker models is part of our roadmap.\\nAmong other options, we will investigate [Pluggable Transports](https://www.pluggabletransports.info/about/) in future articles.\\n\\n## Attacker Types\\n\\nThe following lists various attacker types with varying degrees of power.\\nThe more power an attacker has, the more difficult it is to gain the respective attacker position.\\n\\nEach attacker type comes in a passive and an active variant.\\nWhile a passive attacker can stay hidden and is not suspicious,\\nthe respective active attacker has more (or at least the same) deanonymization power.\\n\\nWe also distinguish between internal and external attackers.\\n\\n### Internal\\n\\nWith respect to Waku relay, an internal attacker participates in the same pubsub topic as its victims.\\nWithout additional measures on higher layer protocols, access to an internal position is easy to get.\\n\\n#### Single Node\\n\\nThis attacker controls a single node.\\nBecause this position corresponds to normal usage of Waku relay, it is trivial to obtain.\\n\\n#### Multi Node\\n\\nThis attacker controls several nodes. We assume a smaller static number of controlled nodes.\\nThe multi node position can be achieved relatively easily by setting up multiple nodes.\\nBotnets might be leveraged to increase the number of available hosts.\\nMulti node attackers could use [Sybil attacks](https://en.wikipedia.org/wiki/Sybil_attack) to increase the number of controlled nodes.\\nA countermeasure is for nodes to only accept libp2p gossipsub graft requests from peers with different IP addresses, or even different subnets.\\n\\n#### Linearly Scaling Nodes\\n\\nThis attacker controls a number of nodes that scales linearly with the number of nodes in the network.\\nThis attacker is especially interesting to investigate in the context of DHT security,\\nwhich Waku uses for ambient peer discovery.\\n\\n### External\\n\\nAn external attacker can only see encrypted traffic (protected by a secure channel set up with [Noise](https://rfc.vac.dev/spec/35/)).\\nBecause an internal position can be easily obtained,\\nin practice external attackers would mount combined attacks that leverage both internal an external attacks.\\nWe cover this more below when describing attacks.\\n\\n#### Local\\n\\nA local attacker has access to communication links in a local network segment.\\nThis could be a rogue access point (with routing capability).\\n\\n#### AS\\n\\nAn AS attacker controls a single AS (autonomous system).\\nA passive AS attacker can listen to traffic on arbitrary links within the AS.\\nAn active AS attacker can drop, inject, and alter traffic on arbitrary links within the AS.\\n\\nIn practice, a malicious ISP would be considered as an AS attacker.\\nA malicious ISP could also easily setup a set of nodes at specific points in the network,\\ngaining internal attack power similar to a strong multi node attacker.\\n\\n#### Global On-Net\\n\\nA global on-net attacker has complete overview over the whole network.\\nA passive global attacker can listen to traffic on all links,\\nwhile the active global attacker basically carries the traffic: it can freely drop, inject, and alter traffic at all positions in the network.\\nThis basically corresponds to the [Dolev-Yao model](https://en.wikipedia.org/wiki/Dolev%E2%80%93Yao_model).\\n\\nAn entity with this power would, in practice, also have the power of the internal linearly scaling nodes attacker.\\n\\n## Attack-based Threat Analysis\\n\\nThe following lists various attacks including the weakest attacker model in which the attack can be successfully performed.\\nThe respective attack can be performed in all stronger attacker models as well.\\n\\nAn attack is considered more powerful if it can be successfully performed in a weaker attacker model.\\n\\nIf not stated otherwise, we look at these attacks with respect to their capability to deanonymize the message sender.\\n\\n### Scope\\n\\nIn this post, we introduce a simple tightly scoped threat model for Waku v2 Relay, which will be extended in the course of this article series.\\n\\nIn this first post, we will look at the relay protocol in isolation.\\nEven though many threats arise from layers Waku relay is based on, and layers that in turn live on top of relay,\\nwe want to first look at relay in isolation because it is at the core of Waku v2.\\nAddressing and trying to solve all security issues of a complex system at once is an overwhelming task, which is why we focus on the soundness of relay first.\\n\\nThis also goes well with the modular design philosophy of Waku v2, as layers of varying levels of security guarantees can be built on top of relay, all of which can relay on the guarantees that Waku provides.\\nInstead of looking at a multiplicative explosion of possible interactions, we look at the core in this article, and cover the most relevant combinations in future posts.\\n\\nFurther restricting the scope, we will look at the data field of a relay message as a black box.\\nIn a second article on Waku v2 relay, we will look into the data field, which according to the [specification of Waku v2 relay](https://rfc.vac.dev/spec/11/#message-fields) must be a [Waku v2 message](https://rfc.vac.dev/spec/14/).\\nWe only consider messages with version field `2`, which indicates that the payload has to be encoded using [35/WAKU2-NOISE](https://rfc.vac.dev/spec/35/).\\n\\n### Prerequisite: Get a Specific Position in the Network\\n\\nSome attacks require the attacker node(s) to be in a specific position in the network.\\nIn most cases, this corresponds to trying to get into the mesh peer list for the desired pubsub topic of the victim node.\\n\\nIn libp2p gossipsub, and by extension Waku v2 relay, nodes can simply send a graft message for the desired topic to the victim node.\\nIf the victim node still has open slots, the attacker gets the desired position.\\nThis only requires the attacker to know the gossipsub multiaddress of the victim node.\\n\\nA linearly scaling nodes attacker can leverage DHT based discovery systems to boost the probability of malicious nodes being returned, which in turn significantly increases the probability of attacker nodes ending up in the peer lists of victim nodes.\\n[Waku v2 discv5](https://vac.dev/wakuv2-apd) will employ countermeasures that mitigate the amplifying effect this attacker type can achieve.\\n\\n### Replay Attack\\n\\nIn the scope we defined above, Waku v2 is resilient against replay attacks.\\nGossipSub nodes, and by extension Waku relay nodes, feature a `seen` cache, and only relay messages they have not seen before.\\nFurther, replay attacks will be punished by [RLN](https://rfc.vac.dev/spec/17/) and [SWAP](https://rfc.vac.dev/spec/18/).\\n\\n### Neighbourhood Surveillance\\n\\nThis attack can be performed by a single node attacker that is connected to all peers of the victim node $v$ with respect to a specific topic mesh.\\nThe attacker also has to be connected to $v$.\\nIn this position, the attacker will receive messages $m_v$ sent by $v$ both on the direct path from $v$, and on indirect paths relayed by peers of $v$.\\nIt will also receive messages $m_x$ that are not sent by $v$. These messages $m_x$ are relayed by both $v$ and the peers of $v$.\\nMessages that are received (significantly) faster from $v$ than from any other of $v$\'s peers are very likely messages that $v$ sent,\\nbecause for these messages the attacker is one hop closer to the source.\\n\\nThe attacker can (periodically) measure latency between itself and $v$, and between itself and the peers of $v$ to get more accurate estimates for the expected timings.\\nAn AS attacker (and if the topology allows, even a local attacker) could also learn the latency between $v$ and its well-behaving peers.\\nAn active AS attacker could also increase the latency between $v$ and its peers to make the timing differences more prominent.\\nThis, however, might lead to $v$ switching to other peers.\\n\\nThis attack cannot (reliably) distinguish messages $m_v$ sent by $v$ from messages $m_y$ relayed by peers of $v$ the attacker is not connected to.\\nStill, there are hop-count variations that might be leveraged.\\nMessages $m_v$ always have a hop-count of 1 on the path from $v$ to the attacker, while all other paths are longer.\\nMessages $m_y$ might have the same hop-count on the path from $v$ as well as on other paths.\\n\\n### Controlled Neighbourhood\\n\\nIf a multi node attacker manages to control all peers of the victim node, it can trivially tell which messages originated from $v$.\\n\\n### Observing Messages\\n\\nIf Waku relay was not protected with Noise, the AS attacker could simply check for messages leaving $v$ which have not been relayed to $v$.\\nThese are the messages sent by $v$.\\nWaku relay protects against this attack by employing secure channels setup using Noise.\\n\\n### Correlation\\n\\nMonitoring all traffic (in an AS or globally), allows the attacker to identify traffic correlated with messages originating from $v$.\\nThis (alone) does not allow an external attacker to learn which message $v$ sent, but it allows identifying the respective traffic propagating through the network.\\nThe more traffic in the network, the lower the success rate of this attack.\\n\\nCombined with just a few nodes controlled by the attacker, the actual message associated with the correlated traffic can eventually be identified.\\n\\n### DoS\\n\\nAn active single node attacker could run a disruption attack by\\n\\n- (1) dropping messages that should be relayed\\n- (2) flooding neighbours with bogus messages\\n\\nWhile (1) has a negative effect on availability, the impact is not significant.\\nA linearly scaling botnet attacker, however, could significantly disrupt the network with such an attack.\\n(2) is thwarted by [RLN](https://rfc.vac.dev/spec/17/).\\nAlso [SWAP](https://rfc.vac.dev/spec/18/) helps mitigating DoS attacks.\\n\\nA local attacker can DoS Waku by dropping all Waku traffic within its controlled network segment.\\nAn AS attacker can DoS Waku within its authority, while a global attacker can DoS the whole network.\\nA countermeasure are censorship resistance techniques like [Pluggable Transports](https://www.pluggabletransports.info/about/).\\n\\n## Summary and Future Work\\n\\nCurrently, Waku v2 relay offers k-anonymity with respect to receiver anonymity.\\nThis also includes k-anonymity towards legitimate members of the same topic.\\n\\nWaku v2 relay offers sender anonymity in the single node attacker model with its [strict no sign policy](https://rfc.vac.dev/spec/11/#signature-policy).\\nCurrently, Waku v2 does not guarantee sender anonymity in the multi node and stronger attacker models.\\nHowever, we are working on modular anonymity-preserving protocols and building blocks as part of our privacy/anonymity roadmap.\\nThe goal is to allow tunable anonymity with respect to trade offs between _strong anonymity_, _low bandwidth_, and _low latency_.\\nAll of these cannot be fully guaranteed as the [the anonymity trilemma](https://freedom.cs.purdue.edu/projects/trilemma.html) states.\\nSome applications have specific requirements, e.g. low latency, which require a compromise on anonymity.\\nAnonymity-preserving mechanisms we plan to investigate and eventually specify as pluggable anonymity protocols for Waku comprise\\n\\n- [Dandelion++](https://arxiv.org/abs/1805.11060) for lightweight anonymity;\\n- [onion routing](https://en.wikipedia.org/wiki/Onion_routing) as a building block adding a low latency anonymization layer;\\n- [a mix network](https://en.wikipedia.org/wiki/Mix_network) for providing strong anonymity (on top of onion routing) even in the strongest attacker model at the cost of higher latency.\\n\\nThese pluggable anonymity-preserving protocols will form a sub-set of the Waku v2 protocol set.\\nAs an intermediate step, we might directly employ Tor for onion-routing, and [Nym](https://nymtech.net/) as a mix-net layer.\\n\\nIn future research log posts, we will cover further Waku v2 protocols and identify anonymity problems that will be added to our roadmap.\\nThese protocols comprise\\n\\n- [13/WAKU2-STORE](https://rfc.vac.dev/spec/13/), which can violate receiver anonymity as it allows filtering by content topic.\\n A countermeasure is using the content topic exclusively for local filters.\\n- [12/WAKU2-FILTER](https://rfc.vac.dev/spec/12/), which discloses nodes\' interest in topics;\\n- [19/WAKU2-LIGHTPUSH](https://rfc.vac.dev/spec/19/), which also discloses nodes\' interest in topics and links the lightpush client as the sender of a message to the lightpush service node;\\n- [21/WAKU2-FTSTORE](https://rfc.vac.dev/spec/21/), which discloses nodes\' interest in specific time ranges allowing to infer information like online times.\\n\\nWhile these protocols are not necessary for the operation of Waku v2, and can be seen as pluggable features,\\nwe aim to provide alternatives without the cost of lowering the anonymity level.\\n\\n## References\\n\\n- [10/WAKU2](https://rfc.vac.dev/spec/10/)\\n- [11/WAKU2-RELAY](https://rfc.vac.dev/spec/11/)\\n- [libp2p GossipSub](https://github.com/libp2p/specs/blob/master/pubsub/gossipsub/README.md)\\n- [Security](https://en.wikipedia.org/wiki/Information_security)\\n- [Authentication](https://en.wikipedia.org/wiki/Authentication)\\n- [Non-repudiation](https://en.wikipedia.org/wiki/Non-repudiation)\\n- [Noise Protocol Framework](https://noiseprotocol.org/)\\n- [plausible deniability](https://en.wikipedia.org/wiki/Plausible_deniability#Use_in_cryptography)\\n- [Waku v2 message](https://rfc.vac.dev/spec/14/)\\n- [partitioned topics](https://specs.status.im/spec/10#partitioned-topic)\\n- [Sybil attack](https://en.wikipedia.org/wiki/Sybil_attack)\\n- [Dolev-Yao model](https://en.wikipedia.org/wiki/Dolev%E2%80%93Yao_model)\\n- [35/WAKU2-NOISE](https://rfc.vac.dev/spec/35/)\\n- [33/WAKU2-DISCV5](https://vac.dev/wakuv2-apd)\\n- [strict no sign policy](https://github.com/ethereum/consensus-specs/blob/dev/specs/phase0/p2p-interface.md#why-are-we-using-the-strictnosign-signature-policy)\\n- [Waku v2 strict no sign policy](https://rfc.vac.dev/spec/11/#signature-policy)\\n- [17/WAKU-RLN-RELAY](https://rfc.vac.dev/spec/17/)\\n- [anonymity trilemma](https://freedom.cs.purdue.edu/projects/trilemma.html)\\n- [18/WAKU2-SWAP](https://rfc.vac.dev/spec/18/)\\n- [Pluggable Transports](https://www.pluggabletransports.info/about/)\\n- [Nym](https://nymtech.net/)\\n- [Dandelion++](https://arxiv.org/abs/1805.11060)\\n- [13/WAKU2-STORE](https://rfc.vac.dev/spec/13/)\\n- [12/WAKU2-FILTER](https://rfc.vac.dev/spec/12/)\\n- [19/WAKU2-LIGHTPUSH](https://rfc.vac.dev/spec/19/)\\n- [21/WAKU2-FTSTORE](https://rfc.vac.dev/spec/21/)"},{"id":"wakuv2-noise","metadata":{"permalink":"/rlog/wakuv2-noise","source":"@site/rlog/2022-05-17-noise.mdx","title":"Noise handshakes as key-exchange mechanism for Waku","description":"We provide an overview of the Noise Protocol Framework as a tool to design efficient and secure key-exchange mechanisms in Waku2.","date":"2022-05-17T10:00:00.000Z","formattedDate":"May 17, 2022","tags":[],"readingTime":21.115,"hasTruncateMarker":true,"authors":[{"name":"s1fr0","github":"s1fr0","key":"s1fr0"}],"frontMatter":{"layout":"post","name":"Noise handshakes as key-exchange mechanism for Waku","title":"Noise handshakes as key-exchange mechanism for Waku","date":"2022-05-17T10:00:00.000Z","authors":"s1fr0","published":true,"slug":"wakuv2-noise","categories":"research","summary":null,"image":"/img/noise/NM.png","discuss":"https://forum.vac.dev/t/discussion-noise-handshakes-as-key-exchange-mechanism-for-waku/137","_includes":["math"]},"prevItem":{"title":"Waku Privacy and Anonymity Analysis Part I: Definitions and Waku Relay","permalink":"/rlog/wakuv2-relay-anon"},"nextItem":{"title":"Waku v2 Ambient Peer Discovery","permalink":"/rlog/wakuv2-apd"}},"content":"We provide an overview of the Noise Protocol Framework as a tool to design efficient and secure key-exchange mechanisms in Waku2.\\n\\n\x3c!--truncate--\x3e\\n\\n## Introduction\\n\\nIn this post we will provide an overview of how [Waku v2](https://rfc.vac.dev/spec/10/) users can adopt [Noise handshakes](http://www.noiseprotocol.org/noise.html) to agree on cryptographic keys used to securely encrypt messages.\\n\\nThis process belongs to the class of _key-exchange_ mechanisms, consisting of all those protocols that, with different levels of complexity and security guarantees, allow two parties to publicly agree on a secret without letting anyone else know what this secret is.\\n\\nBut why do we need key-exchange mechanisms in the first place?\\n\\nWith the advent of [public-key cryptography](https://en.wikipedia.org/wiki/Public-key_cryptography), it become possible to decouple encryption from decryption through use of two distinct cryptographic keys: one _public_, used to encrypt information and that can be made available to anyone, and one _private_ (kept secret), which enables decryption of messages encrypted with its corresponding public key. The same does not happen in the case of [symmetric encryption schemes](https://en.wikipedia.org/wiki/Symmetric-key_algorithm) where, instead, the same key is used for both encryption and decryption operations and hence cannot be publicly revealed as for public keys.\\n\\nIn order to address specific application needs, many different public, symmetric and hybrid cryptographic schemes were designed: [Waku v1](https://rfc.vac.dev/spec/6/) and [Waku v2](https://rfc.vac.dev/spec/10/), which inherits part of their design from the Ethereum messaging protocol [Whisper](https://ethereum.org/en/developers/docs/networking-layer/#whisper), provide [support](https://rfc.vac.dev/spec/26/) to both public-key primitives ([`ECIES`](https://en.wikipedia.org/wiki/Integrated_Encryption_Scheme), [`ECDSA`](https://en.wikipedia.org/wiki/Elliptic_Curve_Digital_Signature_Algorithm)) and symmetric primitives ([`AES-256-GCM`](https://en.wikipedia.org/wiki/Galois/Counter_Mode), [`KECCAK-256`](https://en.wikipedia.org/wiki/SHA-3)), used to sign, hash, encrypt and decrypt exchanged messages.\\n\\nIn principle, when communications employ public-key based encryption schemes (`ECIES`, in the case of Waku), there is no need for a key-agreement among parties: messages can be directly encrypted using the recipient\'s public-key before being sent over the network. However, public-key encryption and decryption primitives are usually very inefficient in processing large amount of data, and this may constitute a bottleneck for many of today\'s applications. Symmetric encryption schemes such as `AES-256-GCM`, on the other hand, are much more efficient, but the encryption/decryption key needs to be shared among users beforehand any encrypted messages is exchanged.\\n\\nTo counter the downsides given by each of these two approaches while taking advantage of their strengths, hybrid constructions were designed. In these, public-key primitives are employed to securely agree on a secret key which, in turn, is used with a symmetric cipher for encrypting messages. In other words, such constructions specify a (public-key based) key-agreement mechanism!\\n\\nWaku, up to [payload version 1](https://rfc.vac.dev/spec/14/#payload-encryption), does not implement nor recommend any protocol for exchanging symmetric ciphers\' keys, leaving such task to the application layer. It is important to note that the kind of key-agreement employed has a direct impact on the security properties that can be granted on later encrypted messages, while security requirements usually depend on the specific application for which encryption is needed in the first place.\\n\\nIn this regard, [Status](https://status.im), which builds on top of Waku, [implements](https://specs.status.im/spec/5) a custom version of the [X3DH](https://signal.org/docs/specifications/x3dh/) key-agreement protocol, in order to allow users to instantiate end-to-end encrypted communication channels. However, although such a solution is optimal when applied to (distributed) E2E encrypted chats, it is not flexible enough to fit or simplify the variety of applications Waku aims to address.\\nHence, proposing and implementing one or few key-agreements which provide certain (presumably _strong_) security guarantees, would inevitably degrade performances of all those applications for which, given their security requirements, more tailored and efficient key-exchange mechanisms can be employed.\\n\\nGuided by different examples, in the following sections we will overview Noise, a protocol framework we are [currently integrating](https://rfc.vac.dev/spec/35/) in Waku, for building secure key-agreements between two parties. One of the great advantage of using Noise is that it is possible to add support to new key-exchanges by just specifying users\' actions from a predefined list, requiring none to minimal modifications to existing implementations. Furthermore, Noise provides a framework to systematically analyze protocols\' security properties and the corresponding attacker threat models. This allows not only to easily design new key-agreements eventually optimized for specific applications we want to address, but also to easily analyze or even [formally verify](https://noiseexplorer.com/) any of such custom protocol!\\n\\nWe believe that with its enormous flexibility and features, Noise represents a perfect candidate for bringing key-exchange mechanisms in Waku.\\n\\n## The Diffie-Hellman Key-exchange\\n\\nThe formalization of modern public-key cryptography started with the pioneering work of Whitefield Diffie and Martin Hellman, who detailed one of the earliest known key-agreement protocols: the famous [Diffie-Hellman Key-Exchange](https://en.wikipedia.org/wiki/Diffie%E2%80%93Hellman_key_exchange).\\n\\nDiffie-Hellman (DH) key-exchange is largely used today and represents the main cryptographic building block on which Noise handshakes\' security is based.\\n\\nIn turn, the security of DH is based on a mathematical problem called [discrete logarithm](https://en.wikipedia.org/wiki/Discrete_logarithm) which is believed to be hard when the agreement is practically instantiated using certain [elliptic curves](https://en.wikipedia.org/wiki/Elliptic_curve) $E$ defined over finite fields $\\\\mathbb{F}_p$.\\n\\nInformally, a DH exchange between Alice and Bob proceeds as follows:\\n\\n- Alice picks a secret scalar $s_A\\\\in\\\\mathbb{F}_p$ and computes, using the underlying [curve\'s arithmetic](https://en.wikipedia.org/wiki/Elliptic_curve_point_multiplication), the point $P_A = s_A\\\\cdot P\\\\in E(\\\\mathbb{F}_p)$ for a certain pre-agreed public generator $P$ of the elliptic curve $E(\\\\mathbb{F}_p)$. She then sends $P_A$ to Bob.\\n- Similarly, Bob picks a secret scalar $s_B\\\\in\\\\mathbb{F}_p$, computes $P_B = s_B\\\\cdot P\\\\in E(\\\\mathbb{F}_p)$ and sends $P_B$ to Alice.\\n- By commutativity of scalar multiplication, both Alice and Bob can now compute the point $P_{AB} = s_As_B\\\\cdot P$, using the elliptic curve point received from the other party and their secret scalar.\\n\\nThe assumed hardness of computing discrete logarithms in the elliptic curve, ensures that it is not possible to compute $s_A$ or $s_B$ from $P_A$ and $P_B$, respectively. Another security assumption (named [Computational Diffie-Hellman assumption](https://en.wikipedia.org/wiki/Computational_Diffie%E2%80%93Hellman_assumption)) ensures that it is not possible to compute $P_{AB}$ from $P$, $P_A$ and $P_B$. Hence the point $P_{AB}$ shared by Alice and Bob at the end of the above protocol cannot be efficiently computed by an attacker intercepting $P_A$ and $P_B$, and can then be used to generate a secret to be later employed, for example, as a symmetric encryption key.\\n\\nOn a side note, this protocol shows the interplay between two components typical to public-key based schemes: the scalars $s_A$ and $s_B$ can be seen as _private keys_ associated to the _public keys_ $P_A$ and $P_B$, respectively, which allow Alice and Bob only to compute the shared secret point $P_{AB}$.\\n\\n## Ephemeral and Static Public Keys\\n\\nAlthough we assumed that it is practically impossible for an attacker to compute the randomly picked secret scalar from the corresponding public elliptic curve point, it may happen that such scalar gets compromised or can be guessed due to a faulty employed random number generator. In such cases, an attacker will be able to recover the final shared secret and all encryption keys eventually derived from that, with clear catastrophic consequences for the privacy of exchanged messages.\\n\\nTo mitigate such issues, multiple DH operations can be combined using two different types of exchanged elliptic curve points or, better, _public keys_: _ephemeral keys_, that is random keys used only once in a DH operation, and long-term _static keys_, used mainly for authentication purposes since employed multiple times.\\n\\nJust to provide an example, let us suppose Alice and Bob perform the following custom DH-based key-exchange protocol:\\n\\n- Alice generates an ephemeral key $E_A=e_A\\\\cdot P$ by picking a random scalar $e_A$ and sends $E_A$ to Bob;\\n- Similarly, Bob generates an ephemeral key $E_B=e_B\\\\cdot P$ and sends $E_B$ to Alice;\\n- Alice and Bob computes $E_{AB} = e_Ae_B \\\\cdot P$ and from it derive a secret encryption key $k$.\\n- Bob sends to Alice his static key $S_B = s_B\\\\cdot P$ encrypted with $k$.\\n- Alice encrypts with $k$ her static key $S_A = s_A\\\\cdot P$ and sends it to Bob.\\n- Alice and Bob decrypt the received static keys, compute the secret $S_{AB} = s_As_B \\\\cdot P$ and use it together with $E_{AB}$ to derive a new encryption key $\\\\tilde{k}$ to be later used with a symmetric cipher.\\n\\nIn this protocol, if Alice\'s and/or Bob\'s static keys get compromised, it would not possible to derive the final secret key $\\\\tilde{k}$, since at least one ephemeral key among $E_A$ and $E_B$ has to be compromised too in order to recover the secret $E_{AB}$. Furthermore, since Alice\'s and Bob\'s long-term static keys are encrypted, an attacker intercepting exchanged (encrypted) public keys will not be able to link such communication to Alice or Bob, unless one of the ephemeral key is compromised (and, even in such case, none of the messages encrypted under the key $\\\\tilde{k}$ can be decrypted).\\n\\n## The Noise Protocol Framework\\n\\nIn previous section we gave a small intuition on how multiple DH operations over ephemeral and static users\' public keys can be combined to create different key-exchange protocols.\\n\\nThe [Noise Protocol Framework](http://www.noiseprotocol.org/noise.html), defines various rules for building custom key-exchange protocols while allowing easy analysis of the security properties and threat models provided given the type and order of the DH operations employed.\\n\\nIn Noise terminology, a key-agreement or _Noise protocol_ consists of one or more _Noise handshakes_. During a Noise handshake, Alice and Bob exchange multiple (handshake) messages containing their ephemeral keys and/or static keys. These public keys are then used to perform a handshake-dependent sequence of Diffie-Hellman operations, whose results are all hashed into a shared secret key. Similarly as we have seen above, after a handshake is complete, each party will use the derived secret key to send and receive [authenticated encrypted data](https://en.wikipedia.org/wiki/Authenticated_encryption) by employing a symmetric cipher.\\n\\nDepending on the _handshake pattern_ adopted, different security guarantees can be provided on messages encrypted using a handshake-derived key.\\n\\nThe Noise handshakes we support in Waku all provide the following security properties:\\n\\n- **Confidentiality**: the adversary should not be able to learn what data is being sent between Alice and Bob.\\n- **Strong forward secrecy**: an active adversary cannot decrypt messages nor infer any information on the employed encryption key, even in the case he has access to Alice\'s and Bob\'s long-term private keys (during or after their communication).\\n- **Authenticity**: the adversary should not be able to cause either Alice or Bob to accept messages coming from a party different than their original senders.\\n- **Integrity**: the adversary should not be able to cause Alice or Bob to accept data that has been tampered with.\\n- **Identity-hiding**: once a secure communication channel is established, a passive adversary should not be able to link exchanged encrypted messages to their corresponding sender and recipient by knowing their long-term static keys.\\n\\nWe refer to [Noise specification](http://www.noiseprotocol.org/noise.html) for more formal security definitions and precise threat models relative to Waku [supported Noise Handshake patterns](#Supported-Noise-Handshakes-in-Waku).\\n\\n## Message patterns\\n\\nNoise handshakes involving DH operations over ephemeral and static keys can be succinctly sketched using the following set of _handshake message tokens_: `e`,`s`,`ee`,`se`,`es`,`ss`.\\n\\nTokens employing single letters denote (the type of) users\' public keys: `e` refers to randomly generated ephemeral key(s), while `s` indicates the users\' long-term static key(s).\\n\\nTwo letters tokens, instead, denotes DH operations over the two users\' public keys the token refers to, given that the left token letter refers to the handshake _initiator\'s_ public key, while the right token letter indicates the used _responder\'s_ public key. Thus, if Alice started a handshake with Bob, the `es` token will shortly represent a DH operation among Alice\'s ephemeral key `e` and Bob\'s static key `s`.\\n\\nSince, in order to perform any DH operations users need to share (or pre-share) the corresponding public keys, Noise compactly represents messages\' exchanges using the two direction `->` and `<-`, where the `->` denotes a message (arbitrary and/or DH public key) from the initiator to the responder, while `<-` the opposite.\\n\\nHence a _message pattern_ consisting of a direction and one or multiple tokens such as `<- e, s, es` has to be interpreted one token at a time: in this example, the responder is sending his ephemeral and static key to the initiator and is then executing a DH operation over the initiator\'s ephemeral key `e` (shared in a previously exchanged message pattern) and his static key `s`. On the other hand, such message indicates also that the initiator received the responder\'s ephemeral and static keys `e` and `s`, respectively, and performed a DH operation over his ephemeral key and the responder\'s just received static key `s`. In this way, both parties will be able to derive at the end of each message pattern processed the same shared secret, which is eventually used to update any derived symmetric encryption keys computed so far.\\n\\nIn some cases, DH public keys employed in a handshake are pre-shared before the handshake itself starts. In order to chronologically separate exchanged keys and DH operations performed before and during a handshake, Noise employs the `...` delimiter.\\n\\nFor example, the following message patterns\\n\\n```\\n<- e\\n...\\n-> e, ee\\n```\\n\\nindicates that the initiator knew the responder\'s ephemeral key before he sends his own ephemeral key and executes a DH operation between both parties ephemeral keys (similarly, the responder receives the initiator\'s ephemeral key and does a `ee` DH operation).\\n\\nAt this point it should be clear how such notation is able to compactly represent a large variety of DH based key-agreements. Nevertheless, we can easily define additional tokens and processing rules in order to address specific applications and security requirements, such as the [`psk`](http://www.noiseprotocol.org/noise.html#handshake-tokens) token used to process arbitrary pre-shared key material.\\n\\nAs an example of Noise flexibility, the custom protocol we detailed [above](#Ephemeral-and-Static-Public-Keys) can be shortly represented as _(Alice is on the left)_:\\n\\n```\\n-> e\\n<- e, ee, s\\n-> s, ss\\n```\\n\\nwhere after each DH operation an encryption key is derived (along with the secrets computed by all previously executed DH operations) in order to encrypt/decrypt any subsequent sent/received message.\\n\\nAnother example is given by the possibility to replicate within Noise the well established Signal\'s [X3DH](https://signal.org/docs/specifications/x3dh/) key-agreement protocols, thus making the latter a general framework to design and study security of many practical and widespread DH-based key-exchange protocols.\\n\\n## The Noise State Objects\\n\\nWe mentioned multiple times that parties derive an encryption key each time they perform a DH operation, but how does this work in more details?\\n\\nNoise defines three _state object_: a _Handshake State_, a _Symmetric State_ and a _Cipher State_, each encapsulated into each other and instantiated during the execution of a handshake.\\n\\nThe Handshake State object stores the user\'s and other party\'s received ephemeral and static keys (if any) and embeds a Symmetric State object.\\n\\nThe Symmetric State, instead, stores a handshake hash value `h`, iteratively updated with any message read/received and DH secret computed, and a chaining key `ck`, updated using a key derivation function every time a DH secret is computed. This object further embeds a Cipher State.\\n\\nLastly, the Cipher State stores a symmetric encryption `k` key and a counter `n` used to encrypt and decrypt messages exchanged during the handshake (not only static keys, but also arbitrary payloads). These key and counter are refreshed every time the chaining key is updated.\\n\\nWhile processing each handshake\'s message pattern token, all these objects are updated according to some specific _processing rules_ which employ a combination of public-key primitives, hash and key-derivation functions and symmetric ciphers. It is important to note, however, that at the end of each processed message pattern, the two users will share the same Symmetric and Cipher State embedded in their respective Handshake States.\\n\\nOnce a handshake is complete, users derive two new Cipher States and can then discard the Handshake State object (and, thus, the embedded Symmetric State and Cipher State objects)\\nemployed during the handshake.\\n\\nThese two Cipher states are used to encrypt and decrypt all outbound and inbound after-handshake messages, respectively, and only to these will be granted the confidentiality, authenticity, integrity and identity-hiding properties we detailed above.\\n\\nFor more details on processing rules, we refer to [Noise specifications](http://www.noiseprotocol.org/noise.html).\\n\\n## Supported Noise Handshakes in Waku\\n\\nThe Noise handshakes we provided support to in Waku address four typical scenarios occurring when an encrypted communication channel between Alice and Bob is going to be created:\\n\\n- Alice and Bob know each others\' static key.\\n- Alice knows Bob\'s static key;\\n- Alice and Bob share no key material and they don\'t know each others\' static key.\\n- Alice and Bob share some key material, but they don\'t know each others\' static key.\\n\\nThe possibility to have handshakes based on the reciprocal knowledge parties have of each other, allows designing Noise handshakes that can quickly reach the desired level of security on exchanged encrypted messages while keeping the number of interactions between Alice and Bob minimum.\\n\\nNonetheless, due to the pure _token-based_ nature of handshake processing rules, implementations can easily add support to any custom handshake pattern with minor modifications, in case more specific application use-cases need to be addressed.\\n\\nOn a side note, we already mentioned that identity-hiding properties can be guaranteed against a passive attacker that only reads the communication occurring between Alice and Bob. However, an active attacker who compromised one party\'s static key and actively interferes with the parties\' exchanged messages, may lower the identity-hiding security guarantees provided by some handshake patterns. In our security model we exclude such adversary, but, for completeness, in the following we report a summary of possible de-anonymization attacks that can be performed by such an active attacker.\\n\\nFor more details on supported handshakes and on how these are implemented in Waku, we refer to [35/WAKU2-NOISE](https://rfc.vac.dev/spec/35/) RFC.\\n\\n### The K1K1 Handshake\\n\\nIf Alice and Bob know each others\' static key (e.g., these are public or were already exchanged in a previous handshake) , they MAY execute a `K1K1` handshake. In Noise notation _(Alice is on the left)_ this can be sketched as:\\n\\n```\\n K1K1:\\n -> s\\n <- s\\n ...\\n -> e\\n <- e, ee, es\\n -> se\\n```\\n\\nWe note that here only ephemeral keys are exchanged. This handshake is useful in case Alice needs to instantiate a new separate encrypted communication channel with Bob, e.g. opening multiple parallel connections, file transfers, etc.\\n\\n**Security considerations on identity-hiding (active attacker)**: no static key is transmitted, but an active attacker impersonating Alice can check candidates for Bob\'s static key.\\n\\n### The XK1 Handshake\\n\\nHere, Alice knows how to initiate a communication with Bob and she knows his public static key: such discovery can be achieved, for example, through a publicly accessible register of users\' static keys, smart contracts, or through a previous public/private advertisement of Bob\'s static key.\\n\\nA Noise handshake pattern that suits this scenario is `XK1`:\\n\\n```\\n XK1:\\n <- s\\n ...\\n -> e\\n <- e, ee, es\\n -> s, se\\n```\\n\\nWithin this handshake, Alice and Bob reciprocally authenticate their static keys `s` using ephemeral keys `e`. We note that while Bob\'s static key is assumed to be known to Alice (and hence is not transmitted), Alice\'s static key is sent to Bob encrypted with a key derived from both parties ephemeral keys and Bob\'s static key.\\n\\n**Security considerations on identity-hiding (active attacker)**: Alice\'s static key is encrypted with forward secrecy to an authenticated party. An active attacker initiating the handshake can check candidates for Bob\'s static key against recorded/accepted exchanged handshake messages.\\n\\n### The XX and XXpsk0 Handshakes\\n\\nIf Alice is not aware of any static key belonging to Bob (and neither Bob knows anything about Alice), she can execute an `XX` handshake, where each party tran**X**mits to the other its own static key.\\n\\nThe handshake goes as follows:\\n\\n```\\n XX:\\n -> e\\n <- e, ee, s, es\\n -> s, se\\n```\\n\\nWe note that the main difference with `XK1` is that in second step Bob sends to Alice his own static key encrypted with a key obtained from an ephemeral-ephemeral Diffie-Hellman exchange.\\n\\nThis handshake can be slightly changed in case both Alice and Bob pre-shares some secret `psk` which can be used to strengthen their mutual authentication during the handshake execution. One of the resulting protocol, called `XXpsk0`, goes as follow:\\n\\n```\\n XXpsk0:\\n -> psk, e\\n <- e, ee, s, es\\n -> s, se\\n```\\n\\nThe main difference with `XX` is that Alice\'s and Bob\'s static keys, when transmitted, would be encrypted with a key derived from `psk` as well.\\n\\n**Security considerations on identity-hiding (active attacker)**: Alice\'s static key is encrypted with forward secrecy to an authenticated party for both `XX` and `XXpsk0` handshakes. In `XX`, Bob\'s static key is encrypted with forward secrecy but is transmitted to a non-authenticated user which can then be an active attacker. In `XXpsk0`, instead, Bob\'s secret key is protected by forward secrecy to a partially authenticated party (through the pre-shared secret `psk` but not through any static key), provided that `psk` was not previously compromised (in such case identity-hiding properties provided by the `XX` handshake applies).\\n\\n## Session Management and Multi-Device Support\\n\\nWhen two users complete a Noise handshake, an encryption/decryption session - or _Noise session_ - consisting of two Cipher States is instantiated.\\n\\nBy identifying Noise session with a `session-id` derived from the handshake\'s cryptographic material, we can take advantage of the [PubSub/GossipSub](https://github.com/libp2p/specs/tree/master/pubsub) protocols used by Waku for relaying messages in order to manage instantiated Noise sessions.\\n\\nThe core idea is to exchange after-handshake messages (encrypted with a Cipher State specific to the Noise session), over a content topic derived from the (secret) `session-id` the corresponding session refers to.\\n\\nThis allows to decouple the handshaking phase from the actual encrypted communication, thus improving users\' identity-hiding capabilities.\\n\\nFurthermore, by publicly revealing a value derived from `session-id` on the corresponding session content topic, a Noise session can be marked as _stale_, enabling peers to save resources by discarding any eventually [stored](https://rfc.vac.dev/spec/13/) message sent to such content topic.\\n\\nOne relevant aspect in today\'s applications is the possibility for users to employ different devices in their communications. In some cases, this is non-trivial to achieve since, for example, encrypted messages might be required to be synced on different devices which do not necessarily share the necessary key material for decryption and may be temporarily offline.\\n\\nWe address this by requiring each user\'s device to instantiate multiple Noise sessions either with all user\'s other devices which, in turn, all together share a Noise session with the other party, or by directly instantiating a Noise session with all other party\'s devices.\\n\\nWe named these two approaches $N11M$ and $NM$, respectively, which are in turn loosely based on the paper [\u201cMulti-Device for Signal\u201d](https://eprint.iacr.org/2019/1363.pdf) and [Signal\u2019s Sesame Algorithm](https://signal.org/docs/specifications/sesame/).\\n\\n![](//img/noise/N11M.png)\\n\\nInformally, in the $N11M$ session management scheme, once the first Noise session between any of Alice\u2019s and Bob\u2019s device is instantiated, its session information is securely propagated to all other devices using previously instantiated Noise sessions. Hence, all devices are able to send and receive new messages on the content topic associated to such session.\\n\\n![](//img/noise/NM.png)\\n\\nIn the $NM$ session management scheme, instead, all pairs of Alice\'s and Bob\'s devices have a distinct Noise session: a message is then sent from the currently-in-use sender\u2019s device to all recipient\u2019s devices, by properly encrypting and sending it to the content topics of each corresponding Noise session. If sent messages should be available on all sender\u2019s devices as well, we require each pair of sender\u2019s devices to instantiate a Noise session used for syncing purposes.\\n\\nFor more technical details on how Noise sessions are instantiated and managed within these two mechanisms and the different trade-offs provided by the latter, we refer to [37/WAKU2-NOISE-SESSIONS](https://rfc.vac.dev/spec/37/).\\n\\n## Conclusions\\n\\nIn this post we provided an overview of Noise, a protocol framework for designing Diffie-Hellman based key-exchange mechanisms allowing systematic security and threat model analysis.\\n\\nThe flexibility provided by Noise components allows not only to fully replicate with same security guarantees well established key-exchange primitives such as X3DH, currently employed by Status [5/TRANSPORT-SECURITY](https://specs.status.im/spec/5), but enables also optimizations based on the reciprocal knowledge parties have of each other while allowing easier protocols\' security analysis and (formal) verification.\\n\\nFurthermore, different handshakes can be combined and executed one after each other, a particularly useful feature to authenticate multiple static keys employed by different applications but also to ease keys revocation.\\n\\nThe possibility to manage Noise sessions over multiple devices and the fact that handshakes can be concretely instantiated using modern, fast and secure cryptographic primitives such as [ChaChaPoly](https://datatracker.ietf.org/doc/html/rfc7539) and [BLAKE2b](https://datatracker.ietf.org/doc/html/rfc7693), make Noise one of the best candidates for efficiently and securely address the many different needs of applications built on top of Waku requiring key-agreement.\\n\\n## Future steps\\n\\nThe available [implementation](https://github.com/status-im/nwaku/tree/master/waku/v2/waku_noise) of Noise in `nwaku`, although mostly complete, is still in its testing phase. As future steps we would like to:\\n\\n- have an extensively tested and robust Noise implementation;\\n- formalize, implement and test performances of the two proposed $N11M$ and $NM$ session management mechanisms and their suitability for common use-case scenarios;\\n- provide Waku network nodes a native protocol to readily support key-exchanges, strongly-encrypted communication and multi-device session management mechanisms with none-to-little interaction besides applications\' connection requests.\\n\\n## References\\n\\n- [6/WAKU1](https://rfc.vac.dev/spec/6/)\\n- [10/WAKU2](https://rfc.vac.dev/spec/10/)\\n- [13/WAKU2-STORE](https://rfc.vac.dev/spec/13/)\\n- [26/WAKU-PAYLOAD](https://rfc.vac.dev/spec/26/)\\n- [35/WAKU2-NOISE](https://rfc.vac.dev/spec/35/)\\n- [37/WAKU2-NOISE-SESSIONS](https://rfc.vac.dev/spec/37/)\\n- [5/TRANSPORT-SECURITY](https://specs.status.im/spec/5)\\n- [The PubSub/GossipSub Protocols](https://github.com/libp2p/specs/tree/master/pubsub)\\n- [The Noise Protocol Framework](http://www.noiseprotocol.org/noise.html)\\n- [The X3DH Key-agreement Protocol](https://signal.org/docs/specifications/x3dh/)\\n- [\u201cMulti-Device for Signal\u201d](https://eprint.iacr.org/2019/1363.pdf)\\n- [Signal\u2019s Sesame Algorithm](https://signal.org/docs/specifications/sesame/).\\n- [Public-key cryptography](https://en.wikipedia.org/wiki/Public-key_cryptography)\\n- [Elliptic curves](https://en.wikipedia.org/wiki/Elliptic_curve)\\n- [Elliptic Curve point multiplication](https://en.wikipedia.org/wiki/Elliptic_curve_point_multiplication)\\n- [Symmetric key algorithm](https://en.wikipedia.org/wiki/Symmetric-key_algorithm)\\n- [Authenticated encryption](https://en.wikipedia.org/wiki/Authenticated_encryption)\\n- [Diffie-Hellman Key-Exchange](https://en.wikipedia.org/wiki/Diffie%E2%80%93Hellman_key_exchange)\\n- [The Discrete Logarithm Problem](https://en.wikipedia.org/wiki/Discrete_logarithm)\\n- [Computational Diffie-Hellman Assumption](https://en.wikipedia.org/wiki/Computational_Diffie%E2%80%93Hellman_assumption)\\n- [The ECIES Encryption Algorithm](https://en.wikipedia.org/wiki/Integrated_Encryption_Scheme)\\n- [The ECDSA Signature Algorithm](https://en.wikipedia.org/wiki/Elliptic_Curve_Digital_Signature_Algorithm)\\n- [The Galois Counter Mode mode of operation](https://en.wikipedia.org/wiki/Galois/Counter_Mode)\\n- [The ChaChaPoly AEAD Cipher](https://datatracker.ietf.org/doc/html/rfc7539)\\n- [The BLAKE2b Hash Function](https://datatracker.ietf.org/doc/html/rfc7693)\\n- [The SHA-3 Hash Function](https://en.wikipedia.org/wiki/SHA-3)"},{"id":"wakuv2-apd","metadata":{"permalink":"/rlog/wakuv2-apd","source":"@site/rlog/2022-05-09-ambient-peer-discovery.mdx","title":"Waku v2 Ambient Peer Discovery","description":"Introducing and discussing ambient peer discovery methods currently used by Waku v2, as well as future plans in this area.","date":"2022-05-09T10:00:00.000Z","formattedDate":"May 9, 2022","tags":[],"readingTime":17.67,"hasTruncateMarker":true,"authors":[{"name":"Daniel","github":"kaiserd","key":"kaiserd"}],"frontMatter":{"layout":"post","name":"Waku v2 Ambient Peer Discovery","title":"Waku v2 Ambient Peer Discovery","date":"2022-05-09T10:00:00.000Z","authors":"kaiserd","published":true,"slug":"wakuv2-apd","categories":"research","image":"/img/waku_v2_discv5_random_walk_estimation.svg","discuss":"https://forum.vac.dev/t/discussion-waku-v2-ambient-peer-discovery/133","_includes":["math"]},"prevItem":{"title":"Noise handshakes as key-exchange mechanism for Waku","permalink":"/rlog/wakuv2-noise"},"nextItem":{"title":"Introducing nwaku","permalink":"/rlog/introducing-nwaku"}},"content":"Introducing and discussing ambient peer discovery methods currently used by Waku v2, as well as future plans in this area.\\n\\n\x3c!--truncate--\x3e\\n\\n[Waku v2](https://rfc.vac.dev/spec/10/) comprises a set of modular protocols for secure, privacy preserving communication.\\nAvoiding centralization, these protocols exchange messages over a P2P network layer.\\nIn order to build a P2P network, participating nodes first have to discover peers within this network.\\nThis is where [_ambient peer discovery_](https://docs.libp2p.io/concepts/publish-subscribe/#discovery) comes into play:\\nit allows nodes to find peers, making it an integral part of any decentralized application.\\n\\nIn this post the term _node_ to refers to _our_ endpoint or the endpoint that takes action,\\nwhile the term _peer_ refers to other endpoints in the P2P network.\\nThese endpoints can be any device connected to the Internet: e.g. servers, PCs, notebooks, mobile devices, or applications like a browser.\\nAs such, nodes and peers are the same. We use these terms for the ease of explanation without loss of generality.\\n\\nIn Waku\'s modular design, ambient peer discovery is an umbrella term for mechanisms that allow nodes to find peers.\\nVarious ambient peer discovery mechanisms are supported, and each is specified as a separate protocol.\\nWhere do these protocols fit into Waku\'s protocol stack?\\nThe P2P layer of Waku v2 builds on [libp2p gossipsub](https://github.com/libp2p/specs/blob/10712c55ab309086a52eec7d25f294df4fa96528/pubsub/gossipsub/README.md).\\nNodes participating in a gossipsub protocol manage a mesh network that is used for routing messages.\\nThis mesh network is an [unstructured P2P network](https://en.wikipedia.org/wiki/Peer-to-peer#Unstructured_networks)\\noffering high robustness and resilience against attacks.\\nGossipsub implements many improvements overcoming the shortcomings typically associated with unstructured P2P networks, e.g. inefficient flooding based routing.\\nThe gossipsub mesh network is managed in a decentralized way, which requires each node to know other participating peers.\\nWaku v2 may use any combination of its ambient discovery protocols to find appropriate peers.\\n\\nSummarizing, Waku v2 comprises a _peer management layer_ based on libp2p gossipsub,\\nwhich manages the peers of nodes, and an _ambient peer discovery layer_,\\nwhich provides information about peers to the peer management layer.\\n\\nWe focus on ambient peer discovery methods that are in line with our goal of building a fully decentralized, generalized, privacy-preserving and censorship-resistant messaging protocol.\\nSome of these protocols still need adjustments to adhere to our privacy and anonymity requirements. For now, we focus on operational stability and feasibility.\\nHowever, when choosing techniques, we pay attention to selecting mechanisms that can feasibly be tweaked for privacy in future research efforts.\\nBecause of the modular design and the fact that Waku v2 has several discovery methods at its disposal, we could even remove a protocol in case future evaluation deems it not fitting our standards.\\n\\nThis post covers the current state and future considerations of ambient peer discovery for Waku v2,\\nand gives reason for changes and modifications we made or plan to make.\\nThe ambient peer discovery protocols currently supported by Waku v2 are a modified version of Ethereum\'s [Discovery v5](https://github.com/ethereum/devp2p/blob/6b0abc3d956a626c28dce1307ee9f546db17b6bd/discv5/discv5.md)\\nand [DNS-based discovery](https://vac.dev/dns-based-discovery).\\nWaku v2 further supports [gossipsub\'s peer exchange protocol](https://github.com/libp2p/specs/blob/10712c55ab309086a52eec7d25f294df4fa96528/pubsub/gossipsub/gossipsub-v1.1.md#prune-backoff-and-peer-exchange).\\nIn addition, we plan to introduce protocols for general peer exchange and capability discovery, respectively.\\nThe former allows resource restricted nodes to outsource querying for peers to stronger peers,\\nthe latter allows querying peers for their supported capabilities.\\nBesides these new protocols, we are working on integrating capability discovery in our existing ambient peer discovery protocols.\\n\\n## Static Node Lists\\n\\nThe simplest method of learning about peers in a P2P network is via static node lists.\\nThese can be given to nodes as start-up parameters or listed in a config-file.\\nThey can also be provided in a script-parseable format, e.g. in JSON.\\nWhile this method of providing bootstrap nodes is very easy to implement, it requires static peers, which introduce centralized elements.\\nAlso, updating static peer information introduces significant administrative overhead:\\ncode and/or config files have to be updated and released.\\nTypically, static node lists only hold a small number of bootstrap nodes, which may lead to high load on these nodes.\\n\\n## DNS-based Discovery\\n\\nCompared to static node lists,\\n[DNS-based discovery](https://vac.dev/dns-based-discovery) (specified in [EIP-1459](https://eips.ethereum.org/EIPS/eip-1459))\\nprovides a more dynamic way of discovering bootstrap nodes.\\nIt is very efficient, can easily be handled by resource restricted devices and provides very good availability.\\nIn addition to a naive DNS approach, Ethereum\'s DNS-based discovery introduces efficient authentication leveraging [Merkle trees](https://en.wikipedia.org/wiki/Merkle_tree).\\n\\nA further advantage over static node lists is the separation of code/release management and bootstrap node management.\\nHowever, changing and updating the list of bootstrap nodes still requires administrative privileges because DNS records have to be added or updated.\\n\\nWhile this method of discovery still requires centralized elements,\\nnode list management can be delegated to various DNS zones managed by other entities mitigating centralization.\\n\\n## Discovery V5\\n\\nA much more dynamic method of ambient peer discovery is [Discovery v5](https://github.com/ethereum/devp2p/blob/6b0abc3d956a626c28dce1307ee9f546db17b6bd/discv5/discv5.md), which is Ethereum\'s peer discovery protocol.\\nIt is based on the [Kademlia](https://en.wikipedia.org/wiki/Kademlia) distributed hashtable (DHT).\\nAn [introduction to discv5 and its history](https://vac.dev/kademlia-to-discv5), and a [discv5 Waku v2 feasibility study](https://vac.dev/feasibility-discv5)\\ncan be found in previous posts on this research log.\\n\\nWe use Discovery v5 as an ambient peer discovery method for Waku v2 because it is decentralized, efficient, actively researched, and has web3 as its main application area.\\nDiscv5 also offers mitigation techniques for various attacks, which we cover later in this post.\\n\\nUsing a DHT (structured P2P network) as a means for ambient peer discovery, while using the gossipsub mesh network (unstructured P2P network) for transmitting actual messages,\\nWaku v2 leverages advantages from both worlds.\\nOne of the main benefits of DHTs is offering a global view over participating nodes.\\nThis, in turn, allows sampling random sets of nodes which is important for equally distributing load.\\nGossipsub, on the other hand, offers great robustness and resilience against attacks.\\nEven if discv5 discovery should not work in advent of a DoS attack, Waku v2 can still operate switching to different discovery methods.\\n\\nDiscovery methods that use separate P2P networks still depend on bootstrapping,\\nwhich Waku v2 does via parameters on start-up or via DNS-based discovery.\\nThis might raise the question of why such discovery methods are beneficial.\\nThe answer lies in the aforementioned global view of DHTs. Without discv5 and similar methods, the bootstrap nodes are used as part of the gossipsub mesh.\\nThis might put heavy load on these nodes and further, might open pathways to inference attacks.\\nDiscv5, on the other hand, uses the bootstrap nodes merely as an entry to the discovery network and can provide random sets of nodes (sampled from a global view)\\nfor bootstrapping or expanding the mesh.\\n\\n### DHT Background\\n\\nDistributed Hash Tables are a class of structured P2P overlay networks.\\nA DHT can be seen as a distributed node set of which each node is responsible for a part of the hash space.\\nIn contrast to unstructured P2P networks, e.g. the mesh network maintained by gossipsub,\\nDHTs have a global view over the node set and the hash space (assuming the participating nodes behave well).\\n\\nDHTs are susceptible to various kinds of attacks, especially [Sybil attacks](https://en.wikipedia.org/wiki/Sybil_attack)\\nand [eclipse attacks](https://www.usenix.org/conference/usenixsecurity15/technical-sessions/presentation/heilman).\\nWhile security aspects have been addressed in various research papers, general practical solutions are not available.\\nHowever, discv5 introduced various practical mitigation techniques.\\n\\n### Random Walk Discovery\\n\\nWhile discv5 is based on the Kademlia DHT, it only uses the _distributed node set_ aspect of DHTs.\\nIt does not map values (items) into the distributed hash space.\\nThis makes sense, because the main purpose of discv5 is discovering other nodes that support discv5, which are expected to be Ethereum nodes.\\nEthereum nodes that want to discover other Ethereum nodes simply query the discv5 network for a random set of peers.\\nIf Waku v2 would do the same, only a small subset of the retrieved nodes would support Waku v2.\\n\\nA first naive solution for Waku v2 discv5 discovery is\\n\\n- retrieve a random node set, which is achieved by querying for a set of randomly chosen node IDs\\n- filter the returned nodes on the query path based on Waku v2 capability via the [Waku v2 ENR](https://rfc.vac.dev/spec/31/)\\n- repeat until enough Waku v2 capable nodes are found\\n\\nThis query process boils down to random walk discovery, which is very resilient against attacks, but also very inefficient if the number of nodes supporting the desired capability is small.\\nWe refer to this as the needle-in-the-haystack problem.\\n\\n### Random Walk Performance Estimation\\n\\nThis subsection provides a rough estimation of the overhead introduced by random walk discovery.\\n\\nGiven the following parameters:\\n\\n- $n$ number of total nodes participating in discv5\\n- $p$ percentage of nodes supporting Waku\\n- $W$ the event of having at least one Waku node in a random sample\\n- $k$ the size of a random sample (default = 16)\\n- $\\\\alpha$ the number of parallel queries started\\n- $b$ bits per hop\\n- $q$ the number of queries\\n\\nA query takes $log_{2^b}n$ hops to retrieve a random sample of nodes.\\n\\n$P(W) = 1 - (1-p/100)^k$ is the probability of having at least one Waku node in the sample.\\n\\n$P(W^q) = 1 - (1-p/100)^{kq}$ is the probability of having at least one Waku node in the union of $q$ samples.\\n\\nExpressing this in terms of $q$, we can write:\\n$$P(W^q) = 1 - (1-p/100)^{kq} \\\\iff q = log_{(1-p/100)^k}(1-P(W^q))$$\\n\\nFigure 1 shows a log-log plot for $P(W^q) = 90\\\\%$.\\n\\n![Figure 1: log-log plot showing the number of queries necessary to retrieve a Waku v2 node with a probability of 90% in relation to the Waku v2 node concentration in the network.](/img/waku_v2_discv5_random_walk_estimation.svg)\\n\\nAssuming $p=0.1$, we would need\\n\\n$$0.9 = 1 - (1-0.1/100)^{16q} => q \\\\approx 144$$\\n\\nqueries to get a Waku node with 90% probability, which leads to $\\\\approx 144 * 18 = 2592$ overlay hops.\\nChoosing $b=3$ would reduce the number to $\\\\approx 144 * 6 = 864$.\\nEven when choosing $\\\\alpha = 10$ we would have to wait at least 80 RTTs.\\nThis effort is just for retrieving a single Waku node. Ideally, we want at least 3 Waku nodes for bootstrapping a Waku relay.\\n\\n[The discv5 doc](https://github.com/ethereum/devp2p/blob/6b0abc3d956a626c28dce1307ee9f546db17b6bd/discv5/discv5-theory.md#ad-placement-and-topic-radius) roughly estimates $p=1%$ to be the threshold for acceptably efficient random walk discovery.\\nThis is in line with our estimation:\\n\\n$$0.9 = 1 - (1-1/100)^{16q} => q \\\\approx 14$$\\n\\nThe number of necessary queries is linearly dependent on the percentage $p$ of Waku nodes.\\nThe number of hops per query is logarithmically dependent on $n$.\\nThus, random walk searching is inefficient for small percentages $p$.\\nStill, random walks are more resilient against attacks.\\n\\nWe can conclude that a Waku node concentration below 1% renders vanilla discv5 unfit for our needs.\\nOur current solution and future plans for solving this issue are covered in the next subsections.\\n\\n### Simple Solution: Separate Discovery Network\\n\\nThe simple solution we currently use for [Waku v2 discv5](https://rfc.vac.dev/spec/33/) is a separate discv5 network.\\nAll (well behaving) nodes in this network support Waku v2, resulting in a very high query efficiency.\\nHowever, this solution reduces resilience because the difficulty of attacking a DHT scales with the number of participating nodes.\\n\\n### Discv5 Topic Discovery\\n\\nWe did not base our solution on the [current version of discv5 topic discovery](https://github.com/ethereum/devp2p/blob/master/discv5/discv5-theory.md#topic-advertisement),\\nbecause, similar to random walk discovery, it suffers from poor performance for relatively rare capabilities/topics.\\n\\nHowever, there is [ongoing research](https://github.com/harnen/service-discovery-paper) in discv5 topic discovery which is close to ideas we explored when pondering efficient and resilient Waku discv5 solutions.\\nWe keep a close eye on this research, give feedback, and make suggestions, as we plan to switch to this version of topic discovery in the future.\\n\\nIn a nutshell, topic discovery will manage separate routing tables for each topic.\\nThese topic specific tables are initialized with nodes from the discv5 routing table.\\nWhile the buckets of the discv5 routing table represent distance intervals from the node\'s `node ID`, the topic table buckets represent distance intervals from `topic ID`s.\\n\\nNodes that want to register a topic try to register that topic at one random peer per bucket.\\nThis leads to registering the topic at peers in closer and closer neighbourhoods around the topic ID, which\\nyields a very efficient and resilient compromise between random walk discovery and DHT discovery.\\nPeers in larger neighbourhoods around the topic ID are less efficient to discover, however more resilient against eclipse attacks and vice versa.\\n\\nFurther, this works well with the overload and DoS protection discv5 employs.\\nDiscv5 limits the amount of nodes registered per topic on a single peer. Further, discv5 enforces a waiting time before nodes can register topics at peers.\\nSo, for popular topics, a node might fail to register the topic in a close neighbourhood.\\nHowever, because the topic is popular (has a high occurrence percentage $p$), it can still be efficiently discovered.\\n\\nIn the future, we also plan to integrate Waku v2 capability discovery, which will not only allow asking for nodes that support Waku v2,\\nbut asking for Waku v2 nodes supporting specific Waku v2 protocols like filter or store.\\nFor the store protocol we envision sub-capabilities reflecting message topics and time frames of messages.\\nWe will also investigate related security implications.\\n\\n### Attacks on DHTs\\n\\nIn this post, we only briefly describe common attacks on DHTs.\\nThese attacks are mainly used for denial of service (DoS),\\nbut can also used as parts of more sophisticated attacks, e.g. deanonymization attacks.\\nA future post on this research log will cover security aspects of ambient peer discovery with a focus on privacy and anonymity.\\n\\n_Sybil Attack_\\n\\nThe power of an attacker in a DHT is proportional to the number of controlled nodes.\\nControlling nodes comes at a high resource cost and/or requires controlling a botnet via a preliminary attack.\\n\\nIn a Sybil attack, an attacker generates lots of virtual node identities.\\nThis allows the attacker to control a large portion of the ID space in a DHT at a relatively low cost.\\nSybil attacks are especially powerful when the attacker can freely choose the IDs of generated nodes,\\nbecause this allows positioning at chosen points in the DHT.\\n\\nBecause Sybil attacks amplify the power of many attacks against DHTs,\\nmaking Sybil attacks as difficult as possible is the basis for resilient DHT operation.\\nThe typical abstract mitigation approach is binding node identities to physical network interfaces.\\nTo some extend, this can be achieved by introducing IP address based limits.\\nFurther, generating node IDs can be bound by proof of work (PoW),\\nwhich, however, comes with a set of shortcomings, e.g. relatively high costs on resource restricted devices.\\n[The discv5 doc](https://github.com/ethereum/devp2p/blob/6b0abc3d956a626c28dce1307ee9f546db17b6bd/discv5/discv5-rationale.md#sybil-and-eclipse-attacks)\\ndescribes both Sybil and eclipse attacks, as well as concrete mitigation techniques employed by discv5.\\n\\n_Eclipse Attack_\\n\\nIn an eclipse attack, nodes controlled by the attacker poison the routing tables of other nodes in a way that parts of the DHT become eclipsed, i.e. invisible.\\nWhen a controlled node is asked for the next step in a path,\\nit provides another controlled node as the next step,\\neffectively navigating the querying node around or away from certain areas of the DHT.\\nWhile several mitigation techniques have been researched, there is no definitive protection against eclipse attacks available as of yet.\\nOne mitigation technique is increasing $\\\\alpha$, the number of parallel queries, and following each concurrent path independently for the lookup.\\n\\nThe eclipse attack becomes very powerful in combination with a successful Sybil attack;\\nespecially when the attacker can freely choose the position of the Sybil nodes.\\n\\nThe aforementioned new topic discovery of discv5 provides a good balance between protection against eclipse attacks and query performance.\\n\\n## Peer Exchange Protocol\\n\\nWhile discv5 based ambient peer discovery has many desirable properties, resource restricted nodes and nodes behind restrictive NAT setups cannot run discv5 satisfactory.\\nWith these nodes in mind, we started working on a simple _peer exchange protocol_ based on ideas proposed [here](https://github.com/libp2p/specs/issues/222).\\nThe peer exchange protocol will allow nodes to ask peers for additional peers.\\nSimilar to discv5, the peer exchange protocol will also support capability discovery.\\n\\nThe new peer exchange protocol can be seen as a simple replacement for the [Rendezvous protocol](https://github.com/libp2p/specs/blob/10712c55ab309086a52eec7d25f294df4fa96528/rendezvous/README.md), which Waku v2 does not support.\\nWhile the rendezvous protocol involves nodes registering at rendezvous peers, the peer exchange protocol simply allows nodes to ask any peer for a list of peers (with a certain set of capabilities).\\nRendezvous tends to introduce centralized elements as rendezvous peers have a super-peer role.\\n\\nIn the future, we will investigate resource usage of [Waku v2 discv5](https://rfc.vac.dev/spec/33/) and provide suggestions for minimal resources nodes should have to run discv5 satisfactory.\\n\\n## Further Protocols Related to Discovery\\n\\nWaku v2 comprises further protocols related to ambient peer discovery. We shortly mention them for context, even though they are not strictly ambient peer discovery protocols.\\n\\n### Gossipsub Peer Exchange Protocol\\n\\nGossipsub provides an integrated [peer exchange](https://github.com/libp2p/specs/blob/10712c55ab309086a52eec7d25f294df4fa96528/pubsub/gossipsub/gossipsub-v1.1.md#prune-backoff-and-peer-exchange) mechanism which is also supported by Waku v2.\\nGossipsub peer exchange works in a _push_ manner. Nodes send peer lists to peers they prune from the active mesh.\\nThis pruning is part of the gossipsub peer management, blurring the boundaries of _peer management_ and _ambient peer discovery_.\\n\\nWe will investigate anonymity implications of this protocol and might disable it in favour of more anonymity-preserving protocols.\\nSending a list of peers discloses information about the sending node.\\nWe consider restricting these peer lists to cached peers that are currently not used in the active gossipsub mesh.\\n\\n### Capability Negotiation\\n\\nSome of the ambient peer discovery methods used by Waku2 will support capability discovery.\\nThis allows to narrow down the set of retrieved peers to peers that support specific capabilities.\\nThis is efficient because it avoids establishing connections to nodes that we are not interested in.\\n\\nHowever, the ambient discovery interface does not require capability discovery, which will lead to nodes having peers with unknown capabilities in their peer lists.\\nWe work on a _capability negotiation protocol_ which allows nodes to ask peers\\n\\n- for their complete list of capabilities, and\\n- whether they support a specific capability\\n\\nWe will investigate security implications, especially when sending full capability lists.\\n\\n## NAT traversal\\n\\nFor [NAT traversal](https://docs.libp2p.io/concepts/nat/), Waku v2 currently supports the port mapping protocols [UPnP](https://en.wikipedia.org/wiki/Universal_Plug_and_Play) and [NAT-PMP](https://datatracker.ietf.org/doc/html/rfc6886) / [PCP](https://datatracker.ietf.org/doc/html/rfc6887).\\n\\nIn the future, we plan to add support for parts of [ICE](https://datatracker.ietf.org/doc/html/rfc8445), e.g. [STUN](https://datatracker.ietf.org/doc/html/rfc7350).\\nWe do not plan to support [TURN](https://www.rfc-editor.org/rfc/rfc5928) because TURN relays would introduce a centralized element.\\nA modified decentralized version of TURN featuring incentivization might be an option in the future;\\nstrong peers could offer a relay service similar to TURN.\\n\\nThere are [plans to integrate more NAT traversal into discv5](https://github.com/ethereum/devp2p/issues/199), in which we might participate.\\nSo far, the only traversal technique supported by discv5 is nodes receiving their external IP address in pong messages.\\n\\nWhile NAT traversal is very important, adding more NAT traversal techniques is not a priority at the moment.\\nNodes behind restrictive symmetric NAT setups cannot be discovered, but they can still discover peers in less restrictive setups.\\nWhile we wish to have as many nodes as possible to be discoverable via ambient peer discovery, two nodes behind a restrictive symmetric NAT can still exchange Waku v2 messages if they discovered a shared peer.\\nThis is one of the nice resilience related properties of flooding based routing algorithms.\\n\\nFor mobile nodes, which suffer from changing IP addresses and double NAT setups, we plan using the peer exchange protocol to ask peers for more peers.\\nBesides saving resources on resource restricted devices, this approach works as long as peers are in less restrictive environments.\\n\\n## Conclusion and Future Prospects\\n\\n_Ambient peer discovery_ is an integral part of decentralized applications. It allows nodes to learn about peers in the network.\\nAs of yet, Waku v2 supports DNS-based discovery and a slightly modified version of discv5.\\nWe are working on further protocols, including a peer exchange protocol that allows resource restricted nodes to ask stronger peers for peer lists.\\nFurther, we are working on adding capability discovery to our ambient discovery protocols, allowing nodes to find peers with desired properties.\\n\\nThese protocols can be combined in a modular way and allow Waku v2 nodes to build a strong and resilient mesh network,\\neven if some discovery methods are not available in a given situation.\\n\\nWe will investigate security properties of these discovery mechanisms with a focus on privacy and anonymity in a future post on this research log.\\nAs an outlook we can already state that DHT approaches typically allow inferring information about the querying node.\\nFurther, sending peer lists allows inferring the position of a node within the mesh, and by extension information about the node.\\nWaku v2 already provides some mitigation, because the mesh for transmitting actual messages, and the peer discovery network are separate.\\nTo mitigate information leakage by transmitting peer lists, we plan to only reply with lists of peers that nodes do not use in their active meshes.\\n\\n---\\n\\n## References\\n\\n- [Waku v2](https://rfc.vac.dev/spec/10/)\\n- [libp2p gossipsub](https://github.com/libp2p/specs/blob/10712c55ab309086a52eec7d25f294df4fa96528/pubsub/gossipsub/README.md)\\n- [unstructured P2P network](https://en.wikipedia.org/wiki/Peer-to-peer#Unstructured_networks)\\n- [ambient peer discovery](https://docs.libp2p.io/concepts/publish-subscribe/#discovery)\\n- [Discovery v5](https://github.com/ethereum/devp2p/blob/6b0abc3d956a626c28dce1307ee9f546db17b6bd/discv5/discv5.md)\\n- [Kademlia](https://en.wikipedia.org/wiki/Kademlia)\\n- [Discv5 history](https://vac.dev/kademlia-to-discv5)\\n- [Discv5 Waku v2 feasibility study](https://vac.dev/feasibility-discv5)\\n- [DNS-based discovery](https://vac.dev/dns-based-discovery)\\n- [EIP-1459](https://eips.ethereum.org/EIPS/eip-1459)\\n- [Merkle trees](https://en.wikipedia.org/wiki/Merkle_tree)\\n- [Sybil attack](https://en.wikipedia.org/wiki/Sybil_attack)\\n- [eclipse attack](https://www.usenix.org/conference/usenixsecurity15/technical-sessions/presentation/heilman)\\n- [Waku v2 ENR](https://rfc.vac.dev/spec/31/)\\n- [Discv5 topic discovery](https://github.com/ethereum/devp2p/blob/6b0abc3d956a626c28dce1307ee9f546db17b6bd/discv5/discv5-theory.md#ad-placement-and-topic-radius)\\n- [Discv5 paper](https://github.com/harnen/service-discovery-paper)\\n- [Discv5 vs Sybil and eclipse attacks](https://github.com/ethereum/devp2p/blob/6b0abc3d956a626c28dce1307ee9f546db17b6bd/discv5/discv5-rationale.md#sybil-and-eclipse-attacks)\\n- [peer exchange idea](https://github.com/libp2p/specs/issues/222)\\n- [Rendezvous protocol](https://github.com/libp2p/specs/blob/10712c55ab309086a52eec7d25f294df4fa96528/rendezvous/README.md)\\n- [Waku v2 discv5](https://rfc.vac.dev/spec/33/)\\n- [Gossipsub peer exchange](https://github.com/libp2p/specs/blob/10712c55ab309086a52eec7d25f294df4fa96528/pubsub/gossipsub/gossipsub-v1.1.md#prune-backoff-and-peer-exchange)\\n- [NAT traversal](https://docs.libp2p.io/concepts/nat/)\\n- [UPnP](https://en.wikipedia.org/wiki/Universal_Plug_and_Play)\\n- [NAT-PMP](https://datatracker.ietf.org/doc/html/rfc6886)\\n- [PCP](https://datatracker.ietf.org/doc/html/rfc6887).\\n- [Discv5 topic efficiency issue](https://github.com/ethereum/devp2p/issues/199)"},{"id":"introducing-nwaku","metadata":{"permalink":"/rlog/introducing-nwaku","source":"@site/rlog/2022-04-12-introducing-nwaku.mdx","title":"Introducing nwaku","description":"Introducing nwaku, a Nim-based Waku v2 client, including a summary of recent developments and preview of current and future focus areas.","date":"2022-04-12T10:00:00.000Z","formattedDate":"April 12, 2022","tags":[],"readingTime":10.765,"hasTruncateMarker":true,"authors":[{"name":"Hanno Cornelius","twitter":"4aelius","github":"jm-clius","key":"hanno"}],"frontMatter":{"layout":"post","name":"Introducing nwaku","title":"Introducing nwaku","date":"2022-04-12T10:00:00.000Z","authors":"hanno","published":true,"slug":"introducing-nwaku","categories":"research","discuss":"https://forum.vac.dev/","toc_min_heading_level":2,"toc_max_heading_level":5},"prevItem":{"title":"Waku v2 Ambient Peer Discovery","permalink":"/rlog/wakuv2-apd"},"nextItem":{"title":"Opinion: Pseudo-ethics in the Surveillance Tech Industry","permalink":"/rlog/ethics-surveillance-tech"}},"content":"Introducing nwaku, a Nim-based Waku v2 client, including a summary of recent developments and preview of current and future focus areas.\\n\\n\x3c!--truncate--\x3e\\n\\n## Background\\n\\nIf you\'ve been following our [research log](https://vac.dev/research-log/),\\nyou\'ll know that many things have happened in the world of Waku v2 since [our last general update](/waku-v2-ethereum-coscup).\\nIn line with our [long term goals](https://vac.dev/#about),\\nwe\'ve introduced new protocols,\\ntweaked our existing protocols\\nand expanded our team.\\nWe\'ve also shown [in a series of practical experiments](/waku-v1-v2-bandwidth-comparison) that Waku v2 does indeed deliver on some of the [theoretical advantages](/waku-v2-plan) it was designed to have over its predecessor, Waku v1.\\nA [sustainability and business workshop](https://forum.vac.dev/t/vac-sustainability-and-business-workshop/116) led to the formulation of a clearer vision for Vac as a team.\\n\\nFrom the beginning, our protocol development has been complemented by various client implementations of these protocols,\\nfirst in [Nim](https://github.com/status-im/nim-waku),\\nbut later also in [JavaScript](https://github.com/status-im/js-waku)\\nand [Go](https://github.com/status-im/go-waku).\\nA follow-up post will clarify the purposes, similarities and differences between these three clients.\\nThe [Nim client](https://github.com/status-im/nim-waku/tree/d2fccb5220144893f994a67f2cc26661247f101f/waku/v2), is our reference implementation,\\ndeveloped by the research team in parallel with the specs\\nand building on a home-grown implementation of [`libp2p`](https://github.com/status-im/nim-libp2p).\\nThe Nim client is suitable to run as [a standalone adaptive node](/waku-update),\\nmanaged by individual operators\\nor as an encapsulated service node in other applications.\\nThis post looks at some recent developments within the Nim client.\\n\\n## 1. _**nim-waku**_ is now known as _**nwaku**_\\n\\nPronounced NWHA-koo.\\nYou may already have seen us refer to \\"`nwaku`\\" on Vac communication channels,\\nbut it is now official:\\nThe `nim-waku` Waku v2 client has been named `nwaku`.\\nWhy? Well, we needed a recognizable name for our client that could easily be referred to in everyday conversations\\nand `nim-waku` just didn\'t roll off the tongue.\\nWe\'ve followed the example of the closely related [`nimbus` project](https://github.com/status-im/nimbus-eth2) to find a punchier name\\nthat explicitly links the client to both the Waku set of protocols and the Nim language.\\n\\n## 2. Improvements in stability and performance\\n\\nThe initial implementation of Waku v2 demonstrated how the suite of protocols can be applied\\nto form a generalized, peer-to-peer messaging network,\\nwhile addressing a wide range of adaptive requirements.\\nThis allowed us to lift several protocol [specifications](https://rfc.vac.dev/) from `raw` to `draft` status,\\nindicating that a reference implementation exists for each.\\nHowever, as internal dogfooding increased and more external applications started using `nwaku`,\\nwe stepped up our focus on the client\'s stability and performance.\\nThis is especially true where we want `nwaku` to run unsupervised in a production environment\\nwithout any degradation in the services it provides.\\n\\nSome of the more significant productionization efforts over the last couple of months included:\\n\\n1. Reworking the `store` implementation to maintain stable memory usage\\n while storing historical messages\\n and serving multiple clients querying history simultaneously.\\n Previously, a `store` node would see gradual service degradation\\n due to inefficient memory usage when responding to history queries.\\n Queries that often took longer than 8 mins now complete in under 100 ms.\\n\\n2. Improved peer management.\\n For example, `filter` nodes will now remove unreachable clients after a number of connection failures,\\n whereas they would previously keep accumulating dead peers.\\n\\n3. Improved disk usage.\\n `nwaku` nodes that persist historical messages on disk now manage their own storage size based on the `--store-capacity`.\\n This can significantly improve node start-up times.\\n\\nMore stability issues may be addressed in future as `nwaku` matures,\\nbut we\'ve noticed a marked improvement in the reliability of running `nwaku` nodes.\\nThese include environments where `nwaku` nodes are expected to run with a long uptime.\\nVac currently operates two long-running fleets of `nwaku` nodes, `wakuv2.prod` and `wakuv2.test`,\\nfor internal dogfooding and\\nto serve as experimental bootstrapping nodes.\\nStatus has also recently deployed similar fleets for production and testing based on `nwaku`.\\nOur goal is to have `nwaku` be stable, performant and flexible enough\\nto be an attractive option for operators to run and maintain their own Waku v2 nodes.\\nSee also the [future work](#future-work) section below for more on our general goal of _`nwaku` for operators_.\\n\\n## 3. Improvements in interoperability\\n\\nWe\'ve implemented several features that improve `nwaku`\'s usability in different environments\\nand its interoperability with other Waku v2 clients.\\nOne major step forward here was adding support for both secure and unsecured WebSocket connections as `libp2p` transports.\\nThis allows direct connectivity with `js-waku`\\nand paves the way for native browser usage.\\nWe\'ve also added support for parsing and resolving DNS-type `multiaddrs`,\\ni.e. multiaddress protocol schemes [`dns`, `dns4`, `dns6` and `dnsaddr`](https://github.com/multiformats/multiaddr/blob/b746a7d014e825221cc3aea6e57a92d78419990f/protocols.csv#L8-L11).\\nA `nwaku` node can now also be [configured with its own IPv4 DNS domain name](https://github.com/status-im/nim-waku/tree/d2fccb5220144893f994a67f2cc26661247f101f/waku/v2#configuring-a-domain-name)\\nallowing dynamic IP address allocation without impacting a node\'s reachability by its peers.\\n\\n## 4. Peer discovery\\n\\n_Peer discovery_ is the method by which nodes become aware of each other\u2019s existence.\\nThe question of peer discovery in a Waku v2 network has been a focus area since the protocol was first conceptualized.\\nSince then several different approaches to discovery have been proposed and investigated.\\nWe\'ve implemented three discovery mechanisms in `nwaku` so far:\\n\\n### DNS-based discovery\\n\\n`nwaku` nodes can retrieve an authenticated, updateable list of peers via DNS to bootstrap connection to a Waku v2 network.\\nOur implementation is based on [EIP-1459](https://eips.ethereum.org/EIPS/eip-1459).\\n\\n### GossipSub peer exchange\\n\\n[GossipSub Peer Exchange (PX)](https://github.com/libp2p/specs/blob/10712c55ab309086a52eec7d25f294df4fa96528/pubsub/gossipsub/gossipsub-v1.1.md#prune-backoff-and-peer-exchange) is a GossipSub v1.1 mechanism\\nwhereby a pruning peer may provide a pruned peer with a set of alternative peers\\nwhere it can connect to reform its mesh.\\nThis is a very suitable mechanism to gradually discover more peers\\nfrom an initial connection to a small set of bootstrap peers.\\nIt is enabled in a `nwaku` node by default.\\n\\n### Waku Node Discovery Protocol v5\\n\\nThis is a DHT-based discovery mechanism adapted to store and relay _node records_.\\nOur implementation is based on [Ethereum\'s Discovery v5 protocol](https://github.com/ethereum/devp2p/blob/fa6428ada7385c13551873b2ae6ad2457c228eb8/discv5/discv5-theory.md)\\nwith some [minor modifications](https://rfc.vac.dev/spec/33/) to isolate our discovery network from that of Ethereum.\\nThe decision to separate the Waku Discovery v5 network from Ethereum\'s was made on considerations of lookup efficiency.\\nThis comes at a possible tradeoff in network resilience.\\nWe are considering merging with the Ethereum Discovery v5 network in future,\\nor even implement a hybrid solution.\\n[This post](https://forum.vac.dev/t/waku-v2-discv5-roadmap-discussion/121/8) explains the decision and future steps.\\n\\n## 5. Spam protection using RLN\\n\\nAn early addition to our suite of protocols was [an extension of `11/WAKU-RELAY`](https://rfc.vac.dev/spec/32/)\\nthat provided spam protection using [Rate Limiting Nullifiers (RLN)](https://rfc.vac.dev/spec/32/).\\nThe `nwaku` client now contains a working demonstration and integration of RLN relay.\\nCheck out [this tutorial](https://github.com/status-im/nim-waku/blob/ee96705c7fbe4063b780ac43b7edee2f6c4e351b/docs/tutorial/rln-chat2-live-testnet.md) to see the protocol in action using a toy chat application built on `nwaku`.\\nWe\'d love for people to join us in dogfooding RLN spam protection as part of our operator incentive testnet.\\nFeel free to join our [Vac Discord](https://discord.gg/KNj3ctuZvZ) server\\nand head to the `#rln` channel for more information.\\n\\n## Future work\\n\\nAs we continue working towards our goal of a fully decentralized, generalized and censorship-resistant messaging protocol,\\nthese are some of the current and future focus areas for `nwaku`:\\n\\n### Reaching out to operators:\\n\\nWe are starting to push for operators to run and maintain their own Waku v2 nodes,\\npreferably contributing to the default Waku v2 network as described by the default pubsub topic (`/waku/2/default-waku/proto`).\\nAmongst other things, a large fleet of stable operator-run Waku v2 nodes will help secure the network,\\nprovide valuable services to a variety of applications\\nand ensure the future sustainability of both Vac as a research organization and the Waku suite of protocols.\\n\\nWe are targeting `nwaku` as the main option for operator-run nodes. \\nSpecifically, we aim to provide through `nwaku`:\\n\\n1. a lightweight and robust Waku v2 client.\\n This client must be first in line to support innovative and new Waku v2 protocols,\\n but configurable enough to serve the adaptive needs of various operators.\\n2. an easy-to-follow guide for operators to configure,\\n set up and maintain their own nodes\\n3. a set of operator-focused tools to monitor and maintain a running node\\n\\n### Better conversational security layer guarantees\\n\\nConversational security guarantees in Waku v2 are currently designed around the Status application.\\nDevelopers building their own applications on top of Waku would therefore\\neither have to reimplement a set of tools similar to Status\\nor build their own security solutions on the application layer above Waku.\\nWe are working on [a set of features](https://github.com/vacp2p/research/issues/97) built into Waku\\nthat will provide the general security properties Waku users may desire\\nand do so in a modern and simple way.\\nThis is useful for applications outside of Status that want similar security guarantees.\\nAs a first step, we\'ve already made good progress toward [integrating noise handshakes](https://forum.vac.dev/t/noise-handshakes-as-key-exchange-mechanism-for-waku2/130) as a key exchange mechanism in Waku v2.\\n\\n### Protocol incentivization\\n\\nWe want to design incentivization around our protocols to encourage desired behaviors in the Waku network,\\nrewarding nodes providing costly services\\nand punishing adversarial actions.\\nThis will increase the overall security of the network\\nand encourage operators to run their own Waku nodes.\\nIn turn, the sustainability of Vac as an organization will be better guaranteed.\\nAs such, protocol incentivization was a major focus in our recent [Vac Sustainability and Business Workshop](https://forum.vac.dev/t/vac-sustainability-and-business-workshop/).\\nOur first step here is to finish integrating RLN relay into Waku\\nwith blockchain interaction to manage members,\\npunish spammers\\nand reward spam detectors.\\nAfter this, we want to design monetary incentivization for providers of `store`, `lightpush` and `filter` services.\\nThis may also tie into a reputation mechanism for service nodes based on a network-wide consensus on service quality.\\nA big challenge for protocol incentivization is doing it in a private fashion,\\nso we can keep similar metadata protection guarantees as the Waku base layer.\\nThis ties into our focus on [Zero Knowledge tech](https://forum.vac.dev/t/vac-3-zk/97).\\n\\n### Improved store capacity\\n\\nThe `nwaku` store currently serves as an efficient in-memory store for historical messages,\\ndimensioned by the maximum number of messages the store node is willing to keep.\\nThis makes the `nwaku` store appropriate for keeping history over a short term\\nwithout any time-based guarantees,\\nbut with the advantage of providing fast responses to history queries.\\nSome applications, such as Status, require longer-term historical message storage\\nwith time-based dimensioning\\nto guarantee that messages will be stored for a specified minimum period.\\nBecause of the relatively high cost of memory compared to disk space,\\na higher capacity store, with time guarantees, should operate as a disk-only database of historical messages.\\nThis is an ongoing effort.\\n\\n### Multipurpose discovery\\n\\nIn addition to [the three discovery methods](#4-peer-discovery) already implemented in `nwaku`,\\nwe are working on improving discovery on at least three fronts:\\n\\n#### _Capability discovery:_\\n\\nWaku v2 nodes may be interested in peers with specific capabilities, for example:\\n\\n1. peers within a specific pubsub topic mesh,\\n2. peers with **store** capability,\\n3. **store** peers with x days of history for a specific content topic, etc.\\n\\nCapability discovery entails mechanisms by which such capabilities can be advertised and discovered/negotiated.\\nOne major hurdle to overcome is the increased complexity of finding a node with specific capabilities within the larger network (a needle in a haystack).\\nSee the [original problem statement](https://github.com/vacp2p/rfc/issues/429) for more.\\n\\n#### _Improvements in Discovery v5_\\n\\nOf the implemented discovery methods,\\nDiscovery v5 best addresses our need for a decentralized and scalable discovery mechanism.\\nWith the basic implementation done,\\nthere are some improvements planned for Discovery v5,\\nincluding methods to increase security such as merging with the Ethereum Discovery v5 network,\\nintroducing explicit NAT traversal\\nand utilizing [topic advertisement](https://github.com/ethereum/devp2p/blob/fa6428ada7385c13551873b2ae6ad2457c228eb8/discv5/discv5-theory.md#topic-advertisement).\\nThe [Waku v2 Discovery v5 Roadmap](https://forum.vac.dev/t/waku-v2-discv5-roadmap-discussion/121) contains more details.\\n\\n#### _Generalized peer exchange_\\n\\n`nwaku` already implements [GossipSub peer exchange](https://github.com/libp2p/specs/blob/10712c55ab309086a52eec7d25f294df4fa96528/pubsub/gossipsub/gossipsub-v1.1.md#prune-backoff-and-peer-exchange).\\nWe now need a general request-response mechanism outside of GossipSub\\nby which a node may learn about other Waku v2 nodes\\nby requesting and receiving a list of peers from a neighbor.\\nThis could, for example, be a suitable way for resource-restricted devices to request a stronger peer\\nto perform a random Discovery v5 lookup on their behalf\\nor simply to be informed of a subset of the peers known to that neighbor.\\nSee [this issue](https://github.com/vacp2p/rfc/issues/495) for more.\\n\\n---\\n\\nThis concludes a general outline of some of the main recent developments in the `nwaku` client\\nand a summary of the current and future focus areas.\\nMuch more is happening behind the scenes, of course,\\nso for more information, or to join the conversation,\\nfeel free to join our [Vac Discord](https://discord.gg/KNj3ctuZvZ) server\\nor to check out the [`nwaku` repo on Github](https://github.com/status-im/nim-waku).\\nYou can also view the changelog for past releases [here](https://github.com/status-im/nim-waku/releases).\\n\\n## References\\n\\n- [17/WAKU-RLN-RELAY](https://rfc.vac.dev/spec/17/)\\n- [32/RLN](https://rfc.vac.dev/spec/32/)\\n- [33/WAKU2-DISCV5](https://rfc.vac.dev/spec/33/)\\n- [Capabilities advertising](https://github.com/vacp2p/rfc/issues/429)\\n- [Configuring a domain name](https://github.com/status-im/nim-waku/tree/d2fccb5220144893f994a67f2cc26661247f101f/waku/v2#configuring-a-domain-name)\\n- [Conversational security](https://github.com/vacp2p/research/issues/97)\\n- [Discovery v5 Topic Advertisement](https://github.com/ethereum/devp2p/blob/fa6428ada7385c13551873b2ae6ad2457c228eb8/discv5/discv5-theory.md#topic-advertisement)\\n- [EIP-1459](https://eips.ethereum.org/EIPS/eip-1459)\\n- [GossipSub Peer Exchange](https://github.com/libp2p/specs/blob/10712c55ab309086a52eec7d25f294df4fa96528/pubsub/gossipsub/gossipsub-v1.1.md#prune-backoff-and-peer-exchange)\\n- [go-waku](https://github.com/status-im/go-waku)\\n- [js-waku](https://github.com/status-im/js-waku)\\n- [`multiaddr` formats](https://github.com/multiformats/multiaddr/blob/b746a7d014e825221cc3aea6e57a92d78419990f/protocols.csv#L8-L11)\\n- [nimbus-eth2](https://github.com/status-im/nimbus-eth2)\\n- [nim-libp2p](https://github.com/status-im/nim-libp2p)\\n- [nim-waku](https://github.com/status-im/nim-waku)\\n- [nim-waku releases](https://github.com/status-im/nim-waku/releases)\\n- [Node Discovery Protocol v5 - Theory](https://github.com/ethereum/devp2p/blob/fa6428ada7385c13551873b2ae6ad2457c228eb8/discv5/discv5-theory.md)\\n- [Noise handshakes](https://forum.vac.dev/t/noise-handshakes-as-key-exchange-mechanism-for-waku2/130)\\n- [RLN tutorial](https://github.com/status-im/nim-waku/blob/ee96705c7fbe4063b780ac43b7edee2f6c4e351b/docs/tutorial/rln-chat2-live-testnet.md)\\n- [Vac <3 ZK](https://forum.vac.dev/t/vac-3-zk/97)\\n- [Vac About page](https://vac.dev/#about)\\n- [Vac Research log](https://vac.dev/research-log/)\\n- [Vac RFC site](https://rfc.vac.dev/)\\n- [Vac Sustainability and Business Workshop](https://forum.vac.dev/t/vac-sustainability-and-business-workshop/)\\n- [Waku Update](/waku-update)\\n- [Waku v1 vs Waku v2: Bandwidth Comparison](/waku-v1-v2-bandwidth-comparison)\\n- [Waku v2 Peer Exchange](https://github.com/vacp2p/rfc/issues/495)\\n- [Waku v2 Discovery v5 Roadmap](https://forum.vac.dev/t/waku-v2-discv5-roadmap-discussion/121)\\n- [What\'s the Plan for Waku v2?](/waku-v2-plan)"},{"id":"ethics-surveillance-tech","metadata":{"permalink":"/rlog/ethics-surveillance-tech","source":"@site/rlog/2021-12-03-ethics-surveillance-tech.mdx","title":"Opinion: Pseudo-ethics in the Surveillance Tech Industry","description":"A look at typical ethical shortfalls in the global surveillance tech industry.","date":"2021-12-03T10:00:00.000Z","formattedDate":"December 3, 2021","tags":[],"readingTime":11.715,"hasTruncateMarker":true,"authors":[{"name":"Circe","twitter":"vacp2p","github":"thecirce","key":"circe"}],"frontMatter":{"layout":"post","name":"Opinion: Pseudo-ethics in the Surveillance Tech Industry","title":"Opinion: Pseudo-ethics in the Surveillance Tech Industry","date":"2021-12-03T10:00:00.000Z","authors":"circe","published":true,"slug":"ethics-surveillance-tech","categories":"research","summary":null,"discuss":null},"prevItem":{"title":"Introducing nwaku","permalink":"/rlog/introducing-nwaku"},"nextItem":{"title":"Waku v1 vs Waku v2: Bandwidth Comparison","permalink":"/rlog/waku-v1-v2-bandwidth-comparison"}},"content":"A look at typical ethical shortfalls in the global surveillance tech industry.\\n\\n\x3c!--truncate--\x3e\\n\\n_This is an opinion piece by pseudonymous contributor, circe._\\n\\n## Preface\\n\\nThe Vac team aims to provide a public good in the form of freely available, open source tools and protocols for decentralized communication.\\nAs such, we value our independence and the usefulness of our protocols for a wide range of applications.\\nAt the same time, we realize that all technical development, including ours, has a moral component.\\nAs a diverse team we are guided by a shared devotion to the principles of human rights and liberty.\\nThis explains why we place such a high premium on security, censorship-resistance and privacy -\\na stance we [share with the wider Status Network](https://our.status.im/our-principles/).\\nThe post below takes a different approach from our usual more technical analyses,\\nby starting to peel back the curtain on the ethical shortfalls of the global surveillance tech industry.\\n\\n## Spotlight on an industry\\n\\n[Apple\'s announcement](https://www.apple.com/newsroom/2021/11/apple-sues-nso-group-to-curb-the-abuse-of-state-sponsored-spyware/) of their lawsuit against Israel\'s NSO Group\\nmarks the latest in a series of recent setbacks for the surveillance tech company.\\nIn early November, the [United States blacklisted the firm](https://public-inspection.federalregister.gov/2021-24123.pdf),\\nciting concerns about the use of their spyware by foreign governments targeting civilians such as \\"journalists, businesspeople, activists\\" and more.\\nThe company is already [embroiled in a lawsuit with Whatsapp](https://www.reuters.com/article/us-facebook-cyber-whatsapp-nsogroup-idUSKBN1X82BE)\\nover their exploit of the chat app\'s video calling service to install malware on target devices.\\nNSO Group\'s most infamous product, [Pegasus](https://forbiddenstories.org/case/the-pegasus-project/), operates as a hidden exploit installed on victims\' mobile phones,\\nsometimes without even requiring as much as an unguarded click on a malicious link.\\nIt has the potential to lay bare, and report to its owners, _everything_ within the reach of the infected device.\\nFor most people this amounts to a significant portion of their private lives and thoughts.\\nPegasus can read your private messages (even encrypted), collect your passwords, record calls, track your location and access your device\'s microphone and camera.\\nNo activity or application on an infected phone would be hidden.\\n\\nThe latest controversies are perhaps less because of the novelty of the revelations -\\nthe existence of Pegasus has been known to civil activists [since at least 2016](https://www.bbc.com/news/technology-37192670).\\nRather, the public was reminded again of the potential scope of surveillance tech\\nin the indiscriminate use of Pegasus on private citizens.\\nThis has far-reaching implications for human freedoms worldwide.\\nEarlier this year, a [leaked list of over 50,000 targets](https://www.theguardian.com/world/2021/jul/18/revealed-leak-uncovers-global-abuse-of-cyber-surveillance-weapon-nso-group-pegasus), or possible targets, of Pegasus included\\nthe phone numbers of human rights advocates, independent journalists, lawyers and political activists.\\nThis should have come as no surprise.\\nThe type of autocratically inclined agents, and governments, who would venture to buy and use such invasive cyber-arms often target those they find politically inconvenient.\\nPegasus, and similar technologies, simply extend the reach and capacity of such individuals and governments -\\nno border or distance, no political rank or social advantage, no sanctity of profession or regard for dignity,\\nprovide any indemnity from becoming a victim.\\nYour best hope is to remain uninteresting enough to escape consideration.\\n\\nThe NSO Group has, of course, denied allegations of culpability and questions the authenticity of the list.\\nAt this stage, the latter is almost beside the point:\\nAmnesty International\'s cybersecurity team, Security Lab, _did_ find [forensic evidence of Pegasus](https://www.amnesty.org/en/latest/research/2021/07/forensic-methodology-report-how-to-catch-nso-groups-pegasus/#_ftn1) on the phones of several volunteers whose numbers appeared on the original list,\\nincluding those of journalists and human rights activists.\\n(Security Lab has since opened up their [infection finding tool](https://github.com/mvt-project/mvt) to the public.)\\nFrench intelligence has similarly [inspected and confirmed](https://www.theguardian.com/news/2021/aug/02/pegasus-spyware-found-on-journalists-phones-french-intelligence-confirms) infection of at least three devices belonging to journalists.\\nThe phones of several people who were close to the Saudi-American journalist, Jamal Khashoggi, were [confirmed hacked](https://www.bbc.com/news/world-57891506)\\nboth before and after Khashoggi\'s brutal murder at the Saudi embassy in Istanbul in 2018.\\n[More reports](https://www.theguardian.com/news/2021/sep/21/hungary-journalist-daniel-nemeth-phones-infected-with-nso-pegasus-spyware) of confirmed Pegasus hacks are still published with some regularity.\\nIt is now an open secret that many authoritarian governments have bought Pegasus.\\nIt\'s not difficult to extrapolate from existing reports and such clients\' track records\\nwhat the potential injuries to human freedoms are that they can inflict with access to such a powerful cyberweapon.\\n\\n## A typical response\\n\\n[NSO\'s response](https://www.theguardian.com/news/2021/jul/18/response-from-nso-and-governments) to the allegations follows a textbook approach\\nof avoiding earnest ethical introspection on the manufacturing, and selling, of cyber-arms.\\nFirstly, shift ethical responsibility to a predetermined process, a list of checkboxes of your own making.\\nThe Group, for example, claims to sell only to \\"vetted governments\\", following a classification process\\nof which they have now [published some procedural details](https://www.nsogroup.com/wp-content/uploads/2021/06/ReportBooklet.pdf) but no tangible criteria.\\nThe next step is to reaffirm continuously, and repetitively, your dedication to the _legal_ combat against crime,\\n[\\"legitimate law enforcement agencies\\"](https://www.nsogroup.com/wp-content/uploads/2021/06/ReportBooklet.pdf) (note the almost tautological phrasing),\\nadherence to international arms trade laws,\\ncompliance clauses in customer contracts, etc.\\nThirdly, having been absolved of any moral suspicions that might exist about product and process,\\nfrom conception to engineering to trade,\\ndistance yourself from the consequences of its use in the world.\\n[\\"NSO does not operate its technology, does not collect, nor possesses, nor has any access to any kind of data of its customers.\\"](https://www.theguardian.com/news/2021/jul/18/response-from-nso-and-governments)\\nIt is interesting that directly after this statement they claim with contradictory confidence that\\ntheir \\"technology was not associated in any way with the heinous murder of Jamal Khashoggi\\".\\nThe unapologetic tone seems hardly appropriate when the same document confirms that the Group had to\\nshut down customers\' systems due to \\"confirmed misuse\\" and have had to do so \\"multiple times\\" in the past.\\nGiven all this, the response manages to evade any serious interrogation of the \\"vetting\\" process itself,\\nwhich forced the company to reject \\"approximately 15% of potential new opportunities for Pegasus\\" in one year.\\nCourageous.\\n\\nWe have heard this all before.\\nThere exists a multi-billion dollar industry of private companies and engineering firms [thriving on proceeds](https://www.economist.com/business/2019/12/12/offering-software-for-snooping-to-governments-is-a-booming-business) from\\nselling surveillance tools and cyber-arms to dubious agencies and foreign governments.\\nIn turn, the most power-hungry and oppressive regimes often _rely_ on such technological innovations -\\nfor which they lack the in-country engineering expertise -\\nto maintain control, suppress uprisings, intimidate opposing journalists, and track their citizens.\\nIt\'s a lucrative business opportunity, and resourceful companies have sprung up everywhere to supply this demand,\\noften in countries where citizens, including employees of the company, would be horrified if they were similarly subject to the oppressions of their own products.\\nWhen, in 2014, Italy\'s _HackingTeam_ were pulsed by the United Nations about their (then alleged) selling of spyware to Sudan,\\nwhich would have been a contravention of the UN\'s weapon export ban,\\nthey simply replied that their product was not controlled as a weapon and therefore not subject to such scrutiny.\\nThey remained within their legal bounds, technically.\\nFurthermore, they similarly shifted ethical responsibility to external standards of legitimacy,\\nclaiming their [\\"software is not sold to governments that are blacklisted by the EU, the US, NATO, and similar international organizations\\"](https://citizenlab.ca/2014/02/mapping-hacking-teams-untraceable-spyware/).\\nWhen the company themselves were [hacked in 2015](https://www.wired.com/2015/07/hacking-team-breach-shows-global-spying-firm-run-amok/),\\nrevelations (confirmations, that is) of widespread misuse by repressive governments were damaging enough to force them to disappear and rebrand as Memento Labs.\\n[Their website](https://www.mem3nt0.com/en/) boasts an impressive list of statutes, regulations, procedures, export controls and legal frameworks,\\nall of which the rebranded hackers proudly comply with.\\nSurely no further ethical scrutiny is necessary?\\n\\n## Ethics != the law\\n\\n### The law is trailing behind\\n\\nSuch recourse to the _legality_ of your action as ethical justification is moot for several reasons.\\nThe first is glaringly obvious -\\nour laws are ill-equipped to address the implications of modern technology.\\nLegal systems are a cumbersome inheritance built over generations.\\nThis is especially true of the statutes and regulations governing international trade, behind which these companies so often hide.\\nOur best legal systems are trailing miles behind the technology for which we seek guidelines.\\nLegislators are still struggling to make sense of technologies like face recognition,\\nthe repercussions of smart devices acting \\"on their own\\" and biases in algorithms.\\nTo claim you are performing ethical due diligence by resorting to an outdated and incomplete system of legal codes is disingenuous.\\n\\n### The law depends on ethics\\n\\nThe second reason is more central to my argument,\\nand an important flaw in these sleight of hand justifications appearing from time to time in the media.\\nEthics can in no way be confused as synonymous with legality or legitimacy.\\nThese are incommensurable concepts.\\nIn an ideal world, of course, the law is meant to track the minimum standards of ethical conduct in a society.\\nLaws are often drafted exactly from some ethical, and practical, impulse to minimize harmful conduct\\nand provide for corrective and punitive measures where transgressions do occur.\\nThe law, however, has a much narrower scope than ethics.\\nIt can be just or unjust.\\nIn fact, it is in need of ethics to constantly reform.\\nEthics and values are born out of collective self-reflection.\\nIt develops in our conversation with ourselves and others about the type of society we strive for.\\nAs such, an ethical worldview summarizes our deepest intuitions about how we should live and measure our impact on the world.\\nFor this reason, ethics is primarily enforced by social and internal pressures, not legal boundaries -\\nour desire to do what _ought_ to be done, however we define that.\\nEthics is therefore a much grander scheme than global legal systems\\nand the diplomatic frameworks that grants legitimacy to governments.\\nThese are but one limited outflow of the human aspiration to form societies in accordance with our ideologies and ethics.\\n\\n### International law is vague and exploitable\\n\\nOf course, the cyber-arms trade has a favorite recourse, _international_ law, which is even more limited.\\nSince such products are seldomly sold to governments and agencies within the country of production,\\nit enables a further distancing from consequences.\\nMany private surveillance companies are based in fairly liberal societies with (seemingly) strict emphases on human rights in their domestic laws.\\nInternational laws are much more complicated - for opportunists a synonym for \\"more grey areas in which to hide\\".\\nCompany conduct can now be governed, and excused, by a system that follows\\nthe whims of autocrats with exploitative intent and vastly different ethical conceptions from the company\'s purported aims.\\nInternational law, and the ways it is most often enforced by way of, say, UN-backed sanctions,\\nhave long been shaped by the compromises of international diplomacy.\\nTo be blunt: these laws are weak and subject to exactly the sort of narrow interests behind which mercenaries have always hidden.\\nThe surveillance tech industry is no exception.\\n\\n## Conclusion\\n\\nMy point is simple:\\nselling cyber-arms with the potential to become vast tools of oppression to governments and bodies with blatant histories of human rights violations,\\nand all but the publicly announced intention to continue operating in this way,\\nis categorically unconscionable.\\nThis seems obvious no matter what ethics system you argue from,\\nprovided it harbors any consideration for human dignity and freedom.\\nIt is a sign of poor moral discourse that such recourses to law and legitimacy are often considered synonymous with ethical justification.\\n\\"_I have acted within the bounds of law_\\", _\\"We supply only to legitimate law enforcement agencies\\"_, etc. are no substitutes.\\nEthical conduct requires an honest evaluation of an action against some conception of \\"the good\\",\\nhowever you define that.\\nToo often the surveillance tech industry precisely sidesteps this question,\\nboth in internal processes and external rationalisations to a concerned public.\\n\\nJohn Locke, he of the life-liberty-and-property, articulated the idea that government exists solely through the consent of the governed.\\nTowards the end of the 17th century, he wrote in his _Second Treatise on Civil Government_,\\n\\"[w]henever legislators endeavor to take away,\\nand destroy the property of the people, or to reduce them to slavery under arbitrary power,\\nthey put themselves in a state of war with the people, who are thereupon absolved from any further obedience\\".\\nThe inference is straightforward and humanist in essence:\\nlegitimacy is not something that is conferred by governments and institutions.\\nRather, they derive their legitimacy from us, their citizens, holding them to standards of ethics and societal ideals.\\nThis legitimacy only remains in tact as long as this mandate is honored and continuously extended by a well-informed public.\\nThis is the principle of informed consent on which all reciprocal ethics is based.\\n\\nThe surveillance tech industry may well have nothing more or less noble in mind than profit-making within legal bounds\\nwhen developing and selling their products.\\nHowever, when such companies are revealed again and again to have supplied tools of gross human rights violations to known human rights violators,\\nthey will do well to remember that ethics always _precedes_ requirements of legality and legitimacy.\\nIt is a fallacy to take normative guidance from the concept of \\"legitimacy\\"\\nif the concept itself depends on such normative guidelines for definition.\\nWithout examining the ethical standards by which institutions, governments, and laws, were created,\\nno value-judgements about their legitimacy can be made.\\nHiding behind legal compliance as substitute for moral justification is not enough.\\nTargets of increasingly invasive governmental snooping are too often chosen precisely to suppress the mechanisms from which the legitimacy of such governments flow -\\nthe consent of ordinary civilians.\\nFree and fair elections, free speech, free media, freedom of thought are all at risk.\\n\\n## References\\n\\n- [Status Principles](https://our.status.im/our-principles/)\\n- [Federal Register: Addition of Certain Entities to the Entity List](https://public-inspection.federalregister.gov/2021-24123.pdf)\\n- [forbiddenstories.org: The Pegasus Project](https://forbiddenstories.org/case/the-pegasus-project/)\\n- [theguardian.com: The Pegasus Project](https://www.theguardian.com/news/series/pegasus-project)\\n- [amnesty.org Forensic Methodology Report: How to catch NSO Group\u2019s Pegasus](https://www.amnesty.org/en/latest/research/2021/07/forensic-methodology-report-how-to-catch-nso-groups-pegasus/#_ftn1)\\n- [Apple sues NSO Group to curb the abuse of state-sponsored spyware](https://www.apple.com/newsroom/2021/11/apple-sues-nso-group-to-curb-the-abuse-of-state-sponsored-spyware/)\\n- [bbc.com: Who are the hackers who cracked the iPhone?](https://www.bbc.com/news/technology-37192670)\\n- [bbc.com: Pegasus: Who are the alleged victims of spyware targeting?](https://www.bbc.com/news/world-57891506)\\n- [citizenlab.ca: Mapping Hacking Team\u2019s \u201cUntraceable\u201d Spyware](https://citizenlab.ca/2014/02/mapping-hacking-teams-untraceable-spyware/)\\n- [economist.com: Offering software for snooping to governments is a booming business](https://www.economist.com/business/2019/12/12/offering-software-for-snooping-to-governments-is-a-booming-business)\\n- [Memento Labs](https://www.mem3nt0.com/en/)\\n- [Mobile Verification Toolkit to identify compromised devices](https://github.com/mvt-project/mvt)\\n- [NSO Group: Transparency and Responsibility Report 2021](https://www.nsogroup.com/wp-content/uploads/2021/06/ReportBooklet.pdf)\\n- [reuters.com: WhatsApp sues Israel\'s NSO for allegedly helping spies hack phones around the world](https://www.reuters.com/article/us-facebook-cyber-whatsapp-nsogroup-idUSKBN1X82BE)\\n- [wired.com: Hacking Team Breach Shows a Global Spying Firm Run Amok](https://www.wired.com/2015/07/hacking-team-breach-shows-global-spying-firm-run-amok/)"},{"id":"waku-v1-v2-bandwidth-comparison","metadata":{"permalink":"/rlog/waku-v1-v2-bandwidth-comparison","source":"@site/rlog/2021-10-25-waku-v1-vs-waku-v2.mdx","title":"Waku v1 vs Waku v2: Bandwidth Comparison","description":"A local comparison of bandwidth profiles showing significantly improved scalability in Waku v2 over Waku v1.","date":"2021-11-03T10:00:00.000Z","formattedDate":"November 3, 2021","tags":[],"readingTime":9.345,"hasTruncateMarker":true,"authors":[{"name":"Hanno Cornelius","twitter":"4aelius","github":"jm-clius","key":"hanno"}],"frontMatter":{"layout":"post","name":"Waku v1 vs Waku v2: Bandwidth Comparison","title":"Waku v1 vs Waku v2: Bandwidth Comparison","date":"2021-11-03T10:00:00.000Z","authors":"hanno","published":true,"slug":"waku-v1-v2-bandwidth-comparison","categories":"research","image":"/img/waku1-vs-waku2/waku1-vs-waku2-overall-network-size.png","discuss":"https://forum.vac.dev/t/discussion-waku-v1-vs-waku-v2-bandwidth-comparison/110"},"prevItem":{"title":"Opinion: Pseudo-ethics in the Surveillance Tech Industry","permalink":"/rlog/ethics-surveillance-tech"},"nextItem":{"title":"[Talk at COSCUP] Vac, Waku v2 and Ethereum Messaging","permalink":"/rlog/waku-v2-ethereum-coscup"}},"content":"A local comparison of bandwidth profiles showing significantly improved scalability in Waku v2 over Waku v1.\\n\\n\x3c!--truncate--\x3e\\n\\n## Background\\n\\nThe [original plan](https://vac.dev/waku-v2-plan) for Waku v2 suggested theoretical improvements in resource usage over Waku v1,\\nmainly as a result of the improved amplification factors provided by GossipSub.\\nIn its turn, [Waku v1 proposed improvements](https://vac.dev/fixing-whisper-with-waku) over its predecessor, Whisper.\\n\\nGiven that Waku v2 is aimed at resource restricted environments,\\nwe are specifically interested in its scalability and resource usage characteristics.\\nHowever, the theoretical performance improvements of Waku v2 over Waku v1,\\nhas never been properly benchmarked and tested.\\n\\nAlthough we\'re working towards a full performance evaluation of Waku v2,\\nthis would require significant planning and resources,\\nif it were to simulate \\"real world\\" conditions faithfully and measure bandwidth and resource usage across different network connections,\\nrobustness against attacks/losses, message latencies, etc.\\n(There already exists a fairly comprehensive [evaluation of GossipSub v1.1](https://research.protocol.ai/publications/gossipsub-v1.1-evaluation-report/vyzovitis2020.pdf),\\non which [`11/WAKU2-RELAY`](https://rfc.vac.dev/spec/11/) is based.)\\n\\nAs a starting point,\\nthis post contains a limited and local comparison of the _bandwidth_ profile (only) between Waku v1 and Waku v2.\\nIt reuses and adapts existing network simulations for [Waku v1](https://github.com/status-im/nim-waku/blob/master/waku/v1/node/quicksim.nim) and [Waku v2](https://github.com/status-im/nim-waku/blob/master/waku/v2/node/quicksim2.nim)\\nand compares bandwidth usage for similar message propagation scenarios.\\n\\n## Theoretical improvements in Waku v2\\n\\nMessages are propagated in Waku v1 using [flood routing]().\\nThis means that every peer will forward every new incoming message to all its connected peers (except the one it received the message from).\\nThis necessarily leads to unnecessary duplication (termed _amplification factor_),\\nwasting bandwidth and resources.\\nWhat\'s more, we expect this effect to worsen the larger the network becomes,\\nas each _connection_ will receive a copy of each message,\\nrather than a single copy per peer.\\n\\nMessage routing in Waku v2 follows the `libp2p` _GossipSub_ protocol,\\nwhich lowers amplification factors by only sending full message contents to a subset of connected peers.\\nAs a Waku v2 network grows, each peer will limit its number of full-message (\\"mesh\\") peerings -\\n`libp2p` suggests a maximum of `12` such connections per peer.\\nThis allows much better scalability than a flood-routed network.\\nFrom time to time, a Waku v2 peer will send metadata about the messages it has seen to other peers (\\"gossip\\" peers).\\n\\nSee [this explainer](https://hackmd.io/@vac/main/%2FYYlZYBCURFyO_ZG1EiteWg#11WAKU2-RELAY-gossipsub) for a more detailed discussion.\\n\\n## Methodology\\n\\nThe results below contain only some scenarios that provide an interesting contrast between Waku v1 and Waku v2.\\nFor example, [star network topologies](https://en.wikipedia.org/wiki/Star_network) do not show a substantial difference between Waku v1 and Waku v2.\\nThis is because each peer relies on a single connection to the central node for every message,\\nwhich barely requires any routing:\\neach connection receives a copy of every message for both Waku v1 and Waku v2.\\nHybrid topologies similarly show only a difference between Waku v1 and Waku v2 for network segments with [mesh-like connections](https://en.wikipedia.org/wiki/Mesh_networking),\\nwhere routing decisions need to be made.\\n\\nFor this reason, the following approach applies to all iterations:\\n\\n1. Simulations are run **locally**.\\n This limits the size of possible scenarios due to local resource constraints,\\n but is a way to quickly get an approximate comparison.\\n2. Nodes are treated as a **blackbox** for which we only measure bandwidth,\\n using an external bandwidth monitoring tool.\\n In other words, we do not consider differences in the size of the envelope (for v1) or the message (for v2).\\n3. Messages are published at a rate of **50 new messages per second** to each network,\\n except where explicitly stated otherwise.\\n4. Each message propagated in the network carries **8 bytes** of random payload, which is **encrypted**.\\n The same symmetric key cryptographic algorithm (with the same keys) are used in both Waku v1 and v2.\\n5. Traffic in each network is **generated from 10 nodes** (randomly-selected) and published in a round-robin fashion to **10 topics** (content topics for Waku v2).\\n In practice, we found no significant difference in _average_ bandwidth usage when tweaking these two parameters (the number of traffic generating nodes and the number of topics).\\n6. Peers are connected in a decentralized **full mesh topology**,\\n i.e. each peer is connected to every other peer in the network.\\n Waku v1 is expected to flood all messages across all existing connections.\\n Waku v2 gossipsub will GRAFT some of these connections for full-message peerings,\\n with the rest being gossip-only peerings.\\n7. After running each iteration, we **verify that messages propagated to all peers** (comparing the number of published messages to the metrics logged by each peer).\\n\\nFor Waku v1, nodes are configured as \\"full\\" nodes (i.e. with full bloom filter),\\nwhile Waku v2 nodes are `relay` nodes, all subscribing and publishing to the same PubSub topic.\\n\\n## Network size comparison\\n\\n### Iteration 1: 10 nodes\\n\\nLet\'s start with a small network of 10 nodes only and see how Waku v1 bandwidth usage compares to that of Waku v2.\\nAt this small scale we don\'t expect to see improved bandwidth usage in Waku v2 over Waku v1,\\nsince all connections, for both Waku v1 and Waku v2, will be full-message connections.\\nThe number of connections is low enough that Waku v2 nodes will likely GRAFT all connections to full-message peerings,\\nessentially flooding every message on every connection in a similar fashion to Waku v1.\\nIf our expectations are confirmed, it helps validate our methodology,\\nshowing that it gives more or less equivalent results between Waku v1 and Waku v2 networks.\\n\\n![](//img/waku1-vs-waku2/waku1-vs-waku2-10-nodes.png)\\n\\nSure enough, the figure shows that in this small-scale setup,\\nWaku v1 actually has a lower per-peer bandwidth usage than Waku v2.\\nOne reason for this may be the larger overall proportion of control messages in a gossipsub-routed network such as Waku v2.\\nThese play a larger role when the total network traffic is comparatively low, as in this iteration.\\nAlso note that the average bandwidth remains more or less constant as long as the rate of published messages remains stable.\\n\\n### Iteration 2: 30 nodes\\n\\nNow, let\'s run the same scenario for a larger network of highly-connected nodes, this time consisting of 30 nodes.\\nAt this point, the Waku v2 nodes will start pruning some connections to limit the number of full-message peerings (to a maximum of `12`),\\nwhile the Waku v1 nodes will continue flooding messages to all connected peers.\\nWe therefore expect to see a somewhat improved bandwidth usage in Waku v2 over Waku v1.\\n\\n![](//img/waku1-vs-waku2/waku1-vs-waku2-30-nodes.png)\\n\\nBandwidth usage in Waku v2 has increased only slightly from the smaller network of 10 nodes (hovering between 2000 and 3000 kbps).\\nThis is because there are only a few more full-message peerings than before.\\nCompare this to the much higher increase in bandwidth usage for Waku v1, which now requires more than 4000 kbps on average.\\n\\n### Iteration 3: 50 nodes\\n\\nFor an even larger network of 50 highly connected nodes,\\nthe divergence between Waku v1 and Waku v2 is even larger.\\nThe following figure shows comparative average bandwidth usage for a throughput of 50 messages per second.\\n\\n![](//img/waku1-vs-waku2/waku1-vs-waku2-50-nodes.png)\\n\\nAverage bandwidth usage (for the same message rate) has remained roughly the same for Waku v2 as it was for 30 nodes,\\nindicating that the number of full-message peerings per node has not increased.\\n\\n### Iteration 4: 85 nodes\\n\\nWe already see a clear trend in the bandwidth comparisons above,\\nso let\'s confirm by running the test once more for a network of 85 nodes.\\nDue to local resource constraints, the effective throughput for Waku v1 falls to below 50 messages per second,\\nso the v1 results below have been normalized and are therefore approximate.\\nThe local Waku v2 simulation maintains the message throughput rate without any problems.\\n\\n![](//img/waku1-vs-waku2/waku1-vs-waku2-85-nodes.png)\\n\\n### Iteration 5: 150 nodes\\n\\nFinally, we simulate message propagation in a network of 150 nodes.\\nDue to local resource constraints, we run this simulation at a lower rate -\\n35 messages per second -\\nand for a shorter amount of time.\\n\\n![](//img/waku1-vs-waku2/waku1-vs-waku2-150-nodes.png)\\n\\nNotice how the Waku v1 bandwidth usage is now more than 10 times worse than that of Waku v2.\\nThis is to be expected, as each Waku v1 node will try to flood each new message to 149 other peers,\\nwhile the Waku v2 nodes limit their full-message peerings to no more than 12.\\n\\n### Discussion\\n\\nLet\'s summarize average bandwidth growth against network growth for a constant message propagation rate.\\nSince we are particularly interested in how Waku v1 compares to Waku v2 in terms of bandwidth usage,\\nthe results are normalised to the Waku v2 average bandwidth usage for each network size.\\n\\n![](//img/waku1-vs-waku2/waku1-vs-waku2-overall-network-size.png)\\n\\nExtrapolation is a dangerous game,\\nbut it\'s safe to deduce that the divergence will only grow for even larger network topologies.\\nAlthough control signalling contributes more towards overall bandwidth for Waku v2 networks,\\nthis effect becomes less noticeable for larger networks.\\nFor network segments with more than ~18 densely connected nodes,\\nthe advantage of using Waku v2 above Waku v1 becomes clear.\\n\\n## Network traffic comparison\\n\\nThe analysis above controls the average message rate while network size grows.\\nIn reality, however, active users (and therefore message rates) are likely to grow in conjunction with the network.\\nThis will have an effect on bandwidth for both Waku v1 and Waku v2, though not in equal measure.\\nConsider the impact of an increasing rate of messages in a network of constant size:\\n\\n![](//img/waku1-vs-waku2/waku1-vs-waku2-overall-message-rate.png)\\n\\nThe _rate_ of increase in bandwidth for Waku v2 is slower than that for Waku v1 for a corresponding increase in message propagation rate.\\nIn fact, for a network of 30 densely-connected nodes,\\nif the message propagation rate increases by 1 per second,\\nWaku v1 requires an increased average bandwidth of almost 70kbps at each node.\\nA similar traffic increase in Waku v2 requires on average 40kbps more bandwidth per peer, just over half that of Waku v1.\\n\\n## Conclusions\\n\\n- **Waku v2 scales significantly better than Waku v1 in terms of average bandwidth usage**,\\n especially for densely connected networks.\\n- E.g. for a network consisting of **150** or more densely connected nodes,\\n Waku v2 provides more than **10x** better average bandwidth usage rates than Waku v1.\\n- As the network continues to scale, both in absolute terms (number of nodes) and in network traffic (message rates) the disparity between Waku v2 and Waku v1 becomes even larger.\\n\\n## Future work\\n\\nNow that we\'ve confirmed that Waku v2\'s bandwidth improvements over its predecessor matches theory,\\nwe can proceed to a more in-depth characterisation of Waku v2\'s resource usage.\\nSome questions that we want to answer include:\\n\\n- What proportion of Waku v2\'s bandwidth usage is used to propagate _payload_ versus bandwidth spent on _control_ messaging to maintain the mesh?\\n- To what extent is message latency (time until a message is delivered to its destination) affected by network size and message rate?\\n- How _reliable_ is message delivery in Waku v2 for different network sizes and message rates?\\n- What are the resource usage profiles of other Waku v2 protocols (e.g.[`12/WAKU2-FILTER`](https://rfc.vac.dev/spec/12/) and [`19/WAKU2-LIGHTPUSH`](https://rfc.vac.dev/spec/19/))?\\n\\nOur aim is to get ever closer to a \\"real world\\" understanding of Waku v2\'s performance characteristics,\\nidentify and fix vulnerabilities\\nand continually improve the efficiency of our suite of protocols.\\n\\n## References\\n\\n- [Evaluation of GossipSub v1.1](https://research.protocol.ai/publications/gossipsub-v1.1-evaluation-report/vyzovitis2020.pdf)\\n- [Fixing Whisper with Waku](https://vac.dev/fixing-whisper-with-waku)\\n- [GossipSub vs flood routing](https://hackmd.io/@vac/main/%2FYYlZYBCURFyO_ZG1EiteWg#11WAKU2-RELAY-gossipsub)\\n- [Network topologies: star](https://www.techopedia.com/definition/13335/star-topology#:~:text=Star%20topology%20is%20a%20network,known%20as%20a%20star%20network.)\\n- [Network topologies: mesh](https://en.wikipedia.org/wiki/Mesh_networking)\\n- [Waku v2 original plan](https://vac.dev/waku-v2-plan)"},{"id":"waku-v2-ethereum-coscup","metadata":{"permalink":"/rlog/waku-v2-ethereum-coscup","source":"@site/rlog/2021-08-06-coscup-waku-ethereum.mdx","title":"[Talk at COSCUP] Vac, Waku v2 and Ethereum Messaging","description":"Learn more about Waku v2, its origins, goals, protocols, implementation and ongoing research. Understand how it is used and how it can be useful for messaging in Ethereum.","date":"2021-08-06T12:00:00.000Z","formattedDate":"August 6, 2021","tags":[],"readingTime":7.12,"hasTruncateMarker":true,"authors":[{"name":"Oskar","twitter":"oskarth","github":"oskarth","key":"oskarth"}],"frontMatter":{"layout":"post","name":"[Talk at COSCUP] Vac, Waku v2 and Ethereum Messaging","title":"[Talk at COSCUP] Vac, Waku v2 and Ethereum Messaging","date":"2021-08-06T12:00:00.000Z","authors":"oskarth","published":true,"slug":"waku-v2-ethereum-coscup","categories":"research","image":"/img/coscup-waku/talk.png","discuss":"https://forum.vac.dev/t/discussion-talk-at-coscup-vac-waku-v2-and-ethereum-messaging/95"},"prevItem":{"title":"Waku v1 vs Waku v2: Bandwidth Comparison","permalink":"/rlog/waku-v1-v2-bandwidth-comparison"},"nextItem":{"title":"Presenting JS-Waku: Waku v2 in the Browser","permalink":"/rlog/presenting-js-waku"}},"content":"Learn more about Waku v2, its origins, goals, protocols, implementation and ongoing research. Understand how it is used and how it can be useful for messaging in Ethereum.\\n\\n\x3c!--truncate--\x3e\\n\\n_This is the English version of a talk originally given in Chinese at COSCUP in Taipei._\\n\\n[video recording with Chinese and English subtitles.](https://www.youtube.com/watch?v=s0ATpQ4_XFc)\\n\\n---\\n\\n## Introduction\\n\\nHi everyone!\\n\\nToday I\'ll talk to you about Waku v2. What it is, what problems it is solving,\\nand how it can be useful for things such as messaging in Ethereum. First, let me\\nstart with some brief background.\\n\\n## Brief history and background\\n\\nBack when Ethereum got started, there used to be this concept of the \\"holy\\ntrinity\\". You had Ethereum for compute/consensus, Swarm for storage, and Whisper\\nfor messaging. This is partly where the term Web3 comes from.\\n\\nStatus started out as an app with the goal of being a window onto Ethereum and\\na secure messenger. As one of the few, if not the only, apps using Whisper in\\nproduction, not to mention on a mobile phone, we quickly realized there were\\nproblems with the underlying protocols and infrastructure. Protocols such as\\nWhisper weren\'t quite ready for prime time yet when it came to things such as\\nscalability and working in the real world.\\n\\nAs we started addressing some of these challenges, and moved from app\\ndevelopement to focusing on protocols, research and infrastructure, we created\\nVac. Vac is an r&d unit doing protocol research focused on creating modular p2p\\nmessaging protocols for private, secure, censorship resistant communication.\\n\\nI won\'t go into too much detail on the issues with Whisper, if you are\\ninterested in this check out this talk\\n[here](https://www.youtube.com/watch?v=6lLT33tsJjs) or this\\n[article](https://vac.dev/fixing-whisper-with-waku).\\n\\nIn a nutshell, we forked Whisper to address immediate shortcomings and this\\nbecame Waku v1. Waku v2 is complete re-thought implementation from scratch on top\\nof libp2p. This will be the subject of today\'s talk.\\n\\n## Waku v2\\n\\n### Overview\\n\\nWaku v2 is a privacy-preserving peer-to-peer messaging protocol for resource\\nrestricted devices. We can look at Waku v2 as several things:\\n\\n- Set of protocols\\n- Set of implementations\\n- Network of nodes\\n\\nLet\'s first look at what the goals are.\\n\\n### Goals\\n\\nWaku v2 provides a PubSub based messaging protocol with the following\\ncharacteristics:\\n\\n1. **Generalized messaging**. Applications that require a messaging protocol to\\n communicate human to human, machine to machine, or a mix.\\n2. **Peer-to-peer**. For applications that require a p2p solution.\\n3. **Resource restricted**. For example, running with limited bandwidth, being\\n mostly-offline, or in a browser.\\n4. **Privacy**. Applications that have privacy requirements, such as pseudonymity,\\n metadata protection, etc.\\n\\nAnd to provide these properties in a modular fashion, where applications can\\nchoose their desired trade-offs.\\n\\n### Protocols\\n\\nWaku v2 consists of several protocols. Here we highlight a few of the most\\nimportant ones:\\n\\n- 10/WAKU2 - main specification, details how all the pieces fit together\\n- 11/RELAY - thin layer on top of GossipSub for message dissemination\\n- 13/STORE - fetching of historical messages\\n- 14/MESSAGE - message payload\\n\\nThis is the recommended subset for a minimal Waku v2 client.\\n\\nIn addition to this there are many other types of specifications at various\\nstages of maturity, such as: content based filtering, bridge mode to Waku v1,\\nJSON RPC API, zkSNARKS based spam protection with RLN, accounting and\\nsettlements with SWAP, fault-tolerant store nodes, recommendations around topic\\nusage, and more.\\n\\nSee https://rfc.vac.dev/ for a full overview.\\n\\n### Implementations\\n\\nWaku v2 consists of multiple implementations. This allows for client diversity,\\nmakes it easier to strengthen the protocols, and allow people to use Waku v2 in\\ndifferent contexts.\\n\\n- nim-waku - the reference client written in Nim, most full-featured.\\n- js-waku - allow usage of Waku v2 from browsers, focus on interacting with dapps.\\n- go-waku - subset of Waku v2 to ease integration into the Status app.\\n\\n### Testnet Huilong and dogfooding\\n\\nIn order to test the protocol we have setup a testnet across all implementations\\ncalled Huilong. Yes, that\'s the Taipei subway station!\\n\\n![](/img/coscup-waku/huilong.jpg)\\n\\nAmong us core devs we have disabled the main #waku Discord channel used for\\ndevelopment, and people run their own node connected to this toy chat application.\\n\\nFeel free to join and say hi! Instructions can be found here:\\n\\n- [nim-waku chat](https://github.com/status-im/nim-waku/blob/master/docs/tutorial/chat2.md)\\n\\n- [js-waku chat](https://status-im.github.io/js-waku/)\\n\\n- [go-waku chat](https://github.com/status-im/go-waku/tree/master/examples/chat2)\\n\\n### Research\\n\\nWhile Waku v2 is being used today, we are actively researching improvements.\\nSince the design is modular, we can gracefully introduce new capabilities. Some\\nof these research areas are:\\n\\n- Privacy-preserving spam protection using zkSNARKs and RLN\\n- Accounting and settlement of resource usage to incentivize nodes to provide services with SWAP\\n- State synchronization for store protocol to make it easier to run a store node without perfect uptime\\n- Better node discovery\\n- More rigorous privacy analysis\\n- Improving interaction with wallets and dapp\\n\\n## Use cases\\n\\nLet\'s look at where Waku v2 is and can be used.\\n\\n### Prelude: Topics in Waku v2\\n\\nTo give some context, there are two different types of topics in Waku v2. One is\\na PubSub topic, for routing. The other is a content topic, which is used for\\ncontent based filtering. Here\'s an example of the default PubSub topic:\\n\\n`/waku/2/default-waku/proto`\\n\\nThis is recommended as it increases privacy for participants and it is stored by\\ndefault, however this is up to the application.\\n\\nThe second type of topic is a content topic, which is application specific. For\\nexample, here\'s the content topic used in our testnet:\\n\\n`/toychat/2/huilong/proto`\\n\\nFor more on topics, see https://rfc.vac.dev/spec/23/\\n\\n### Status app\\n\\nIn the Status protocol, content topics - topics in Whisper/Waku v1 - are used for several things:\\n\\n- Contact code topic to discover X3DH bundles for perfect forward secrecy\\n - Partitioned into N (currently 5000) content topics to balance privacy with efficiency\\n- Public chats correspond to hash of the plaintext name\\n- Negotiated topic for 1:1 chat with DHKE derived content topic\\n\\nSee more here https://specs.status.im/spec/10\\n\\nCurrently, Status app is in the process of migrating to and testing Waku v2.\\n\\n### DappConnect: Ethereum messaging\\n\\nIt is easy to think of Waku as being for human messaging, since that\'s how it is\\nprimarily used in the Status app, but the goal is to be useful for generalized\\nmessaging, which includes Machine-To-Machine (M2M) messaging.\\n\\nRecall the concept of the holy trinity with Ethereum/Swarm/Whisper and Web3 that\\nwe mentioned in the beginning. Messaging can be used as a building block for\\ndapps, wallets, and users to communicate with each other. It can be used for\\nthings such as:\\n\\n- Multisig and DAO vote transactions only needing one on-chain operation\\n- Giving dapps ability to send push notifications to users\\n- Giving users ability to directly respond to requests from dapps\\n- Decentralized WalletConnect\\n- Etc\\n\\nBasically anything that requires communication and doesn\'t have to be on-chain.\\n\\n### WalletConnect v2\\n\\nWalletConnect is an open protocol for connecting dapps to wallets with a QR\\ncode. Version 2 is using Waku v2 as a communication channel to do so in a\\ndecentralized and private fashion.\\n\\n![](/img/coscup-waku/walletconnect.png)\\n\\nSee for more: https://docs.walletconnect.org/v/2.0/tech-spec\\n\\nWalletConnect v2 is currently in late alpha using Waku v2.\\n\\n### More examples\\n\\n- Gasless voting and vote aggregation off-chain\\n- Dapp games using Waku as player discovery mechanism\\n- Send encrypted message to someone with an Ethereum key\\n- <Your dapp here>\\n\\nThese are all things that are in progress / proof of concept stage.\\n\\n## Contribute\\n\\nWe\'d love to see contributions of any form!\\n\\n- You can play with it here: [nim-waku chat](https://github.com/status-im/nim-waku/blob/master/docs/tutorial/chat2.md) (/ [js-waku browser chat](https://status-im.github.io/js-waku/))\\n- Use Waku to build a dapp: [js-waku docs](https://status-im.github.io/js-waku/docs/)\\n- Contribute to code: [js-waku](https://github.com/status-im/js-waku) / [nim-waku](https://github.com/status-im/nim-waku)\\n- Contribute to specs: [vacp2p/rfc](https://github.com/vacp2p/rfc)\\n- We are hiring: Wallet & Dapp Integration Developer, Distributed Systems Engineer, Protocol Engineer, Protocol Researcher - all [job listings](https://status.im/our_team/jobs.html)\\n- Join our new [Discord](https://discord.gg/bJCTqS5H)\\n\\n## Conclusion\\n\\nIn this talk we\'ve gone over the original vision for Web3 and how Waku came to\\nbe. We\'ve also looked at what Waku v2 aims to do. We looked at its protocols,\\nimplementations, the current testnet as well as briefly on some ongoing\\nresearch for Vac.\\n\\nWe\'ve also looked at some specific use cases for Waku. First we looked at how\\nStatus uses it with different topics. Then we looked at how it can be useful for\\nmessaging in Ethereum, including for things like WalletConnect.\\n\\nI hope this talk gives you a better idea of what Waku is, why it exists, and\\nthat it inspires you to contribute, either to Waku itself or by using it in your\\nown project!"},{"id":"presenting-js-waku","metadata":{"permalink":"/rlog/presenting-js-waku","source":"@site/rlog/2021-06-04-presenting-js-waku.mdx","title":"Presenting JS-Waku: Waku v2 in the Browser","description":"JS-Waku is bringing Waku v2 to the browser. Learn what we achieved so far and what is next in our pipeline!","date":"2021-06-04T12:00:00.000Z","formattedDate":"June 4, 2021","tags":[],"readingTime":6.84,"hasTruncateMarker":true,"authors":[{"name":"Franck","twitter":"fryorcraken","github":"fryorcraken","key":"franck"}],"frontMatter":{"layout":"post","name":"Presenting JS-Waku: Waku v2 in the Browser","title":"Presenting JS-Waku: Waku v2 in the Browser","date":"2021-06-04T12:00:00.000Z","authors":"franck","published":true,"slug":"presenting-js-waku","categories":"platform","image":"/img/js-waku-gist.png","discuss":"https://forum.vac.dev/t/discussion-presenting-js-waku-waku-v2-in-the-browser/81"},"prevItem":{"title":"[Talk at COSCUP] Vac, Waku v2 and Ethereum Messaging","permalink":"/rlog/waku-v2-ethereum-coscup"},"nextItem":{"title":"Privacy-preserving p2p economic spam protection in Waku v2","permalink":"/rlog/rln-relay"}},"content":"JS-Waku is bringing Waku v2 to the browser. Learn what we achieved so far and what is next in our pipeline!\\n\\n\x3c!--truncate--\x3e\\n\\nFor the past 3 months, we have been working on bringing Waku v2 to the browser.\\nOur aim is to empower dApps with Waku v2, and it led to the creation of a new library.\\nWe believe now is good time to introduce it!\\n\\n## Waku v2\\n\\nFirst, let\'s review what Waku v2 is and what problem it is trying to solve.\\n\\nWaku v2 comes from a need to have a more scalable, better optimised solution for the Status app to achieve decentralised\\ncommunications on resource restricted devices (i.e., mobile phones).\\n\\nThe Status chat feature was initially built over Whisper.\\nHowever, Whisper has a number of caveats which makes it inefficient for mobile phones.\\nFor example, with Whisper, all devices are receiving all messages which is not ideal for limited data plans.\\n\\nTo remediate this, a Waku mode (then Waku v1), based on devp2p, was introduced.\\nTo further enable web and restricted resource environments, Waku v2 was created based on libp2p.\\nThe migration of the Status chat feature to Waku v2 is currently in progress.\\n\\nWe see the need of such solution in the broader Ethereum ecosystem, beyond Status.\\nThis is why we are building Waku v2 as a decentralised communication platform for all to use and build on.\\nIf you want to read more about Waku v2 and what it aims to achieve,\\ncheckout [What\'s the Plan for Waku v2?](/waku-v2-plan).\\n\\nSince last year, we have been busy defining and implementing Waku v2 protocols in [nim-waku](https://github.com/status-im/nim-waku),\\nfrom which you can build [wakunode2](https://github.com/status-im/nim-waku#wakunode).\\nWakunode2 is an adaptive and modular Waku v2 node,\\nit allows users to run their own node and use the Waku v2 protocols they need.\\nThe nim-waku project doubles as a library, that can be used to add Waku v2 support to native applications.\\n\\n## Waku v2 in the browser\\n\\nWe believe that dApps and wallets can benefit from the Waku network in several ways.\\nFor some dApps, it makes sense to enable peer-to-peer communications.\\nFor others, machine-to-machine communications would be a great asset.\\nFor example, in the case of a DAO,\\nWaku could be used for gas-less voting.\\nEnabling the DAO to notify their users of a new vote,\\nand users to vote without interacting with the blockchain and spending gas.\\n\\n[Murmur](https://github.com/status-im/murmur) was the first attempt to bring Whisper to the browser,\\nacting as a bridge between devp2p and libp2p.\\nOnce Waku v2 was started and there was a native implementation on top of libp2p,\\na [chat POC](https://github.com/vacp2p/waku-web-chat) was created to demonstrate the potential of Waku v2\\nin web environment.\\nIt showed how using js-libp2p with few modifications enabled access to the Waku v2 network.\\nThere was still some unresolved challenges.\\nFor example, nim-waku only support TCP connections which are not supported by browser applications.\\nHence, to connect to other node, the POC was connecting to a NodeJS proxy application using websockets,\\nwhich in turn could connect to wakunode2 via TCP.\\n\\nHowever, to enable dApp and Wallet developers to easily integrate Waku in their product,\\nwe need to give them a library that is easy to use and works out of the box:\\nintroducing [JS-Waku](https://github.com/status-im/js-waku).\\n\\nJS-Waku is a JavaScript library that allows your dApp, wallet or other web app to interact with the Waku v2 network.\\nIt is available right now on [npm](https://www.npmjs.com/package/js-waku):\\n\\n`npm install js-waku`.\\n\\nAs it is written in TypeScript, types are included in the npm package to allow easy integration with TypeScript, ClojureScript and other typed languages that compile to JavaScript.\\n\\nKey Waku v2 protocols are already available:\\n[message](https://rfc.vac.dev/spec/14/), [store](https://rfc.vac.dev/spec/13/), [relay](https://rfc.vac.dev/spec/11/) and [light push](https://rfc.vac.dev/spec/19/),\\nenabling your dApp to:\\n\\n- Send and receive near-instant messages on the Waku network (relay),\\n- Query nodes for messages that may have been missed, e.g. due to poor cellular network (store),\\n- Send messages with confirmations (light push).\\n\\nJS-Waku needs to operate in the same context from which Waku v2 was born:\\na restricted environment were connectivity or uptime are not guaranteed;\\nJS-Waku brings Waku v2 to the browser.\\n\\n## Achievements so far\\n\\nWe focused the past month on developing a [ReactJS Chat App](https://status-im.github.io/js-waku/).\\nThe aim was to create enough building blocks in JS-Waku to enable this showcase web app that\\nwe now [use for dogfooding](https://github.com/status-im/nim-waku/issues/399) purposes.\\n\\nMost of the effort was on getting familiar with the [js-libp2p](https://github.com/libp2p/js-libp2p) library\\nthat we heavily rely on.\\nJS-Waku is the second implementation of Waku v2 protocol,\\nso a lot of effort on interoperability was needed.\\nFor example, to ensure compatibility with the nim-waku reference implementation,\\nwe run our [tests against wakunode2](https://github.com/status-im/js-waku/blob/90c90dea11dfd1277f530cf5d683fb92992fe141/src/lib/waku_relay/index.spec.ts#L137) as part of the CI.\\n\\nThis interoperability effort helped solidify the current Waku v2 specifications:\\nBy clarifying the usage of topics\\n([#327](https://github.com/vacp2p/rfc/issues/327), [#383](https://github.com/vacp2p/rfc/pull/383)),\\nfix discrepancies between specs and nim-waku\\n([#418](https://github.com/status-im/nim-waku/issues/418), [#419](https://github.com/status-im/nim-waku/issues/419))\\nand fix small nim-waku & nim-libp2p bugs\\n([#411](https://github.com/status-im/nim-waku/issues/411), [#439](https://github.com/status-im/nim-waku/issues/439)).\\n\\nTo fully access the waku network, JS-Waku needs to enable web apps to connect to nim-waku nodes.\\nA standard way to do so is using secure websockets as it is not possible to connect directly to a TCP port from the browser.\\nUnfortunately websocket support is not yet available in [nim-libp2p](https://github.com/status-im/nim-libp2p/issues/407) so\\nwe ended up deploying [websockify](https://github.com/novnc/websockify) alongside wakunode2 instances.\\n\\nAs we built the [web chat app](https://github.com/status-im/js-waku/tree/main/examples/web-chat),\\nwe were able to fine tune the API to provide a simple and succinct interface.\\nYou can start a node, connect to other nodes and send a message in less than ten lines of code:\\n\\n```javascript\\nimport { Waku } from \'js-waku\'\\n\\nconst waku = await Waku.create({})\\n\\nconst nodes = await getStatusFleetNodes()\\nawait Promise.all(nodes.map((addr) => waku.dial(addr)))\\n\\nconst msg = WakuMessage.fromUtf8String(\\n \'Here is a message!\',\\n \'/my-cool-app/1/my-use-case/proto\',\\n)\\nawait waku.relay.send(msg)\\n```\\n\\nWe have also put a bounty at [0xHack](https://0xhack.dev/) for using JS-Waku\\nand running a [workshop](https://www.youtube.com/watch?v=l77j0VX75QE).\\nWe were thrilled to have a couple of hackers create new software using our libraries.\\nOne of the projects aimed to create a decentralised, end-to-end encrypted messenger app,\\nsimilar to what the [ETH-DM](https://rfc.vac.dev/spec/20/) protocol aims to achieve.\\nAnother project was a decentralised Twitter platform.\\nSuch projects allow us to prioritize the work on JS-Waku and understand how DevEx can be improved.\\n\\nAs more developers use JS-Waku, we will evolve the API to allow for more custom and fine-tune usage of the network\\nwhile preserving this out of the box experience.\\n\\n## What\'s next?\\n\\nNext, we are directing our attention towards [Developer Experience](https://github.com/status-im/js-waku/issues/68).\\nWe already have [documentation](https://www.npmjs.com/package/js-waku) available but we want to provide more:\\n[Tutorials](https://github.com/status-im/js-waku/issues/56), various examples\\nand showing how [JS-Waku can be used with Web3](https://github.com/status-im/js-waku/issues/72).\\n\\nBy prioritizing DevEx we aim to enable JS-Waku integration in dApps and wallets.\\nWe think JS-Waku builds a strong case for machine-to-machine (M2M) communications.\\nThe first use cases we are looking into are dApp notifications:\\nEnabling dApp to notify their user directly in their wallets!\\nLeveraging Waku as a decentralised infrastructure and standard so that users do not have to open their dApp to be notified\\nof events such as DAO voting.\\n\\nWe already have some POC in the pipeline to enable voting and polling on the Waku network,\\nallowing users to save gas by **not** broadcasting each individual vote on the blockchain.\\n\\nTo facilitate said applications, we are looking at improving integration with Web3 providers by providing examples\\nof signing, validating, encrypting and decrypting messages using Web3.\\nWaku is privacy conscious, so we will also provide signature and encryption examples decoupled from users\' Ethereum identity.\\n\\nAs you can read, we have grand plans for JS-Waku and Waku v2.\\nThere is a lot to do, and we would love some help so feel free to\\ncheck out the new role in our team:\\n[js-waku: Wallet & Dapp Integration Developer](https://status.im/our_team/jobs.html?gh_jid=3157894).\\nWe also have a number of [positions](https://status.im/our_team/jobs.html) open to work on Waku protocol and nim-waku.\\n\\nIf you are as excited as us by JS-Waku, why not build a dApp with it?\\nYou can find documentation on the [npmjs page](https://www.npmjs.com/package/js-waku).\\n\\nWhether you are a developer, you can come chat with us using [WakuJS Web Chat](https://status-im.github.io/js-waku/)\\nor [chat2](https://github.com/status-im/nim-waku/blob/master/docs/tutorial/chat2.md).\\nYou can get support in #dappconnect-support on [Vac Discord](https://discord.gg/j5pGbn7MHZ) or [Telegram](https://t.me/dappconnectsupport).\\nIf you have any ideas on how Waku could enable a specific dapp or use case, do share, we are always keen to hear it."},{"id":"rln-relay","metadata":{"permalink":"/rlog/rln-relay","source":"@site/rlog/2021-03-03-rln-relay.mdx","title":"Privacy-preserving p2p economic spam protection in Waku v2","description":"This post is going to give you an overview of how spam protection can be achieved in Waku Relay through rate-limiting nullifiers. We will cover a summary of spam-protection methods in centralized and p2p systems, and the solution overview and details of the economic spam-protection method. The open issues and future steps are discussed in the end.","date":"2021-03-05T12:00:00.000Z","formattedDate":"March 5, 2021","tags":[],"readingTime":20.775,"hasTruncateMarker":true,"authors":[{"name":"Sanaz","twitter":"sanaz2016","github":"staheri14","key":"sanaz"}],"frontMatter":{"layout":"post","name":"Privacy-preserving p2p economic spam protection in Waku v2","title":"Privacy-preserving p2p economic spam protection in Waku v2","date":"2021-03-05T12:00:00.000Z","authors":"sanaz","published":true,"slug":"rln-relay","categories":"reserach","image":"/img/rain.png","discuss":"https://forum.vac.dev/t/privacy-preserving-p2p-economic-spam-protection-in-waku-v2-with-rate-limiting-nullfiers/66","toc_min_heading_level":2,"toc_max_heading_level":5},"prevItem":{"title":"Presenting JS-Waku: Waku v2 in the Browser","permalink":"/rlog/presenting-js-waku"},"nextItem":{"title":"[Talk] Vac, Waku v2 and Ethereum Messaging","permalink":"/rlog/waku-v2-ethereum-messaging"}},"content":"This post is going to give you an overview of how spam protection can be achieved in Waku Relay through rate-limiting nullifiers. We will cover a summary of spam-protection methods in centralized and p2p systems, and the solution overview and details of the economic spam-protection method. The open issues and future steps are discussed in the end.\\n\\n\x3c!--truncate--\x3e\\n\\n## Introduction\\n\\nThis post is going to give you an overview of how spam protection can be achieved in Waku Relay protocol[^2] through Rate-Limiting Nullifiers[^3] [^4] or RLN for short.\\n\\nLet me give a little background about Waku(v2)[^1]. Waku is a privacy-preserving peer-to-peer (p2p) messaging protocol for resource-restricted devices. Being p2p means that Waku relies on **No** central server. Instead, peers collaboratively deliver messages in the network. Waku uses GossipSub[^16] as the underlying routing protocol (as of the writeup of this post). At a high level, GossipSub is based on publisher-subscriber architecture. That is, _peers, congregate around topics they are interested in and can send messages to topics. Each message gets delivered to all peers subscribed to the topic_. In GossipSub, a peer has a constant number of direct connections/neighbors. In order to publish a message, the author forwards its message to a subset of neighbors. The neighbors proceed similarly till the message gets propagated in the network of the subscribed peers. The message publishing and routing procedures are part of the Waku Relay[^17] protocol.\\n![Figure 1: An overview of privacy-preserving p2p economic spam protection in Waku v2 RLN-Relay protocol.](/img/rln-relay/rln-relay-overview.png)\\n\\n## What do we mean by spamming?\\n\\nIn centralized messaging systems, a spammer usually indicates an entity that uses the messaging system to send an unsolicited message (spam) to large numbers of recipients. However, in Waku with a p2p architecture, spam messages not only affect the recipients but also all the other peers involved in the routing process as they have to spend their computational power/bandwidth/storage capacity on processing spam messages. As such, we define a spammer as an entity that uses the messaging system to publish a large number of messages in a short amount of time. The messages issued in this way are called spam. In this definition, we disregard the intention of the spammer as well as the content of the message and the number of recipients.\\n\\n## Possible Solutions\\n\\nHas the spamming issue been addressed before? Of course yes! Here is an overview of the spam protection techniques with their trade-offs and use-cases. In this overview, we distinguish between protection techniques that are targeted for centralized messaging systems and those for p2p architectures.\\n\\n### Centralized Messaging Systems\\n\\nIn traditional centralized messaging systems, spam usually signifies unsolicited messages sent in bulk or messages with malicious content like malware. Protection mechanisms include\\n\\n- authentication through some piece of personally identifiable information e.g., phone number\\n- checksum-based filtering to protect against messages sent in bulk\\n- challenge-response systems\\n- content filtering on the server or via a proxy application\\n\\nThese methods exploit the fact that the messaging system is centralized and a global view of the users\' activities is available based on which spamming patterns can be extracted and defeated accordingly. Moreover, users are associated with an identifier e.g., a username which enables the server to profile each user e.g., to detect suspicious behavior like spamming. Such profiling possibility is against the user\'s anonymity and privacy.\\n\\nAmong the techniques enumerated above, authentication through phone numbers is a some-what economic-incentive measure as providing multiple valid phone numbers will be expensive for the attacker. Notice that while using an expensive authentication method can reduce the number of accounts owned by a single spammer, cannot address the spam issue entirely. This is because the spammer can still send bulk messages through one single account. For this approach to be effective, a centralized mediator is essential. That is why such a solution would not fit the p2p environments where no centralized control exists.\\n\\n### P2P Systems\\n\\nWhat about spam prevention in p2p messaging platforms? There are two techniques, namely _Proof of Work_[^8] deployed by Whisper[^9] and _Peer scoring_[^6] method (namely reputation-based approach) adopted by LibP2P. However, each of these solutions has its own shortcomings for real-life use-cases as explained below.\\n\\n#### Proof of work\\n\\nThe idea behind the Proof Of Work i.e., POW[^8] is to make messaging a computationally costly operation hence lowering the messaging rate of **all** the peers including the spammers. In specific, the message publisher has to solve a puzzle and the puzzle is to find a nonce such that the hash of the message concatenated with the nonce has at least z leading zeros. z is known as the difficulty of the puzzle. Since the hash function is one-way, peers have to brute-force to find a nonce. Hashing is a computationally-heavy operation so is the brute-force. While solving the puzzle is computationally expensive, it is comparatively cheap to verify the solution.\\n\\nPOW is also used as the underlying mining algorithm in Ethereum and Bitcoin blockchain. There, the goal is to contain the mining speed and allow the decentralized network to come to a consensus, or agree on things like account balances and the order of transactions.\\n\\nWhile the use of POW makes perfect sense in Ethereum / Bitcoin blockchain, it shows practical issues in heterogeneous p2p messaging systems with resource-restricted peers. Some peers won\'t be able to carry the designated computation and will be effectively excluded. Such exclusion showed to be practically an issue in applications like Status, which used to rely on POW for spam-protection, to the extent that the difficulty level had to be set close to zero.\\n\\n#### Peer Scoring\\n\\nThe peer scoring method[^6] that is utilized by libp2p is to limit the number of messages issued by a peer in connection to another peer. That is each peer monitors all the peers to which it is directly connected and adjusts their messaging quota i.e., to route or not route their messages depending on their past activities. For example, if a peer detects its neighbor is sending more than x messages per month, can drop its quota to z.x where z is less than one. The shortcoming of this solution is that scoring is based on peers\' local observations and the concept of the score is defined in relation to one single peer. This leaves room for an attack where a spammer can make connections to k peers in the system and publishes k.(x-1) messages by exploiting all of its k connections. Another attack scenario is through botnets consisting of a large number of e.g., a million bots. The attacker rents a botnet and inserts each of them as a legitimate peer to the network and each can publish x-1 messages per month[^7].\\n\\n#### Economic-Incentive Spam protection\\n\\nIs this the end of our spam-protection journey? Shall we simply give up and leave spammers be? Certainly not!\\nWaku RLN-Relay gives us a p2p spam-protection method which:\\n\\n- suits **p2p** systems and does not rely on any central entity.\\n- is **efficient** i.e., with no unreasonable computational, storage, memory, and bandwidth requirement! as such, it fits the network of **heterogeneous** peers.\\n- respects users **privacy** unlike reputation-based and centralized methods.\\n- deploys **economic-incentives** to contain spammers\' activity. Namely, there is a financial sacrifice for those who want to spam the system. How? follow along ...\\n\\nWe devise a general rule to save everyone\'s life and that is\\n\\n**No one can publish more than M messages per epoch without being financially charged!**\\n\\nWe set M to 1 for now, but this can be any arbitrary value. You may be thinking \\"This is too restrictive! Only one per epoch?\\". Don\'t worry, we set the epoch to a reasonable value so that it does not slow down the communication of innocent users but will make the life of spammers harder! Epoch here can be every second, as defined by UTC date-time +-20s.\\n\\nThe remainder of this post is all about the story of how to enforce this limit on each user\'s messaging rate as well as how to impose the financial cost when the limit gets violated. This brings us to the Rate Limiting Nullifiers and how we integrate this technique into Waku v2 (in specific the Waku Relay protocol) to protect our valuable users against spammers.\\n\\n## Technical Terms\\n\\n**Zero-knowledge proof**: Zero-knowledge proof (ZKP)[^14] allows a _prover_ to show a _verifier_ that they know something, without revealing what that something is. This means you can do the trust-minimized computation that is also privacy-preserving. As a basic example, instead of showing your ID when going to a bar you simply give them proof that you are over 18, without showing the doorman your id. In this write-up, by ZKP we essentially mean zkSNARK[^15] which is one of the many types of ZKPs.\\n\\n**Threshold Secret Sharing Scheme**: (m,n) Threshold secret-sharing is a method by which you can split a secret value s into n pieces in a way that the secret s can be reconstructed by having m pieces (m <= n). The economic-incentive spam protection utilizes a (2,n) secret sharing realized by Shamir Secret Sharing Scheme[^13].\\n\\n## Overview: Economic-Incentive Spam protection through Rate Limiting Nullifiers\\n\\n**Context**: We started the idea of economic-incentive spam protection more than a year ago and conducted a feasibility study to identify blockers and unknowns. The results are published in our prior [post](https://vac.dev/feasibility-semaphore-rate-limiting-zksnarks). Since then major progress has been made and the prior identified blockers that are listed below are now addressed. Kudos to [Barry WhiteHat](https://github.com/barryWhiteHat), [Onur Kilic](https://github.com/kilic), [Koh Wei Jie](https://github.com/weijiekoh/perpetualpowersoftau) for all of their hard work, research, and development which made this progress possible.\\n\\n- the proof time[^22] which was initially in the order of minutes ~10 mins and now is almost 0.5 seconds\\n- the prover key size[^21] which was initially ~110MB and now is ~3.9MB\\n- the lack of Shamir logic[^19] which is now implemented and part of the RLN repository[^4]\\n- the concern regarding the potential multi-party computation for the trusted setup of zkSNARKs which got resolved[^20]\\n- the lack of end-to-end integration that now we made it possible, have it implemented, and are going to present it in this post. New blockers are also sorted out during the e2e integration which we will discuss in the [Feasibility and Open Issues](#feasibility-and-open-issues) section.\\n\\nNow that you have more context, let\'s see how the final solution works. The fundamental point is to make it economically costly to send more than your share of messages and to do so in a privacy-preserving and e2e fashion. To do that we have the following components:\\n\\n- 1- **Group**: We manage all the peers inside a large group (later we can split peers into smaller groups, but for now consider only one). The group management is done via a smart contract which is devised for this purpose and is deployed on the Ethereum blockchain.\\n- 2- **Membership**: To be able to send messages and in specific for the published messages to get routed by all the peers, publishing peers have to register to the group. Membership involves setting up public and private key pairs (think of it as the username and password). The private key remains at the user side but the public key becomes a part of the group information on the contract (publicly available) and everyone has access to it. Public keys are not human-generated (like usernames) and instead they are random numbers, as such, they do not reveal any information about the owner (think of public keys as pseudonyms). Registration is mandatory for the users who want to publish a message, however, users who only want to listen to the messages are more than welcome and do not have to register in the group.\\n- **Membership fee**: Membership is not for free! each peer has to lock a certain amount of funds during the registration (this means peers have to have an Ethereum account with sufficient balance for this sake). This fund is safely stored on the contract and remains intact unless the peer attempts to break the rules and publish more than one message per epoch.\\n- **Zero-knowledge Proof of membership**: Do you want your message to get routed to its destination, fine, but you have to prove that you are a member of the group (sorry, no one can escape the registration phase!). Now, you may be thinking that should I attach my public key to my message to prove my membership? Absolutely Not! we said that our solution respects privacy! membership proofs are done in a zero-knowledge manner that is each message will carry cryptographic proof asserting that \\"the message is generated by one of the current members of the group\\", so your identity remains private and your anonymity is preserved!\\n- **Slashing through secret sharing**: Till now it does not seem like we can catch spammers, right? yes, you are right! now comes the exciting part, detecting spammers and slashing them. The core idea behind the slashing is that each publishing peer (not routing peers!) has to integrate a secret share of its private key inside the message. The secret share is deterministically computed over the private key and the current epoch. The content of this share is harmless for the peer\'s privacy (it looks random) unless the peer attempts to publish more than one message in the same epoch hence disclosing more than one secret share of its private key. Indeed two distinct shares of the private key under the same epoch are enough to reconstruct the entire private key. Then what should you do with the recovered private key? hurry up! go to the contract and withdraw the private key and claim its fund and get rich!! Are you thinking what if spammers attach junk values instead of valid secret shares? Of course, that wouldn\'t be cool! so, there is a zero-knowledge proof for this sake as well where the publishing peer has to prove that the secret shares are generated correctly.\\n\\nA high-level overview of the economic spam protection is shown in Figure 1.\\n\\n## Flow\\n\\nIn this section, we describe the flow of the economic-incentive spam detection mechanism from the viewpoint of a single peer. An overview of this flow is provided in Figure 3.\\n\\n## Setup and Registration\\n\\nA peer willing to publish a message is required to register. Registration is moderated through a smart contract deployed on the Ethereum blockchain. The state of the contract contains the list of registered members\' public keys. An overview of registration is illustrated in Figure 2.\\n\\nFor the registration, a peer creates a transaction that sends x amount of Ether to the contract. The peer who has the \\"private key\\" `sk` associated with that deposit would be able to withdraw x Ether by providing valid proof. Note that `sk` is initially only known by the owning peer however it may get exposed to other peers in case the owner attempts spamming the system i.e., sending more than one message per epoch.\\nThe following relation holds between the `sk` and `pk` i.e., `pk = H(sk)` where `H` denotes a hash function.\\n![Figure 2: Registration](/img/rln-relay/rln-relay.png)\\n\\n## Maintaining the membership Merkle Tree\\n\\nThe ZKP of membership that we mentioned before relies on the representation of the entire group as a [Merkle Tree](/#). The tree construction and maintenance is delegated to the peers (the initial idea was to keep the tree on the chain as part of the contract, however, the cost associated with member deletion and insertion was high and unreasonable, please see [Feasibility and Open Issues](#Feasibility-and-Open-Issues) for more details). As such, each peer needs to build the tree locally and sync itself with the contract updates (peer insertion and deletion) to mirror them on its tree.\\nTwo pieces of information of the tree are important as they enable peers to generate zero-knowledge proofs. One is the root of the tree and the other is the membership proof (or the authentication path). The tree root is public information whereas the membership proof is private data (or more precisely the index of the peer in the tree).\\n\\n## Publishing\\n\\nIn order to publish at a given epoch, each message must carry a proof i.e., a zero-knowledge proof signifying that the publishing peer is a registered member, and has not exceeded the messaging rate at the given epoch.\\n\\nRecall that the enforcement of the messaging rate was through associating a secret shared version of the peer\'s `sk` into the message together with a ZKP that the secret shares are constructed correctly. As for the secret sharing part, the peer generates the following data:\\n\\n1. `shareX`\\n2. `shareY`\\n3. `nullifier`\\n\\nThe pair (`shareX`, `shareY`) is the secret shared version of `sk` that are generated using Shamir secret sharing scheme. Having two such pairs for an identical `nullifier` results in full disclosure of peer\'s `sk` and hence burning the associated deposit. Note that the `nullifier` is a deterministic value derived from `sk` and `epoch` therefore any two messages issued by the same peer (i.e., using the same `sk`) for the same `epoch` are guaranteed to have identical `nullifier`s.\\n\\nFinally, the peer generates a zero-knowledge proof `zkProof` asserting the membership of the peer in the group and the correctness of the attached secret share (`shareX`, `shareY`) and the `nullifier`. In order to generate a valid proof, the peer needs to have two private inputs i.e., its `sk` and its authentication path. Other inputs are the tree root, epoch, and the content of the message.\\n\\n**Privacy Hint:** Note that the authentication path of each peer depends on the recent list of members (hence changes when new peers register or leave). As such, it is recommended (and necessary for privacy/anonymity) that the publisher updates her authentication path based on the latest status of the group and attempts the proof using the updated version.\\n\\nAn overview of the publishing procedure is provided in Figure 3.\\n\\n## Routing\\n\\nUpon the receipt of a message, the routing peer needs to decide whether to route it or not. This decision relies on the following factors:\\n\\n1. If the epoch value attached to the message has a non-reasonable gap with the routing peer\'s current epoch then the message must be dropped (this is to prevent a newly registered peer spamming the system by messaging for all the past epochs).\\n2. The message MUST contain valid proof that gets verified by the routing peer.\\n If the preceding checks are passed successfully, then the message is relayed. In case of an invalid proof, the message is dropped. If spamming is detected, the publishing peer gets slashed (see [Spam Detection and Slashing](#Spam-Detection-and-Slashing)).\\n\\nAn overview of the routing procedure is provided in Figure 3.\\n\\n### Spam Detection and Slashing\\n\\nIn order to enable local spam detection and slashing, routing peers MUST record the `nullifier`, `shareX`, and `shareY` of any incoming message conditioned that it is not spam and has valid proof. To do so, the peer should follow the following steps.\\n\\n1. The routing peer first verifies the `zkProof` and drops the message if not verified.\\n2. Otherwise, it checks whether a message with an identical `nullifier` has already been relayed.\\n - a) If such message exists and its `shareX` and `shareY` components are different from the incoming message, then slashing takes place (if the `shareX` and `shareY` fields of the previously relayed message is identical to the incoming message, then the message is a duplicate and shall be dropped).\\n - b) If none found, then the message gets relayed.\\n\\nAn overview of the slashing procedure is provided in Figure 3.\\n![Figure 3: Publishing, Routing and Slashing workflow.](/img/rln-relay/rln-message-verification.png)\\n\\n## Feasibility and Open Issues\\n\\nWe\'ve come a long way since a year ago, blockers resolved, now we have implemented it end-to-end. We learned lot and could identify further issues and unknowns some of which are blocking getting to production. The summary of the identified issues are presented below.\\n\\n## Storage overhead per peer\\n\\nCurrently, peers are supposed to maintain the entire tree locally and it imposes storage overhead which is linear in the size of the group (see this [issue](https://github.com/vacp2p/research/issues/57)[^11] for more details). One way to cope with this is to use the light-node and full-node paradigm in which only a subset of peers who are more resourceful retain the tree whereas the light nodes obtain the necessary information by interacting with the full nodes. Another way to approach this problem is through a more storage efficient method (as described in this research issue[^12]) where peers store a partial view of the tree instead of the entire tree. Keeping the partial view lowers the storage complexity to O(log(N)) where N is the size of the group. There are still unknown unknowns to this solution, as such, it must be studied further to become fully functional.\\n\\n## Cost-effective way of member insertion and deletion\\n\\nCurrently, the cost associated with RLN-Relay membership is around 30 USD[^10]. We aim at finding a more cost-effective approach. Please feel free to share with us your solution ideas in this regard in this [issue](https://github.com/vacp2p/research/issues/56).\\n\\n## Exceeding the messaging rate via multiple registrations\\n\\nWhile the economic-incentive solution has an economic incentive to discourage spamming, we should note that there is still **expensive attack(s)**[^23] that a spammer can launch to break the messaging rate limit. That is, the attacker can pay for multiple legit registrations e.g., k, hence being able to publish k messages per epoch. We believe that the higher the membership fee is, the less probable would be such an attack, hence a stronger level of spam-protection can be achieved. Following this argument, the high fee associated with the membership (which we listed above as an open problem) can indeed be contributing to a better protection level.\\n\\n## Conclusion and Future Steps\\n\\nAs discussed in this post, Waku RLN Relay can achieve a privacy-preserving economic spam protection through rate-limiting nullifiers. The idea is to financially discourage peers from publishing more than one message per epoch. In specific, exceeding the messaging rate results in a financial charge. Those who violate this rule are called spammers and their messages are spam. The identification of spammers does not rely on any central entity. Also, the financial punishment of spammers is cryptographically guaranteed.\\nIn this solution, privacy is guaranteed since: 1) Peers do not have to disclose any piece of personally identifiable information in any phase i.e., neither in the registration nor in the messaging phase 2) Peers can prove that they have not exceeded the messaging rate in a zero-knowledge manner and without leaving any trace to their membership accounts.\\nFurthermore, all the computations are light hence this solution fits the heterogenous p2p messaging system. Note that the zero-knowledge proof parts are handled through zkSNARKs and the benchmarking result can be found in the RLN benchmark report[^5].\\n\\n**Future steps**:\\n\\nWe are still at the PoC level, and the development is in progress. As our future steps,\\n\\n- we would like to evaluate the running time associated with the Merkle tree operations. Indeed, the need to locally store Merkle tree on each peer was one of the unknowns discovered during this PoC and yet the concrete benchmarking result in this regard is not available.\\n- We would also like to pursue our storage-efficient Merkle Tree maintenance solution in order to lower the storage overhead of peers.\\n- In line with the storage optimization, the full-node light-node structure is another path to follow.\\n- Another possible improvement is to replace the membership contract with a distributed group management scheme e.g., through distributed hash tables. This is to address possible performance issues that the interaction with the Ethereum blockchain may cause. For example, the registration transactions are subject to delay as they have to be mined before being visible in the state of the membership contract. This means peers have to wait for some time before being able to publish any message.\\n\\n## Acknowledgement\\n\\nThanks to Onur K\u0131l\u0131\xe7 for his explanation and pointers and for assisting with development and runtime issues. Also thanks to Barry Whitehat for his time and insightful comments. Special thanks to Oskar Thoren for his constructive comments and his guides during the development of this PoC and the writeup of this post.\\n\\n## References\\n\\n[^1]: Waku v2: https://rfc.vac.dev/spec/10/\\n[^2]: RLN-Relay specification: https://rfc.vac.dev/spec/17/\\n[^3]: RLN documentation: [https://hackmd.io/tMTLMYmTR5eynw2lwK9n1w?both](https://hackmd.io/tMTLMYmTR5eynw2lwK9n1w?both)\\n[^4]: RLN repositories: [https://github.com/kilic/RLN](https://github.com/kilic/RLN) and [https://github.com/kilic/rlnapp](https://github.com/kilic/rlnapp)\\n[^5]: RLN Benchmark: [https://hackmd.io/tMTLMYmTR5eynw2lwK9n1w?view#Benchmarks](https://hackmd.io/tMTLMYmTR5eynw2lwK9n1w?view#Benchmarks)\\n[^6]: Peer Scoring: [https://github.com/libp2p/specs/blob/master/pubsub/gossipsub/gossipsub-v1.1.md#peer-scoring](https://github.com/libp2p/specs/blob/master/pubsub/gossipsub/gossipsub-v1.1.md#peer-scoring)\\n[^7]: Peer scoring security issues: [https://github.com/vacp2p/research/issues/44](https://github.com/vacp2p/research/issues/44)\\n[^8]: Proof of work: [http://www.infosecon.net/workshop/downloads/2004/pdf/clayton.pdf](http://www.infosecon.net/workshop/downloads/2004/pdf/clayton.pdf) and [https://link.springer.com/content/pdf/10.1007/3-540-48071-4_10.pdf](https://link.springer.com/content/pdf/10.1007/3-540-48071-4_10.pdf)\\n[^9]: EIP-627 Whisper: https://eips.ethereum.org/EIPS/eip-627\\n[^10]: Cost-effective way of member insertion and deletion: [https://github.com/vacp2p/research/issues/56](https://github.com/vacp2p/research/issues/56)\\n[^11]: Storage overhead per peer: [https://github.com/vacp2p/research/issues/57](https://github.com/vacp2p/research/issues/57)\\n[^12]: Storage-efficient Merkle Tree maintenance: [https://github.com/vacp2p/research/pull/54](https://github.com/vacp2p/research/pull/54)\\n[^13]: Shamir Secret Sharing Scheme: [https://en.wikipedia.org/wiki/Shamir%27s_Secret_Sharing](https://en.wikipedia.org/wiki/Shamir%27s_Secret_Sharing)\\n[^14]: Zero Knowledge Proof: [https://dl.acm.org/doi/abs/10.1145/3335741.3335750](https://dl.acm.org/doi/abs/10.1145/3335741.3335750) and [https://en.wikipedia.org/wiki/Zero-knowledge_proof](https://en.wikipedia.org/wiki/Zero-knowledge_proof)\\n[^15]: zkSNARKs: [https://link.springer.com/chapter/10.1007/978-3-662-49896-5_11](https://link.springer.com/chapter/10.1007/978-3-662-49896-5_11) and [https://coinpare.io/whitepaper/zcash.pdf](https://coinpare.io/whitepaper/zcash.pdf)\\n[^16]: GossipSub: [https://docs.libp2p.io/concepts/publish-subscribe/](https://docs.libp2p.io/concepts/publish-subscribe/)\\n[^17]: Waku Relay: https://rfc.vac.dev/spec/11/\\n[^18]: Prior blockers of RLN-Relay: [https://vac.dev/feasibility-semaphore-rate-limiting-zksnarks](https://vac.dev/feasibility-semaphore-rate-limiting-zksnarks)\\n[^19]: The lack of Shamir secret sharing in zkSNARKs: [https://github.com/vacp2p/research/issues/10](https://github.com/vacp2p/research/issues/10)\\n[^20]: The MPC required for zkSNARKs trusted setup: [https://github.com/vacp2p/research/issues/9](https://github.com/vacp2p/research/issues/9)\\n[^21]: Prover key size: [https://github.com/vacp2p/research/issues/8](https://github.com/vacp2p/research/issues/8)\\n[^22]: zkSNARKs proof time: [https://github.com/vacp2p/research/issues/7](https://github.com/vacp2p/research/issues/7)\\n[^23]: Attack on the messaging rate: [https://github.com/vacp2p/specs/issues/251](https://github.com/vacp2p/specs/issues/251)"},{"id":"waku-v2-ethereum-messaging","metadata":{"permalink":"/rlog/waku-v2-ethereum-messaging","source":"@site/rlog/2020-11-10-waku-v2-ethereum-messaging.mdx","title":"[Talk] Vac, Waku v2 and Ethereum Messaging","description":"Talk from Taipei Ethereum Meetup. Read on to find out about our journey from Whisper to Waku v2, as well as how Waku v2 can be useful for Etherum Messaging.","date":"2020-11-10T12:00:00.000Z","formattedDate":"November 10, 2020","tags":[],"readingTime":9.51,"hasTruncateMarker":true,"authors":[{"name":"Oskar","twitter":"oskarth","github":"oskarth","key":"oskarth"}],"frontMatter":{"layout":"post","name":"[Talk] Vac, Waku v2 and Ethereum Messaging","title":"[Talk] Vac, Waku v2 and Ethereum Messaging","date":"2020-11-10T12:00:00.000Z","authors":"oskarth","published":true,"slug":"waku-v2-ethereum-messaging","categories":"research","image":"/img/taipei_ethereum_meetup_slide.png","discuss":"https://forum.vac.dev/t/discussion-talk-vac-waku-v2-and-ethereum-messaging/60"},"prevItem":{"title":"Privacy-preserving p2p economic spam protection in Waku v2","permalink":"/rlog/rln-relay"},"nextItem":{"title":"Waku v2 Update","permalink":"/rlog/waku-v2-update"}},"content":"Talk from Taipei Ethereum Meetup. Read on to find out about our journey from Whisper to Waku v2, as well as how Waku v2 can be useful for Etherum Messaging.\\n\\n\x3c!--truncate--\x3e\\n\\n_The following post is a transcript of the talk given at the [Taipei Ethereum meetup, November 5](https://www.meetup.com/Taipei-Ethereum-Meetup/events/274033344/). There is also a [video recording](https://www.youtube.com/watch?v=lUDy1MoeYnI)._\\n\\n---\\n\\n## 0. Introduction\\n\\nHi! My name is Oskar and I\'m the protocol research lead at Vac. This talk will be divided into two parts. First I\'ll talk about the journey from Whisper, to Waku v1 and now to Waku v2. Then I\'ll talk about messaging in Ethereum. After this talk, you should have an idea of what Waku v2 is, the problems it is trying to solve, as well as where it can be useful for messaging in Ethereum.\\n\\n## PART 1 - VAC AND THE JOURNEY FROM WHISPER TO WAKU V1 TO WAKU V2\\n\\n## 1. Vac intro\\n\\nFirst, what is Vac? Vac grew out of our efforts Status to create a window on to Ethereum and secure messenger. Vac is modular protocol stack for p2p secure messaging, paying special attention to resource restricted devices, privacy and censorship resistance.\\n\\nToday we are going to talk mainly about Waku v2, which is the transport privacy / routing aspect of the Vac protocol stack. It sits \\"above\\" the p2p overlay, such as libp2p dealing with transports etc, and below a conversational security layer dealing with messaging encryption, such as using Double Ratchet etc.\\n\\n## 2. Whisper to Waku v1\\n\\nIn the beginning, there was Whisper. Whisper was part of the holy trinity of Ethereum. You had Ethereum for consensus/computation, Whisper for messaging, and Swarm for storage.\\n\\nHowever, for various reasons, Whisper didn\'t get the attention it deserved. Development dwindled, it promised too much and it suffered from many issues, such as being extremely inefficient and not being suitable for running on e.g. mobile phone. Despite this, Status used it in its app from around 2017 to 2019. As far as I know, it was one of very few, if not the only, production uses of Whisper.\\n\\nIn an effort to solve some of its immediate problems, we forked Whisper into Waku and formalized it with a proper specification. This solved immediate bandwidth issues for light nodes, introduced rate limiting for better spam protection, improved historical message support, etc.\\n\\nIf you are interested in this journey, checkout the [EthCC talk Dean and I gave in Paris earlier this year](https://www.youtube.com/watch?v=6lLT33tsJjs).\\n\\nStatus upgraded to Waku v1 early 2020. What next?\\n\\n## 3. Waku v1 to v2\\n\\nWe were far from done. The changes we had made were quite incremental and done in order to get tangible improvements as quickly as possible. This meant we couldn\'t address more fundamental issues related to full node routing scalability, running with libp2p for more transports, better security, better spam protection and incentivization.\\n\\nThis kickstarted Waku v2 efforts, which is what we\'ve been working on since July. This work was and is initally centered around a few pieces:\\n\\n(a) Moving to libp2p\\n\\n(b) Better routing\\n\\n(c) Accounting and user-run nodes\\n\\nThe general theme was: making the Waku network more scalable and robust.\\n\\nWe also did a scalability study to show at what point the network would run into issues, due to the inherent lack of routing that Whisper and Waku v1 provided.\\n\\nYou can read more about this [here](https://vac.dev/waku-v2-plan).\\n\\n## 3.5 Waku v2 - Design goals\\n\\nTaking a step back, what problem does Waku v2 attempt to solve compared to all the other solutions that exists out there? What type of applications should use it and why? We have the following design goals:\\n\\n1. **Generalized messaging**. Many applications requires some form of messaging protocol to communicate between different subsystems or different nodes. This messaging can be human-to-human or machine-to-machine or a mix.\\n\\n2. **Peer-to-peer**. These applications sometimes have requirements that make them suitable for peer-to-peer solutions.\\n\\n3. **Resource restricted**. These applications often run in constrained environments, where resources or the environment is restricted in some fashion. E.g.:\\n\\n - limited bandwidth, CPU, memory, disk, battery, etc\\n - not being publicly connectable\\n - only being intermittently connected; mostly-offline\\n\\n4. **Privacy**. These applications have a desire for some privacy guarantees, such as pseudonymity, metadata protection in transit, etc.\\n\\nAs well as to do so in a modular fashion. Meaning you can find a reasonable trade-off depending on your exact requirements. For example, you usually have to trade off some bandwidth to get metadata protection, and vice versa.\\n\\nThe concept of designing for resource restricted devices also leads to the concept of adaptive nodes, where you have more of a continuum between full nodes and light nodes. For example, if you switch your phone from mobile data to WiFi you might be able to handle more bandwidth, and so on.\\n\\n## 4. Waku v2 - Breakdown\\n\\nWhere is Waku v2 at now, and how is it structured?\\n\\nIt is running over libp2p and we had our second internal testnet last week or so. As a side note, we name our testnets after subway stations in Taipei, the first one being Nangang, and the most recent one being Dingpu.\\n\\nThe main implementation is written in Nim using nim-libp2p, which is also powering Nimbus, an Ethereum 2 client. There is also a PoC for running Waku v2 in the browser. On a spec level, we have the following specifications that corresponds to the components that make up Waku v2:\\n\\n- Waku v2 - this is the main spec that explains the goals of providing generalized messaging, in a p2p context, with a focus on privacy and running on resources restricted devices.\\n- Relay - this is the main PubSub spec that provides better routing. It builds on top of GossipSub, which is what Eth2 heavily relies on as well.\\n- Store - this is a 1-1 protocol for light nodes to get historical messages, if they are mostly-offline.\\n- Filter - this is a 1-1 protocol for light nodes that are bandwidth restricted to only (or mostly) get messages they care about.\\n- Message - this explains the payload, to get some basic encryption and content topics. It corresponds roughly to envelopes in Whisper/Waku v1.\\n- Bridge - this explains how to do bridging between Waku v1 and Waku v2 for compatibility.\\n\\nRight now, all protocols, with the exception of bridge, are in draft mode, meaning they have been implemented but are not yet being relied upon in production.\\n\\nYou can read more about the breakdown in this [update](https://vac.dev/waku-v2-update) though some progress has been made since then, as well was in the [main Waku v2 spec](https://rfc.vac.dev/spec/10).\\n\\n## 5. Waku v2 - Upcoming\\n\\nWhat\'s coming up next? There are a few things.\\n\\nFor Status to use it in production, it needs to be integrated into the main app using the Nim Node API. The bridge also needs to be implemented and tested.\\n\\nFor other users, we are currently overhauling the API to allow usage from a browser, e.g. To make this experience great, there are also a few underlying infrastructure things that we need in nim-libp2p, such as a more secure HTTP server in Nim, Websockets and WebRTC support.\\n\\nThere are also some changes we made to at what level content encryption happens, and this needs to be made easier to use in the API. This means you can use a node without giving your keys to it, which is useful in some environments.\\n\\nMore generally, beyond getting to production-ready use, there are a few bigger pieces that we are working on or will work on soon. These are things like:\\n\\n- Better scaling, by using topic sharding.\\n- Accounting and user-run nodes, to account for and incentives full nodes.\\n- Stronger and more rigorous privacy guarantees, e.g. through study of GossipSub, unlinkable packet formats, etc.\\n- Rate Limit Nullifier for privacy preserving spam protection, a la what Barry Whitehat has presented before.\\n\\nAs well as better support for Ethereum M2M Messaging. Which is what I\'ll talk about next.\\n\\n## PART 2 - ETHEREUM MESSAGING\\n\\nA lot of what follows is inspired by exploratory work that John Lea has done at Status, previously Head of UX Architecture at Ubuntu.\\n\\n## 6. Ethereum Messaging - Why?\\n\\nIt is easy to think that Waku v2 is only for human to human messaging, since that\'s how Waku is currently primarily used in the Status app. However, the goal is to be useful for generalized messaging, which includes other type of information as well as machine to machine messaging.\\n\\nWhat is Ethereum M2M messaging? Going back to the Holy Trinity of Ethereum/Whisper/Swarm, the messaging component was seen as something that could facilitate messages between dapps and acts as a building block. This can help with things such as:\\n\\n- Reducing on-chain transactions\\n- Reduce latency for operations\\n- Decentralize centrally coordinated services (like WalletConnect)\\n- Improve UX of dapps\\n- Broadcast live information\\n- A message transport layer for state channels\\n\\nAnd so on.\\n\\n## 7. Ethereum Messaging - Why? (Cont)\\n\\nWhat are some examples of practical things Waku as used for Ethereum Messaging could solve?\\n\\n- Multisig transfers only needing one on chain transaction\\n- DAO votes only needing one one chain transaction\\n- Giving dapps ability to direct push notifications to users\\n- Giving users ability to directly respond to requests from daps\\n- Decentralized Wallet Connect\\n\\nEtc.\\n\\n## 8. What\'s needed to deliver this?\\n\\nWe can break it down into our actors:\\n\\n- Decentralized M2M messaging system (Waku)\\n- Native wallets (Argent, Metamask, Status, etc)\\n- Dapps that benefit from M2M messaging\\n- Users whose problems are being solved\\n\\nEach of these has a bunch of requirements in turn. The messaging system needs to be decentralized, scalable, robust, etc. Wallets need support for messaging layer, dapps need to integrate this, etc.\\n\\nThis is a lot! Growing adoption is a challenge. There is a catch 22 in terms of justifying development efforts for wallets, when no dapps need it, and likewise for dapps when no wallets support Waku. In addition to this, there must be proven usage of Waku before it can be relied on, etc. How can we break this up into smaller pieces of work?\\n\\n## 9. Breaking up the problem and a high level roadmap\\n\\nWe can start small. It doesn\'t and need to be used for critical features first. A more hybrid approach can be taken where it acts more as nice-to-haves.\\n\\n1. Forking Whisper and solving scalablity, spam etc issues with it.\\n This is a work in progress. What we talked about in part 1.\\n2. Expose messaging API for Dapp developers.\\n3. Implement decentralized version of WalletConnect.\\n Currently wallets connect ot dapps with centralized service. Great UX.\\n4. Solve DAO/Multi-Sig coordination problem.\\n E.g. send message to wallet-derived key when it is time to sign a transaction.\\n5. Extend dapp-to-user and user-to-dapp communication to more dapps.\\n Use lessons learned and examples to drive adoptation for wallets/dapps.\\n\\nAnd then build up from there.\\n\\n## 10. We are hiring!\\n\\nA lot of this will happen in Javascript and browsers, since that\'s the primarily environment for a lot of wallets and dapps. We are currently hiring for a Waku JS Wallet integration lead to help push this effort further.\\n\\nCome talk to me after or [apply here](https://status.im/our_team/open_positions.html?gh_jid=2385338).\\n\\nThat\'s it! You can find us on Status, Telegram, vac.dev. I\'m on twitter [here](https://twitter.com/oskarth).\\n\\nQuestions?\\n\\n---"},{"id":"waku-v2-update","metadata":{"permalink":"/rlog/waku-v2-update","source":"@site/rlog/2020-09-28-waku-v2-update.mdx","title":"Waku v2 Update","description":"A research log. Read on to find out what is going on with Waku v2, a messaging protocol. What has been happening? What is coming up next?","date":"2020-09-28T12:00:00.000Z","formattedDate":"September 28, 2020","tags":[],"readingTime":7.435,"hasTruncateMarker":true,"authors":[{"name":"Oskar","twitter":"oskarth","github":"oskarth","key":"oskarth"}],"frontMatter":{"layout":"post","name":"Waku v2 Update","title":"Waku v2 Update","date":"2020-09-28T12:00:00.000Z","authors":"oskarth","published":true,"slug":"waku-v2-update","categories":"research","discuss":"https://forum.vac.dev/t/discussion-waku-v2-update/56"},"prevItem":{"title":"[Talk] Vac, Waku v2 and Ethereum Messaging","permalink":"/rlog/waku-v2-ethereum-messaging"},"nextItem":{"title":"What\'s the Plan for Waku v2?","permalink":"/rlog/waku-v2-plan"}},"content":"A research log. Read on to find out what is going on with Waku v2, a messaging protocol. What has been happening? What is coming up next?\\n\\n\x3c!--truncate--\x3e\\n\\nIt has been a while since the last post. It is time for an update on Waku v2. Aside from getting more familiar with libp2p (specifically nim-libp2p) and some vacation, what have we been up to? In this post we\'ll talk about what we\'ve gotten done since last time, and briefly talk about immediate next steps and future. But first, a recap.\\n\\n## Recap\\n\\nIn the last post ([Waku v2 plan](https://vac.dev/waku-v2-plan)) we explained the rationale of Waku v2 - the current Waku network is fragile and doesn\'t scale. To solve this, Waku v2 aims to reduce amplification factors and get more user run nodes. We broke the work down into three separate tracks.\\n\\n1. Track 1 - Move to libp2p\\n2. Track 2 - Better routing\\n3. Track 3 - Accounting and user-run nodes\\n\\nAs well as various rough components for each track. The primary initial focus is track 1. This means things like: moving to FloodSub, simplify the protocol, core integration, topic interest behavior, historical message caching, and Waku v1<\\\\>v2 bridge.\\n\\n## Current state\\n\\nLet\'s talk about the state of specs and our main implementation nim-waku. Then we\'ll go over our recent testnet, Nangang, and finish off with a Web PoC.\\n\\n## Specs\\n\\nAfter some back and forth on how to best structure things, we ended up breaking down the specs into a few pieces. While Waku v2 is best thought of as a cohesive whole in terms of its capabilities, it is made up of several protocols. Here\'s a list of the current specs and their status:\\n\\n- [Main spec](https://rfc.vac.dev/spec/10/) (draft)\\n- [Relay protocol spec](https://rfc.vac.dev/spec/11/) (draft)\\n- [Filter protocol spec](https://rfc.vac.dev/spec/12) (raw)\\n- [Store protocol spec](https://rfc.vac.dev/spec/13) (raw)\\n- [Bridge spec](https://rfc.vac.dev/spec/15/) (raw)\\n\\nRaw means there is not yet an implementation that corresponds fully to the spec, and draft means there is an implementation that corresponds to the spec. In the interest of space, we won\'t go into too much detail on the specs here except to note a few things:\\n\\n- The relay spec is essentially a thin wrapper on top of PubSub/FloodSub/GossipSub\\n- The filter protocol corresponds to previous light client mode in Waku v1\\n- The store protocol corresponds to the previous mailserver construct in Waku v1\\n\\nThe filter and store protocol allow for adaptive nodes, i.e. nodes that have various capabilities. For example, a node being mostly offline, or having limited bandwidth capacity. The bridge spec outlines how to bridge the Waku v1 and v2 networks.\\n\\n## Implementation\\n\\nThe main implementation we are working on is [nim-waku](https://github.com/status-im/nim-waku/). This builds on top of libraries such as [nim-libp2p](https://github.com/status-im/nim-libp2p) and others that the [Nimbus team](https://nimbus.team/) have been working on as part of their Ethereum 2.0 client.\\n\\nCurrently nim-waku implements the relay protocol, and is close to implementing filter and store protocol. It also exposes a [Nim Node API](https://github.com/status-im/nim-waku/blob/master/docs/api/v2/node.md) that allows libraries such as [nim-status](https://github.com/status-im/status-nim) to use it. Additionally, there is also a rudimentary JSON RPC API for command line scripting.\\n\\n## Nangang testnet\\n\\nLast week we launched a very rudimentary internal testnet called Nangang. The goal was to test basic connectivity and make sure things work end to end. It didn\'t have things like: client integration, encryption, bridging, multiple clients, store/filter protocol, or even a real interface. What it did do is allow Waku developers to \\"chat\\" via RPC calls and looking in the log output. Doing this meant we exposed and fixed a few blockers, such as connection issues, deployment, topic subscription management, protocol and node integration, and basic scripting/API usage. After this, we felt confident enough to upgrade the main and relay spec to \\"draft\\" status.\\n\\n## Waku Web PoC\\n\\nAs a bonus, we wanted to see what it\'d take to get Waku running in a browser. This is a very powerful capability that enables a lot of use cases, and something that libp2p enables with its multiple transport support.\\n\\nUsing the current stack, with nim-waku, would require quite a lot of ground work with WASM, WebRTC, Websockets support etc. Instead, we decided to take a shortcut and hack together a JS implementation called [Waku Web Chat](https://github.com/vacp2p/waku-web-chat/). This quick hack wouldn\'t be possible without the people behind [js-libp2p-examples](https://github.com/libp2p/js-libp2p-examples/) and [js-libp2p](https://github.com/libp2p/js-libp2p) and all its libraries. These are people like Jacob Heun, Vasco Santos, and Cayman Nava. Thanks!\\n\\nIt consists of a brower implementation, a NodeJS implementation and a bootstrap server that acts as a signaling server for WebRTC. It is largely a bastardized version of GossipSub, and while it isn\'t completely to spec, it does allow messages originating from a browser to eventually end up at a nim-waku node, and vice versa. Which is pretty cool.\\n\\n## Coming up\\n\\nNow that we know what the current state is, what is still missing? what are the next steps?\\n\\n## Things that are missing\\n\\nWhile we are getting closer to closing out work for track 1, there are still a few things missing from the initial scope:\\n\\n1. Store and filter protocols need to be finished. This means basic spec, implementation, API integration and proven to work in a testnet. All of these are work in progress and expected to be done very soon. Once the store protocol is done in a basic form, it needs further improvements to make it production ready, at least on a spec/basic implementation level.\\n\\n2. Core integration was mentioned in scope for track 1 initially. This work has stalled a bit, largely due to organizational bandwidth and priorities. While there is a Nim Node API that in theory is ready to be used, having it be used in e.g. Status desktop or mobile app is a different matter. The team responsible for this at Status ([status-nim](https://github.com/status-im/status-nim) has been making progress on getting nim-waku v1 integrated, and is expected to look into nim-waku v2 integration soon. One thing that makes this a especially tricky is the difference in interface between Waku v1 and v2, which brings\\n us too...\\n\\n3. Companion spec for encryption. As part of simplifying the protocol, the routing is decoupled from the encryption in v2 ([1](https://github.com/vacp2p/specs/issues/158), [2](https://github.com/vacp2p/specs/issues/181)). There are multiple layers of encryption at play here, and we need to figure out a design that makes sense for various use cases (dapps using Waku on their own, Status app, etc).\\n\\n4. Bridge implementation. The spec is done and we know how it should work, but it needs to be implemented.\\n\\n5. General tightening up of specs and implementation.\\n\\nWhile this might seem like a lot, a lot has been done already, and the majority of the remaining tasks are more amendable to be pursued in parallel with other efforts. It is also worth mentioning that part of track 2 and 3 have been started, in the form of moving to GossipSub (amplification factors) and basics of adaptive nodes (multiple protocols). This is in addition to things like Waku Web which were not part of the initial scope.\\n\\n## Upcoming\\n\\nAside from the things mentioned above, what is coming up next? There are a few areas of interest, mentioned in no particular order. For track 2 and 3, see previous post for more details.\\n\\n1. Better routing (track 2). While we are already building on top of GossipSub, we still need to explore things like topic sharding in more detail to further reduce amplification factors.\\n\\n2. Accounting and user-run nodes (track 3). With store and filter protocol getting ready, we can start to implement accounting and light connection game for incentivization in a bottom up and iterative manner.\\n\\n3. Privacy research. Study better and more rigorous privacy guarantees. E.g. how FloodSub/GossipSub behaves for common threat models, and how custom packet\\n format can improve things like unlinkability.\\n\\n4. zkSnarks RLN for spam protection and incentivization. We studied this [last year](https://vac.dev/feasibility-semaphore-rate-limiting-zksnarks) and recent developments have made this relevant to study again. Create an [experimental spec/PoC](https://github.com/vacp2p/specs/issues/189) as an extension to the relay protocol. Kudos to Barry Whitehat and others like Kobi Gurkan and Koh Wei Jie for pushing this!\\n\\n5. Ethereum M2M messaging. Being able to run in the browser opens up a lot of doors, and there is an opportunity here to enable things like a decentralized WalletConnect, multi-sig transactions, voting and similar use cases. This was the original goal of Whisper, and we\'d like to deliver on that.\\n\\nAs you can tell, quite a lot of thing! Luckily, we have two people joining as protocol engineers soon, which will bring much needed support for the current team of ~2-2.5 people. More details to come in further updates.\\n\\n---\\n\\nIf you are feeling adventurous and want to use early stage alpha software, check out the [docs](https://github.com/status-im/nim-waku/tree/master/docs). If you want to read the specs, head over to [Waku spec](https://rfc.vac.dev/spec/10/). If you want to talk with us, join us on [Status](https://get.status.im/chat/public/vac) or on [Telegram](https://t.me/vacp2p) (they are bridged)."},{"id":"waku-v2-plan","metadata":{"permalink":"/rlog/waku-v2-plan","source":"@site/rlog/2020-07-01-waku-v2-pitch.mdx","title":"What\'s the Plan for Waku v2?","description":"Read about our plans for Waku v2, moving to libp2p, better routing, adaptive nodes and accounting!","date":"2020-07-01T12:00:00.000Z","formattedDate":"July 1, 2020","tags":[],"readingTime":13.7,"hasTruncateMarker":true,"authors":[{"name":"Oskar","twitter":"oskarth","github":"oskarth","key":"oskarth"}],"frontMatter":{"layout":"post","name":"What\'s the Plan for Waku v2?","title":"What\'s the Plan for Waku v2?","date":"2020-07-01T12:00:00.000Z","authors":"oskarth","published":true,"slug":"waku-v2-plan","categories":"research","image":"/img/status_scaling_model_fig4.png","discuss":"https://forum.vac.dev/t/waku-version-2-pitch/52"},"prevItem":{"title":"Waku v2 Update","permalink":"/rlog/waku-v2-update"},"nextItem":{"title":"Feasibility Study: Discv5","permalink":"/rlog/feasibility-discv5"}},"content":"Read about our plans for Waku v2, moving to libp2p, better routing, adaptive nodes and accounting!\\n\\n\x3c!--truncate--\x3e\\n\\n**tldr: The Waku network is fragile and doesn\'t scale. Here\'s how to solve it.**\\n\\n_NOTE: This post was originally written with Status as a primary use case in mind, which reflects how we talk about some problems here. However, Waku v2 is a general-purpose private p2p messaging protocol, especially for people running in resource restricted environments._\\n\\n## Problem\\n\\nThe Waku network is fragile and doesn\'t scale.\\n\\nAs [Status](https://status.im) is moving into a user-acquisition phase and is improving retention rates for users they need the infrastructure to keep up, specifically when it comes to messaging.\\n\\nBased on user acquisition models, the initial goal is to support 100k DAU in September, with demand growing from there.\\n\\nWith the Status Scaling Model we have studied the current bottlenecks as a function of concurrent users (CCU) and daily active users (DAU). Here are the conclusions.\\n\\n\\\\***\\\\*1. Connection limits\\\\*\\\\***. With 100 full nodes we reach ~10k CCU based on connection limits. This can primarily be addressed by increasing the number of nodes (cluster or user operated). This assumes node discovery works. It is also worth investigating the limitations of max number of connections, though this is likely to be less relevant for user-operated nodes. For a user-operated network, this means 1% of users have to run a full node. See Fig 1-2.\\n\\n\\\\***\\\\*2. Bandwidth as a bottleneck\\\\*\\\\***. We notice that memory usage appears to not be\\nthe primary bottleneck for full nodes, and the bottleneck is still bandwidth. To support 10k DAU, and full nodes with an amplification factor of 25 the required Internet speed is ~50 Mbps, which is a fast home Internet connection. For ~100k DAU only cloud-operated nodes can keep up (500 Mbps). See Fig 3-5.\\n\\n\\\\***\\\\*3. Amplification factors\\\\*\\\\***. Reducing amplification factors with better routing, would have a high impact, but it is likely we\'d need additional measures as well, such as topic sharding or similar. See Fig 8-13.\\n\\nFigure 1-5:\\n\\n![](/img/status_scaling_model_fig1.png)\\n![](/img/status_scaling_model_fig2.png)\\n![](/img/status_scaling_model_fig3.png)\\n![](/img/status_scaling_model_fig4.png)\\n![](/img/status_scaling_model_fig5.png)\\n\\nSee for the full report.\\n\\nWhat we need to do is:\\n\\n1. Reduce amplification factors\\n2. Get more user-run full nodes\\n\\nDoing this means the Waku network will be able to scale, and doing so in the right way, in a robust fashion. What would a fragile way of scaling be? Increasing our reliance on a Status Pte Ltd operated cluster which would paint us in a corner where we:\\n\\n- keep increasing requirements for Internet speed for full nodes\\n- are vulnerable to censorship and attacks\\n- have to control the topology in an artifical manner to keep up with load\\n- basically re-invent a traditional centralized client-server app with extra steps\\n- deliberately ignore most of our principles\\n- risk the network being shut down when we run out of cash\\n\\n## Appetite\\n\\nOur initial risk appetite for this is 6 weeks for a small team.\\n\\nThe idea is that we want to make tangible progress towards the goal in a limited period of time, as opposed to getting bogged down in trying to find a theoretically perfect generalized solution. Fixed time, variable scope.\\n\\nIt is likely some elements of a complete solution will be done separately. See later sections for that.\\n\\n## Solution\\n\\nThere are two main parts of the solution. One is to reduce amplification factors, and the other is incentivization to get more user run full nodes with desktop, etc.\\n\\nWhat does a full node provide? It provides connectivity to the network, can act as a bandwidth \\"barrier\\" and be high or reasonably high availability. What this means right now is essentially topic interest and storing historical messages.\\n\\nThe goal is here to improve the status quo, not get a perfect solution from the get go. All of this can be iterated on further, for stronger guarantees, as well as replaced by other new modules.\\n\\nLet\'s first look at the baseline, and then go into some of the tracks and their phases. Track 1 is best done first, after which track 2 and 3 can be executed in parallel. Track 1 gives us more options for track 2 and 3. The work in track 1 is currently more well-defined, so it is likely the specifics of track 2 and 3 will get refined at a later stage.\\n\\n## Baseline\\n\\nHere\'s where we are at now. In reality, the amplification factor are likely even worse than this (15 in the graph below), up to 20-30. Especially with an open network, where we can\'t easily control connectivity and availability of nodes. Left unchecked, with a full mesh, it could even go as high x100, though this is likely excessive and can be dialed down. See scaling model for more details.\\n\\n![](/img/waku_v1_routing_small.png)\\n\\n## Track 1 - Move to libp2p\\n\\nMoving to PubSub over libp2p wouldn\'t improve amplification per se, but it would be stepping stone. Why? It paves the way for GossipSub, and would be a checkpoint on this journey. Additionally, FloodSub and GossipSub are compatible, and very likely other future forms of PubSub such as GossipSub 1.1 (hardened/more secure), EpiSub, forwarding Kademlia / PubSub over Kademlia, etc. Not to mention security This would also give us access to the larger libp2p ecosystem (multiple protocols, better encryption, quic, running in the browser, security audits, etc, etc), as well as be a joint piece of infrastructured used for Eth2 in Nimbus. More wood behind fewer arrows.\\n\\nSee more on libp2p PubSub here: \\n\\nAs part of this move, there are a few individual pieces that are needed.\\n\\n### 1. FloodSub\\n\\nThis is essentially what Waku over libp2p would look like in its most basic form.\\n\\nOne difference that is worth noting is that the app topics would **not** be the same as Waku topics. Why? In Waku we currently don\'t use topics for routing between full nodes, but only for edge/light nodes in the form of topic interest. In FloodSub, these topics are used for routing.\\n\\nWhy can\'t we use Waku topics for routing directly? PubSub over libp2p isn\'t built for rare and ephemeral topics, and nodes have to explicitly subscribe to a topic. See topic sharding section for more on this.\\n\\n![](/img/waku_v2_routing_flood_small.png)\\n\\nMoving to FloodSub over libp2p would also be an opportunity to clean up and simplify some components that are no longer needed in the Waku v1 protocol, see point below.\\n\\nVery experimental and incomplete libp2p support can be found in the nim-waku repo under v2: \\n\\n### 2. Simplify the protocol\\n\\nDue to Waku\'s origins in Whisper, devp2p and as a standalone protocol, there are a lot of stuff that has accumulated (). Not all of it serves it purpose anymore. For example, do we still need RLP here when we have Protobuf messages? What about extremely low PoW when we have peer scoring? What about key management / encryption when have encryption at libp2p and Status protocol level?\\n\\nNot everything has to be done in one go, but being minimalist at this stage will the protocol lean and make us more adaptable.\\n\\nThe essential characteristic that has to be maintained is that we don\'t need to change the upper layers, i.e. we still deal with (Waku) topics and some envelope like data unit.\\n\\n### 3. Core integration\\n\\nAs early as possible we want to integrate with Core via Stimbus in order to mitigate risk and catch integration issues early in the process. What this looks like in practice is some set of APIs, similar to how Whisper and Waku were working in parallel, and experimental feature behind a toggle in core/desktop.\\n\\n### 4. Topic interest behavior\\n\\nWhile we target full node traffic here, we want to make sure we maintain the existing bandwidth requirements for light nodes that Waku v1 addressed (). This means implementing topic-interest in the form of Waku topics. Note that this would be separate from app topics notes above.\\n\\n### 5. Historical message caching\\n\\nBasically what mailservers are currently doing. This likely looks slightly different in a libp2p world. This is another opportunity to simplify things with a basic REQ-RESP architecture, as opposed to the roundabout way things are now. Again, not everything has to be done in one go but there\'s no reason to reimplement a poor API if we don\'t have to.\\n\\nAlso see section below on adaptive nodes and capabilities.\\n\\n### 6. Waku v1 <\\\\> Libp2p bridge\\n\\nTo make the transition complete, there has to a be bridge mode between current Waku and libp2p. This is similar to what was done for Whisper and Waku, and allows any nodes in the network to upgrade to Waku v2 at their leisure. For example, this would likely look different for Core, Desktop, Research and developers.\\n\\n## Track 2 - Better routing\\n\\nThis is where we improve the amplification factors.\\n\\n### 1. GossipSub\\n\\nThis is a subprotocol of FloodSub in the libp2p world. Moving to GossipSub would allow traffic between full nodes to go from an amplification factor of ~25 to ~6. This basically creates a mesh of stable bidirectional connections, together with some gossiping capabilities outside of this view.\\n\\nExplaining how GossipSub works is out of scope of this document. It is implemented in nim-libp2p and used by Nimbus as part of Eth2. You can read the specs here in more detail if you are interested: and \\n\\n![](/img/waku_v2_routing_gossip_small.png)\\n\\n![](/img/status_scaling_model_fig8.png)\\n![](/img/status_scaling_model_fig9.png)\\n![](/img/status_scaling_model_fig10.png)\\n![](/img/status_scaling_model_fig11.png)\\n\\nWhile we technically could implement this over existing Waku, we\'d have to re-implement it, and we\'d lose out on all the other benefits libp2p would provide, as well as the ecosystem of people and projects working on improving the scalability and security of these protocols.\\n\\n### 2. Topic sharding\\n\\nThis one is slightly more speculative in terms of its ultimate impact. The basic idea is to split the application topic into N shards, say 10, and then each full node can choose which shards to listen to. This can reduce amplification factors by another factor of 10.\\n\\n![](/img/waku_v2_routing_sharding_small.png)\\n\\n![](/img/status_scaling_model_fig12.png)\\n![](/img/status_scaling_model_fig13.png)\\n\\nNote that this means a light node that listens to several topics would have to be connected to more full nodes to get connectivity. For a more exotic version of this, see \\n\\nThis is orthogonal from the choice of FloodSub or GossipSub, but due to GossipSub\'s more dynamic nature it is likely best combined with it.\\n\\n### 3. Other factors\\n\\nNot a primary focus, but worth a look. Looking at the scaling model, there might be other easy wins to improve overall bandwidth consumption between full nodes. For example, can we reduce envelope size by a significant factor?\\n\\n## Track 3 - Accounting and user-run nodes\\n\\nThis is where we make sure the network isn\'t fragile, become a true p2p app, get our users excited and engaged, and allow us to scale the network without creating an even bigger cluster.\\n\\nTo work in practice, this has a soft dependency on node discovery such as DNS based discovery () or Discovery v5 ().\\n\\n### 1. Adaptive nodes and capabilities\\n\\nWe want to make the gradation between light nodes, full nodes, storing (partial set of) historical messages, only acting for a specific shard, etc more flexible and explicit. This is required to identify and discover the nodes you want. See \\n\\nDepending on how the other tracks come together, this design should allow for a desktop node to identify as a full relaying node for some some app topic shard, but also express waku topic interest and retrieve historical messages itself.\\n\\nE.g. Disc v5 can be used to supply node properties through ENR.\\n\\n### 2. Accounting\\n\\nThis is based on a few principles:\\n\\n1. Some nodes contribute a lot more than other nodes in the network\\n2. We can account for the difference in contribution in some fashion\\n3. We want to incentivize nodes to tell the true, and be incentivized not to lie\\n\\nAccounting here is a stepping stone, where accounting is the raw data upon which some settlement later occurs. It can have various forms of granularity. See for discussion.\\n\\nWe also note that in GossipSub, the mesh is bidrectional. Additionally, it doesn\'t appears to be a high priority issue in terms of nodes misreporting. What is an issue is having people run full nodes in the first place. There are a few points to that. It has to be possible in the end-user UX, nodes have to be discovered, and it has to be profitable/visible that you are contributing. UX and discovery are out of scope for this work, whereas visibility/accounting is part of this scope. Settlement is a stretch goal here.\\n\\nThe general shape of the solution is inspired by the Swarm model, where we do accounting separate from settlement. It doesn\'t require any specific proofs, but nodes are incentivized to tell the truth in the following way:\\n\\n1. Both full node and light node do accounting in a pairwise, local fashion\\n2. If a light node doesn\'t ultimately pay or lie about reporting, they get disconnected (e.g.)\\n3. If a full node doesn\'t provide its service the light node may pick another full node (e.g.)\\n\\nWhile accounting for individual resource usage is useful, for the ultimate end user experience we can ideally account for other things such as:\\n\\n- end to end delivery\\n- online time\\n- completeness of storage\\n\\nThis can be gradually enhanced and strengthened, for example with proofs, consistency checks, Quality of Service, reputation systems. See for one attempt to provide stronger guarantees with periodic consistency checks and a shared fund mechanism. And for using validity proofs and removing liveness requirement for settlement.\\n\\nAll of this is optional at this stage, because our goal here is to improve the status quo for user run nodes. Accounting at this stage should be visible and correspond to the net benefit a node provides to another.\\n\\nAs a concrete example: a light node has some topic interest and cares about historical messages on some topic. A full node communicates envelopes as they come in, communicates their high availability (online time) and stores/forward stored messages. Both nodes have this information, and if they agree settlement (initially just a mock message) can be sending a payment to an address at some time interval / over some defined volume. See future sections for how this can be improved upon.\\n\\nAlso see below in section 4, using constructs such as eigentrust as a local reputation mechanism.\\n\\n### 3. Relax high availability requirement\\n\\nIf we want desktop nodes to participate in the storing of historical messages, high availability is a problem. It is a problem for any node, especially if they lie about it, but assuming they are honest it is still an issue.\\n\\nBy being connected to multiple nodes, we can get an overlapping online window. Then these can be combined together to get consistency. This is obviously experimental and would need to be tested before being deployed, but if it works it\'d be very useful.\\n\\nAdditionally or alternatively, instead of putting a high requirement on message availability, focus on detection of missing information. This likely requires re-thinking how we do data sync / replication.\\n\\n### 4. Incentivize light and full nodes to tell the truth (policy, etc)\\n\\nIn accounting phase it is largely assumed nodes are honest. What happens when they lie, and how do we incentivize them to be honest? In the case of Bittorrent this is done with tit-for-tat, however this is a different kind of relationship. What follows are some examples of how this can be done.\\n\\nFor light nodes:\\n\\n- if they don\'t, they get disconnected\\n- prepayment (especially to \\"high value\\" nodes)\\n\\nFor full nodes:\\n\\n- multiple nodes reporting to agree, where truth becomes a shelling point\\n- use eigentrust\\n- staking for discovery visibility with slashing\\n\\n### 5. Settlement PoC\\n\\nCan be done after phase 2 if so desired. Basically integrate payments based on accounting and policy.\\n\\n## Out of scope\\n\\n1. We assume the Status Base model requirements are accurate.\\n2. We assume Core will improve retention rates.\\n3. We assume the Stimbus production team will enable integration of nim-waku.\\n4. We assume Discovery mechanisms such as DNS and Discovery v5 will be worked on separately.\\n5. We assume Core will, at some point, provide an UX for integrating payment of services.\\n6. We assume the desktop client is sufficiently usable.\\n7. We assume Core and Infra will investigate ways of improving MaxPeers."},{"id":"feasibility-discv5","metadata":{"permalink":"/rlog/feasibility-discv5","source":"@site/rlog/2020-04-27-feasibility-discv5.mdx","title":"Feasibility Study: Discv5","description":"Looking at discv5 and the theoretical numbers behind finding peers.","date":"2020-04-27T12:00:00.000Z","formattedDate":"April 27, 2020","tags":[],"readingTime":5.655,"hasTruncateMarker":true,"authors":[{"name":"Dean","twitter":"DeanEigenmann","github":"decanus","website":"https://dean.eigenmann.me","key":"dean"}],"frontMatter":{"layout":"post","name":"Feasibility Study: Discv5","title":"Feasibility Study: Discv5","date":"2020-04-27T12:00:00.000Z","authors":"dean","published":true,"slug":"feasibility-discv5","categories":"research","discuss":"https://discuss.status.im/t/discv5-feasibility-study/1632"},"prevItem":{"title":"What\'s the Plan for Waku v2?","permalink":"/rlog/waku-v2-plan"},"nextItem":{"title":"What Would a WeChat Replacement Need?","permalink":"/rlog/wechat-replacement-need"}},"content":"Looking at discv5 and the theoretical numbers behind finding peers.\\n\\n\x3c!--truncate--\x3e\\n\\n> Disclaimer: some of the numbers found in this write-up could be inaccurate. They are based on the current understanding of theoretical parts of the protocol itself by the author and are meant to provide a rough overview rather than bindable numbers.\\n\\nThis post serves as a more authoritative overview of the discv5 study, for a discussionary post providing more context make sure to check out the corresponding [discuss post](https://discuss.status.im/t/discv5-feasibility-study/1632). Additionally, if you are unfamiliar with discv5, check out my previous write-up: [\\"From Kademlia to Discv5\\"](https://vac.dev/kademlia-to-discv5).\\n\\n## Motivating Problem\\n\\nThe discovery method currently used by [Status](https://status.im), is made up of various components and grew over time to solve a mix of problems. We want to simplify this while maintaining some of the properties we currently have.\\n\\nNamely, we want to ensure censorship resistance to state-level adversaries. One of the issues Status had which caused us them add to their discovery method was the fact that addresses from providers like AWS and GCP were blocked both in Russia and China. Additionally, one of the main factors required is the ability to function on resource restricted devices.\\n\\nConsidering we are talking about resource restricted devices, let\'s look at the implications and what we need to consider:\\n\\n- **Battery consumption** - constant connections like websockets consume a lot of battery life.\\n- **CPU usage** - certain discovery methods may be CPU incentive, slowing an app down and making it unusable.\\n- **Bandwidth consumption** - a lot of users will be using data plans, the discovery method needs to be efficient in order to accommodate those users without using up significant portions of their data plans.\\n- **Short connection windows** - the discovery algorithm needs to be low latency, that means it needs to return results fast. This is because many users will only have the app open for a short amount of time.\\n- **Not publicly connectable** - There is a good chance that most resource restricted devices are not publicly connectable.\\n\\nFor a node to be able to participate as both a provider, and a consumer in the discovery method. Meaning a node both reads from other nodes\' stored DHTs and hosts the DHT for other nodes to read from, it needs to be publically connectable. This means another node must be able to connect to some public IP of the given node.\\n\\nWith devices that are behind a NAT, this is easier said than done. Especially mobile devices, that when connected to 4G LTE networks are often stuck behind a symmetric NAT, drastically reducing the the succeess rate of NAT traversal. Keeping this in mind, it becomes obvious that most resource restricted devices will be consumers rather than providers due to this technical limitation.\\n\\nIn order to answer our questions, we formulated the problem with a simple method for testing. The \\"needle in a haystack\\" problem was formulated to figure out how easily a specific node can be found within a given network. This issue was fully formulated in [vacp2p/research#15](https://github.com/vacp2p/research/issues/15).\\n\\n## Overview\\n\\nThe main things we wanted to investigate was the overhead on finding a peer. This means we wanted to look at both the bandwidth, latency and effectiveness of this. There are 2 methods which we can use to find a peer:\\n\\n- We can find a peer with a specific ID, using normal lookup methods as documented by Kademlia.\\n- We can find a peer that advertises a capability, this is possible using either capabilities advertised in the ENR or through [topic tables](https://github.com/ethereum/devp2p/blob/master/discv5/discv5-theory.md#topic-advertisement).\\n\\n## Feasbility\\n\\nTo be able to investigate the feasibility of discv5, we used various methods including rough calculations which can be found in the [notebook](https://vac.dev/discv5-notebook/), and a simulation isolated in [vacp2p/research#19](https://github.com/vacp2p/research/pull/19).\\n\\n### CPU & Memory Usage\\n\\nThe experimental discv5 has already been used within Status, however what was noticed was that the CPU and memory usage was rather high. It therefore should be investiaged if this is still the case, and if it is, it should be isolated where this stems from. Additionally it is worth looking at whether or not this is the case with both the go and nim implementation.\\n\\nSee details: [vacp2p/research#31](https://github.com/vacp2p/research/issues/31)\\n\\n### NAT on Cellular Data\\n\\nIf a peer is not publically connectable it can not participate in the DHT both ways. A lot of mobile phones are behind symmetric NATs which UDP hole-punching close to impossible. It should be investigated whether or not mobile phones will be able to participate both ways and if there are good methods for doing hole-punching.\\n\\nSee details: [vacp2p/research#29](https://github.com/vacp2p/research/issues/29)\\n\\n### Topic Tables\\n\\nTopic Tables allow us the ability to efficiently find nodes given a specific topic. However, they are not implemented in the [status-im/nim-eth](https://github.com/status-im/nim-eth/) implementation nor are they fully finalized in the spec. These are important if the network grows past a size where the concentration of specific nodes is relatively low making them hard to find.\\n\\nSee details: [vacp2p/research#26](https://github.com/vacp2p/research/issues/26)\\n\\n### Finding a node\\n\\nIt is important to note, that given a network is relatively small sized, eg 100-500 nodes, then finding a node given a specific address is relatively managable. Additionally, if the concentration of a specific capability in a network is reasonable, then finding a node advertising its capabilities using an ENR rather than the topic table is also managable. A reasonable concentration for example would be 10%, which would give us an 80% chance of getting a node with that capability in the first lookup request. This can be explored more using our [discv5 notebook](https://vac.dev/discv5-notebook/#Needle-in-a-haystack-with-ENR-records-indicating-capabilities).\\n\\n## Results\\n\\nResearch has shown that finding a node in the DHT has a relatively low effect on bandwidth, both inbound and outbound. For example when trying to find a node in a network of 100 nodes, it would take roughly 5668 bytes total. Additionally if we assume 100ms latency per request it would range at \u2248 300ms latency, translating to 3 requests to find a specific node.\\n\\n## General Thoughts\\n\\nOne of the main blockers right now is figuring out what the CPU and memory usage of discv5 is on mobile phones, this is a large blocker as it affects one of the core problems for us. We need to consider whether discv5 is an upgrade as it allows us to simplify our current discovery process or if it is too much of an overhead for resource restricted devices. The topic table feature could largely enhance discovery however it is not yet implemented. Given that CPU and memory isn\'t too high, discv5 could probably be used as the other issues are more \\"features\\" than large scale issues. Implementing it would already reduce the ability for state level adversaries to censor our nodes.\\n\\n## Acknowledgements\\n\\n- Oskar Thoren\\n- Dmitry Shmatko\\n- Kim De Mey\\n- Corey Petty"},{"id":"wechat-replacement-need","metadata":{"permalink":"/rlog/wechat-replacement-need","source":"@site/rlog/2020-04-16-wechat-replacement-need.mdx","title":"What Would a WeChat Replacement Need?","description":"What would a self-sovereign, private, censorship-resistant and open alternative to WeChat look like?","date":"2020-04-16T12:00:00.000Z","formattedDate":"April 16, 2020","tags":[],"readingTime":25.24,"hasTruncateMarker":true,"authors":[{"name":"Oskar","twitter":"oskarth","github":"oskarth","key":"oskarth"}],"frontMatter":{"layout":"post","name":"What Would a WeChat Replacement Need?","title":"What Would a WeChat Replacement Need?","date":"2020-04-16T12:00:00.000Z","authors":"oskarth","published":true,"slug":"wechat-replacement-need","categories":"research","image":"/img/tianstatue.jpg","discuss":"https://forum.vac.dev/t/discussion-what-would-a-wechat-replacement-need/42"},"prevItem":{"title":"Feasibility Study: Discv5","permalink":"/rlog/feasibility-discv5"},"nextItem":{"title":"From Kademlia to Discv5","permalink":"/rlog/kademlia-to-discv5"}},"content":"What would a self-sovereign, private, censorship-resistant and open alternative to WeChat look like?\\n\\n\x3c!--truncate--\x3e\\n\\nWhat would it take to replace WeChat? More specifically, what would a self-sovereign, private, censorship-resistant and open alternative look like? One that allows people to communicate, coordinate and transact freely.\\n\\n## Background\\n\\n### What WeChat provides to the end-user\\n\\nLet\'s first look at some of the things that WeChat providers. It is a lot:\\n\\n- **Messaging:** 1:1 and group chat. Text, as well as voice and video. Post gifs. Share location.\\n- **Group chat:** Limited to 500 people; above 100 people people need to verify with a bank account. Also has group video chat and QR code to join a group.\\n- **Timeline/Moments:** Post comments with attachments and have people like/comment on it.\\n- **Location Discovery:** See WeChat users that are nearby.\\n- **Profile:** Nickname and profile picture; can alias people.\\n- **\\"Broadcast\\" messages:** Send one message to many contacts, up to 200 people (spam limited).\\n- **Contacts:** Max 5000 contacts (people get around it with multiple accounts and sim cards).\\n- **App reach:** Many diferent web apps, extensions, native apps, etc. Scan QR code to access web app from phone.\\n- **Selective posting:** Decide who can view your posts and who can view your comments on other people\'s post.\\n- **Transact:** Send money gifts through red envelopes.\\n- **Transact:** Use WeChat pay to transfer money to friends and businesses; linked account with Alipay that is connected to your bank account.\\n- **Services:** Find taxis and get notifications; book flights, train tickets, hotels etc.\\n- **Mini apps:** API for all kinds of apps that allow you to provide services etc.\\n- **Picture in picture:** allowing you to have a video call while using the app.\\n\\nAnd much more. Not going to through it all in detail, and there are probably many things I don\'t know about WeChat since I\'m not a heavy user living in mainland China.\\n\\n### How WeChat works - a toy model\\n\\nThis is an overly simplistic model of how WeChat works, but it is sufficient for our purposes. This general design applies to most traditional client-server apps today.\\n\\nTo sign up for account you need a phone number or equivalent. To get access to some features you need to verify your identity further, for example with official ID and/or bank account.\\n\\nWhen you signup this creates an entry in the WeChat server, from now on treated as a black box. You authenticate with that box, and thats where you get your messages from. If you go online the app asks that box for messages you have received while you were offline. If you login from a different app your contacts and conversations are synced from that box.\\n\\nThe box gives you an account, it deals with routing to your contacts, it stores messages and attachments and gives access to mini apps that people have uploaded. For transacting money, there is a partnership with a different company that has a different box which talks to your bank account.\\n\\nThis is done in a such a way that they can support a billion users with the features above, no sweat.\\n\\nWhoever controls that box can sees who you are talking with and what the content of those messages are. There is no end to end encryption. If WeChat/Tencent disagrees with you for some reason they can ban you. This means you can\'t interact with the box under that name anymore.\\n\\n## What do we want?\\n\\nWe want something that is self-sovereign, private, censorship-resistant and open that allows individuals and groups of people to communicate and transact freely. To explore what this means in more detail, without getting lost in the weeds, we provide the following list of properties. A lot of these are tied together, and some fall out of the other requirements. Some of them stand in slight opposition to each other.\\n\\n**Self-sovereignity identity**. Exercises authority within your own sphere. If you aren\'t harming anyone, you should be able to have an account and communicate with other people.\\n\\n**Pseudonymity, and ideally total anonymity**. Not having your identity tied to your real name (e.g. through phone number, bank account, ID, etc). This allows people to act more freely without being overly worried about censorship and coercion in the real world. While total anonymity is even more desirable - especially to break multiple hops to a true-name action - real-world constraints sometimes makes this more challenging.\\n\\n**Private and secure communication**. Your communication and who you transact with should be for your eyes only. This includes transactions (transfer of value) as a form of communication.\\n\\n**Censorship-resistance**. Not being able to easily censor individuals on the platform. Both at an individual, group and collective level. Not having single points of failure that allow service to be disrupted.\\n\\n**Decentralization**. Partly falls out of censorship-resistance and other properties. If infrastructure isn\'t decentralized it means there\'s a single point of failure that can be disrupted. This is more of a tool than a goal on its own, but it is an important tool.\\n\\n**Built for mass adoption**. Includes scalabiltiy, UX (latency, reliability, bandwidth consumption, UI etc), and allowing for people to stick around. One way of doing this is to allow users to discover people they want to talk to.\\n\\n**Scalability**. Infrastructure needs to support a lot of users to be a viabile alternative. Like, a billion of them (eventually).\\n\\n**Fundamentals in place to support great user experience**. To be a viable alternative, aside from good UI and distribution, fundamentals such as latency, bandwidth usage, consistency etc must support great UX to be a viable alternative.\\n\\n**Works for resource restricted devices, including smartphones**. Most people will use a smartphone to use this. This means it has to work well on them and similar devices, without becoming a second-class citizen where we ignore properties such as censorship-resistance and privacy. Some concession to reality will be necessary due to additional constraints, which leads us to...\\n\\n**Adaptive nodes**. Nodes will have different capabilities, and perhaps at different times. To maintain a lot of the properties described here it is desirable if as many participants as possible are first-class citizens. If a phone is switching from a limited data plan to a WiFi network or from battery to AC power it can do more useful work, and so on. Likewise for a laptop with a lot of free disk space and spare compute power, etc.\\n\\n**Sustainable**. If there\'s no centralized, top down ad-driven model, this means all the infrastructure has to be sustainable somehow. Since these are individual entitites, this means it has to be paid for. While altruistic modes and similar can be used, this likely requires some form of incentivization scheme for useful services provided in the network. Related: free rider problem.\\n\\n**Spam resistant**. Relates to sustainability, scalability and built for mass adoption. Made more difficult by pseudonymous identity due to whitewashing attacks.\\n\\n**Trust-minimized**. To know that properties are provided for and aren\'t compromised, various ways of minimizing trust requirements are useful. This also related to mass adoption and social cohesion. Examples include: open and audited protocols, open source, reproducible builds, etc. This also relates to how mini apps are provided for, since we may not know their source but want to be able to use them anyway.\\n\\n**Open source**. Related to above, where we must be able to inspect the software to know that it functions as advertised and hasn\'t been compromised, e.g. by uploading private data to a third party.\\n\\nSome of these are graded and a bit subtle, i.e.:\\n\\n- Censorship resistance would ideally be able to absorb Internet shutdowns. This would require an extensive MANET/meshnet infrastructure, which while desirable, requires a lot of challenges to be overcome to be feasible.\\n- Privacy would ideally make all actions (optionally) totally anoymous, though this may incur undue costs on bandwidth and latency, which impacts user experience.\\n- Decentralization, certain topologies, such as DHTs, are efficient and quite decentralized but still have some centralized aspects, which makes it attackable in various ways. Ditto for blockchains compared with bearer instruments which requires some coordinating infrastructure, compared with naturally occuring assets such as precious metals.\\n- \\"Discover people\\" and striving for \\"total anonymity\\" might initially seem incompatible. The idea is to provide for sane defaults, and then allow people to decide how much information they want to disclose. This is the essence of privacy.\\n- Users often want _some_ form of moderation to get a good user experience, which can be seen as a form of censorship. The idea to raise the bar on the basics, the fundamental infrastructure. If individuals or specific communities want certain moderation mechanisms, that is still a compatible requirement.\\n\\n### Counterpoint 1\\n\\nWe could refute the above by saying that the design goals are undesirable. We want a system where people can censor others, and where everyone is tied to their real identity. Or we could say something like, freedom of speech is a general concept, and it doesn\'t apply to Internet companies, even if they provide a vital service. You can survive without it and you should\'ve read the terms of service. This roughly charactericizes the mainstream view.\\n\\nAdditional factor here is the idea that a group of people know more about what\'s good for you then you do, so they are protecting you.\\n\\n### Counterpoint 2\\n\\nWe could agree with all these design goals, but think they are too extreme in terms of their requirements. For example, we could operate as a non profit, take donations and volunteers, and then host the whole infrastructure ourselves. We could say we are in a friendly legislation, so we won\'t be a single point of failure. Since we are working on this and maybe even our designs are open, you can trust us and we\'ll provide service and infrastructure that gives you what you want without having to pay for it or solve all these complex decentralized computation and so on problems. If you don\'t trust us for some reason, you shouldn\'t use us regardless. Also, this is better than status quo. And we are more likely to survive by doing this, either by taking shortcuts or by being less ambituous in terms of scope.\\n\\n## Principal components\\n\\nThere are many ways to skin a cat, but this is one way of breaking down the problem. We have a general direction with the properties listed above, together with some understanding of how WeChat works for the everday user. Now the question is, what infrastructure do we need to support this? How do we achieve the above properties, or at least get closer to them? We want to figure out the necessary building blocks, and one of doing this is to map out likely necessary components.\\n\\n### Background: Ethereum and Web3 stack\\n\\nIt is worth noting that a lot of the required infrastructure has been developed, at least as concepts, in the original Ethereum / Web3 vision. In it there is Ethereum for consensus/compute/transact, storage through Swarm, and communication through Whisper. That said, the main focus has been on the Ethereum blockchain itself, and a lot of things have happened in the last 5y+ with respect to technology around privacy and scalabilty. It is worth revisiting things from a fresh point of view, with the WeChat alternative in mind as a clear use case.\\n\\n### Account - self-sovereign identity and the perils of phone numbers\\n\\nStarting from the most basic: what is an account and how do you get one? With most internet services today, WeChat and almost all popular messaging apps included, you need to signup with some centralized authority. Usually you also have to verify this with some data that ties this account to you as an individual. E.g. by requiring a phone number, which in most jurisdictions [^1] means giving out your real ID. This also means you can be banned from using the service by a somewhat arbitrary process, with no due process.\\n\\nNow, we could argue these app providers can do what they want. And they are right, in a very narrow sense. As apps like WeChat (and Google) become general-purpose platforms, they become more and more ingrained in our everyday lives. They start to provide utilities that we absolutely require to work to go about our day, such as paying for food or transportation. This means we need higher standard than this.\\n\\nJustifications for requiring phone numbers are usually centered around three claims:\\n\\n1. Avoiding spam\\n2. Tying your account to your real name, for various reasons\\n3. Using as a commonly shared identifier as a social network discovery mechanism\\n\\nOf course, many services require more than phone numbers. E.g. email, other forms of personal data such as voice recording, linking a bank account, and so on.\\n\\nIn contrast, a self-sovereign system would allow you to \\"create an account\\" completely on your own. This can easily be done with public key cryptograpy, and it also paves the way for end-to-end encryption to make your messages private.\\n\\nThe main issue with this that you need to get more creative about avoiding spam (e.g. through white washing attacks), and ideally there is some other form of social discovery mechanism.\\n\\nJust having a public key as an account isn\'t enough though. If it goes through a central server, then nothing is stopping that server from arbitrarly blocking requests related to that public key. Of course, this also depends on how transparent such requests are. Fundamentally, lest we rely completely on goodwill, there needs to be multiple actors by which you can use the service. This naturally points to decentralization as a requirement. See counterpoint.\\n\\nEven so, if the system is closed source we don\'t know what it is doing. Perhaps the app communicating is also uploading data to another place, or somehow making it possible to see who is who and act accordingly.\\n\\nYou might notice that just one simple property, self-sovereign identity, leads to a slew of other requirements and properties. You might also notice that WeChat is far from alone in this, even if their identity requirements might be a bit stringent than, say, Telegram. Their control aspects are also a bit more extreme, at least for someone with western sensibilities [^2].\\n\\nMost user facing applications have similar issues, Google Apps/FB/Twitter etc. For popular tools that have this built in, we can look at git - which is truly decentralized and have keypair at the bottom. It is for a very specific technical domain, and even then people rely on Github. Key management is fairly difficult even for technical people, and for normal people even more so. Banks are generally far behind on this tech, relying on arcane procedures and special purpose hardware for 2FA. That\'s another big issue.\\n\\nLet\'s shift gears a bit and talk about some other functional requirements.\\n\\n### Routing - packets from A to B\\n\\nIn order to get a lot of the features WeChat provides, we need the ability to do three things: communicate, store data, and transact with people. We need a bit more than that, but let\'s focus on this for now.\\n\\nTo communicate with people, in the base case, we need to go from one phone to another phone that is separated by a large distance. This requires some form of routing. The most natural platform to build this on is the existing Internet, though not the only one. Most phones are resource restricted, and are only \\"on\\" for brief periods of time. This is needed to preserve battery and bandwidth. Additionally, Internet uses IPs as endpoints, which change as a phones move through space. NAT punching etc isn\'t always perfect either. This means we need a way to get a message from one public key to another, and through some intermediate nodes. We can think of these nodes as a form of service network. Similar to how a power grid works, or phone lines, or collection of ISPs.\\n\\nOne important property here is to ensure we don\'t end up in a situation like the centralized capture scenario above, something we\'ve seen with centralized ISPs [^3] [^4] where they can choose which traffic is good and which is bad. We want to allow the use of different service nodes, just like if a restaurant gives you food poisioning you can go to the one next door and then the first one goes out of business after a while. And the circle of life continues.\\n\\nWe shouldn\'t be naive though, and think that this is something nodes are likely to do for free. They need to be adequately compensated for their services, in some of incentivization scheme. That can either be monetary, or as in the case of Bittorrent, more of a barter situation where you use game theory to coordinate with strangers [^5], and some form of reputation attached to it (for private trackers).\\n\\nThere are many ways of doing routing, and we won\'t go into too much technical detail here. Suffice to say is that you likely want both a structured and unstructured alternative, and that these comes with several trade-offs when it comes to efficiency, metadata protection, ability to incentivize, compatibility with existing topologies, and suitability for mobilephones (mostly offline, bandwidth restricted, not directly connectable). Expect more on this in a future article.\\n\\nSome of these considerations naturally leads us into the storage and transaction components.\\n\\n### Storage - available and persistant for later\\n\\nIf mobile phones are mostly offline, we need some way to store these messages so they can be retrieved when online again. The same goes for various kinds attachments as well, and for when people are switching devices. A user might control their timeline, but in the WeChat case that timeline is stored on Tencent\'s servers, and queried from there as well. This naturally needs to happen by some other service nodes. In the WeChat case, and for most IMs, the way these servers are paid for is through some indirect ad mechanism. The entity controlling these ads and so on is the same one as the one operating the servers for storage. A more direct model with different entities would see these services being compensated for their work.\\n\\nWe also need storage for attachments, mini-apps, as well as a way of understanding the current state of consensus when it comes to the compute/transact module. In the WeChat case, this state is completely handled by the bank institution or one of their partners, such as Alibaba. When it comes to bearer instruments like cash, no state needs to be kept as that\'s a direct exchange in the physical world. This isn\'t directly compatible with transfering value over a distance.\\n\\nAll of this state requires availability and persistance. It should be done in a trust minimized fashion and decentralized, which requires some form of incentivization for keeping data around. If it isn\'t, you are relying on social cohesion which breaks down at very large scales.\\n\\nSince data will be spread out across multiple nodes, you need a way to sync data and transfer it in the network. As well as being able to add and query data from it. All of this requires a routing component.\\n\\nTo make it more censorship resistant it might be better to keep it as a general-purpose store, i.e. individuals don\'t need to know what they storing. Otherwise, you naturally end up in a situation where individual nodes can be pressured to not store certain content.\\n\\n### Messaging - from me to you to all of us (not them)\\n\\nThis builds on top of routing, but it has a slightly different focus. The goal is to allow for individuals and groups to communicate in a private, secure and censorship-resistant manner.\\n\\nIt also needs to provide a decent interface to the end user, in terms of dealing seamlessly with offline messages, providing reliable and timely messaging.\\n\\nIn order to get closer to the ideal of total anonymity, it is useful to be able to hide metadata of who is talking to whom. This applies to both normal communication as well as for transactions. Ideally, no one but the parties involved can see who is taking part in a conversation. This can be achieved through various techniques such as mixnets, anonymous credentials, private information retrieval, and so on. Many of these techniques have a fundamental trade-off with latency and bandwidth, something that is a big concern for mobilephones. Being able to do some form of tuning, in an adaptive node manner, depending on your threat model and current capabilities is useful here.\\n\\nThe baseline here is pseudonymity, and having tools to allow individuals to \\"cut off\\" ties to their real world identity and transactions. People act different in different circles in the real world, and this should be mimicked online as well. Your company, family or government shouldn\'t be able to know what exactly you use your paycheck for, and who you are talking to.\\n\\n### Compute - transact, contract and settle\\n\\nThe most immediate need here is transaction from A to B. Direct exchange. There is also a more indirect need for private lawmaking and contracting.\\n\\nWe talked about routing and storage and how they likely need to be incentivized to work properly. How are they going to be compensated? While this could in theory work via existing banking system and so on, this would be rather heavy. It\'d also very likely require tying your identifier to your legal name, something that goes against what we want to achieve. What we want is something that acts more as right-to-access, similar to the way cash functions in a society [^6]. I pay for a fruit with something that is valuable to you and then I\'m on my way.\\n\\nWhile there might be other candidates, such as pre-paid debit cards and so on, this transaction mode pretty much requires a cryptocurrency component. The alternative is to do it on a reputation basis, which might work for small communities, due to social cohesion, but quickly detoriates for large ones [^7]. Ad hoc models like private Bittorrent trackers are centralized and easy to censor.\\n\\nNow, none of the existing cryptocurrency models are ideal. They also all suffer from lack of widespread use, and it is difficult to get onboarded to them in the first place. Transactions in Bitcoin are slow. Ethereum is faster and has more capabilities, but it still suffers from linking payments over time, which makes the privacy part of this more difficult. Zcash, Monero and similar are interesting, but also require more use. For Zcash, shielded transactions appear to only account for less than 2% of all transactions in 2019 [^8] [^9].\\n\\nAnother dimension is what sets general purpose cryptocurrencies like Ethereum apart. Aside from just paying from A to B, you can encode rules about when something should be paid out and not. This is very useful for doing a form of private lawmaking, contracting, for setting up service agreements with these nodes. If there\'s no trivial recourse as in the meatspace world, where you know someone\'s name and you can sue them, you need a different kind of model.\\n\\nWhat makes something like Zcash interesting is that it works more like digital cash. Instead of leaving a public trail for everyone, where someone can see where you got the initial money from and then trace you across various usage, for Zcash every hop is privacy preserving.\\n\\nTo fulfill the general goals of being censorship resistance and secure, it is also vital that the system being used stays online and can\'t be easily disrupted. That points to disintermediation, as opposed to using gateways and exchanges. This is a case where something like cash, or gold, is more direct, since no one can censor this transaction without being physically present where this direct exchange is taking place. However, like before, this doesn\'t work over distance.\\n\\n### Secure chat - just our business\\n\\nSimilar to the messaging module above. The distinction here is that we assume the network part has already taken place. Here we are interested in keeping the contents of messages private, so that means confidentiality/end-to-end encryption, integrity, authentication, as well as forward secrecy and plausible deniability. This means that even if there\'s some actor that gets some private key material, or confiscated your phone, there is some level of...ephemerality to your conversations. Another issue here in terms of scalable private group chat.\\n\\n### Extensible mini apps\\n\\nThis relates to the compute and storage module above. Essentially we want to provide mini apps as in WeChat, but to do so in a way that is compatible with what we want to achieve more generally. This allows individuals and small businesses to create small tools for various purposes, and coordinate with strangers. E.g. booking a cab or getting an insurance, and so on.\\n\\nThis has a higher dependency on the contracting/general computation aspect. I.e. often it isn\'t only a transaction, but you might want to encode some specific rules here that strangers can abide by without having too high trust requirements. As a simple example: escrows.\\n\\nThis also needs an open API that anyone can use. It should be properly secured, so using one doesn\'t compromise the rest of the system it is operating in. To be censorship resistant it requires the routing and storage component to work properly.\\n\\n## Where are we now?\\n\\nLet\'s look back at some of desirable properties we set out in the beginning and see how close we are to building out the necessary components. Is it realistic at all or just a pipe dream? We\'ll see that there are many building blocks in place, and there\'s reason for hope.\\n\\n**Self-sovereignity identity**. Public key crypto and web of trust like constructs makes this possible.\\n\\n**Pseudonymity, and ideally total anonymity**. Pseudonymity can largely be achieved with public key crypto and open systems that allow for permissionless participation. For transactions, pseudonymity exists in most cryptocurrencies. The challenge is linkage across time, especially when interfacing with other \\"legacy\\" system. There are stronger constructs that are actively being worked on and are promising here, such as mixnets (Nym), mixers (Wasabi Wallet, Tornado.Cash) and zero knowledge proofs (Zcash, Ethereum, Starkware). This area of applied research has exploded over the last few years.\\n\\n**Private and secure communication**. Signal has pioneered a lot of this, following OTR. Double Ratchet, X3DH. E2EE is minimum these days, and properties like PFS and PD are getting better. For metadata protection, you have Tor, with its faults, and more active research on mixnets and private information retrieval, etc.\\n\\n**Censorship-resistance**. This covers a lot of ground across the spectrum. You have technologies like Bittorrent, Bitcoin/Ethereum, Tor obfuscated transports, E2EE by default, partial mesh networks in production, abilit to move/replicate host machines more quickly have all made this more of a reality than it used to be. this easier. Of course, techniques such as deep packet inspection and internet shutdowns have increased.\\n\\n**Decentralization**. Cryptocurrencies, projects like libp2p and IPFS. Need to be mindful here of many projects that claim decentralization but are still vulnerable to single points of failures, such as relying on gateways.\\n\\n**Built for mass adoption**. This one is more subjective. There\'s definitely a lot of work to be done here, both when it comes to fundamental performance, key management and things like social discoverability. Directionally these things are improving and becoming easier for the average person but there is a lot ot be done here.\\n\\n**Scalability**. With projects like Ethereum 2.0 and IPFS more and more resources are a being put into this, both at the consensus/compute layer as well as networking (gossip, scalable Kademlia) layer. Also various layer 2 solutions for transactions.\\n\\n**Fundamentals in place to support great user experience**. Similar to built for mass adoption. As scalability becomes more important, more applied research is being done in the p2p area to improve things like latency, bandwidth.\\n\\n**Works for resource restricted devices, including smartphones**. Work in progress and not enough focus here, generally an after thought. Also have stateless clients etc.\\n\\n**Adaptive nodes**. See above. With subprotocols and capabilities in Ethereum and libp2p, this is getting easier.\\n\\n**Sustainable**. Token economics is a thing. While a lot of it won\'t stay around, there are many more projects working on making themselves dispensable. Being open source, having an engaged community and enabling users run their own infrastructure. Users as stakeholders.\\n\\n**Spam resistant**. Tricky problem if you want to be pseudonymous, but some signs of hope with incentivization mechanisms, zero knowledge based signaling, etc. Together with various forms of rate limiting and better controlling of topology and network amplification. And just generally being battle-tested by real world attacks, such as historical Ethereum DDoS attacks.\\n\\n**Trust minimized**. Bitcoin. Zero knowledge provable computation. Open source. Reproducible builds. Signed binaries. Incentive compatible structures. Independent audits. Still a lot of work, but getting better.\\n\\n**Open source**. Big and only getting bigger. Including mainstream companies.\\n\\n## What\'s next?\\n\\nWe\'ve look at what WeChat provides and what we\'d like an alternative to look like. We\'ve also seen a few principal modules that are necessary to achieve those goals. To achieve all of this is a daunting task, and one might call it overly ambitiuous. We\'ve also seen how far we\'ve come with some of the goals, and how a lot of the pieces are there, in one form or another. Then it is a question of putting them all together in the right mix.\\n\\nThe good news is that a lot of people are working all these building blocks and thinking about these problems. Compared to a few years ago we\'ve come quite far when it comes to p2p infrastructure, privacy, security, scalability, and general developer mass and mindshare. If you want to join us in building some of these building blocks, and assembling them, check out our forum.\\n\\nPS. We are [hiring protocol engineers](https://status.im/our_team/open_positions.html). DS\\n\\n## Acknowledgements\\n\\nCorey, Dean, Jacek.\\n\\n## References\\n\\n[^1]: Mandatory SIM card registration laws: https://privacyinternational.org/long-read/3018/timeline-sim-card-registration-laws\\n[^2]: On WeChat keyword censorship: https://citizenlab.ca/2016/11/wechat-china-censorship-one-app-two-systems/\\n[^3]: Net Neutrality: https://www.eff.org/issues/net-neutrality\\n[^4]: ISP centralization: https://ilsr.org/repealing-net-neutrality-puts-177-million-americans-at-risk/\\n[^5]: Incentives Build Robustness in BitTorrent bittorrent.org/bittorrentecon.pdf\\n[^6]: The Case for Electronic Cash: https://coincenter.org/files/2019-02/the-case-for-electronic-cash-coin-center.pdf\\n[^7]: Money, blockchains, and social scalability: http://unenumerated.blogspot.com/2017/02/money-blockchains-and-social-scalability.html\\n[^8]: Zcash private transactions (partial paywall): https://www.theblockcrypto.com/genesis/48413/an-analysis-of-zcashs-private-transactions\\n[^9]: Shielded transactions usage (stats page 404s): https://z.cash/support/faq/"},{"id":"kademlia-to-discv5","metadata":{"permalink":"/rlog/kademlia-to-discv5","source":"@site/rlog/2020-04-9-kademlia-to-discv5.mdx","title":"From Kademlia to Discv5","description":"A quick history of discovery in peer-to-peer networks, along with a look into discv4 and discv5, detailing what they are, how they work and where they differ.","date":"2020-04-09T16:00:00.000Z","formattedDate":"April 9, 2020","tags":[],"readingTime":8.045,"hasTruncateMarker":true,"authors":[{"name":"Dean","twitter":"DeanEigenmann","github":"decanus","website":"https://dean.eigenmann.me","key":"dean"}],"frontMatter":{"layout":"post","name":"From Kademlia to Discv5","title":"From Kademlia to Discv5","date":"2020-04-09T16:00:00.000Z","authors":"dean","published":true,"slug":"kademlia-to-discv5","categories":"research"},"prevItem":{"title":"What Would a WeChat Replacement Need?","permalink":"/rlog/wechat-replacement-need"},"nextItem":{"title":"Waku Update","permalink":"/rlog/waku-update"}},"content":"A quick history of discovery in peer-to-peer networks, along with a look into discv4 and discv5, detailing what they are, how they work and where they differ.\\n\\n\x3c!--truncate--\x3e\\n\\nIf you\'ve been working on Ethereum or adjacent technologies you\'ve probably heard of [discv4](https://github.com/ethereum/devp2p/blob/master/discv4.md) or [discv5](https://github.com/ethereum/devp2p/blob/master/discv5/discv5.md). But what are they actually? How do they work and what makes them different? To answer these questions, we need to start at the beginning, so this post will assume that there is little knowledge on the subject so the post should be accessible for anyone.\\n\\n## The Beginning\\n\\nLet\'s start right at the beginning: the problem of discovery and organization of nodes in peer-to-peer networks.\\n\\nEarly P2P file sharing technologies, such as Napster, would share information about who holds what file using a single server. A node would connect to the central server and give it a list of the files it owns. Another node would then connect to that central server, find a node that has the file it is looking for and contact that node. This however was a flawed system -- it was vulnerable to attacks and left a single party open to lawsuits.\\n\\nIt became clear that another solution was needed, and after years of research and experimentation, we were given the distributed hash table or DHT.\\n\\n## Distributed Hash Tables\\n\\nIn 2001 4 new protocols for such DHTs were conceived, [Tapestry](https://pdos.csail.mit.edu/~strib/docs/tapestry/tapestry_jsac03.pdf), [Chord](https://pdos.csail.mit.edu/papers/chord:sigcomm01/chord_sigcomm.pdf), [CAN](https://people.eecs.berkeley.edu/~sylvia/papers/cans.pdf) and [Pastry](http://rowstron.azurewebsites.net/PAST/pastry.pdf), all of which made various trade-offs and changes in their core functionality, giving them unique characteristics.\\n\\nBut as said, they\'re all DHTs. So what is a DHT?\\n\\nA distributed hash table (DHT) is essentially a distributed key-value list. Nodes participating in the DHT can easily retrieve the value for a key.\\n\\nIf we have a network with 9 key-value pairs and 3 nodes, ideally each node would store 3 (optimally 6 for redundancy) of those key-value pairs, meaning that if a key-value pair were to be updated, only part of the network would responsible for ensuring that it is. The idea is that any node in the network would know where to find the specific key-value pair it is looking for based on how things are distributed amongst the nodes.\\n\\n## Kademlia\\n\\nSo now that we know what DHTs are, let\'s get to Kademlia, the predecessor of discv4. Kademlia was created by Petar Maymounkov and David Mazi\xe8res in 2002. I will naively say that this is probably one of the most popular and most used DHT protocols. It\'s quite simple in how it works, so let\'s look at it.\\n\\nIn Kademlia, nodes and values are arranged by distance (in a very mathematical definition). This distance is not a geographical one, but rather based on identifiers. It is calculated how far 2 identifiers are from eachother using some distance function.\\n\\nKademlia uses an `XOR` as its distance function. An `XOR` is a function that outputs `true` only when inputs differ. Here is an example with some binary identifiers:\\n\\n```\\nXOR 10011001\\n 00110010\\n --------\\n 10101011\\n```\\n\\nThe top in decimal numbers means that the distance between `153` and `50` is `171`.\\n\\nThere are several reasons why `XOR` was taken:\\n\\n1. The distance from one ID to itself will be `0`.\\n2. Distance is symmetric, A to B is the same as B to A.\\n3. Follows triangle inequality, if `A`, `B` and `C` are points on a triangle then the distance `A` to `B` is closer or equal to that of `A` to `C` plus the one from `B` to `C`.\\n\\nIn summary, this distance function allows a node to decide what is \\"close\\" to it and make decisions based on that \\"closeness\\".\\n\\nKademlia nodes store a routing table. This table contains multiple lists. Each subsequent list contains nodes which are a little further distanced than the ones included in the previous list. Nodes maintain detailed knowledge about nodes closest to them, and the further away a node is, the less knowledge the node maintains about it.\\n\\nSo let\'s say I want to find a specific node. What I would do is go to any node which I already know and ask them for all their neighbours closest to my target. I repeat this process for the returned neighbours until I find my target.\\n\\nThe same thing happens for values. Values have a certain distance from nodes and their IDs are structured the same way so we can calculate this distance. If I want to find a value, I simply look for the neighbours closest to that value\'s key until I find the one storing said value.\\n\\nFor Kademlia nodes to support these functions, there are several messages with which the protocol communicates.\\n\\n- `PING` - Used to check whether a node is still running.\\n- `STORE` - Stores a value with a given key on a node.\\n- `FINDNODE` - Returns the closest nodes requested to a given ID.\\n- `FINDVALUE` - The same as `FINDNODE`, except if a node stores the specific value it will return it directly.\\n\\n_This is a **very** simplified explanation of Kademlia and skips various important details. For the full description, make sure to check out the [paper](https://pdos.csail.mit.edu/~petar/papers/maymounkov-kademlia-lncs.pdf) or a more in-depth [design specification](http://xlattice.sourceforge.net/components/protocol/kademlia/specs.html)_\\n\\n## Discv4\\n\\nNow after that history lesson, we finally get to discv4 (which stands for discovery v4), Ethereum\'s current node discovery protocol. The protocol itself is essentially based off of Kademlia, however it does away with certain aspects of it. For example, it does away with any usage of the value part of the DHT.\\n\\nKademlia is mainly used for the organisation of the network, so we only use the routing table to locate other nodes. Due to the fact that discv4 doesn\'t use the value portion of the DHT at all, we can throw away the `FINDVALUE` and `STORE` commands described by Kademlia.\\n\\nThe lookup method previously described by Kademlia describes how a node gets its peers. A node contacts some node and asks it for the nodes closest to itself. It does so until it can no longer find any new nodes.\\n\\nAdditionally, discv4 adds mutual endpoint verification. This is meant to ensure that a peer calling `FINDNODE` also participates in the discovery protocol.\\n\\nFinally, all discv4 nodes are expected to maintain up-to-date ENR records. These contain information about a node. They can be requested from any node using a discv4-specific packet called `ENRRequest`.\\n\\n_If you want some more details on ENRs, check out one of my posts [\\"Network Addresses in Ethereum\\"](https://dean.eigenmann.me/blog/2020/01/21/network-addresses-in-ethereum/)_\\n\\nDiscv4 comes with its own range of problems however. Let\'s look at a few of them.\\n\\nFirstly, the way discv4 works right now, there is no way to differentiate between node sub-protocols. This means for example that an Ethereum node could add an Ethereum Classic Node, Swarm or Whisper node to its DHT without realizing that it is invalid until more communication has happened. This inability to differentiate sub-protocols makes it harder to find specific nodes, such as Ethereum nodes with light-client support.\\n\\nNext, in order to prevent replay attacks, discv4 uses timestamps. This however can lead to various issues when a host\'s clock is wrong. For more details, see the [\\"Known Issues\\"](https://github.com/ethereum/devp2p/blob/master/discv4.md#known-issues-in-the-current-version) section of the discv4 specification.\\n\\nFinally, we have an issue with the way mutual endpoint verification works. Messages can get dropped and there is no way to tell if both peers have verified eachother. This means that we could consider our peer verified while it does not consider us so making them drop the `FINDNODE` packet.\\n\\n## Discv5\\n\\nFinally, let\'s look at discv5. The next iteration of discv4 and the discovery protocol which will be used by Eth 2.0. It aims at fixing various issues present in discv4.\\n\\nThe first change is the way `FINDNODE` works. In traditional Kademlia as well as in discv5, we pass an identifier. However, in discv5 we instead pass the logarithmic distance, meaning that a `FINDNODE` request gets a response containing all nodes at the specified logarithmic distance from the called node.\\n\\nLogarithmic distance means we first calculate the distance and then run it through our log base 2 function. See:\\n\\n```\\nlog2(A xor B)\\n```\\n\\nAnd the second, more important change, is that discv5 aims at solving one of the biggest issues of discv4: the differentiation of sub-protocols. It does this by adding topic tables. Topic tables are [first in first out]() lists that contain nodes which have advertised that they provide a specific service. Nodes get themselves added to this list by registering `ads` on their peers.\\n\\nAs of writing, there is still an issue with this proposal. There is currently no efficient way for a node to place `ads` on multiple peers, since it would require separate requests for every peer which is inefficient in a large-scale network.\\n\\nAdditionally, it is unclear how many peers a node should place these `ads` on and exactly which peers to place them on. For more details, check out the issue [devp2p#136](https://github.com/ethereum/devp2p/issues/136).\\n\\nThere are a bunch more smaller changes to the protocol, but they are less important hence they were ommitted from this summary.\\n\\nNevertheless, discv5 still does not resolve a couple issues present in discv4, such as unreliable endpoint verification. As of writing this post, there is currently no new method in discv5 to improve the endpoint verification process.\\n\\nAs you can see discv5 is still a work in progress and has a few large challenges to overcome. However if it does, it will most likely be a large improvement to a more naive Kademlia implementations.\\n\\n---\\n\\nHopefully this article helped explain what these discovery protocols are and how they work. If you\'re interested in their full specifications you can find them on [github](https://github.com/ethereum/devp2p)."},{"id":"waku-update","metadata":{"permalink":"/rlog/waku-update","source":"@site/rlog/2020-02-14-waku-update.mdx","title":"Waku Update","description":"A research log. What\'s the current state of Waku? How many users does it support? What are the bottlenecks? What\'s next?","date":"2020-02-14T12:00:00.000Z","formattedDate":"February 14, 2020","tags":[],"readingTime":5.63,"hasTruncateMarker":true,"authors":[{"name":"Oskar","twitter":"oskarth","github":"oskarth","key":"oskarth"}],"frontMatter":{"layout":"post","name":"Waku Update","title":"Waku Update","date":"2020-02-14T12:00:00.000Z","authors":"oskarth","published":true,"slug":"waku-update","categories":"research","image":"/img/waku_infrastructure_sky.jpg","discuss":"https://forum.vac.dev/t/waku-update-where-are-we-at/34"},"prevItem":{"title":"From Kademlia to Discv5","permalink":"/rlog/kademlia-to-discv5"},"nextItem":{"title":"DNS Based Discovery","permalink":"/rlog/dns-based-discovery"}},"content":"A research log. What\'s the current state of Waku? How many users does it support? What are the bottlenecks? What\'s next?\\n\\n\x3c!--truncate--\x3e\\n\\nWaku is our fork of Whisper where we address the shortcomings of Whisper in an iterative manner. We\'ve seen a in [previous post](https://vac.dev/fixing-whisper-with-waku) that Whisper doesn\'t scale, and why. In this post we\'ll talk about what the current state of Waku is, how many users it can support, and future plans.\\n\\n## Current state\\n\\n**Specs:**\\n\\nWe released [Waku spec v0.3](https://rfc.vac.dev/spec/6) this week! You can see the full changelog [here](https://rfc.vac.dev/spec/6/#changelog).\\n\\nThe main change from 0.2 is making the handshake more flexible. This enables us to communicate topic interest immediately without ambiguity. We also did the following:\\n\\n- added recommendation for DNS based discovery\\n- added an upgradability and compatibility policy\\n- cut the spec up into several components\\n\\nWe cut the spec up in several components to make Vac as modular as possible. The components right now are:\\n\\n- Waku (main spec), currently in [version 0.3.0](https://rfc.vac.dev/spec/6)\\n- Waku envelope data field, currently in [version 0.1.0](https://rfc.vac.dev/spec/7)\\n- Waku mailserver, currently in [version 0.2.0](https://rfc.vac.dev/spec/8)\\n\\nWe can probably factor these out further as the main spec is getting quite big, but this is good enough for now.\\n\\n**Clients:**\\n\\nThere are currently two clients that implement Waku v0.3, these are [Nimbus (Update: now nim-waku)](https://github.com/status-im/nim-waku) in Nim and [status-go](https://github.com/status-im/status-go) in Go.\\n\\nFor more details on what each client support and don\'t, you can follow the [work in progress checklist](https://github.com/vacp2p/pm/issues/7).\\n\\nWork is currently in progress to integrate it into the [Status core app](https://github.com/status-im/status-react/pull/9949). Waku is expected to be part of their upcoming 1.1 release (see [Status app roadmap (link deprecated)](https://trello.com/b/DkxQd1ww/status-app-roadmap)).\\n\\n**Simulation:**\\n\\nWe have a [simulation](https://github.com/status-im/nim-waku/blob/master/waku/v1/node/quicksim.nim) that verifies - or rather, fails to falsify - our [scalability model](https://vac.dev/fixing-whisper-with-waku). More on the simulation and what it shows below.\\n\\n## How many users does Waku support?\\n\\nThis is our current understanding of how many users a network running Waku can support. Specifically in the context of the Status chat app, since that\'s the most immediate consumer of Waku. It should generalize fairly well to most deployments.\\n\\n**tl;dr (for Status app):**\\n\\n- beta: 100 DAU\\n- v1: 1k DAU\\n- v1.1 (waku only): 10k DAU (up to x10 with deployment hotfixes)\\n- v1.2 (waku+dns): 100k DAU (can optionally be folded into v1.1)\\n\\n_Assuming 10 concurrent users = 100 DAU. Estimate uncertainty increases for each order of magnitude until real-world data is observed._\\n\\nAs far as we know right now, these are the bottlenecks we have:\\n\\n- Immediate bottleneck - Receive bandwidth for end user clients (aka \u2018Fixing Whisper with Waku\u2019)\\n- Very likely bottleneck - Nodes and cluster capacity (aka \u2018DNS based node discovery\u2019)\\n- Conjecture but not unlikely to appear- Full node traffic (aka \u2018the routing / partition problem\u2019)\\n\\nWe\'ve already seen the first bottleneck being discussed in the initial post. Dean wrote a post on [DNS based discovery](https://vac.dev/dns-based-discovery) which explains how we will address the likely second bottleneck. More on the third one in future posts.\\n\\nFor more details on these bottlenecks, see [Scalability estimate: How many users can Waku and the Status app support?](https://discuss.status.im/t/scalability-estimate-how-many-users-can-waku-and-the-status-app-support/1514).\\n\\n## Simulation\\n\\nThe ultimate test is real-world usage. Until then, we have a simulation thanks to Kim De Mey from the Nimbus team!\\n\\n![](/img/waku_simulation.jpeg)\\n\\nWe have two network topologies, Star and full mesh. Both networks have 6 full nodes, one traditional light node with bloom filter, and one Waku light node.\\n\\nOne of the full nodes sends 1 envelope over 1 of the 100 topics that the two light nodes subscribe to. After that, it sends 10000 envelopes over random topics.\\n\\nFor light node, bloom filter is set to almost 10% false positive (bloom filter: n=100, k=3, m=512). It shows the number of valid and invalid envelopes received for the different nodes.\\n\\n**Star network:**\\n\\n| Description | Peers | Valid | Invalid |\\n| --------------- | ----- | ----- | ------- |\\n| Master node | 7 | 10001 | 0 |\\n| Full node 1 | 3 | 10001 | 0 |\\n| Full node 2 | 1 | 10001 | 0 |\\n| Full node 3 | 1 | 10001 | 0 |\\n| Full node 4 | 1 | 10001 | 0 |\\n| Full node 5 | 1 | 10001 | 0 |\\n| Light node | 2 | 815 | 0 |\\n| Waku light node | 2 | 1 | 0 |\\n\\n**Full mesh:**\\n\\n| Description | Peers | Valid | Invalid |\\n| --------------- | ----- | ----- | ------- |\\n| Full node 0 | 7 | 10001 | 20676 |\\n| Full node 1 | 7 | 10001 | 9554 |\\n| Full node 2 | 5 | 10001 | 23304 |\\n| Full node 3 | 5 | 10001 | 11983 |\\n| Full node 4 | 5 | 10001 | 24425 |\\n| Full node 5 | 5 | 10001 | 23472 |\\n| Light node | 2 | 803 | 803 |\\n| Waku light node | 2 | 1 | 1 |\\n\\nThings to note:\\n\\n- Whisper light node with ~10% false positive gets ~10% of total traffic\\n- Waku light node gets ~1000x less envelopes than Whisper light node\\n- Full mesh results in a lot more duplicate messages, expect for Waku light node\\n\\nRun the simulation yourself [here](https://github.com/status-im/nim-waku/blob/master/waku/v1/node/quicksim.nim). The parameters are configurable, and it is integrated with Prometheus and Grafana.\\n\\n## Difference between Waku and Whisper\\n\\nSummary of main differences between Waku v0 spec and Whisper v6, as described in [EIP-627](https://eips.ethereum.org/EIPS/eip-627):\\n\\n- Handshake/Status message not compatible with shh/6 nodes; specifying options as association list\\n- Include topic-interest in Status handshake\\n- Upgradability policy\\n- `topic-interest` packet code\\n- RLPx subprotocol is changed from shh/6 to waku/0.\\n- Light node capability is added.\\n- Optional rate limiting is added.\\n- Status packet has following additional parameters: light-node, confirmations-enabled and rate-limits\\n- Mail Server and Mail Client functionality is now part of the specification.\\n- P2P Message packet contains a list of envelopes instead of a single envelope.\\n\\n## Next steps and future plans\\n\\nSeveral challenges remain to make Waku a robust and suitable base\\ncommunication protocol. Here we outline a few challenges that we are addressing and will continue to work on:\\n\\n- scalability of the network\\n- incentived infrastructure and spam-resistance\\n- build with resource restricted devices in mind, including nodes being mostly offline\\n\\nFor the third bottleneck, a likely candidate for fixing this is Kademlia routing. This is similar to what is done in [Swarm\'s](https://www.ethswarm.org/) PSS. We are in the early stages of experimenting with this over libp2p in [nim-libp2p](https://github.com/status-im/nim-libp2p). More on this in a future post!\\n\\n## Acknowledgements\\n\\n_Image from \\"caged sky\\" by mh.xbhd.org is licensed under CC BY 2.0 (https://ccsearch.creativecommons.org/photos/a9168311-78de-4cb7-a6ad-f92be8361d0e)_"},{"id":"dns-based-discovery","metadata":{"permalink":"/rlog/dns-based-discovery","source":"@site/rlog/2020-02-7-dns-based-discovery.mdx","title":"DNS Based Discovery","description":"A look at EIP-1459 and the benefits of DNS based discovery.","date":"2020-02-07T12:00:00.000Z","formattedDate":"February 7, 2020","tags":[],"readingTime":5.635,"hasTruncateMarker":true,"authors":[{"name":"Dean","twitter":"DeanEigenmann","github":"decanus","website":"https://dean.eigenmann.me","key":"dean"}],"frontMatter":{"layout":"post","name":"DNS Based Discovery","title":"DNS Based Discovery","date":"2020-02-07T12:00:00.000Z","authors":"dean","published":true,"slug":"dns-based-discovery","categories":"research"},"prevItem":{"title":"Waku Update","permalink":"/rlog/waku-update"},"nextItem":{"title":"Fixing Whisper with Waku","permalink":"/rlog/fixing-whisper-with-waku"}},"content":"A look at EIP-1459 and the benefits of DNS based discovery.\\n\\n\x3c!--truncate--\x3e\\n\\nDiscovery in p2p networks is the process of how nodes find each other and specific resources they are looking for. Popular discovery protocols, such as [Kademlia](https://pdos.csail.mit.edu/~petar/papers/maymounkov-kademlia-lncs.pdf) which utilizes a [distributed hash table](https://en.wikipedia.org/wiki/Distributed_hash_table) or DHT, are highly inefficient for resource restricted devices. These methods use short connection windows, and it is quite battery intensive to keep establishing connections. Additionally, we cannot expect a mobile phone for example to synchronize an entire DHT using cellular data.\\n\\nAnother issue is how we do the initial bootstrapping. In other words, how does a client find its first node to then discover the rest of the network? In most applications, including Status right now, this is done with a [static list of nodes](https://specs.status.im/spec/1#bootstrapping) that a client can connect to.\\n\\nIn summary, we have a static list that provides us with nodes we can connect to which then allows us to discover the rest of the network using something like Kademlia. But what we need is something that can easily be mutated, guarantees a certain amount of security, and is efficient for resource restricted devices. Ideally our solution would also be robust and scalable.\\n\\nHow do we do this?\\n\\n[EIP 1459: Node Discovery via DNS](https://eips.ethereum.org/EIPS/eip-1459), which is one of the strategies we are using for discovering waku nodes. [EIP-1459](https://eips.ethereum.org/EIPS/eip-1459) is a DNS-based discovery protocol that stores [merkle trees](https://en.wikipedia.org/wiki/Merkle_tree) in DNS records which contain connection information for nodes.\\n\\n_Waku is our fork of Whisper. Oskar recently wrote an [entire post](https://vac.dev/fixing-whisper-with-waku) explaining it. In short, Waku is our method of fixing the shortcomings of Whisper in a more iterative fashion. You can find the specification [here](https://rfc.vac.dev/spec/6/)_\\n\\nDNS-based methods for bootstrapping p2p networks are quite popular. Even Bitcoin uses it, but it uses a concept called DNS seeds, which are just DNS servers that are configured to return a list of randomly selected nodes from the network upon being queried. This means that although these seeds are hardcoded in the client, the IP addresses of actual nodes do not have to be.\\n\\n```console\\n> dig dnsseed.bluematt.me +short\\n129.226.73.12\\n107.180.78.111\\n169.255.56.123\\n91.216.149.28\\n85.209.240.91\\n66.232.124.232\\n207.55.53.96\\n86.149.241.168\\n193.219.38.57\\n190.198.210.139\\n74.213.232.234\\n158.181.226.33\\n176.99.2.207\\n202.55.87.45\\n37.205.10.3\\n90.133.4.73\\n176.191.182.3\\n109.207.166.232\\n45.5.117.59\\n178.211.170.2\\n160.16.0.30\\n```\\n\\nThe above displays the result of querying on of these DNS seeds. All the nodes are stored as [`A` records](https://simpledns.plus/help/a-records) for the given domain name. This is quite a simple solution which Bitcoin almost soley relies on since removing the [IRC bootstrapping method in v0.8.2](https://en.bitcoin.it/wiki/Network#IRC).\\n\\nWhat makes this DNS based discovery useful? It allows us to have a mutable list of bootstrap nodes without needing to ship a new version of the client every time a list is mutated. It also allows for a more lightweight method of discovering nodes, something very important for resource restricted devices.\\n\\nAdditionally, DNS provides us with a robust and scalable infrastructure. This is due to its hierarchical architecture. This hierarchical architecture also already makes it distributed such that the failure of one DNS server does not result in us no longer being able to resolve our name.\\n\\nAs with every solution though, there is a trade-off. By storing the list in DNS name an adversary would simply need to censor the DNS records for a specific name. This would prevent any new client trying to join the network from being able to do so.\\n\\nOne thing you notice when looking at [EIP-1459](https://eips.ethereum.org/EIPS/eip-1459) is that it is a lot more technically complex than Bitcoin\'s way of doing this. So if Bitcoin uses this simple method and has proven that it works, why did we need a new method?\\n\\nThere are multiple reasons, but the main one is **security**. In the Bitcoin example, an attacker could create a new list and no one querying would be able to tell. This is however mitigated in [EIP-1459](https://eips.ethereum.org/EIPS/eip-1459) where we can verify the integrity of the entire returned list by storing an entire merkle tree in the DNS records.\\n\\nLet\'s dive into this. Firstly, a client that is using these DNS records for discovery must know the public key corresponding to the private key controlled by the entity creating the list. This is because the entire list is signed using a secp256k1 private key, giving the client the ability to authenticate the list and know that it has not been tampered with by some external party.\\n\\nSo that already makes this a lot safer than the method Bitcoin uses. But how are these lists even stored? As previously stated they are stored using **merkle trees** as follows:\\n\\n- The root of the tree is stored in a [`TXT` record](https://simpledns.plus/help/txt-records), this record contains the tree\'s root hash, a sequence number which is incremented every time the tree is updated and a signature as stated above.\\n\\n Additionally, there is also a root hash to a second tree called a **link tree**, it contains the information to different lists. This link tree allows us to delegate trust and build a graph of multiple merkle trees stored across multiple DNS names.\\n\\n The sequence number ensures that an attacker cannot replace a tree with an older version because when a client reads the tree, they should ensure that the sequence number is greater than the last synchronized version.\\n\\n- Using the root hash for the tree, we can find the merkle tree\'s first branch, the branch is also stored in a `TXT` record. The branch record contains all the hashes of the branch\'s leafs.\\n\\n- Once a client starts reading all the leafs, they can find one of two things: either a new branch record leading them further down the tree or an Ethereum Name Records (ENR) which means they now have the address of a node to connect to! To learn more about ethereum node records you can have a look at [EIP-778](https://eips.ethereum.org/EIPS/eip-778), or read a short blog post I wrote explaining them [here](https://dean.eigenmann.me/blog/2020/01/21/network-addresses-in-ethereum/#enr).\\n\\nBelow is the zone file taken from the [EIP-1459](https://eips.ethereum.org/EIPS/eip-1459), displaying how this looks in practice.\\n\\n```\\n; name ttl class type content\\n@ 60 IN TXT enrtree-root:v1 e=JWXYDBPXYWG6FX3GMDIBFA6CJ4 l=C7HRFPF3BLGF3YR4DY5KX3SMBE seq=1 sig=o908WmNp7LibOfPsr4btQwatZJ5URBr2ZAuxvK4UWHlsB9sUOTJQaGAlLPVAhM__XJesCHxLISo94z5Z2a463gA\\nC7HRFPF3BLGF3YR4DY5KX3SMBE 86900 IN TXT enrtree://AM5FCQLWIZX2QFPNJAP7VUERCCRNGRHWZG3YYHIUV7BVDQ5FDPRT2@morenodes.example.org\\nJWXYDBPXYWG6FX3GMDIBFA6CJ4 86900 IN TXT enrtree-branch:2XS2367YHAXJFGLZHVAWLQD4ZY,H4FHT4B454P6UXFD7JCYQ5PWDY,MHTDO6TMUBRIA2XWG5LUDACK24\\n2XS2367YHAXJFGLZHVAWLQD4ZY 86900 IN TXT enr:-HW4QOFzoVLaFJnNhbgMoDXPnOvcdVuj7pDpqRvh6BRDO68aVi5ZcjB3vzQRZH2IcLBGHzo8uUN3snqmgTiE56CH3AMBgmlkgnY0iXNlY3AyNTZrMaECC2_24YYkYHEgdzxlSNKQEnHhuNAbNlMlWJxrJxbAFvA\\nH4FHT4B454P6UXFD7JCYQ5PWDY 86900 IN TXT enr:-HW4QAggRauloj2SDLtIHN1XBkvhFZ1vtf1raYQp9TBW2RD5EEawDzbtSmlXUfnaHcvwOizhVYLtr7e6vw7NAf6mTuoCgmlkgnY0iXNlY3AyNTZrMaECjrXI8TLNXU0f8cthpAMxEshUyQlK-AM0PW2wfrnacNI\\nMHTDO6TMUBRIA2XWG5LUDACK24 86900 IN TXT enr:-HW4QLAYqmrwllBEnzWWs7I5Ev2IAs7x_dZlbYdRdMUx5EyKHDXp7AV5CkuPGUPdvbv1_Ms1CPfhcGCvSElSosZmyoqAgmlkgnY0iXNlY3AyNTZrMaECriawHKWdDRk2xeZkrOXBQ0dfMFLHY4eENZwdufn1S1o\\n```\\n\\nAll of this has already been introduced into go-ethereum with the pull request [#20094](https://github.com/ethereum/go-ethereum/pull/20094), created by Felix Lange. There\'s a lot of tooling around it that already exists too which is really cool. So if your project is written in Golang and wants to use this, it\'s relatively simple! Additionally, here\'s a proof of concept that shows what this might look like with libp2p on [github](https://github.com/decanus/dns-discovery).\\n\\nI hope this was a helpful explainer into DNS based discovery, and shows [EIP-1459](https://eips.ethereum.org/EIPS/eip-1459)\'s benefits over more traditional DNS-based discovery schemes."},{"id":"fixing-whisper-with-waku","metadata":{"permalink":"/rlog/fixing-whisper-with-waku","source":"@site/rlog/2019-12-03-fixing-whisper-with-waku.mdx","title":"Fixing Whisper with Waku","description":"A research log. Why Whisper doesn\'t scale and how to fix it.","date":"2019-12-03T12:00:00.000Z","formattedDate":"December 3, 2019","tags":[],"readingTime":9.995,"hasTruncateMarker":true,"authors":[{"name":"Oskar","twitter":"oskarth","github":"oskarth","key":"oskarth"}],"frontMatter":{"layout":"post","name":"Fixing Whisper with Waku","title":"Fixing Whisper with Waku","date":"2019-12-03T12:00:00.000Z","authors":"oskarth","published":true,"slug":"fixing-whisper-with-waku","categories":"research","image":"/img/whisper_scalability.png","discuss":"https://forum.vac.dev/t/discussion-fixing-whisper-with-waku/27"},"prevItem":{"title":"DNS Based Discovery","permalink":"/rlog/dns-based-discovery"},"nextItem":{"title":"Feasibility Study: Semaphore rate limiting through zkSNARKs","permalink":"/rlog/feasibility-semaphore-rate-limiting-zksnarks"}},"content":"A research log. Why Whisper doesn\'t scale and how to fix it.\\n\\n\x3c!--truncate--\x3e\\n\\nThis post will introduce Waku. Waku is a fork of Whisper that attempts to\\naddresses some of Whisper\'s shortcomings in an iterative fashion. We will also\\nintroduce a theoretical scaling model for Whisper that shows why it doesn\'t\\nscale, and what can be done about it.\\n\\n## Introduction\\n\\nWhisper is a gossip-based communication protocol or an ephemeral key-value store\\ndepending on which way you look at it. Historically speaking, it is the\\nmessaging pilllar of [Web3](http://gavwood.com/dappsweb3.html), together with\\nEthereum for consensus and Swarm for storage.\\n\\nWhisper, being a somewhat esoteric protocol and with some fundamental issues,\\nhasn\'t seen a lot of usage. However, applications such as Status are using it,\\nand have been making minor ad hoc modifications to it to make it run on mobile\\ndevices.\\n\\nWhat are these fundamental issues? In short:\\n\\n1. scalability, most immediately when it comes to bandwidth usage\\n2. spam-resistance, proof of work is a poor mechanism for heterogeneous nodes\\n3. no incentivized infrastructure, leading to centralized choke points\\n4. lack of formal and unambiguous specification makes it hard to analyze and implement\\n5. running over devp2p, which limits where it can run and how\\n\\nIn this post, we\'ll focus on the first problem, which is scalability through bandwidth usage.\\n\\n## Whisper theoretical scalability model\\n\\n_(Feel free to skip this section if you want to get right to the results)._\\n\\nThere\'s widespread implicit knowledge that Whisper \\"doesn\'t scale\\", but it is less understood exactly why. This theoretical model attempts to encode some characteristics of it. Specifically for use case such as one by Status (see [Status Whisper usage\\nspec](https://specs.status.im/spec/3)).\\n\\n### Caveats\\n\\nFirst, some caveats: this model likely contains bugs, has wrong assumptions, or completely misses certain dimensions. However, it acts as a form of existence proof for unscalability, with clear reasons.\\n\\nIf certain assumptions are wrong, then we can challenge them and reason about them in isolation. It doesn\u2019t mean things will definitely work as the model predicts, and that there aren\u2019t unknown unknowns.\\n\\nThe model also only deals with receiving bandwidth for end nodes, uses mostly static assumptions of averages, and doesn\u2019t deal with spam resistance, privacy guarantees, accounting, intermediate node or network wide failures.\\n\\n### Goals\\n\\n1. Ensure network scales by being user or usage bound, as opposed to bandwidth growing in proportion to network size.\\n2. Staying with in a reasonable bandwidth limit for limited data plans.\\n3. Do the above without materially impacting existing nodes.\\n\\nIt proceeds through various case with clear assumptions behind them, starting from the most naive assumptions. It shows results for 100 users, 10k users and 1m users.\\n\\n### Model\\n\\n```\\nCase 1. Only receiving messages meant for you [naive case]\\n\\nAssumptions:\\n- A1. Envelope size (static): 1024kb\\n- A2. Envelopes / message (static): 10\\n- A3. Received messages / day (static): 100\\n- A4. Only receiving messages meant for you.\\n\\nFor 100 users, receiving bandwidth is 1000.0KB/day\\nFor 10k users, receiving bandwidth is 1000.0KB/day\\nFor 1m users, receiving bandwidth is 1000.0KB/day\\n\\n------------------------------------------------------------\\n\\nCase 2. Receiving messages for everyone [naive case]\\n\\nAssumptions:\\n- A1. Envelope size (static): 1024kb\\n- A2. Envelopes / message (static): 10\\n- A3. Received messages / day (static): 100\\n- A5. Received messages for everyone.\\n\\nFor 100 users, receiving bandwidth is 97.7MB/day\\nFor 10k users, receiving bandwidth is 9.5GB/day\\nFor 1m users, receiving bandwidth is 953.7GB/day\\n\\n------------------------------------------------------------\\n\\nCase 3. All private messages go over one discovery topic [naive case]\\n\\nAssumptions:\\n- A1. Envelope size (static): 1024kb\\n- A2. Envelopes / message (static): 10\\n- A3. Received messages / day (static): 100\\n- A6. Proportion of private messages (static): 0.5\\n- A7. Public messages only received by relevant recipients (static).\\n- A8. All private messages are received by everyone (same topic) (static).\\n\\nFor 100 users, receiving bandwidth is 49.3MB/day\\nFor 10k users, receiving bandwidth is 4.8GB/day\\nFor 1m users, receiving bandwidth is 476.8GB/day\\n\\n------------------------------------------------------------\\n\\nCase 4. All private messages are partitioned into shards [naive case]\\n\\nAssumptions:\\n- A1. Envelope size (static): 1024kb\\n- A2. Envelopes / message (static): 10\\n- A3. Received messages / day (static): 100\\n- A6. Proportion of private messages (static): 0.5\\n- A7. Public messages only received by relevant recipients (static).\\n- A9. Private messages partitioned across partition shards (static), n=5000\\n\\nFor 100 users, receiving bandwidth is 1000.0KB/day\\nFor 10k users, receiving bandwidth is 1.5MB/day\\nFor 1m users, receiving bandwidth is 98.1MB/day\\n\\n------------------------------------------------------------\\n\\nCase 5. 4 + Bloom filter with false positive rate\\n\\nAssumptions:\\n- A1. Envelope size (static): 1024kb\\n- A2. Envelopes / message (static): 10\\n- A3. Received messages / day (static): 100\\n- A6. Proportion of private messages (static): 0.5\\n- A7. Public messages only received by relevant recipients (static).\\n- A9. Private messages partitioned across partition shards (static), n=5000\\n- A10. Bloom filter size (m) (static): 512\\n- A11. Bloom filter hash functions (k) (static): 3\\n- A12. Bloom filter elements, i.e. topics, (n) (static): 100\\n- A13. Bloom filter assuming optimal k choice (sensitive to m, n).\\n- A14. Bloom filter false positive proportion of full traffic, p=0.1\\n\\nFor 100 users, receiving bandwidth is 10.7MB/day\\nFor 10k users, receiving bandwidth is 978.0MB/day\\nFor 1m users, receiving bandwidth is 95.5GB/day\\n\\nNOTE: Traffic extremely sensitive to bloom false positives\\nThis completely dominates network traffic at scale.\\nWith p=1% we get 10k users ~100MB/day and 1m users ~10gb/day)\\n\\n------------------------------------------------------------\\n\\nCase 6. Case 5 + Benign duplicate receives\\n\\nAssumptions:\\n- A1. Envelope size (static): 1024kb\\n- A2. Envelopes / message (static): 10\\n- A3. Received messages / day (static): 100\\n- A6. Proportion of private messages (static): 0.5\\n- A7. Public messages only received by relevant recipients (static).\\n- A9. Private messages partitioned across partition shards (static), n=5000\\n- A10. Bloom filter size (m) (static): 512\\n- A11. Bloom filter hash functions (k) (static): 3\\n- A12. Bloom filter elements, i.e. topics, (n) (static): 100\\n- A13. Bloom filter assuming optimal k choice (sensitive to m, n).\\n- A14. Bloom filter false positive proportion of full traffic, p=0.1\\n- A15. Benign duplicate receives factor (static): 2\\n- A16. No bad envelopes, bad PoW, expired, etc (static).\\n\\nFor 100 users, receiving bandwidth is 21.5MB/day\\nFor 10k users, receiving bandwidth is 1.9GB/day\\nFor 1m users, receiving bandwidth is 190.9GB/day\\n\\n------------------------------------------------------------\\n\\nCase 7. 6 + Mailserver under good conditions; small bloom fp; mostly offline\\n\\nAssumptions:\\n- A1. Envelope size (static): 1024kb\\n- A2. Envelopes / message (static): 10\\n- A3. Received messages / day (static): 100\\n- A6. Proportion of private messages (static): 0.5\\n- A7. Public messages only received by relevant recipients (static).\\n- A9. Private messages partitioned across partition shards (static), n=5000\\n- A10. Bloom filter size (m) (static): 512\\n- A11. Bloom filter hash functions (k) (static): 3\\n- A12. Bloom filter elements, i.e. topics, (n) (static): 100\\n- A13. Bloom filter assuming optimal k choice (sensitive to m, n).\\n- A14. Bloom filter false positive proportion of full traffic, p=0.1\\n- A15. Benign duplicate receives factor (static): 2\\n- A16. No bad envelopes, bad PoW, expired, etc (static).\\n- A17. User is offline p% of the time (static) p=0.9\\n- A18. No bad request, dup messages for mailservers; overlap perfect (static).\\n- A19. Mailserver requests can change false positive rate to be p=0.01\\n\\nFor 100 users, receiving bandwidth is 3.9MB/day\\nFor 10k users, receiving bandwidth is 284.8MB/day\\nFor 1m users, receiving bandwidth is 27.8GB/day\\n\\n------------------------------------------------------------\\n\\nCase 8. No metadata protection w bloom filter; 1 node connected; static shard\\n\\nAka waku mode.\\n\\nNext step up is to either only use contact code, or shard more aggressively.\\nNote that this requires change of other nodes behavior, not just local node.\\n\\nAssumptions:\\n- A1. Envelope size (static): 1024kb\\n- A2. Envelopes / message (static): 10\\n- A3. Received messages / day (static): 100\\n- A6. Proportion of private messages (static): 0.5\\n- A7. Public messages only received by relevant recipients (static).\\n- A9. Private messages partitioned across partition shards (static), n=5000\\n\\nFor 100 users, receiving bandwidth is 1000.0KB/day\\nFor 10k users, receiving bandwidth is 1.5MB/day\\nFor 1m users, receiving bandwidth is 98.1MB/day\\n\\n------------------------------------------------------------\\n```\\n\\nSee [source](https://github.com/vacp2p/research/tree/master/whisper_scalability)\\nfor more detail on the model and its assumptions.\\n\\n### Takeaways\\n\\n1. Whisper as it currently works doesn\u2019t scale, and we quickly run into unacceptable bandwidth usage.\\n2. There are a few factors of this, but largely it boils down to noisy topics usage and use of bloom filters. Duplicate (e.g. see [Whisper vs PSS](https://our.status.im/whisper-pss-comparison/)) and bad envelopes are also factors, but this depends a bit more on specific deployment configurations.\\n3. Waku mode (case 8) is an additional capability that doesn\u2019t require other nodes to change, for nodes that put a premium on performance.\\n4. The next bottleneck after this is the partitioned topics (app/network specific), which either needs to gracefully (and potentially quickly) grow, or an alternative way of consuming those messages needs to be deviced.\\n\\n![](/img/whisper_scalability.png)\\n\\nThe results are summarized in the graph above. Notice the log-log scale. The\\ncolored backgrounds correspond to the following bandwidth usage:\\n\\n- Blue: <10mb/d (<~300mb/month)\\n- Green: <30mb/d (<~1gb/month)\\n- Yellow: <100mb/d (<~3gb/month)\\n- Red: >100mb/d (>3gb/month)\\n\\nThese ranges are somewhat arbitrary, but are based on [user\\nrequirements](https://github.com/status-im/status-react/issues/9081) for users\\non a limited data plan, with comparable usage for other messaging apps.\\n\\n## Introducing Waku\\n\\n### Motivation for a new protocol\\n\\nApps such as Status will likely use something like Whisper for the forseeable\\nfuture, and we want to enable them to use it with more users on mobile devices\\nwithout bandwidth exploding with minimal changes.\\n\\nAdditionally, there\'s not a clear cut alternative that maps cleanly to the\\ndesired use cases (p2p, multicast, privacy-preserving, open, etc).\\n\\nWe are actively researching, developing and collaborating with more greenfield\\napproaches. It is likely that Waku will either converge to those, or Waku will\\nlay the groundwork (clear specs, common issues/components) necessary to make\\nswitching to another protocol easier. In this project we want to emphasize\\niterative work with results on the order of weeks.\\n\\n### Briefly on Waku mode\\n\\n- Doesn\u2019t impact existing clients, it\u2019s just a separate node and capability.\\n- Other nodes can still use Whisper as is, like a full node.\\n- Sacrifices metadata protection and incurs higher connectivity/availability requirements for scalbility\\n\\n**Requirements:**\\n\\n- Exposes API to get messages from a set of list of topics (no bloom filter)\\n- Way of being identified as a Waku node (e.g. through version string)\\n- Option to statically encode this node in app, e.g. similar to custom bootnodes/mailserver\\n- Only node that needs to be connected to, possibly as Whisper relay / mailserver hybrid\\n\\n**Provides:**\\n\\n- likely provides scalability of up to 10k users and beyond\\n- with some enhancements to partition topic logic, can possibly scale up to 1m users (app/network specific)\\n\\n**Caveats:**\\n\\n- hasn\u2019t been tested in a large-scale simulation\\n- other network and intermediate node bottlenecks might become apparent (e.g. full bloom filter and private cluster capacity; can likely be dealt with in isolation using known techniques, e.g. load balancing) (deployment specific)\\n\\n### Progress so far\\n\\nIn short, we have a [Waku version 0 spec up](https://rfc.vac.dev/spec/5) as well as a [PoC](https://github.com/status-im/nim-eth/pull/120) for backwards compatibility. In the coming weeks, we are going to solidify the specs, get a more fully featured PoC for [Waku mode](https://github.com/status-im/nim-eth/pull/114). See [rough roadmap](https://github.com/vacp2p/pm/issues/5), project board [link deprecated] and progress thread on the [Vac forum](https://forum.vac.dev/t/waku-project-and-progress/24).\\n\\nThe spec has been rewrittten for clarity, with ABNF grammar and less ambiguous language. The spec also incorporates several previously [ad hoc implemented features](https://rfc.vac.dev/spec/6/#additional-capabilities), such as light nodes and mailserver/client support. This has already caught a few incompatibilities between the `geth` (Go), `status/whisper` (Go) and `nim-eth` (Nim) versions, specifically around light node usage and the handshake.\\n\\nIf you are interested in this effort, please check out [our forum](https://forum.vac.dev/) for questions, comments and proposals. We already have some discussion for better [spam protection](https://forum.vac.dev/t/stake-priority-based-queuing/26) (see [previous post](https://vac.dev/feasibility-semaphore-rate-limiting-zksnarks) for a more complex but privacy-preserving proposal), something that is likely going to be addressed in future versions of Waku, along with many other fixes and enhancement."},{"id":"feasibility-semaphore-rate-limiting-zksnarks","metadata":{"permalink":"/rlog/feasibility-semaphore-rate-limiting-zksnarks","source":"@site/rlog/2019-11-08-feasibility-semaphore-rate-limiting-zksnarks.mdx","title":"Feasibility Study: Semaphore rate limiting through zkSNARKs","description":"A research log. Zero knowledge signaling as a rate limiting mechanism to prevent spam in p2p networks.","date":"2019-11-08T12:00:00.000Z","formattedDate":"November 8, 2019","tags":[],"readingTime":7.54,"hasTruncateMarker":true,"authors":[{"name":"Oskar","twitter":"oskarth","github":"oskarth","key":"oskarth"}],"frontMatter":{"layout":"post","name":"Feasibility Study: Semaphore rate limiting through zkSNARKs","title":"Feasibility Study: Semaphore rate limiting through zkSNARKs","date":"2019-11-08T12:00:00.000Z","authors":"oskarth","published":true,"slug":"feasibility-semaphore-rate-limiting-zksnarks","categories":"research","image":"/img/peacock-signaling.jpg","discuss":"https://forum.vac.dev/t/discussion-feasibility-study-semaphore-rate-limiting-through-zksnarks/21","toc_min_heading_level":2,"toc_max_heading_level":5},"prevItem":{"title":"Fixing Whisper with Waku","permalink":"/rlog/fixing-whisper-with-waku"},"nextItem":{"title":"P2P Data Sync with a Remote Log","permalink":"/rlog/remote-log"}},"content":"A research log. Zero knowledge signaling as a rate limiting mechanism to prevent spam in p2p networks.\\n\\n\x3c!--truncate--\x3e\\n\\n**tldr: Moon math promising for solving spam in Whisper, but to get there we need to invest more in performance work and technical upskilling.**\\n\\n## Motivating problem\\n\\nIn open p2p networks for messaging, one big problem is spam-resistance. Existing solutions, such as Whisper\'s proof of work, are insufficient, especially for heterogeneous nodes. Other reputation-based approaches might not be desirable, due to issues around arbitrary exclusion and privacy.\\n\\nOne possible solution is to use a right-to-access staking-based method, where a node is only able to send a message, signal, at a certain rate, and otherwise they can be slashed. One problem with this is in terms of privacy-preservation, where we specifically don\'t want a user to be tied to a specific payment or unique fingerprint.\\n\\n### Related problems\\n\\nIn addition to above, there are a lot of related problems that share similarities in terms of their structure and proposed solution.\\n\\n- Private transactions ([Zcash](https://z.cash/), [AZTEC](https://www.aztecprotocol.com/))\\n- Private voting ([Semaphore](https://github.com/kobigurk/semaphore))\\n- Private group membership (Semaphore)\\n- Layer 2 scaling, poss layer 1 ([ZK Rollup](https://ethresear.ch/t/on-chain-scaling-to-potentially-500-tx-sec-through-mass-tx-validation/3477); StarkWare/Eth2-3)\\n\\n## Overview\\n\\n## Basic terminology\\n\\nA _zero-knowledge proof_ allows a _prover_ to show a _verifier_ that they know something, without revealing what that something is. This means you can do trust-minimized computation that is also privacy preserving. As a basic example, instead of showing your ID when going to a bar you simply give them a proof that you are over 18, without showing the doorman your id.\\n\\n_zkSNARKs_ is a form of zero-knowledge proofs. There are many types of zero-knowledge proofs, and the field is evolving rapidly. They come with various trade-offs in terms of things such as: trusted setup, cryptographic assumptions, proof/verification key size, proof/verification time, proof size, etc. See section below for more.\\n\\n_Semaphore_ is a framework/library/construct on top of zkSNARks. It allows for zero-knowledge signaling, specifically on top of Ethereum. This means an approved user can broadcast some arbitrary string without revealing their identity, given some specific constraints. An approved user is someone who has been added to a certain merkle tree. See [current Github home](https://github.com/kobigurk/semaphore) for more.\\n\\n_Circom_ is a DSL for writing arithmetic circuits that can be used in zkSNARKs, similar to how you might write a NAND gate. See [Github](https://github.com/iden3/circom) for more.\\n\\n## Basic flow\\n\\nWe start with a private voting example, and then extend it to the slashable rate limiting example.\\n\\n1. A user registers an identity (arbitrary keypair), along with a small fee, to a smart contract. This adds them to a merkle tree and allows them to prove that they are member of that group, without revealing who they are.\\n\\n2. When a user wants to send a message, they compute a zero-knowledge proof. This ensures certain invariants, have some _public outputs_, and can be verified by anyone (including a smart contract).\\n3. Any node can verify the proof, including smart contracts on chain (as of Byzantinum HF). Additionally, a node can have rules for the public output. In the case of voting, one such rule is that a specific output hash has to be equal to some predefined value, such as \\"2020-01-01 vote on Foo Bar for president\\".\\n4. Because of how the proof is constructed, and the rules around output values, this ensures that: a user is part of the approved set of voters and that a user can only vote once.\\n5. As a consequence of above, we have a system where registered users can only vote once, no one can see who voted for what, and this can all be proven and verified.\\n\\n### Rate limiting example\\n\\nIn the case of rate limiting, we do want nodes to send multiple messages. This changes step 3-5 above somewhat.\\n\\n_NOTE: It is a bit more involved than this, and if we precompute proofs the flow might look a bit different. But the general idea is the same_.\\n\\n1. Instead of having a rule that you can only vote once, we have a rule that you can only send a message per epoch. Epoch here can be every second, as defined by UTC date time +-20s.\\n2. Additionally, if a users sends more than one message per epoch, one of the public outputs is a random share of a private key. Using Shamir\'s Secret Sharing (similar to a multisig) and 2/3 key share as an example threshold: in the normal case only 1/3 private keys is revealed, which is insufficient to have access. In the case where two messages are sent in an epoch, probabilistically 2/3 shares is sufficient to have access to the key (unless you get the same random share of the key).\\n3. This means any untrusted user who detects a spamming user, can use it to access their private key corresponding to funds in the contract, and thus slash them.\\n\\n4. As a consequence of above, we have a system where registered users can only messages X times per epoch, and no one can see who is sending what messages. Additionally, if a user is violating the above rate limit, they can be punished and any user can profit from it.\\n\\n### Briefly on scope of \'approved users\'\\n\\nIn the case of an application like Status, this construct can either be a global StatusNetwork group, or one per chat, or network, etc. It can be applied both at the network and user level. There are no specific limitations on where or who deploys this, and it is thus more of a UX consideration.\\n\\n## Technical details\\n\\nFor a fairly self-contained set of examples above, see exploration in [Vac research repo](https://github.com/vacp2p/research/blob/master/zksnarks/semaphore/src/hello.js). Note that the Shamir secret sharing is not inside the SNARK, but out-of-band for now.\\n\\nThe [current version](https://github.com/kobigurk/semaphore) of Semaphore is using NodeJS and [Circom](https://github.com/iden3/circom) from Iden3 for Snarks.\\n\\nFor more on rate limiting idea, see [ethresearch post](https://ethresear.ch/t/semaphore-rln-rate-limiting-nullifier-for-spam-prevention-in-anonymous-p2p-setting/5009/).\\n\\n## Feasibility\\n\\nThe above repo was used to exercise the basic paths and to gain intution of feasibility. Based on it and related reading we outline a few blockers and things that require further study.\\n\\n### Technical feasibility\\n\\n#### Proof time\\n\\nProve time for Semaphore () zKSNARKs using circom, groth and snarkjs is currently way too long. It takes on the order of ~10m to generate a proof. With Websnark, it is likely to take 30s, which might still be too long. We should experiment with native code on mobile here.\\n\\nSee [details](https://github.com/vacp2p/research/issues/7).\\n\\n#### Proving key size\\n\\nProver key size is ~110mb for Semaphore. Assuming this is embedded on mobile device, it bloats the APK a lot. Current APK size is ~30mb and even that might be high for people with limited bandwidth.\\n\\nSee [details](https://github.com/vacp2p/research/issues/8).\\n\\n#### Trusted setup\\n\\nUsing zkSNARKs a trusted setup is required to generate prover and verifier keys. As part of this setup, a toxic parameter lambda is generated. If a party gets access to this lambda, they can prove anything. This means people using zKSNARKs usually have an elaborate MPC ceremony to ensure this parameter doesn\'t get discovered.\\n\\nSee [details](https://github.com/vacp2p/research/issues/9).\\n\\n#### Shamir logic in SNARK\\n\\nFor [Semaphore RLN](https://ethresear.ch/t/semaphore-rln-rate-limiting-nullifier-for-spam-prevention-in-anonymous-p2p-setting/5009) we need to embed the Shamir logic inside the SNARK in order to do slashing for spam. Currently the [implementation](https://github.com/vacp2p/research/blob/master/zksnarks/semaphore/src/hello.js#L450) is trusted and very hacky.\\n\\nSee [details](https://github.com/vacp2p/research/issues/10).\\n\\n#### End to end integation\\n\\n[Currently](https://github.com/vacp2p/research/blob/master/zksnarks/semaphore/src/hello.js) is standalone and doesn\'t touch multiple users, deployed contract with merkle tree and verification, actual transactions, a mocked network, add/remove members, etc. There are bound to be edge cases and unknown unknowns here.\\n\\nSee [details](https://github.com/vacp2p/research/issues/11).\\n\\n#### Licensing issues\\n\\nCurrently Circom [uses a GPL license](https://github.com/iden3/circom/blob/master/COPYING), which can get tricky when it comes to the App Store etc.\\n\\nSee [details](https://github.com/vacp2p/research/issues/12).\\n\\n#### Alternative ZKPs?\\n\\nSome of the isolated blockers for zKSNARKs ([#7](https://github.com/vacp2p/research/issues/7), [#8](https://github.com/vacp2p/research/issues/8), [#9](https://github.com/vacp2p/research/issues/9)) might be mitigated by the use of other ZKP technology. However, they likely have their own issues.\\n\\nSee [details](https://github.com/vacp2p/research/issues/13).\\n\\n### Social feasibility\\n\\n#### Technical skill\\n\\nzkSNARKs and related technologies are quite new. To learn how they work and get an intuition for them requires individuals to dedicate a lot of time to studying them. This means we must make getting competence in these technologies if we wish to use them to our advantage.\\n\\n#### Time and resources\\n\\nIn order for this and related projects (such as private transaction) to get anywhere, it must be made an explicit area of focus for an extend period of time.\\n\\n## General thoughts\\n\\nSimilar to Whisper, and in line with moving towards protocol and infrastructure, we need to upskill and invest resources into this. This doesn\'t mean developing all of the technologies ourselves, but gaining enough competence to leverage and extend existing solutions by the growing ZKP community.\\n\\nFor example, this might also include leveraging largely ready made solutions such as AZTEC for private transaction; more fundamental research into ZK rollup and similar; using Semaphore for private group membership and private voting; Nim based wrapper aronud Bellman, etc.\\n\\n## Acknowledgement\\n\\nThanks to Barry Whitehat for patient explanation and pointers. Thanks to WJ for helping with runtime issues.\\n\\n_Peacock header image from [Tonos]().\\\\_"},{"id":"remote-log","metadata":{"permalink":"/rlog/remote-log","source":"@site/rlog/2019-10-04-remote-log.mdx","title":"P2P Data Sync with a Remote Log","description":"A research log. Asynchronous P2P messaging? Remote logs to the rescue!","date":"2019-10-04T12:00:00.000Z","formattedDate":"October 4, 2019","tags":[],"readingTime":4.515,"hasTruncateMarker":true,"authors":[{"name":"Oskar","twitter":"oskarth","github":"oskarth","key":"oskarth"}],"frontMatter":{"layout":"post","name":"P2P Data Sync with a Remote Log","title":"P2P Data Sync with a Remote Log","date":"2019-10-04T12:00:00.000Z","authors":"oskarth","published":true,"slug":"remote-log","categories":"research","summary":null,"image":"/img/remote-log.png"},"prevItem":{"title":"Feasibility Study: Semaphore rate limiting through zkSNARKs","permalink":"/rlog/feasibility-semaphore-rate-limiting-zksnarks"},"nextItem":{"title":"Vac - A Rough Overview","permalink":"/rlog/vac-overview"}},"content":"A research log. Asynchronous P2P messaging? Remote logs to the rescue!\\n\\n\x3c!--truncate--\x3e\\n\\nA big problem when doing end-to-end data sync between mobile nodes is that most devices are offline most of the time. With a naive approach, you quickly run into issues of \'ping-pong\' behavior, where messages have to be constantly retransmitted. We saw some basic calculations of what this bandwidth multiplier looks like in a [previous post](https://vac.dev/p2p-data-sync-for-mobile).\\n\\nWhile you could do some background processing, this is really battery-draining, and on iOS these capabilities are limited. A better approach instead is to loosen the constraint that two nodes need to be online at the same time. How do we do this? There are two main approaches, one is the _store and forward model_, and the other is a _remote log_.\\n\\nIn the _store and forward_ model, we use an intermediate node that forward messages on behalf of the recipient. In the _remote log_ model, you instead replicate the data onto some decentralized storage, and have a mutable reference to the latest state, similar to DNS. While both work, the latter is somewhat more elegant and \\"pure\\", as it has less strict requirements of an individual node\'s uptime. Both act as a highly-available cache to smoothen over non-overlapping connection windows between endpoints.\\n\\nIn this post we are going to describe how such a remote log schema could work. Specifically, how it enhances p2p data sync and takes care of the [following requirements](https://vac.dev/p2p-data-sync-for-mobile):\\n\\n> 3. MUST allow for mobile-friendly usage. By mobile-friendly we mean devices\\n> that are resource restricted, mostly-offline and often changing network.\\n\\n> 4. MAY use helper services in order to be more mobile-friendly. Examples of\\n> helper services are decentralized file storage solutions such as IPFS and\\n> Swarm. These help with availability and latency of data for mostly-offline\\n> devices.\\n\\n## Remote log\\n\\nA remote log is a replication of a local log. This means a node can read data from a node that is offline.\\n\\nThe spec is in an early draft stage and can be found [here](https://github.com/vacp2p/specs/pull/16). A very basic [spike]() / proof-of-concept can be found [here](https://github.com/vacp2p/research/tree/master/remote_log).\\n\\n### Definitions\\n\\n| Term | Definition |\\n| ---------- | ------------------------------------------------------------------------- |\\n| CAS | Content-addressed storage. Stores data that can be addressed by its hash. |\\n| NS | Name system. Associates mutable data to a name. |\\n| Remote log | Replication of a local log at a different location. |\\n\\n### Roles\\n\\nThere are four fundamental roles:\\n\\n1. Alice\\n2. Bob\\n3. Name system (NS)\\n4. Content-addressed storage (CAS)\\n\\nThe _remote log_ is the data format of what is stored in the name system.\\n\\n\\"Bob\\" can represent anything from 0 to N participants. Unlike Alice, Bob only needs read-only access to NS and CAS.\\n\\n### Flow\\n\\n![Figure 1: Remote log data synchronization.](/img/remote-log.png)\\n\\n### Data format\\n\\nThe remote log lets receiving nodes know what data they are missing. Depending on the specific requirements and capabilities of the nodes and name system, the information can be referred to differently. We distinguish between three rough modes:\\n\\n1. Fully replicated log\\n2. Normal sized page with CAS mapping\\n3. \\"Linked list\\" mode - minimally sized page with CAS mapping\\n\\nA remote log is simply a mapping from message identifiers to their corresponding address in a CAS:\\n\\n| Message Identifier (H1) | CAS Hash (H2) |\\n| ----------------------- | ------------- |\\n| H1_3 | H2_3 |\\n| H1_2 | H2_2 |\\n| H1_1 | H2_1 |\\n| | |\\n| _address to next page_ |\\n\\nThe numbers here corresponds to messages. Optionally, the content itself can be included, just like it normally would be sent over the wire. This bypasses the need for a dedicated CAS and additional round-trips, with a trade-off in bandwidth usage.\\n\\n| Message Identifier (H1) | Content |\\n| ----------------------- | ------- |\\n| H1_3 | C3 |\\n| H1_2 | C2 |\\n| H1_1 | C1 |\\n| | |\\n| _address to next page_ |\\n\\nBoth patterns can be used in parallel, e,g. by storing the last `k` messages directly and use CAS pointers for the rest. Together with the `next_page` page semantics, this gives users flexibility in terms of bandwidth and latency/indirection, all the way from a simple linked list to a fully replicated log. The latter is useful for things like backups on durable storage.\\n\\n### Interaction with MVDS\\n\\n[vac.mvds.Message](https://rfc.vac.dev/spec/2/#payloads) payloads are the only payloads that MUST be uploaded. Other messages types MAY be uploaded, depending on the implementation.\\n\\n## Future work\\n\\nThe spec is still in an early draft stage, so it is expected to change. Same with the proof of concept. More work is needed on getting a fully featured proof of concept with specific CAS and NAS instances. E.g. Swarm and Swarm Feeds, or IPFS and IPNS, or something else.\\n\\nFor data sync in general:\\n\\n- Make consistency guarantees more explicit for app developers with support for sequence numbers and DAGs, as well as the ability to send non-synced messages. E.g. ephemeral typing notifications, linear/sequential history and casual consistency/DAG history\\n- Better semantics and scalability for multi-user sync contexts, e.g. CRDTs and joining multiple logs together\\n- Better usability in terms of application layer usage (data sync clients) and supporting more transports\\n\\n---\\n\\nPS1. Thanks everyone who submitted great [logo proposals](https://explorer.bounties.network/bounty/3389) for Vac!\\n\\nPPS2. Next week on October 10th decanus and I will be presenting Vac at [Devcon](https://devcon.org/agenda), come say hi :)"},{"id":"vac-overview","metadata":{"permalink":"/rlog/vac-overview","source":"@site/rlog/2019-08-02-vac-overview.mdx","title":"Vac - A Rough Overview","description":"Vac is a modular peer-to-peer messaging stack, with a focus on secure messaging. Overview of terms, stack and open problems.","date":"2019-08-02T12:00:00.000Z","formattedDate":"August 2, 2019","tags":[],"readingTime":5.535,"hasTruncateMarker":true,"authors":[{"name":"Oskar","twitter":"oskarth","github":"oskarth","key":"oskarth"}],"frontMatter":{"layout":"post","name":"Vac - A Rough Overview","title":"Vac - A Rough Overview","date":"2019-08-02T12:00:00.000Z","authors":"oskarth","published":true,"slug":"vac-overview","categories":"research"},"prevItem":{"title":"P2P Data Sync with a Remote Log","permalink":"/rlog/remote-log"},"nextItem":{"title":"P2P Data Sync for Mobile","permalink":"/rlog/p2p-data-sync-for-mobile"}},"content":"Vac is a modular peer-to-peer messaging stack, with a focus on secure messaging. Overview of terms, stack and open problems.\\n\\n\x3c!--truncate--\x3e\\n\\nVac is a **modular peer-to-peer messaging stack, with a focus on secure messaging**. What does that mean? Let\'s unpack it a bit.\\n\\n## Basic terms\\n\\n_messaging stack_. While the initial focus is on [data sync](https://vac.dev/p2p-data-sync-for-mobile), we are concerned with all layers in the stack. That means all the way from underlying transports, p2p overlays and routing, to initial trust establishment and semantics for things like group chat. The ultimate goal is to give application developers the tools they need to provide secure messaging for their users, so they can focus on their domain expertise.\\n\\n_modular_. Unlike many other secure messaging applications, our goal is not to have a tightly coupled set of protocols, nor is it to reinvent the wheel. Instead, we aim to provide options at each layer in the stack, and build on the shoulders of giants, putting a premimum on interoperability. It\'s similar in philosophy to projects such as [libp2p](https://libp2p.io/) or [Substrate](https://www.parity.io/substrate/) in that regard. Each choice comes with different trade-offs, and these look different for different applications.\\n\\n_peer-to-peer_. The protocols we work on are pure p2p, and aim to minimize centralization. This too is in opposition to many initiatives in the secure messaging space.\\n\\n_messaging_. By messaging we mean messaging in a generalized sense. This includes both human to human communication, as well machine to machine communication. By messaging we also mean something more fundamental than text messages, we also include things like transactions (state channels, etc) under this moniker.\\n\\n_secure messaging_. Outside of traditional notions of secure messaging, such as ensuring end to end encryption, forward secrecy, avoiding MITM-attacks, etc, we are also concerned with two other forms of secure messaging. We call these _private messaging_ and _censorship-resistance_. Private messaging means viewing privacy as a security property, with all that entails. Censorship resistance ties into being p2p, but also in terms of allowing for transports and overlays that can\'t easily be censored by port blocking, traffic analysis, and similar.\\n\\n_V\u0101c_. Is a Vedic goddess of speech. It also hints at being a vaccine.\\n\\n## Protocol stack\\n\\nWhat does this stack look like? We take inspiration from [core](https://tools.ietf.org/html/rfc793) [internet architecture](https://www.ietf.org/rfc/rfc1122.txt), existing [survey work](https://css.csail.mit.edu/6.858/2020/readings/secure-messaging.pdf) and other [efforts](https://code.briarproject.org/briar/briar/wikis/A-Quick-Overview-of-the-Protocol-Stack) that have been done to decompose the problem into orthogonal pieces. Each layer provides their own set of properties and only interact with the layers it is adjacent to. Note that this is a rough sketch.\\n\\n| Layer / Protocol | Purpose | Examples |\\n| ------------------- | --------------------------------- | -------------------- |\\n| Application layer | End user semantics | 1:1 chat, group chat |\\n| Data Sync | Data consistency | MVDS, BSP |\\n| Secure Transport | Confidentiality, PFS, etc | Double Ratchet, MLS |\\n| Transport Privacy | Transport and metadata protection | Whisper, Tor, Mixnet |\\n| P2P Overlay | Overlay routing, NAT traversal | devp2p, libp2p |\\n| | |\\n| Trust Establishment | Establishing end-to-end trust | TOFU, web of trust |\\n\\nAs an example, end user semantics such as group chat or moderation capabilities can largely work regardless of specific choices further down the stack. Similarly, using a mesh network or Tor doesn\'t impact the use of Double Ratchet at the Secure Transport layer.\\n\\nData Sync plays a similar role to what TCP does at the transport layer in a traditional Internet architecture, and for some applications something more like UDP is likely to be desirable.\\n\\nIn terms of specific properties and trade-offs at each layer, we\'ll go deeper down into them as we study them. For now, this is best treated as a rough sketch or mental map.\\n\\n## Problems and rough priorities\\n\\nWith all the pieces involved, this is quite an undertaking. Luckily, a lot of pieces are already in place and can be either incorporated as-is or iterated on. In terms of medium and long term, here\'s a rough sketch of priorities and open problems.\\n\\n1. **Better data sync.** While the current [MVDS](https://rfc.vac.dev/spec/2/) works, it is lacking in a few areas:\\n\\n- Lack of remote log for mostly-offline offline devices\\n- Better scalability for multi-user chat contexts\\n- Better usability in terms of application layer usage and supporting more transports\\n\\n2. **Better transport layer support.** Currently MVDS runs primarily over Whisper, which has a few issues:\\n\\n- scalability, being able to run with many nodes\\n- spam-resistance, proof of work is a poor mechanism for heterogeneous devices\\n- no incentivized infrastructure, leading to centralized choke points\\n\\nIn addition to these most immediate concerns, there are other open problems. Some of these are overlapping with the above.\\n\\n3. **Adaptive nodes.** Better support for resource restricted devices and nodes of varying capabilities. Light connection strategy for resources and guarantees. Security games to outsource processing with guarantees.\\n\\n4. **Incentivized and spam-resistant messaging.** Reasons to run infrastructure and not relying on altruistic nodes. For spam resistance, in p2p multicast spam is a big attack vector due to amplification. There are a few interesting directions here, such as EigenTrust, proof of burn with micropayments, and leveraging zero-knowledge proofs.\\n\\n5. **Strong privacy guarantees at transport privacy layer**. More rigorous privacy guarantees and explicit trade-offs for metadata protection. Includes Mixnet.\\n6. **Censorship-resistant and robust P2P overlay**. NAT traversal; running in the browser; mesh networks; pluggable transports for traffic obfuscation.\\n\\n7. **Scalable and decentralized secure conversational security.** Strong security guarantees such as forward secrecy, post compromise security, for large group chats. Includes projects such MLS and extending Double Ratchet.\\n\\n8. **Better trust establishment and key handling**. Avoiding MITM attacks while still enabling a good user experience. Protecting against ghost users in group chat and providing better ways to do key handling.\\n\\nThere is also a set of more general problems, that touch multiple layers:\\n\\n9. **Ensuring modularity and interoperability**. Providing interfaces that allow for existing and new protocols to be at each layer of the stack.\\n\\n10. **Better specifications**. Machine-readable and formally verified specifications. More rigorous analysis of exact guarantees and behaviors. Exposing work in such a way that it can be analyzed by academics.\\n\\n11. **Better simulations**. Providing infrastructure and tooling to be able to test protocols in adverse environments and at scale.\\n\\n12. **Enabling excellent user experience**. A big reason for the lack of widespread adoption of secure messaging is the fact that more centralized, insecure methods provide a better user experience. Given that incentives can align better for users interested in secure messaging, providing an even better user experience should be doable.\\n\\n---\\n\\nWe got some work to do. Come help us if you want. See you in the next update!"},{"id":"p2p-data-sync-for-mobile","metadata":{"permalink":"/rlog/p2p-data-sync-for-mobile","source":"@site/rlog/2019-07-19-p2p-data-sync-for-mobile.mdx","title":"P2P Data Sync for Mobile","description":"A research log. Reliable and decentralized, pick two.","date":"2019-07-19T12:00:00.000Z","formattedDate":"July 19, 2019","tags":[],"readingTime":11.01,"hasTruncateMarker":true,"authors":[{"name":"Oskar","twitter":"oskarth","github":"oskarth","key":"oskarth"}],"frontMatter":{"title":"P2P Data Sync for Mobile","date":"2019-07-19T12:00:00.000Z","authors":"oskarth","published":true,"slug":"p2p-data-sync-for-mobile","categories":"research","image":"/img/mvds_interactive.png","toc_min_heading_level":2,"toc_max_heading_level":5},"prevItem":{"title":"Vac - A Rough Overview","permalink":"/rlog/vac-overview"}},"content":"A research log. Reliable and decentralized, pick two.\\n\\n\x3c!--truncate--\x3e\\n\\nTogether with decanus, I\'ve been working on the problem of data sync lately.\\n\\nIn building p2p messaging systems, one problem you quickly come across is the problem of reliably transmitting data. If there\'s no central server with high availability guarantees, you can\'t meaningfully guarantee that data has been transmitted. One way of solving this problem is through a synchronization protocol.\\n\\nThere are many synchronization protocols out there and I won\'t go into detail of how they differ with our approach here. Some common examples are Git and Bittorrent, but there are also projects like IPFS, Swarm, Dispersy, Matrix, Briar, SSB, etc.\\n\\n## Problem motivation\\n\\nWhy do we want to do p2p sync for mobilephones in the first place? There are three components to that question. One is on the value of decentralization and peer-to-peer, the second is on why we\'d want to reliably sync data at all, and finally why mobilephones and other resource restricted devices.\\n\\n### Why p2p?\\n\\nFor decentralization and p2p, there are both technical and social/philosophical reasons. Technically, having a user-run network means it can scale with the number of users. Data locality is also improved if you query data that\'s close to you, similar to distributed CDNs. The throughput is also improved if there are more places to get data from.\\n\\nSocially and philosophically, there are several ways to think about it. Open and decentralized networks also relate to the idea of open standards, i.e. compare the longevity of AOL with IRC or Bittorrent. One is run by a company and is shut down as soon as it stops being profitable, the others live on. Additionally increasingly control of data and infrastructure is becoming a liability. By having a network with no one in control, everyone is. It\'s ultimately a form of democratization, more similar to organic social structures pre Big Internet companies. This leads to properties such as censorship resistance and coercion resistance, where we limit the impact a 3rd party might have a voluntary interaction between individuals or a group of people. Examples of this are plentiful in the world of Facebook, Youtube, Twitter and WeChat.\\n\\n### Why reliably sync data?\\n\\nAt risk of stating the obvious, reliably syncing data is a requirement for many problem domains. You don\'t get this by default in a p2p world, as it is unreliable with nodes permissionslessly join and leave the network. In some cases you can get away with only ephemeral data, but usually you want some kind of guarantees. This is a must for reliable group chat experience, for example, where messages are expected to arrive in a timely fashion and in some reasonable order. The same is true for messages there represent financial transactions, and so on.\\n\\n### Why mobilephones?\\n\\nMost devices people use daily are mobile phones. It\'s important to provide the same or at least similar guarantees to more traditional p2p nodes that might run on a desktop computer or computer. The alternative is to rely on gateways, which shares many of the drawbacks of centralized control and prone to censorship, control and surveillence.\\n\\nMore generally, resource restricted devices can differ in their capabilities. One example is smartphones, but others are: desktop, routers, Raspberry PIs, POS systems, and so on. The number and diversity of devices are exploding, and it\'s useful to be able to leverage this for various types of infrastructure. The alternative is to centralize on big cloud providers, which also lends itself to lack of democratization and censorship, etc.\\n\\n## Minimal Requirements\\n\\nFor requirements or design goals for a solution, here\'s what we came up with.\\n\\n1. MUST sync data reliably between devices. By reliably we mean having the ability to deal with messages being out of order, dropped, duplicated, or delayed.\\n\\n2. MUST NOT rely on any centralized services for reliability. By centralized services we mean any single point of failure that isn\u2019t one of the endpoint devices.\\n\\n3. MUST allow for mobile-friendly usage. By mobile-friendly we mean devices that are resource restricted, mostly-offline and often changing network.\\n\\n4. MAY use helper services in order to be more mobile-friendly. Examples of helper services are decentralized file storage solutions such as IPFS and Swarm. These help with availability and latency of data for mostly-offline devices.\\n\\n5. MUST have the ability to provide casual consistency. By casual consistency we mean the commonly accepted definition in distributed systems literature. This means messages that are casually related can achieve a partial ordering.\\n\\n6. MUST support ephemeral messages that don\u2019t need replication. That is, allow for messages that don\u2019t need to be reliabily transmitted but still needs to be transmitted between devices.\\n\\n7. MUST allow for privacy-preserving messages and extreme data loss. By privacy-preserving we mean things such as exploding messages (self-destructing messages). By extreme data loss we mean the ability for two trusted devices to recover from a, deliberate or accidental, removal of data.\\n\\n8. MUST be agnostic to whatever transport it is running on. It should not rely on specific semantics of the transport it is running on, nor be tightly coupled with it. This means a transport can be swapped out without loss of reliability between devices.\\n\\n## MVDS - a minimium viable version\\n\\nThe first minimum viable version is in an alpha stage, and it has a [specification](https://rfc.vac.dev/spec/2), [implementation](https://github.com/vacp2p/mvds) and we have deployed it in a [console client](https://github.com/status-im/status-console-client) for end to end functionality. It\'s heavily inspired by [Bramble Sync Protocol](https://code.briarproject.org/briar/briar-spec/blob/master/protocols/BSP.md).\\n\\nThe spec is fairly minimal. You have nodes that exchange records over some secure transport. These records are of different types, such as `OFFER`, `MESSAGE`, `REQUEST`, and `ACK`. A peer keep tracks of the state of message for each node it is interacting with. There\'s also logic for message retransmission with exponential delay. The positive ACK and retransmission model is quite similar to how TCP is designed.\\n\\nThere are two different modes of syncing, interactive and batch mode. See sequence diagrams below.\\n\\nInteractive mode:\\n![Interactive mode](/img/mvds_interactive.png)\\n\\nBatch mode:\\n![Batch mode](/img/mvds_batch.png)\\n\\nWhich mode should you choose? It\'s a tradeoff of latency and bandwidth. If you want to minimize latency, batch mode is better. If you care about preserving bandwidth interactive mode is better. The choice is up to each node.\\n\\n### Basic simulation\\n\\nInitial ad hoc bandwidth and latency testing shows some issues with a naive approach. Running with the [default simulation settings](https://github.com/vacp2p/mvds/):\\n\\n- communicating nodes: 2\\n- nodes using interactive mode: 2\\n- interval between messages: 5s\\n- time node is offine: 90%\\n- nodes each node is sharing with: 2\\n\\nwe notice a [huge overhead](https://notes.status.im/7QYa4b6bTH2wMk3HfAaU0w#). More specifically, we see a ~5 minute latency overhead and a bandwidth multiplier of x100-1000, i.e. 2-3 orders of magnitude just for receiving a message with interactive mode, without acks.\\n\\nNow, that seems terrible. A moment of reflection will reveal why that is. If each node is offline uniformly 90% of the time, that means that each record will be lost 90% of the time. Since interactive mode requires offer, request, payload (and then ack), that\'s three links just for Bob to receive the actual message.\\n\\nEach failed attempt implies another retransmission. That means we have `(1/0.1)^3 = 1000` expected overhead to receive a message in interactive mode. The latency follows naturally from that, with the retransmission logic.\\n\\n### Mostly-offline devices\\n\\nThe problem above hints at the requirements 3 and 4 above. While we did get reliable syncing (requirement 1), it came at a big cost.\\n\\nThere are a few ways of getting around this issue. One is having a _store and forward_ model, where some intermediary node picks up (encrypted) messages and forwards them to the recipient. This is what we have in production right now at Status.\\n\\nAnother, arguably more pure and robust, way is having a _remote log_, where the actual data is spread over some decentralized storage layer, and you have a mutable reference to find the latest messages, similar to DNS.\\n\\nWhat they both have in common is that they act as a sort of highly-available cache to smooth over the non-overlapping connection windows between two endpoints. Neither of them are _required_ to get reliable data transmission.\\n\\n### Basic calculations for bandwidth multiplier\\n\\nWhile we do want better simulations, and this is a work in progress, we can also look at the above scenarios using some basic calculations. This allows us to build a better intuition and reason about the problem without having to write code. Let\'s start with some assumptions:\\n\\n- two nodes exchanging a single message in batch mode\\n- 10% uniformly random uptime for each node\\n- in HA cache case, 100% uptime of a piece of infrastructure C\\n- retransmission every epoch (with constant or exponential backoff)\\n- only looking at average (p50) case\\n\\n#### First case, no helper services\\n\\nA sends a message to B, and B acks it.\\n\\n```\\nA message -> B (10% chance of arrival)\\nA <- ack B (10% chance of arrival)\\n```\\n\\nWith a constant backoff, A will send messages at epoch `1, 2, 3, ...`. With exponential backoff and a multiplier of 2, this would be `1, 2, 4, 8, ...`. Let\'s assume constant backoff for now, as this is what will influence the success rate and thus the bandwidth multiplier.\\n\\nThere\'s a difference between _time to receive_ and _time to stop sending_. Assuming each send attempt is independent, it takes on average 10 epochs for A\'s message to arrive with B. Furthermore:\\n\\n1. A will send messages until it receives an ACK.\\n2. B will send ACK if it receives a message.\\n\\nTo get an average of one ack through, A needs to send 100 messages, and B send on average 10 acks. That\'s a multiplier of roughly a 100. That\'s roughly what we saw with the simulation above for receiving a message in interactive mode.\\n\\n#### Second case, high-availability caching layer\\n\\nLet\'s introduce a helper node or piece of infrastructure, C. Whenever A or B sends a message, it also sends it to C. Whenever A or B comes online, it queries for messages with C.\\n\\n```\\nA message -> B (10% chance of arrival)\\nA message -> C (100% chance of arrival)\\nB <- req/res -> C (100% chance of arrival)\\nA <- ack B (10% chance of arrival)\\nC <- ack B (100% chance of arrival)\\nA <- req/res -> C (100% chance of arrival)\\n```\\n\\nWhat\'s the probability that A\'s messages will arrive at B? Directly, it\'s still 10%. But we can assume it\'s 100% that C picks up the message. (Giving C a 90% chance success rate doesn\'t materially change the numbers).\\n\\nB will pick up A\'s message from C after an average of 10 epochs. Then B will send ack to A, which will also be picked up by C 100% of the time. Once A comes online again, it\'ll query C and receive B\'s ack.\\n\\nAssuming we use exponential backoff with a multiplier of 2, A will send a message directly to B at epoch `1, 2, 4, 8` (assuming it is online). At this point, epoch `10`, B will be online in the average case. These direct sends will likely fail, but B will pick the message up from C and send one ack, both directly to A and to be picked up by C. Once A comes online, it\'ll query C and receive the ack from B, which means it won\'t do any more retransmits.\\n\\nHow many messages have been sent? Not counting interactions with C, A sends 4 (at most) and B 1. Depending on if the interaction with C is direct or indirect (i.e. multicast), the factor for interaction with C will be ~2. This means the total bandwidth multiplier is likely to be `<10`, which is a lot more acceptable.\\n\\nSince the syncing semantics are end-to-end, this is without relying on the reliablity of C.\\n\\n#### Caveat\\n\\nNote that both of these are probabilistic argument. They are also based on heuristics. More formal analysis would be desirable, as well as better simulations to experimentally verify them. In fact, the calculations could very well be wrong!\\n\\n## Future work\\n\\nThere are many enhancements that can be made and are desirable. Let\'s outline a few.\\n\\n1. Data sync clients. Examples of actual usage of data sync, with more interesting domain semantics. This also includes usage of sequence numbers and DAGs to know what content is missing and ought to be synced.\\n\\n2. Remote log. As alluded to above, this is necessary. It needs a more clear specification and solid proof of concepts.\\n\\n3. More efficient ways of syncing with large number of nodes. When the number of nodes goes up, the algorithmic complexity doesn\'t look great. This also touches on things such as ambient content discovery.\\n\\n4. More robust simulations and real-world deployments. Exisiting simulation is ad hoc, and there are many improvements that can be made to gain more confidence and identify issues. Additionally, better formal analysis.\\n\\n5. Example usage over multiple transports. Including things like sneakernet and meshnets. The described protocol is designed to work over unstructured, structured and private p2p networks. In some cases it can leverage differences in topology, such as multicast, or direct connections."}]}')}}]); \ No newline at end of file diff --git a/assets/js/a413eb42.4fd28c32.js b/assets/js/a413eb42.4fd28c32.js deleted file mode 100644 index f5fa7ed9..00000000 --- a/assets/js/a413eb42.4fd28c32.js +++ /dev/null @@ -1 +0,0 @@ -(self.webpackChunkvac_dev=self.webpackChunkvac_dev||[]).push([[9834],{67124:(e,i,n)=>{"use strict";var t=n(65701);n.o(t,"Box")&&n.d(i,{Box:function(){return t.Box}}),n.o(t,"Grid")&&n.d(i,{Grid:function(){return t.Grid}}),n.o(t,"JobsPerDepartment")&&n.d(i,{JobsPerDepartment:function(){return t.JobsPerDepartment}}),n.o(t,"SocialCard")&&n.d(i,{SocialCard:function(){return t.SocialCard}})},73673:(e,i,n)=>{"use strict";n.r(i),n.d(i,{assets:()=>c,contentTitle:()=>l,default:()=>m,frontMatter:()=>r,metadata:()=>_,toc:()=>p});var t=n(87462),d=(n(67294),n(3905));const a=JSON.parse('{"departments":[{"id":87842,"name":"App","parent_id":43806,"child_ids":[87847,87852,87850,87848,45530,87849],"jobs":[]},{"id":54504,"name":"Brand Design Studio","parent_id":null,"child_ids":[],"jobs":[]},{"id":45532,"name":"Business Development","parent_id":null,"child_ids":[],"jobs":[]},{"id":87841,"name":"Codex","parent_id":43806,"child_ids":[],"jobs":[]},{"id":84549,"name":"Communications","parent_id":null,"child_ids":[],"jobs":[]},{"id":45531,"name":"Design","parent_id":null,"child_ids":[],"jobs":[]},{"id":87847,"name":"Desktop","parent_id":87842,"child_ids":[],"jobs":[]},{"id":87852,"name":"Documentation","parent_id":87842,"child_ids":[],"jobs":[]},{"id":45547,"name":"Engineering ","parent_id":null,"child_ids":[],"jobs":[]},{"id":49925,"name":"Finance","parent_id":87845,"child_ids":[],"jobs":[]},{"id":87854,"name":"Infrastructure","parent_id":43806,"child_ids":[],"jobs":[]},{"id":87853,"name":"Insights","parent_id":87845,"child_ids":[],"jobs":[]},{"id":87850,"name":"Keycard","parent_id":87842,"child_ids":[],"jobs":[]},{"id":145838,"name":"Leadership","parent_id":null,"child_ids":[],"jobs":[]},{"id":74156,"name":"Legal","parent_id":87845,"child_ids":[],"jobs":[]},{"id":91698,"name":"Logos","parent_id":null,"child_ids":[],"jobs":[]},{"id":43807,"name":"Marketing","parent_id":null,"child_ids":[],"jobs":[]},{"id":87848,"name":"Mobile","parent_id":87842,"child_ids":[],"jobs":[]},{"id":87843,"name":"Nimbus","parent_id":43806,"child_ids":[],"jobs":[]},{"id":144866,"name":"Nomos","parent_id":43806,"child_ids":[],"jobs":[]},{"id":45548,"name":"People Operations","parent_id":87845,"child_ids":[],"jobs":[]},{"id":45530,"name":"Product Design","parent_id":87842,"child_ids":[],"jobs":[]},{"id":90941,"name":"Program Management","parent_id":null,"child_ids":[],"jobs":[]},{"id":43806,"name":"Research & Development","parent_id":null,"child_ids":[87842,87841,87854,87843,144866,87846,87981,87847,87852,87850,87848,45530,87849],"jobs":[]},{"id":87851,"name":"Security","parent_id":87845,"child_ids":[],"jobs":[]},{"id":87845,"name":"Services","parent_id":null,"child_ids":[49925,87853,74156,45548,87851],"jobs":[]},{"id":91697,"name":"Status App ","parent_id":null,"child_ids":[],"jobs":[]},{"id":216509,"name":"Status Network","parent_id":null,"child_ids":[],"jobs":[]},{"id":54783,"name":"Technical Writing ","parent_id":null,"child_ids":[],"jobs":[]},{"id":87846,"name":"Vac","parent_id":43806,"child_ids":[],"jobs":[{"absolute_url":"https://boards.greenhouse.io/vac/jobs/5671819","data_compliance":[{"type":"gdpr","requires_consent":false,"requires_processing_consent":false,"requires_retention_consent":false,"retention_period":null}],"internal_job_id":2778364,"location":{"name":"Remote (Worldwide)"},"metadata":null,"id":5671819,"updated_at":"2024-04-29T11:27:14-04:00","requisition_id":"BACK-1205","title":"Libp2p Networking Engineer"},{"absolute_url":"https://boards.greenhouse.io/vac/jobs/5700917","data_compliance":[{"type":"gdpr","requires_consent":false,"requires_processing_consent":false,"requires_retention_consent":false,"retention_period":null}],"internal_job_id":2785448,"location":{"name":"Remote (Worldwide)"},"metadata":null,"id":5700917,"updated_at":"2024-07-30T12:42:59-04:00","requisition_id":"BACK-1330","title":"Software Developer in Test (Low Level Programming)"},{"absolute_url":"https://boards.greenhouse.io/vac/jobs/5543925","data_compliance":[{"type":"gdpr","requires_consent":false,"requires_processing_consent":false,"requires_retention_consent":false,"retention_period":null}],"internal_job_id":2735796,"location":{"name":"Remote (Worldwide)"},"metadata":null,"id":5543925,"updated_at":"2024-04-29T11:27:14-04:00","requisition_id":"Back-1245","title":"Zero Knowledge Research Engineer (ACZ)"},{"absolute_url":"https://boards.greenhouse.io/vac/jobs/5453093","data_compliance":[{"type":"gdpr","requires_consent":false,"requires_processing_consent":false,"requires_retention_consent":false,"retention_period":null}],"internal_job_id":2331302,"location":{"name":"Remote (Worldwide)"},"metadata":null,"id":5453093,"updated_at":"2024-04-29T11:27:14-04:00","requisition_id":"PROV-ZKE-1","title":"Zero Knowledge Researcher (Nescience) "}]},{"id":87981,"name":"Waku","parent_id":43806,"child_ids":[],"jobs":[]},{"id":87849,"name":"Web","parent_id":87842,"child_ids":[],"jobs":[]},{"id":0,"name":"No Department","parent_id":null,"child_ids":[],"jobs":[]}]}');var s=n.t(a,2),o=n(67124);const r={title:"Join Us",hide_title:!0,pagination_prev:null,pagination_next:null,displayed_sidebar:null,hide_table_of_contents:!0},l=void 0,_={unversionedId:"join-us",id:"join-us",title:"Join Us",description:"",source:"@site/docs/join-us.mdx",sourceDirName:".",slug:"/join-us",permalink:"/join-us",draft:!1,tags:[],version:"current",frontMatter:{title:"Join Us",hide_title:!0,pagination_prev:null,pagination_next:null,displayed_sidebar:null,hide_table_of_contents:!0}},c={},p=[],u={toc:p};function m(e){let{components:i,...n}=e;return(0,d.kt)("wrapper",(0,t.Z)({},u,n,{components:i,mdxType:"MDXLayout"}),(0,d.kt)(o.JobsPerDepartment,{jobData:s,mdxType:"JobsPerDepartment"}))}m.isMDXComponent=!0},46102:()=>{}}]); \ No newline at end of file diff --git a/assets/js/a413eb42.cbda4164.js b/assets/js/a413eb42.cbda4164.js new file mode 100644 index 00000000..09e09a14 --- /dev/null +++ b/assets/js/a413eb42.cbda4164.js @@ -0,0 +1 @@ +(self.webpackChunkvac_dev=self.webpackChunkvac_dev||[]).push([[9834],{67124:(e,i,n)=>{"use strict";var d=n(65701);n.o(d,"Box")&&n.d(i,{Box:function(){return d.Box}}),n.o(d,"Grid")&&n.d(i,{Grid:function(){return d.Grid}}),n.o(d,"JobsPerDepartment")&&n.d(i,{JobsPerDepartment:function(){return d.JobsPerDepartment}}),n.o(d,"SocialCard")&&n.d(i,{SocialCard:function(){return d.SocialCard}})},73673:(e,i,n)=>{"use strict";n.r(i),n.d(i,{assets:()=>c,contentTitle:()=>l,default:()=>m,frontMatter:()=>r,metadata:()=>_,toc:()=>p});var d=n(87462),t=(n(67294),n(3905));const a=JSON.parse('{"departments":[{"id":87842,"name":"App","parent_id":43806,"child_ids":[87847,87852,87850,87848,45530,87849],"jobs":[]},{"id":54504,"name":"Brand Design Studio","parent_id":null,"child_ids":[],"jobs":[]},{"id":45532,"name":"Business Development","parent_id":null,"child_ids":[],"jobs":[]},{"id":87841,"name":"Codex","parent_id":43806,"child_ids":[],"jobs":[]},{"id":84549,"name":"Communications","parent_id":null,"child_ids":[],"jobs":[]},{"id":45531,"name":"Design","parent_id":null,"child_ids":[],"jobs":[]},{"id":87847,"name":"Desktop","parent_id":87842,"child_ids":[],"jobs":[]},{"id":87852,"name":"Documentation","parent_id":87842,"child_ids":[],"jobs":[]},{"id":45547,"name":"Engineering ","parent_id":null,"child_ids":[],"jobs":[]},{"id":49925,"name":"Finance","parent_id":87845,"child_ids":[],"jobs":[]},{"id":87854,"name":"Infrastructure","parent_id":43806,"child_ids":[],"jobs":[]},{"id":87853,"name":"Insights","parent_id":87845,"child_ids":[],"jobs":[]},{"id":87850,"name":"Keycard","parent_id":87842,"child_ids":[],"jobs":[]},{"id":145838,"name":"Leadership","parent_id":null,"child_ids":[],"jobs":[]},{"id":74156,"name":"Legal","parent_id":87845,"child_ids":[],"jobs":[]},{"id":91698,"name":"Logos","parent_id":null,"child_ids":[],"jobs":[]},{"id":43807,"name":"Marketing","parent_id":null,"child_ids":[],"jobs":[]},{"id":87848,"name":"Mobile","parent_id":87842,"child_ids":[],"jobs":[]},{"id":87843,"name":"Nimbus","parent_id":43806,"child_ids":[],"jobs":[]},{"id":144866,"name":"Nomos","parent_id":43806,"child_ids":[],"jobs":[]},{"id":45548,"name":"People Operations","parent_id":87845,"child_ids":[],"jobs":[]},{"id":45530,"name":"Product Design","parent_id":87842,"child_ids":[],"jobs":[]},{"id":90941,"name":"Program Management","parent_id":null,"child_ids":[],"jobs":[]},{"id":43806,"name":"Research & Development","parent_id":null,"child_ids":[87842,87841,87854,87843,144866,87846,87981,87847,87852,87850,87848,45530,87849],"jobs":[]},{"id":87851,"name":"Security","parent_id":87845,"child_ids":[],"jobs":[]},{"id":87845,"name":"Services","parent_id":null,"child_ids":[49925,87853,74156,45548,87851],"jobs":[]},{"id":91697,"name":"Status App ","parent_id":null,"child_ids":[],"jobs":[]},{"id":216509,"name":"Status Network","parent_id":null,"child_ids":[],"jobs":[]},{"id":54783,"name":"Technical Writing ","parent_id":null,"child_ids":[],"jobs":[]},{"id":87846,"name":"Vac","parent_id":43806,"child_ids":[],"jobs":[{"absolute_url":"https://boards.greenhouse.io/vac/jobs/6258104","data_compliance":[{"type":"gdpr","requires_consent":false,"requires_processing_consent":false,"requires_retention_consent":false,"retention_period":null}],"internal_job_id":2964440,"location":{"name":"Remote (Worldwide)"},"metadata":null,"id":6258104,"updated_at":"2024-09-17T08:45:19-04:00","requisition_id":"BACK-1469","title":"Networking Engineer P2P "},{"absolute_url":"https://boards.greenhouse.io/vac/jobs/5543925","data_compliance":[{"type":"gdpr","requires_consent":false,"requires_processing_consent":false,"requires_retention_consent":false,"retention_period":null}],"internal_job_id":2735796,"location":{"name":"Remote (Worldwide)"},"metadata":null,"id":5543925,"updated_at":"2024-04-29T11:27:14-04:00","requisition_id":"Back-1245","title":"Zero Knowledge Research Engineer (ACZ)"},{"absolute_url":"https://boards.greenhouse.io/vac/jobs/5453093","data_compliance":[{"type":"gdpr","requires_consent":false,"requires_processing_consent":false,"requires_retention_consent":false,"retention_period":null}],"internal_job_id":2331302,"location":{"name":"Remote (Worldwide)"},"metadata":null,"id":5453093,"updated_at":"2024-04-29T11:27:14-04:00","requisition_id":"PROV-ZKE-1","title":"Zero Knowledge Researcher (Nescience) "}]},{"id":87981,"name":"Waku","parent_id":43806,"child_ids":[],"jobs":[]},{"id":87849,"name":"Web","parent_id":87842,"child_ids":[],"jobs":[]},{"id":0,"name":"No Department","parent_id":null,"child_ids":[],"jobs":[]}]}');var s=n.t(a,2),o=n(67124);const r={title:"Join Us",hide_title:!0,pagination_prev:null,pagination_next:null,displayed_sidebar:null,hide_table_of_contents:!0},l=void 0,_={unversionedId:"join-us",id:"join-us",title:"Join Us",description:"",source:"@site/docs/join-us.mdx",sourceDirName:".",slug:"/join-us",permalink:"/join-us",draft:!1,tags:[],version:"current",frontMatter:{title:"Join Us",hide_title:!0,pagination_prev:null,pagination_next:null,displayed_sidebar:null,hide_table_of_contents:!0}},c={},p=[],u={toc:p};function m(e){let{components:i,...n}=e;return(0,t.kt)("wrapper",(0,d.Z)({},u,n,{components:i,mdxType:"MDXLayout"}),(0,t.kt)(o.JobsPerDepartment,{jobData:s,mdxType:"JobsPerDepartment"}))}m.isMDXComponent=!0},46102:()=>{}}]); \ No newline at end of file diff --git a/assets/js/b8fd8041.7e4da9c9.js b/assets/js/b8fd8041.0f505322.js similarity index 99% rename from assets/js/b8fd8041.7e4da9c9.js rename to assets/js/b8fd8041.0f505322.js index 0cb91d11..537d95ae 100644 --- a/assets/js/b8fd8041.7e4da9c9.js +++ b/assets/js/b8fd8041.0f505322.js @@ -1 +1 @@ -"use strict";(self.webpackChunkvac_dev=self.webpackChunkvac_dev||[]).push([[4588],{61357:(e,t,a)=>{a.r(t),a.d(t,{assets:()=>s,contentTitle:()=>o,default:()=>u,frontMatter:()=>n,metadata:()=>l,toc:()=>p});var r=a(87462),i=(a(67294),a(3905));const n={title:"Exploring zkVMs: Which Projects Truly Qualify as Zero-Knowledge Virtual Machines?",date:new Date("2024-08-27T12:00:00.000Z"),authors:"moudy",published:!0,slug:"zkVM-explorations",categories:"research",discuss:"https://forum.vac.dev/t/exploring-zkvms-which-projects-truly-qualify-as-zero-knowledge-virtual-machines/317",toc_min_heading_level:2,toc_max_heading_level:5},o=void 0,l={permalink:"/rlog/zkVM-explorations",source:"@site/rlog/2024-08-27-Zkvm.mdx",title:"Exploring zkVMs: Which Projects Truly Qualify as Zero-Knowledge Virtual Machines?",description:"The blockchain space is rapidly evolving, and with it, new technologies are emerging that promise enhanced privacy, scalability, and security.",date:"2024-08-27T12:00:00.000Z",formattedDate:"August 27, 2024",tags:[],readingTime:23.53,hasTruncateMarker:!0,authors:[{name:"Moudy",github:"moudyellaz",key:"moudy"}],frontMatter:{title:"Exploring zkVMs: Which Projects Truly Qualify as Zero-Knowledge Virtual Machines?",date:"2024-08-27T12:00:00.000Z",authors:"moudy",published:!0,slug:"zkVM-explorations",categories:"research",discuss:"https://forum.vac.dev/t/exploring-zkvms-which-projects-truly-qualify-as-zero-knowledge-virtual-machines/317",toc_min_heading_level:2,toc_max_heading_level:5},nextItem:{title:"Nescience: A User-Centric State-Separation Architecture",permalink:"/rlog/Nescience-state-separation-architecture"}},s={authorsImageUrls:[void 0]},p=[{value:"1. SP1",id:"1-sp1",level:2},{value:"2. Nexus",id:"2-nexus",level:2},{value:"3. RISC0",id:"3-risc0",level:2},{value:"4. Powdr",id:"4-powdr",level:2},{value:"5. ZkMIPS",id:"5-zkmips",level:2},{value:"6. Valida",id:"6-valida",level:2},{value:"7. Jolt",id:"7-jolt",level:2},{value:"8. ZkWASM",id:"8-zkwasm",level:2},{value:"9. Aleo",id:"9-aleo",level:2},{value:"10. Ola",id:"10-ola",level:2},{value:"11. Miden",id:"11-miden",level:2},{value:"12. ZkOS",id:"12-zkos",level:2},{value:"13. Triton",id:"13-triton",level:2},{value:"14. Cairo",id:"14-cairo",level:2},{value:"15. SnarkOS",id:"15-snarkos",level:2},{value:"16. Lurk",id:"16-lurk",level:2},{value:"17. Piecrust",id:"17-piecrust",level:2},{value:"18. Ceno",id:"18-ceno",level:2},{value:"19. Stellar",id:"19-stellar",level:2},{value:"20. NovaNet",id:"20-novanet",level:2},{value:"21. ZkLLVM",id:"21-zkllvm",level:2},{value:"22. ZkMove",id:"22-zkmove",level:2},{value:"23. O1VM",id:"23-o1vm",level:2}],c={toc:p};function u(e){let{components:t,...a}=e;return(0,i.kt)("wrapper",(0,r.Z)({},c,a,{components:t,mdxType:"MDXLayout"}),(0,i.kt)("h1",{id:"introduction"},"Introduction"),(0,i.kt)("p",null,'The blockchain space is rapidly evolving, and with it, new technologies are emerging that promise enhanced privacy, scalability, and security.\nAs decentralized systems grow in complexity and usage, the need for secure and private computation has never been greater.\nZero-knowledge virtual machines (zkVMs) are one such innovation, allowing for computations to be proven correct without revealing the underlying data.\nZkVMs have enormous implications for privacy-preserving applications, decentralized finance (DeFi), and other blockchain-based use cases.\nHowever, as the term "zkVM" becomes more widely adopted, it is critical to distinguish between projects that truly satisfy the stringent requirements of a zkVM and those that do not.'),(0,i.kt)("h1",{id:"what-is-a-zkvm"},"What is a zkVM?"),(0,i.kt)("p",null,"A zkVM is a virtual machine that combines the principles of cryptographic proof generation and privacy preservation with the computational model\nof traditional virtual machines. Essentially, a zkVM enables the execution of arbitrary programs while generating cryptographic proofs\u2014specifically, zero-knowledge proofs (ZKPs)\u2014that\ncan verify the correctness of these computations without revealing any sensitive information. This ensures that computations can be trusted while protecting the privacy of the data involved.\nThe key characteristics of a zkVM include:"),(0,i.kt)("ul",null,(0,i.kt)("li",{parentName:"ul"},"Proof generation: The ability to produce ZKPs that verify the correct execution of programs. There are several types of cryptographic techniques used in zkVMs to\ngenerate these proofs, such as zk-SNARKs, zk-STARKs, and recursive proofs. A zkVM\u2019s ability to generate these proofs determines how effectively it can ensure the integrity of computations\nin a privacy-preserving manner."),(0,i.kt)("li",{parentName:"ul"},"Privacy preservation: The system must maintain privacy, ensuring that only the proof is revealed, not the underlying computation or data. Privacy-preserving zkVMs allow users to maintain\nconfidentiality without compromising the security or verifiability of their operations. However, not all zkVMs achieve the same level of privacy. Some may focus more on proof generation\nand scalability while deprioritizing privacy features, which can limit their use in certain privacy-sensitive applications."),(0,i.kt)("li",{parentName:"ul"},"Scalability and performance: zkVMs should offer scalable and efficient computation, leveraging advanced cryptographic techniques like zk-SNARKs, zk-STARKs, or recursive proofs.\nA zkVM's performance must also be measured in terms of latency (time to generate and verify a proof) and throughput (number of computations processed within a certain time frame)."),(0,i.kt)("li",{parentName:"ul"},"Verifiable computation: The zkVM should be able to prove the execution of arbitrary programs in a secure and verifiable manner. Verifiable computation ensures that zkVMs can be deployed\nacross a wide range of applications, from DeFi to private data-sharing platforms and more.")),(0,i.kt)("h1",{id:"why-zkvms-matter"},"Why zkVMs matter"),(0,i.kt)("p",null,"The rise of zkVMs is a crucial development for the future of blockchain and decentralized technologies. As more systems require the ability to scale while maintaining privacy and trust,\nzkVMs provide a powerful solution. They offer the potential to reshape the way decentralized applications (dapps) handle sensitive information, enabling them to be both efficient and private."),(0,i.kt)("p",null,"It is essential to distinguish between projects that fully realize the potential of zkVMs and those that do not. In the remainder of this post, we evaluate several zkVM projects, analyzing\nwhether they satisfy the criteria for being classified as zkVMs based on our research."),(0,i.kt)("h1",{id:"our-methodology"},"Our methodology"),(0,i.kt)("p",null,"We analyzed each project\u2019s documentation, source code, and available benchmarks to determine whether they meet the definition of a zkVM.\nOur criteria focus on the key capabilities of zkVMs\u2014proof generation, privacy, scalability, and integration with existing systems."),(0,i.kt)("h1",{id:"zkvm-project-analysis"},"ZkVM project analysis"),(0,i.kt)("h2",{id:"1-sp1"},"1. ","[SP1]"),(0,i.kt)("ul",null,(0,i.kt)("li",{parentName:"ul"},"Overview: SP1 [",(0,i.kt)("a",{parentName:"li",href:"https://blog.succinct.xyz/introducing-sp1/"},"1"),"] is a developer-friendly zkVM designed to enable ZKP execution for LLVM-based languages like C, C++, Rust, and others. It supports a RISC-V-like instruction set architecture (ISA),\nwhich makes it compatible with various programming languages compiled through LLVM."),(0,i.kt)("li",{parentName:"ul"},"Main focus: The main focus of SP1 is scalability, open-source contributions, and accessibility for developers. It prioritizes performance over privacy,\nmaking it a good fit for environments where privacy isn't the primary concern."),(0,i.kt)("li",{parentName:"ul"},"Privacy: Not explicitly mentioned, making it less suitable for privacy-preserving applications."),(0,i.kt)("li",{parentName:"ul"},"Performance: SP1 has demonstrated up to 5.4x better performance than similar zkVMs like RISC0 for specific computations such as Fibonacci sequence generation."),(0,i.kt)("li",{parentName:"ul"},"Integration: SP1 is highly adaptable for rollups, light client verifiers, oracles, and even web2 projects like verifying the originality of images."),(0,i.kt)("li",{parentName:"ul"},"Conclusion: Yes, SP1 is a zkVM, but it does not prioritize zero-knowledge privacy, focusing more on scalability and performance.")),(0,i.kt)("h2",{id:"2-nexus"},"2. ","[Nexus]"),(0,i.kt)("ul",null,(0,i.kt)("li",{parentName:"ul"},"Overview: Nexus [",(0,i.kt)("a",{parentName:"li",href:"https://docs.nexus.xyz/"},"2"),"] is a highly modular zkVM designed to process up to a trillion CPU cycles per second. It relies on RISC-V instructions for computation, making it extensible and scalable.\nHowever, it currently lacks full ZKP capabilities due to its use of Spartan proofs."),(0,i.kt)("li",{parentName:"ul"},"Main focus: Nexus focuses on high performance and scalability, aiming to create an efficient execution environment for computationally intensive tasks."),(0,i.kt)("li",{parentName:"ul"},"Privacy: Although zero-knowledge privacy isn't the primary feature of Nexus, the project hints at potential privacy enhancements in the future."),(0,i.kt)("li",{parentName:"ul"},"Performance: Nexus has a high theoretical throughput, but it has yet to demonstrate benchmarks on zero-knowledge privacy."),(0,i.kt)("li",{parentName:"ul"},"Integration: Nexus is a good fit for high-performance environments that do not necessarily require full privacy."),(0,i.kt)("li",{parentName:"ul"},"Conclusion: Yes, Nexus qualifies as a zkVM in terms of scalability and proof generation, but it does not yet achieve full zero-knowledge privacy.")),(0,i.kt)("h2",{id:"3-risc0"},"3. ","[RISC0]"),(0,i.kt)("ul",null,(0,i.kt)("li",{parentName:"ul"},"Overview: Risc0 [",(0,i.kt)("a",{parentName:"li",href:"https://www.risczero.com/zkvm"},"3"),"] is a general-purpose zkVM with strong developer support. It allows for the execution of Rust and C code on a RISC-V virtual machine\nand generates zk-SNARK and zk-STARK proofs for these computations."),(0,i.kt)("li",{parentName:"ul"},"Main focus: Risc0 is focused on ease of use for developers by abstracting away the complexities of circuit generation, making it accessible for a wide range of use cases."),(0,i.kt)("li",{parentName:"ul"},"Privacy: Full zero-knowledge privacy is supported via zk-SNARK and zk-STARK proofs, with Groth16 used for constant-size proof generation."),(0,i.kt)("li",{parentName:"ul"},"Performance: Risc0 offers strong benchmarks across different hardware setups, making it one of the most versatile zkVMs in terms of performance and scalability."),(0,i.kt)("li",{parentName:"ul"},"Integration: Risc0 integrates with several ecosystems, including Ethereum, and supports verifiable execution of Rust-based programs."),(0,i.kt)("li",{parentName:"ul"},"Conclusion: Yes, Risc0 qualifies as a zkVM, offering a balance of developer usability, scalability, and privacy.")),(0,i.kt)("h2",{id:"4-powdr"},"4. ","[Powdr]"),(0,i.kt)("ul",null,(0,i.kt)("li",{parentName:"ul"},"Overview: Powdr [",(0,i.kt)("a",{parentName:"li",href:"https://docs.powdr.org/"},"4"),"] is a toolkit for creating custom zkVMs. It allows developers to select from various front-end and back-end components to create zkVMs tailored to specific needs."),(0,i.kt)("li",{parentName:"ul"},"Main focus: Powdr is focused on providing a modular architecture for zkVM creation. It enables flexibility by allowing the combination of different ZK-proof backends like Halo2 or Valida."),(0,i.kt)("li",{parentName:"ul"},"Privacy: Powdr itself does not generate ZKPs, but it facilitates the creation of zkVMs that do."),(0,i.kt)("li",{parentName:"ul"},"Performance: The performance depends on the components chosen by the developer, as Powdr itself is more of a framework."),(0,i.kt)("li",{parentName:"ul"},"Integration: Powdr is highly customizable and can integrate with existing zkVM frameworks to extend their capabilities."),(0,i.kt)("li",{parentName:"ul"},"Conclusion: No, Powdr is not a zkVM itself, but it is a powerful tool for building customized zkVMs with different privacy and performance needs.")),(0,i.kt)("h2",{id:"5-zkmips"},"5. ","[ZkMIPS]"),(0,i.kt)("ul",null,(0,i.kt)("li",{parentName:"ul"},"Overview: ZkMIPS [",(0,i.kt)("a",{parentName:"li",href:"https://docs.zkm.io/zkm-architecture"},"5"),"] uses zk-STARKs to ensure privacy during computation, ensuring that private inputs are preserved while still proving correctness."),(0,i.kt)("li",{parentName:"ul"},"Performance: ZkMIPS is built for scalability, though explicit benchmarks are not widely published."),(0,i.kt)("li",{parentName:"ul"},"Integration: ZkMIPS can be integrated into systems that rely on MIPS architecture, making it versatile for legacy codebases that require privacy."),(0,i.kt)("li",{parentName:"ul"},"Conclusion: Yes, zkMIPS is a zkVM focused on scalability and privacy for MIPS-based architectures.")),(0,i.kt)("h2",{id:"6-valida"},"6. ","[Valida]"),(0,i.kt)("ul",null,(0,i.kt)("li",{parentName:"ul"},"Overview: Valida [",(0,i.kt)("a",{parentName:"li",href:"https://delendum.xyz/writings/2023-05-10-zkvm-design.html"},"6"),"] is a performance-oriented zkVM that generates proofs for programs using a custom ISA designed to optimize zkVM implementation.\nIt uses Plonky3 for its proof system."),(0,i.kt)("li",{parentName:"ul"},"Main focus: Valida is centered around optimizing prover performance and extensibility, making it a valuable tool for generating proofs efficiently."),(0,i.kt)("li",{parentName:"ul"},"Privacy: While Valida is focused on performance, it does not prioritize zero-knowledge privacy as much as other zkVMs."),(0,i.kt)("li",{parentName:"ul"},"Performance: Valida has benchmarks indicating its performance advantages in proving computations quickly, particularly through parallel processing."),(0,i.kt)("li",{parentName:"ul"},"Integration: Valida is specialized and may not integrate as seamlessly into general-purpose systems, as it is optimized for performance over broad applicability."),(0,i.kt)("li",{parentName:"ul"},"Conclusion: Yes, Valida qualifies as a zkVM based on proof generation, but its lack of focus on privacy makes it less suitable for privacy-first use cases.")),(0,i.kt)("h2",{id:"7-jolt"},"7. ","[Jolt]"),(0,i.kt)("ul",null,(0,i.kt)("li",{parentName:"ul"},"Overview: Jolt [",(0,i.kt)("a",{parentName:"li",href:"https://a16zcrypto.com/posts/article/building-jolt/"},"7"),"] is a zkVM built to optimize prover performance using a modified Hyrax polynomial commitment system. It relies on RISC-V instructions for computation\nbut falls short of full zero-knowledge capabilities."),(0,i.kt)("li",{parentName:"ul"},"Main focus: Jolt's main goal is to optimize the speed of proving program execution, making it suitable for high-performance applications where privacy isn't the primary concern."),(0,i.kt)("li",{parentName:"ul"},"Privacy: Jolt does not fully achieve zero-knowledge privacy due to the choice of polynomial commitment schemes."),(0,i.kt)("li",{parentName:"ul"},"Performance: Jolt offers strong performance, with benchmarks highlighting its ability to process proofs efficiently."),(0,i.kt)("li",{parentName:"ul"},"Integration: Jolt can be integrated with systems that prioritize speed over privacy, particularly where rapid proof generation is essential."),(0,i.kt)("li",{parentName:"ul"},"Conclusion: Yes, Jolt qualifies as a zkVM based on proof generation, though it does not provide full zero-knowledge privacy.")),(0,i.kt)("h2",{id:"8-zkwasm"},"8. ","[ZkWASM]"),(0,i.kt)("ul",null,(0,i.kt)("li",{parentName:"ul"},"Overview: ZkWASM [",(0,i.kt)("a",{parentName:"li",href:"https://delphinuslab.com/zk-wasm/"},"8"),"] is a zkVM designed to execute WebAssembly (WASM) code in a privacy-preserving and scalable manner. It uses zk-SNARKs to prove the correctness of WASM\nprogram execution while ensuring privacy."),(0,i.kt)("li",{parentName:"ul"},"Main focus: ZkWASM focuses on scalability and privacy for WebAssembly, making it ideal for dapps that require verifiable computation without compromising privacy."),(0,i.kt)("li",{parentName:"ul"},"Privacy: Full zero-knowledge privacy is provided through zk-SNARKs, ensuring that the execution of WASM programs remains confidential."),(0,i.kt)("li",{parentName:"ul"},"Performance: ZkWASM is optimized for running WASM programs efficiently, with offchain computation and onchain verification to enhance performance."),(0,i.kt)("li",{parentName:"ul"},"Integration: ZkWASM is ideal for dapps, particularly those that use WebAssembly and require verifiable execution."),(0,i.kt)("li",{parentName:"ul"},"Conclusion: Yes, zkWASM qualifies as a zkVM, providing strong privacy, scalability, and verifiable execution for WebAssembly code.")),(0,i.kt)("h2",{id:"9-aleo"},"9. ","[Aleo]"),(0,i.kt)("ul",null,(0,i.kt)("li",{parentName:"ul"},"Overview: Aleo's [",(0,i.kt)("a",{parentName:"li",href:"https://aleo.org/blog/"},"9"),"] snarkVM converts code into Aleo instructions, which are then compiled into bytecode executable on its zkVM. Aleo emphasizes building private, scalable dapps."),(0,i.kt)("li",{parentName:"ul"},"Main focus: Aleo prioritizes privacy and scalability for dapps, providing a robust framework for developers building private dapps."),(0,i.kt)("li",{parentName:"ul"},"Privacy: Aleo offers full privacy through zk-SNARK proofs, making it suitable for building fully private applications."),(0,i.kt)("li",{parentName:"ul"},"Performance: Aleo focuses on scalability through efficient proof systems, though detailed performance benchmarks are not widely available."),(0,i.kt)("li",{parentName:"ul"},"Integration: Aleo is built for privacy-first dapps and integrates with other zkVM-based systems."),(0,i.kt)("li",{parentName:"ul"},"Conclusion: Yes, Aleo qualifies as a zkVM, offering a comprehensive solution for private and scalable dapps.")),(0,i.kt)("h2",{id:"10-ola"},"10. ","[Ola]"),(0,i.kt)("ul",null,(0,i.kt)("li",{parentName:"ul"},"Overview: Ola [",(0,i.kt)("a",{parentName:"li",href:"https://github.com/Sin7Y/olavm-whitepaper-v2/tree/master"},"10"),"] is a ZK-friendly, high-performance layer-2 (L2) rollup platform that is still under development. It is designed to execute computations offchain while generating\nvalidity proofs for these computations, ensuring that they are correctly executed without compromising security. "),(0,i.kt)("li",{parentName:"ul"},"Privacy: Ola does not specifically prioritize privacy in the same way that zkVMs do. While it leverages ZKPs for scalability, its focus is on proving the correctness of\ntransactions and computations rather than ensuring that the data remains private."),(0,i.kt)("li",{parentName:"ul"},"Performance: Ola is designed to achieve high performance, particularly in terms of transaction throughput."),(0,i.kt)("li",{parentName:"ul"},"Integration: Ola is designed to be interoperable with various layer-1 blockchains. The platform supports a hybrid ZK-rollup architecture and is expected to include bridges for cross-chain\ninteroperability, enabling assets and data to move seamlessly between the layer-1 blockchain and the Ola rollup."),(0,i.kt)("li",{parentName:"ul"},"Conclusion: No, Ola is not a zkVM. While it leverages ZKPs (in the form of ZK-rollups) to ensure the validity of offchain computations, its primary focus is on scalability and performance\nrather than privacy or verifiable execution of arbitrary programs. Ola is more accurately described as a ZK-rollup platform aimed at improving transaction throughput and reducing transaction costs on\nlayer-1 blockchains. ")),(0,i.kt)("h2",{id:"11-miden"},"11. ","[Miden]"),(0,i.kt)("ul",null,(0,i.kt)("li",{parentName:"ul"},"Overview: Miden zkVM [",(0,i.kt)("a",{parentName:"li",href:"https://0xpolygonmiden.github.io/miden-vm/intro/main.html"},"11"),"] is a zk-STARK-based virtual machine that converts code into Miden VM instructions and proves the execution of these instructions with zero-knowledge privacy."),(0,i.kt)("li",{parentName:"ul"},"Main focus: Miden focuses on scalability and privacy for ZK-rollups, offering efficient proof generation for dapps."),(0,i.kt)("li",{parentName:"ul"},"Privacy: Miden ensures privacy for transactions and programs via zk-STARK proofs, making it suitable for private dapps."),(0,i.kt)("li",{parentName:"ul"},"Performance: Miden is optimized for scalability, with benchmarks showing its ability to handle up to 1,000 transactions per second (TPS)."),(0,i.kt)("li",{parentName:"ul"},"Integration: Miden integrates well with ZK-rollup solutions, making it ideal for L2 scaling solutions on blockchains like Ethereum."),(0,i.kt)("li",{parentName:"ul"},"Conclusion: Yes, Miden qualifies as a zkVM, providing strong privacy and scalability for dapps and ZK-rollups.")),(0,i.kt)("h2",{id:"12-zkos"},"12. ","[ZkOS]"),(0,i.kt)("ul",null,(0,i.kt)("li",{parentName:"ul"},"Overview: ZkOS [",(0,i.kt)("a",{parentName:"li",href:"https://osblog.stephenmarz.com/index.html"},"12"),"] is a verifiable operating system focused on running zkApps in a decentralized manner. It is built on the RISC-V architecture and aims to create\na world computer where all untrusted executions can be verified."),(0,i.kt)("li",{parentName:"ul"},"Main focus: ZkOS is primarily designed to offer a proof-of-concept operating system where all executions can be verified in a trustless manner.\nHowever, its focus is more on the infrastructure for verifiable applications rather than being a traditional zkVM."),(0,i.kt)("li",{parentName:"ul"},"Privacy: ZkOS does not focus on privacy guarantees such as those found in zkVMs that generate ZKPs."),(0,i.kt)("li",{parentName:"ul"},"Performance: ZkOS focuses on the efficient execution of dapps, but performance benchmarks specific to ZKP generation are not provided."),(0,i.kt)("li",{parentName:"ul"},"Integration: ZkOS supports the execution of zkApps, but it is more of a verifiable operating system rather than a zkVM, making it distinct in its functionality."),(0,i.kt)("li",{parentName:"ul"},"Conclusion: No, zkOS is not a zkVM. It is a verifiable operating system focused on the infrastructure to support zkApps but does not directly generate ZKPs or focus on privacy preservation.")),(0,i.kt)("h2",{id:"13-triton"},"13. ","[Triton]"),(0,i.kt)("ul",null,(0,i.kt)("li",{parentName:"ul"},"Overview: Triton [",(0,i.kt)("a",{parentName:"li",href:"https://triton-vm.org/spec/"},"13"),"] is a domain-specific language (DSL) and compiler designed primarily for high-performance GPU kernels, particularly those used in deep learning applications. "),(0,i.kt)("li",{parentName:"ul"},"Main focus: The primary goal of Triton is to optimize computation for machine learning and GPU workloads. It is focused on enhancing performance and efficiency in processing data\nrather than on ZKPs or verifiable computation."),(0,i.kt)("li",{parentName:"ul"},"Privacy: Triton does not provide ZKPs or privacy features typically associated with zkVMs. Its focus is on high-performance computation rather than cryptographic verifiability."),(0,i.kt)("li",{parentName:"ul"},"Performance: Triton is highly optimized for GPU execution, offering significant improvements in performance for computationally intensive tasks such as those found in deep learning."),(0,i.kt)("li",{parentName:"ul"},"Integration: Triton is integrated with GPU-based computation environments and is highly specialized for optimizing low-level operations on hardware rather\nthan being a general-purpose virtual machine."),(0,i.kt)("li",{parentName:"ul"},"Conclusion: No, Triton is not a zkVM. It is a specialized tool for optimizing GPU workloads, focusing on performance rather than privacy or ZKPs.")),(0,i.kt)("h2",{id:"14-cairo"},"14. ","[Cairo]"),(0,i.kt)("ul",null,(0,i.kt)("li",{parentName:"ul"},"Overview: Cairo zkVM [",(0,i.kt)("a",{parentName:"li",href:"https://github.com/lambdaclass/cairo-vm/blob/main/docs/python_vm/README.md"},"14"),"] uses a custom language that compiles to an optimized STARK-based proof system, ensuring verifiable computation. It is primarily used in systems like Starknet."),(0,i.kt)("li",{parentName:"ul"},"Main focus: Cairo focuses on scalability and performance, using zk-STARK proofs to ensure the verifiable and secure execution of programs."),(0,i.kt)("li",{parentName:"ul"},"Privacy: Cairo provides privacy through zk-STARKs, but it focuses more on scalability and performance than privacy-first use cases."),(0,i.kt)("li",{parentName:"ul"},"Performance: Cairo is highly optimized for performance, making it well-suited for scalable applications on Starknet."),(0,i.kt)("li",{parentName:"ul"},"Integration: Cairo integrates deeply with systems like Starknet, supporting verifiable computation in a highly scalable and efficient manner."),(0,i.kt)("li",{parentName:"ul"},"Conclusion: Yes, Cairo qualifies as a zkVM, focusing on performance and verifiable execution while being ZK-friendly.")),(0,i.kt)("h2",{id:"15-snarkos"},"15. ","[SnarkOS]"),(0,i.kt)("ul",null,(0,i.kt)("li",{parentName:"ul"},"Overview: SnarkOS [",(0,i.kt)("a",{parentName:"li",href:"https://aleo.org/post/aleo-completes-security-audits-of-snarkos-and-snarkvm/"},"15"),"] is a decentralized operating system designed to power Aleo's network, enabling secure and private dapps.\nIt manages transactions and consensus, making it a critical infrastructure component for Aleo's zkVM-based ecosystem."),(0,i.kt)("li",{parentName:"ul"},"Main focus: SnarkOS primarily focuses on securing Aleo's network through consensus mechanisms and privacy-preserving transactions rather than acting as a\nzkVM that directly proves program execution."),(0,i.kt)("li",{parentName:"ul"},"Privacy: SnarkOS supports zero-knowledge privacy through its integration with Aleo's zkVM, but the operating system itself does not generate ZKPs for arbitrary computations."),(0,i.kt)("li",{parentName:"ul"},"Performance: SnarkOS is optimized for managing dapps on the Aleo network and handling private transactions, but its focus is more on infrastructure\nand consensus than on proof generation."),(0,i.kt)("li",{parentName:"ul"},"Integration: SnarkOS integrates seamlessly with Aleo's zkVM to support private dapps and transactions, but its primary role is as a consensus layer."),(0,i.kt)("li",{parentName:"ul"},"Conclusion: No, SnarkOS is not a zkVM. It serves as an operating system for Aleo's decentralized network, focusing on privacy and consensus rather than on generating ZKPs for computations.")),(0,i.kt)("h2",{id:"16-lurk"},"16. ","[Lurk]"),(0,i.kt)("ul",null,(0,i.kt)("li",{parentName:"ul"},"Overview: Lurk [",(0,i.kt)("a",{parentName:"li",href:"https://github.com/lurk-lab"},"16"),"] is a Turing-complete programming language designed for recursive zk-SNARKs. It focuses on enabling developers to build complex,\nrecursive ZKPs efficiently through a custom language tailored for verifiable computation."),(0,i.kt)("li",{parentName:"ul"},"Main focus: Lurk is centered around recursive proof generation rather than serving as a traditional virtual machine. Its purpose is to facilitate the creation of complex zk-SNARK-based proofs,\nmaking it a specialized tool for cryptographic proofs rather than general-purpose computation."),(0,i.kt)("li",{parentName:"ul"},"Privacy: Lurk is built for generating zk-SNARKs, which inherently provide privacy. However, Lurk itself is a language and not a zkVM that executes arbitrary programs and generates ZKPs for them."),(0,i.kt)("li",{parentName:"ul"},"Performance: Lurk is optimized for recursive zk-SNARK generation, but specific performance metrics are tied to its proof-generation capabilities rather than traditional execution environments."),(0,i.kt)("li",{parentName:"ul"},"Integration: Lurk is specialized for zk-SNARKs and may not easily integrate with other general-purpose systems, as it focuses on specific cryptographic tasks."),(0,i.kt)("li",{parentName:"ul"},"Conclusion: No, Lurk is not a zkVM. It is a programming language designed for recursive zk-SNARKs and focuses on proof generation rather than program execution in a virtual machine environment.")),(0,i.kt)("h2",{id:"17-piecrust"},"17. ","[Piecrust]"),(0,i.kt)("ul",null,(0,i.kt)("li",{parentName:"ul"},"Overview: Piecrust [",(0,i.kt)("a",{parentName:"li",href:"https://docs.rs/piecrust/latest/piecrust/"},"17"),"] is a WASM-based zkVM designed to run on the Dusk Network. It supports concurrent execution and focuses on providing privacy and scalability for smart contracts."),(0,i.kt)("li",{parentName:"ul"},"Main focus: Piecrust is designed to provide private and efficient execution of smart contracts through the use of ZKPs."),(0,i.kt)("li",{parentName:"ul"},"Privacy: Piecrust supports ZK-friendly computations and enhances privacy through cryptographic primitives such as Merkle trees."),(0,i.kt)("li",{parentName:"ul"},"Performance: Piecrust is designed to be scalable and concurrent, allowing multiple sessions to run simultaneously, which improves overall performance."),(0,i.kt)("li",{parentName:"ul"},"Integration: Piecrust integrates with the Dusk Network and supports private smart contracts, making it ideal for dapps."),(0,i.kt)("li",{parentName:"ul"},"Conclusion: Yes, Piecrust qualifies as a zkVM, offering scalability, privacy, and support for succinct proof generation.")),(0,i.kt)("h2",{id:"18-ceno"},"18. ","[Ceno]"),(0,i.kt)("ul",null,(0,i.kt)("li",{parentName:"ul"},"Overview: Ceno [",(0,i.kt)("a",{parentName:"li",href:"https://eprint.iacr.org/2024/387"},"18"),"] is a zkVM that provides a theoretical framework for reducing proving time by grouping common portions of code together. It uses recursive proofs to enhance prover efficiency."),(0,i.kt)("li",{parentName:"ul"},"Main focus: Ceno aims to optimize prover performance through recursive proofs, making it a powerful tool for handling complex computations efficiently."),(0,i.kt)("li",{parentName:"ul"},"Privacy: Ceno supports zero-knowledge privacy through recursive proofs and is designed to handle large-scale computations securely."),(0,i.kt)("li",{parentName:"ul"},"Performance: Ceno's recursive proof framework ensures that it can efficiently prove the execution of programs, reducing the time required for proof generation."),(0,i.kt)("li",{parentName:"ul"},"Integration: Ceno can be integrated into systems that require high efficiency and privacy, particularly those handling complex, repeated computations."),(0,i.kt)("li",{parentName:"ul"},"Conclusion: Yes, Ceno qualifies as a zkVM, providing efficient and private computation through the use of recursive proofs.")),(0,i.kt)("h2",{id:"19-stellar"},"19. ","[Stellar]"),(0,i.kt)("ul",null,(0,i.kt)("li",{parentName:"ul"},"Overview: Stellar [",(0,i.kt)("a",{parentName:"li",href:"https://stellar.org/blog/developers/zkvm-a-new-design-for-fast-confidential-smart-contracts"},"19"),"] is a decentralized protocol designed to facilitate cross-border transactions between digital and fiat currencies."),(0,i.kt)("li",{parentName:"ul"},"Main focus: Stellar's primary goal is to improve financial transactions by enabling decentralized, low-cost currency transfers. It does not aim to provide ZKPs or run verifiable computations\nlike a zkVM."),(0,i.kt)("li",{parentName:"ul"},"Privacy: Stellar focuses on confidentiality and security for financial transactions, but it does not employ ZKPs in the way zkVMs do for verifying computation without revealing data."),(0,i.kt)("li",{parentName:"ul"},"Performance: Stellar prioritizes the performance of financial transactions, ensuring low latency and high throughput across its decentralized network.\nHowever, this performance focus is specific to transactions rather than general-purpose program execution."),(0,i.kt)("li",{parentName:"ul"},"Integration: Stellar is designed for integration with financial systems, enabling currency conversions and transfers, but it is not built for executing smart contracts or verifiable computations."),(0,i.kt)("li",{parentName:"ul"},"Conclusion: No, Stellar is not a zkVM. It is a decentralized financial protocol focused on facilitating cross-border payments rather than verifiable or privacy-preserving computation.")),(0,i.kt)("h2",{id:"20-novanet"},"20. ","[NovaNet]"),(0,i.kt)("ul",null,(0,i.kt)("li",{parentName:"ul"},"Overview: NovaNet [",(0,i.kt)("a",{parentName:"li",href:"https://www.novanet.xyz/blog"},"20"),"] is an open peer-to-peer network that aims to build upon concepts of non-uniform incremental verifiable computation. "),(0,i.kt)("li",{parentName:"ul"},"Main focus: NovaNet's focus is on peer-to-peer networking and decentralized computing rather than on proving the execution of programs in a zero-knowledge manner."),(0,i.kt)("li",{parentName:"ul"},"Privacy: NovaNet does not provide ZKPs or privacy features typically associated with zkVMs. Its focus is on decentralized networking and computation."),(0,i.kt)("li",{parentName:"ul"},"Performance: NovaNet prioritizes efficient decentralized computation but does not focus on privacy or performance benchmarks related to ZKPs."),(0,i.kt)("li",{parentName:"ul"},"Integration: NovaNet is built for decentralized networks but is not designed to integrate with systems requiring verifiable computation or ZKP generation."),(0,i.kt)("li",{parentName:"ul"},"Conclusion: No, NovaNet is not a zkVM. It is a decentralized peer-to-peer network focused on distributed computing rather than zero-knowledge computation.")),(0,i.kt)("h2",{id:"21-zkllvm"},"21. ","[ZkLLVM]"),(0,i.kt)("ul",null,(0,i.kt)("li",{parentName:"ul"},"Overview: ZkLLVM [",(0,i.kt)("a",{parentName:"li",href:"https://github.com/NilFoundation/zkLLVM"},"21"),"] is a compiler that transforms C++ or Rust code into circuits for use in zk-SNARK or zk-STARK systems. Its primary purpose is to bridge high-level programming\nlanguages with ZKP systems by compiling code into arithmetic circuits that can be used to generate and verify proofs."),(0,i.kt)("li",{parentName:"ul"},"Main focus: ZkLLVM focuses on making ZKPs accessible to developers by enabling them to write code in familiar languages (C++, Rust) and then compile that code into ZK circuits."),(0,i.kt)("li",{parentName:"ul"},"Privacy: ZkLLVM enables the generation of ZKPs by compiling high-level code into ZK-compatible circuits. It plays a crucial role in privacy-preserving applications but does not act\nas a zkVM itself."),(0,i.kt)("li",{parentName:"ul"},"Performance: ZkLLVM allows for the performance of ZKPs to be closely tied to the complexity of the compiled circuits. The performance depends on the underlying\nzk-SNARK or zk-STARK system used."),(0,i.kt)("li",{parentName:"ul"},"Integration: ZkLLVM integrates with zk-SNARK and zk-STARK proof systems, making it useful for a variety of privacy-focused applications, but it does not serve as a zkVM\nfor general-purpose computation."),(0,i.kt)("li",{parentName:"ul"},"Conclusion: No, zkLLVM is not a zkVM. It is a compiler that transforms high-level code into ZK circuits, enabling ZKPs but not acting as a virtual machine for executing and proving programs.")),(0,i.kt)("h2",{id:"22-zkmove"},"22. ","[ZkMove]"),(0,i.kt)("ul",null,(0,i.kt)("li",{parentName:"ul"},"Overview: ZkMove [",(0,i.kt)("a",{parentName:"li",href:"https://www.zkmove.net/2023-06-20-zkMove-0.2.0-Achieving-Full-Bytecode-Compatibility-with-Move/"},"22"),"] is a zkVM designed to execute smart contracts written in the Move language. It utilizes ZKPs to ensure that the execution of these contracts remains verifiable and secure."),(0,i.kt)("li",{parentName:"ul"},"Main focus: ZkMove focuses on privacy and verifiable execution for Move-based smart contracts, providing a framework for ZK-friendly computation."),(0,i.kt)("li",{parentName:"ul"},"Privacy: ZkMove ensures that smart contract execution remains private through ZKPs, making it suitable for privacy-preserving applications."),(0,i.kt)("li",{parentName:"ul"},"Performance: ZkMove is optimized for verifiable execution, ensuring that contracts can be proven correct while preserving privacy."),(0,i.kt)("li",{parentName:"ul"},"Integration: ZkMove integrates well with systems that use the Move language, particularly in environments that require private smart contract execution."),(0,i.kt)("li",{parentName:"ul"},"Conclusion: Yes, zkMove qualifies as a zkVM, offering ZK-friendly execution and privacy for smart contracts written in the Move language.")),(0,i.kt)("h2",{id:"23-o1vm"},"23. ","[O1VM]"),(0,i.kt)("ul",null,(0,i.kt)("li",{parentName:"ul"},"Overview: O1VM [",(0,i.kt)("a",{parentName:"li",href:"https://github.com/o1-labs/proof-systems/tree/master/o1vm"},"23"),"] is a general-purpose zkVM developed by o1Labs. It is designed to prove the execution of MIPS programs efficiently through a combination of zk-SNARKs\nand specialized techniques like folding schemes and RAMLookups."),(0,i.kt)("li",{parentName:"ul"},"Main focus: O1VM focuses on scalability and verifiable computation for MIPS-based programs, making it a strong contender for executing and proving complex programs efficiently."),(0,i.kt)("li",{parentName:"ul"},"Privacy: O1VM ensures privacy through zk-SNARK proofs, keeping the details of the computation private while proving its correctness."),(0,i.kt)("li",{parentName:"ul"},"Performance: O1VM is optimized for handling long execution traces and complex computations, making it highly scalable."),(0,i.kt)("li",{parentName:"ul"},"Integration: O1VM integrates well with MIPS-based architectures and systems that require privacy-preserving computation."),(0,i.kt)("li",{parentName:"ul"},"Conclusion: Yes, o1VM qualifies as a zkVM, providing privacy, scalability, and strong proof generation for MIPS programs.")),(0,i.kt)("h1",{id:"summary-of-findings"},"Summary of findings"),(0,i.kt)("table",null,(0,i.kt)("thead",{parentName:"table"},(0,i.kt)("tr",{parentName:"thead"},(0,i.kt)("th",{parentName:"tr",align:null},"Project name"),(0,i.kt)("th",{parentName:"tr",align:null},"ZkVM status"),(0,i.kt)("th",{parentName:"tr",align:null},"Zero knowledge"),(0,i.kt)("th",{parentName:"tr",align:null},"Reasoning/comments"))),(0,i.kt)("tbody",{parentName:"table"},(0,i.kt)("tr",{parentName:"tbody"},(0,i.kt)("td",{parentName:"tr",align:null},(0,i.kt)("strong",{parentName:"td"},"SP1")),(0,i.kt)("td",{parentName:"tr",align:null},"Yes"),(0,i.kt)("td",{parentName:"tr",align:null},"No"),(0,i.kt)("td",{parentName:"tr",align:null},"Proves execution of LLVM-based programs but lacks privacy features.")),(0,i.kt)("tr",{parentName:"tbody"},(0,i.kt)("td",{parentName:"tr",align:null},(0,i.kt)("strong",{parentName:"td"},"Nexus")),(0,i.kt)("td",{parentName:"tr",align:null},"Yes"),(0,i.kt)("td",{parentName:"tr",align:null},"No"),(0,i.kt)("td",{parentName:"tr",align:null},"Strong proof generation but lacks zero-knowledge privacy due to Spartan.")),(0,i.kt)("tr",{parentName:"tbody"},(0,i.kt)("td",{parentName:"tr",align:null},(0,i.kt)("strong",{parentName:"td"},"Risc0")),(0,i.kt)("td",{parentName:"tr",align:null},"Yes"),(0,i.kt)("td",{parentName:"tr",align:null},"Yes"),(0,i.kt)("td",{parentName:"tr",align:null},"Supports full ZKP generation for Rust programs.")),(0,i.kt)("tr",{parentName:"tbody"},(0,i.kt)("td",{parentName:"tr",align:null},(0,i.kt)("strong",{parentName:"td"},"Powdr")),(0,i.kt)("td",{parentName:"tr",align:null},"No"),(0,i.kt)("td",{parentName:"tr",align:null},"Yes"),(0,i.kt)("td",{parentName:"tr",align:null},"Toolkit for creating custom zkVMs, not a zkVM itself.")),(0,i.kt)("tr",{parentName:"tbody"},(0,i.kt)("td",{parentName:"tr",align:null},(0,i.kt)("strong",{parentName:"td"},"ZkMIPS")),(0,i.kt)("td",{parentName:"tr",align:null},"Yes"),(0,i.kt)("td",{parentName:"tr",align:null},"Yes"),(0,i.kt)("td",{parentName:"tr",align:null},"Supports MIPS-like architecture with full zero-knowledge and proof generation.")),(0,i.kt)("tr",{parentName:"tbody"},(0,i.kt)("td",{parentName:"tr",align:null},(0,i.kt)("strong",{parentName:"td"},"Valida")),(0,i.kt)("td",{parentName:"tr",align:null},"Yes"),(0,i.kt)("td",{parentName:"tr",align:null},"No"),(0,i.kt)("td",{parentName:"tr",align:null},"Performance-focused zkVM, lacks privacy guarantees.")),(0,i.kt)("tr",{parentName:"tbody"},(0,i.kt)("td",{parentName:"tr",align:null},(0,i.kt)("strong",{parentName:"td"},"Jolt")),(0,i.kt)("td",{parentName:"tr",align:null},"Yes"),(0,i.kt)("td",{parentName:"tr",align:null},"No"),(0,i.kt)("td",{parentName:"tr",align:null},"Performance-focused zkVM, does not achieve zero-knowledge privacy.")),(0,i.kt)("tr",{parentName:"tbody"},(0,i.kt)("td",{parentName:"tr",align:null},(0,i.kt)("strong",{parentName:"td"},"ZkWASM")),(0,i.kt)("td",{parentName:"tr",align:null},"Yes"),(0,i.kt)("td",{parentName:"tr",align:null},"Yes"),(0,i.kt)("td",{parentName:"tr",align:null},"Full zero-knowledge and verifiable execution of WebAssembly code.")),(0,i.kt)("tr",{parentName:"tbody"},(0,i.kt)("td",{parentName:"tr",align:null},(0,i.kt)("strong",{parentName:"td"},"Aleo")),(0,i.kt)("td",{parentName:"tr",align:null},"Yes"),(0,i.kt)("td",{parentName:"tr",align:null},"Yes"),(0,i.kt)("td",{parentName:"tr",align:null},"Fully private and scalable dapps.")),(0,i.kt)("tr",{parentName:"tbody"},(0,i.kt)("td",{parentName:"tr",align:null},(0,i.kt)("strong",{parentName:"td"},"Ola")),(0,i.kt)("td",{parentName:"tr",align:null},"No"),(0,i.kt)("td",{parentName:"tr",align:null},"No"),(0,i.kt)("td",{parentName:"tr",align:null},"Primarily a ZK-rollup platform, not a zkVM, focusing on scalability and performance rather than privacy.")),(0,i.kt)("tr",{parentName:"tbody"},(0,i.kt)("td",{parentName:"tr",align:null},(0,i.kt)("strong",{parentName:"td"},"Miden")),(0,i.kt)("td",{parentName:"tr",align:null},"Yes"),(0,i.kt)("td",{parentName:"tr",align:null},"Yes"),(0,i.kt)("td",{parentName:"tr",align:null},"Zk-STARK-based zkVM with strong privacy and scalability.")),(0,i.kt)("tr",{parentName:"tbody"},(0,i.kt)("td",{parentName:"tr",align:null},(0,i.kt)("strong",{parentName:"td"},"ZkOS")),(0,i.kt)("td",{parentName:"tr",align:null},"No"),(0,i.kt)("td",{parentName:"tr",align:null},"No"),(0,i.kt)("td",{parentName:"tr",align:null},"Verifiable operating system focused on zkApps, not a zkVM.")),(0,i.kt)("tr",{parentName:"tbody"},(0,i.kt)("td",{parentName:"tr",align:null},(0,i.kt)("strong",{parentName:"td"},"Triton")),(0,i.kt)("td",{parentName:"tr",align:null},"No"),(0,i.kt)("td",{parentName:"tr",align:null},"No"),(0,i.kt)("td",{parentName:"tr",align:null},"Optimizes GPU workloads but not designed for ZKPs.")),(0,i.kt)("tr",{parentName:"tbody"},(0,i.kt)("td",{parentName:"tr",align:null},(0,i.kt)("strong",{parentName:"td"},"Cairo")),(0,i.kt)("td",{parentName:"tr",align:null},"Yes"),(0,i.kt)("td",{parentName:"tr",align:null},"ZK-friendly"),(0,i.kt)("td",{parentName:"tr",align:null},"Custom Rust-based language with zk-STARK proof generation.")),(0,i.kt)("tr",{parentName:"tbody"},(0,i.kt)("td",{parentName:"tr",align:null},(0,i.kt)("strong",{parentName:"td"},"SnarkOS")),(0,i.kt)("td",{parentName:"tr",align:null},"No"),(0,i.kt)("td",{parentName:"tr",align:null},"Yes"),(0,i.kt)("td",{parentName:"tr",align:null},"Decentralized OS for Aleo's network, focuses on consensus rather than verifiable computation.")),(0,i.kt)("tr",{parentName:"tbody"},(0,i.kt)("td",{parentName:"tr",align:null},(0,i.kt)("strong",{parentName:"td"},"Lurk")),(0,i.kt)("td",{parentName:"tr",align:null},"No"),(0,i.kt)("td",{parentName:"tr",align:null},"No"),(0,i.kt)("td",{parentName:"tr",align:null},"Programming language for recursive zk-SNARKs, not a zkVM.")),(0,i.kt)("tr",{parentName:"tbody"},(0,i.kt)("td",{parentName:"tr",align:null},(0,i.kt)("strong",{parentName:"td"},"Piecrust")),(0,i.kt)("td",{parentName:"tr",align:null},"Yes"),(0,i.kt)("td",{parentName:"tr",align:null},"ZK-friendly"),(0,i.kt)("td",{parentName:"tr",align:null},"ZkVM with recursive SNARK capabilities, focused on succinct proof generation.")),(0,i.kt)("tr",{parentName:"tbody"},(0,i.kt)("td",{parentName:"tr",align:null},(0,i.kt)("strong",{parentName:"td"},"Ceno")),(0,i.kt)("td",{parentName:"tr",align:null},"Yes"),(0,i.kt)("td",{parentName:"tr",align:null},"Yes"),(0,i.kt)("td",{parentName:"tr",align:null},"Theoretical zkVM improving prover efficiency through recursive proofs.")),(0,i.kt)("tr",{parentName:"tbody"},(0,i.kt)("td",{parentName:"tr",align:null},(0,i.kt)("strong",{parentName:"td"},"Stellar")),(0,i.kt)("td",{parentName:"tr",align:null},"No"),(0,i.kt)("td",{parentName:"tr",align:null},"No"),(0,i.kt)("td",{parentName:"tr",align:null},"Focuses on cross-border transactions, not ZK-proof generation or verifiable computation.")),(0,i.kt)("tr",{parentName:"tbody"},(0,i.kt)("td",{parentName:"tr",align:null},(0,i.kt)("strong",{parentName:"td"},"NovaNet")),(0,i.kt)("td",{parentName:"tr",align:null},"No"),(0,i.kt)("td",{parentName:"tr",align:null},"No"),(0,i.kt)("td",{parentName:"tr",align:null},"Peer-to-peer network focused on distributed computing, not zero-knowledge computation.")),(0,i.kt)("tr",{parentName:"tbody"},(0,i.kt)("td",{parentName:"tr",align:null},(0,i.kt)("strong",{parentName:"td"},"ZkLLVM")),(0,i.kt)("td",{parentName:"tr",align:null},"No"),(0,i.kt)("td",{parentName:"tr",align:null},"Yes, in some cases"),(0,i.kt)("td",{parentName:"tr",align:null},"Compiler for generating ZK-circuits, not a zkVM.")),(0,i.kt)("tr",{parentName:"tbody"},(0,i.kt)("td",{parentName:"tr",align:null},(0,i.kt)("strong",{parentName:"td"},"ZkMove")),(0,i.kt)("td",{parentName:"tr",align:null},"Yes"),(0,i.kt)("td",{parentName:"tr",align:null},"ZK-friendly"),(0,i.kt)("td",{parentName:"tr",align:null},"ZkVM supporting Move language with ZKP execution.")),(0,i.kt)("tr",{parentName:"tbody"},(0,i.kt)("td",{parentName:"tr",align:null},(0,i.kt)("strong",{parentName:"td"},"O1VM")),(0,i.kt)("td",{parentName:"tr",align:null},"Yes"),(0,i.kt)("td",{parentName:"tr",align:null},"Yes"),(0,i.kt)("td",{parentName:"tr",align:null},"MIPS-based zkVM with strong privacy, scalability, and proof generation.")))),(0,i.kt)("h1",{id:"insights-and-conclusions"},"Insights and conclusions"),(0,i.kt)("p",null,"Our analysis reveals that many of the projects labeled as zkVMs do meet the core criteria for zkVMs, offering verifiable computation and proof generation\nas foundational features. However, a number of these projects fall short of delivering full zero-knowledge privacy. Projects like Risc0, Aleo, and Miden stand out as leading zkVM frameworks\nthat balance proof generation, privacy, and scalability, offering strong platforms for developers seeking to build privacy-preserving applications."),(0,i.kt)("p",null,"Conversely, projects like SP1 and Nexus excel in generating verifiable proofs but currently lack comprehensive zero-knowledge privacy mechanisms. These platforms are excellent for\nscenarios where proof generation and scalability are paramount, but privacy is not a primary concern."),(0,i.kt)("p",null,"As zkVM technology continues to evolve, we expect to see more projects integrating enhanced privacy-preserving mechanisms while simultaneously improving performance and scalability.\nThis ongoing development will likely broaden the application of zkVMs across the blockchain ecosystem, particularly in privacy-sensitive sectors such as finance, data security,\nand decentralized applications."),(0,i.kt)("p",null,"What are your thoughts on our zkVM analysis? Do you agree with our findings, or do you know of other zkVM projects that should be on our radar? We would love to hear your insights, questions,\nor suggestions! Feel free to join the ",(0,i.kt)("a",{parentName:"p",href:"https://forum.vac.dev/t/exploring-zkvms-which-projects-truly-qualify-as-zero-knowledge-virtual-machines/317"},"discussion")," on our forum."),(0,i.kt)("h1",{id:"references"},"References"),(0,i.kt)("p",null,"[1]"," Introducing SP1: A performant, 100% open-source, contributor-friendly zkVM. Retrieved from ",(0,i.kt)("a",{parentName:"p",href:"https://blog.succinct.xyz/introducing-sp1/"},"https://blog.succinct.xyz/introducing-sp1/")),(0,i.kt)("p",null,"[2]"," The Nexus 2.0 zkVM. Retrieved from ",(0,i.kt)("a",{parentName:"p",href:"https://docs.nexus.xyz/"},"https://docs.nexus.xyz/")),(0,i.kt)("p",null,"[3]"," The first general purpose zkVM. Retrieved from ",(0,i.kt)("a",{parentName:"p",href:"https://www.risczero.com/zkvm"},"https://www.risczero.com/zkvm")),(0,i.kt)("p",null,"[4]"," Powdr. Retrieved from ",(0,i.kt)("a",{parentName:"p",href:"https://docs.powdr.org/"},"https://docs.powdr.org/")),(0,i.kt)("p",null,"[5]"," ZKM Architecture. Retrieved from ",(0,i.kt)("a",{parentName:"p",href:"https://docs.zkm.io/zkm-architecture"},"https://docs.zkm.io/zkm-architecture")),(0,i.kt)("p",null,"[6]"," Valida zkVM Design. Retrieved from ",(0,i.kt)("a",{parentName:"p",href:"https://delendum.xyz/writings/2023-05-10-zkvm-design.html"},"https://delendum.xyz/writings/2023-05-10-zkvm-design.html")),(0,i.kt)("p",null,"[7]"," Building Jolt: A fast, easy-to-use zkVM. Retrieved from ",(0,i.kt)("a",{parentName:"p",href:"https://a16zcrypto.com/posts/article/building-jolt/"},"https://a16zcrypto.com/posts/article/building-jolt/")),(0,i.kt)("p",null,"[8]"," ZK-WASM. Retrieved from ",(0,i.kt)("a",{parentName:"p",href:"https://delphinuslab.com/zk-wasm/"},"https://delphinuslab.com/zk-wasm/")),(0,i.kt)("p",null,"[9]"," Aleo. Retrieved from ",(0,i.kt)("a",{parentName:"p",href:"https://aleo.org/blog/"},"https://aleo.org/blog/")),(0,i.kt)("p",null,"[10]"," OlaVM Whitepaper V2. Retrieved from ",(0,i.kt)("a",{parentName:"p",href:"https://github.com/Sin7Y/olavm-whitepaper-v2/tree/master"},"https://github.com/Sin7Y/olavm-whitepaper-v2/tree/master")),(0,i.kt)("p",null,"[11]"," Polygon Miden VM. Retrieved from ",(0,i.kt)("a",{parentName:"p",href:"https://0xpolygonmiden.github.io/miden-vm/intro/main.html"},"https://0xpolygonmiden.github.io/miden-vm/intro/main.html")),(0,i.kt)("p",null,"[12]"," The Adventures of OS: Making a RISC-V Operating System using Rust. Retrieved from ",(0,i.kt)("a",{parentName:"p",href:"https://osblog.stephenmarz.com/index.html"},"https://osblog.stephenmarz.com/index.html")),(0,i.kt)("p",null,"[13]"," Triton VM. Retrieved from ",(0,i.kt)("a",{parentName:"p",href:"https://triton-vm.org/spec/"},"https://triton-vm.org/spec/")),(0,i.kt)("p",null,"[14]"," How does the original Cairo VM work?. Retrieved from ",(0,i.kt)("a",{parentName:"p",href:"https://github.com/lambdaclass/cairo-vm/blob/main/docs/python_vm/README.md"},"https://github.com/lambdaclass/cairo-vm/blob/main/docs/python_vm/README.md")),(0,i.kt)("p",null,"[15]"," Aleo completes security audits of snarkOS & snarkVM. Retrieved from ",(0,i.kt)("a",{parentName:"p",href:"https://aleo.org/post/aleo-completes-security-audits-of-snarkos-and-snarkvm/"},"https://aleo.org/post/aleo-completes-security-audits-of-snarkos-and-snarkvm/")),(0,i.kt)("p",null,"[16]"," Lurk zkVM. Retrieved from ",(0,i.kt)("a",{parentName:"p",href:"https://github.com/lurk-lab"},"https://github.com/lurk-lab")),(0,i.kt)("p",null,"[17]"," Piecrust VM. Retrieved from ",(0,i.kt)("a",{parentName:"p",href:"https://docs.rs/piecrust/latest/piecrust/"},"https://docs.rs/piecrust/latest/piecrust/")),(0,i.kt)("p",null,"[18]"," Ceno: Non-uniform, Segment and Parallel Zero-knowledge Virtual Machine. Retrieved from ",(0,i.kt)("a",{parentName:"p",href:"https://eprint.iacr.org/2024/387"},"https://eprint.iacr.org/2024/387")),(0,i.kt)("p",null,"[19]"," ZkVM: a new design for fast, confidential smart contracts. Retrieved from ",(0,i.kt)("a",{parentName:"p",href:"https://stellar.org/blog/developers/zkvm-a-new-design-for-fast-confidential-smart-contracts"},"https://stellar.org/blog/developers/zkvm-a-new-design-for-fast-confidential-smart-contracts")),(0,i.kt)("p",null,"[20]"," Novanet. Retrieved from ",(0,i.kt)("a",{parentName:"p",href:"https://www.novanet.xyz/blog"},"https://www.novanet.xyz/blog")),(0,i.kt)("p",null,"[21]"," ZKLLVM. Retrieved from ",(0,i.kt)("a",{parentName:"p",href:"https://github.com/NilFoundation/zkLLVM"},"https://github.com/NilFoundation/zkLLVM")),(0,i.kt)("p",null,"[22]"," zkMove 0.2.0 - Achieving Full Bytecode Compatibility with Move. Retrieved from ",(0,i.kt)("a",{parentName:"p",href:"https://www.zkmove.net/2023-06-20-zkMove-0.2.0-Achieving-Full-Bytecode-Compatibility-with-Move/"},"https://www.zkmove.net/2023-06-20-zkMove-0.2.0-Achieving-Full-Bytecode-Compatibility-with-Move/")),(0,i.kt)("p",null,"[23]"," O1VM. Retrieved from ",(0,i.kt)("a",{parentName:"p",href:"https://github.com/o1-labs/proof-systems/tree/master/o1vm"},"https://github.com/o1-labs/proof-systems/tree/master/o1vm")))}u.isMDXComponent=!0},3905:(e,t,a)=>{a.d(t,{Zo:()=>c,kt:()=>d});var r=a(67294);function i(e,t,a){return t in e?Object.defineProperty(e,t,{value:a,enumerable:!0,configurable:!0,writable:!0}):e[t]=a,e}function n(e,t){var a=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),a.push.apply(a,r)}return a}function o(e){for(var t=1;t=0||(i[a]=e[a]);return i}(e,t);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,a)&&(i[a]=e[a])}return i}var s=r.createContext({}),p=function(e){var t=r.useContext(s),a=t;return e&&(a="function"==typeof e?e(t):o(o({},t),e)),a},c=function(e){var t=p(e.components);return r.createElement(s.Provider,{value:t},e.children)},u={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},m=r.forwardRef((function(e,t){var a=e.components,i=e.mdxType,n=e.originalType,s=e.parentName,c=l(e,["components","mdxType","originalType","parentName"]),m=p(a),d=i,k=m["".concat(s,".").concat(d)]||m[d]||u[d]||n;return a?r.createElement(k,o(o({ref:t},c),{},{components:a})):r.createElement(k,o({ref:t},c))}));function d(e,t){var a=arguments,i=t&&t.mdxType;if("string"==typeof e||i){var n=a.length,o=new Array(n);o[0]=m;var l={};for(var s in t)hasOwnProperty.call(t,s)&&(l[s]=t[s]);l.originalType=e,l.mdxType="string"==typeof e?e:i,o[1]=l;for(var p=2;p{a.r(t),a.d(t,{assets:()=>s,contentTitle:()=>o,default:()=>u,frontMatter:()=>n,metadata:()=>l,toc:()=>p});var r=a(87462),i=(a(67294),a(3905));const n={title:"Exploring zkVMs: Which Projects Truly Qualify as Zero-Knowledge Virtual Machines?",date:new Date("2024-08-27T12:00:00.000Z"),authors:"moudy",published:!0,slug:"zkVM-explorations",categories:"research",discuss:"https://forum.vac.dev/t/exploring-zkvms-which-projects-truly-qualify-as-zero-knowledge-virtual-machines/317",toc_min_heading_level:2,toc_max_heading_level:5},o=void 0,l={permalink:"/rlog/zkVM-explorations",source:"@site/rlog/2024-08-27-Zkvm.mdx",title:"Exploring zkVMs: Which Projects Truly Qualify as Zero-Knowledge Virtual Machines?",description:"The blockchain space is rapidly evolving, and with it, new technologies are emerging that promise enhanced privacy, scalability, and security.",date:"2024-08-27T12:00:00.000Z",formattedDate:"August 27, 2024",tags:[],readingTime:23.53,hasTruncateMarker:!0,authors:[{name:"Moudy",github:"moudyellaz",key:"moudy"}],frontMatter:{title:"Exploring zkVMs: Which Projects Truly Qualify as Zero-Knowledge Virtual Machines?",date:"2024-08-27T12:00:00.000Z",authors:"moudy",published:!0,slug:"zkVM-explorations",categories:"research",discuss:"https://forum.vac.dev/t/exploring-zkvms-which-projects-truly-qualify-as-zero-knowledge-virtual-machines/317",toc_min_heading_level:2,toc_max_heading_level:5},prevItem:{title:"zkVM Testing Report: Evaluating Zero-Knowledge Virtual Machines for Nescience",permalink:"/rlog/zkVM-testing"},nextItem:{title:"Nescience: A User-Centric State-Separation Architecture",permalink:"/rlog/Nescience-state-separation-architecture"}},s={authorsImageUrls:[void 0]},p=[{value:"1. SP1",id:"1-sp1",level:2},{value:"2. Nexus",id:"2-nexus",level:2},{value:"3. RISC0",id:"3-risc0",level:2},{value:"4. Powdr",id:"4-powdr",level:2},{value:"5. ZkMIPS",id:"5-zkmips",level:2},{value:"6. Valida",id:"6-valida",level:2},{value:"7. Jolt",id:"7-jolt",level:2},{value:"8. ZkWASM",id:"8-zkwasm",level:2},{value:"9. Aleo",id:"9-aleo",level:2},{value:"10. Ola",id:"10-ola",level:2},{value:"11. Miden",id:"11-miden",level:2},{value:"12. ZkOS",id:"12-zkos",level:2},{value:"13. Triton",id:"13-triton",level:2},{value:"14. Cairo",id:"14-cairo",level:2},{value:"15. SnarkOS",id:"15-snarkos",level:2},{value:"16. Lurk",id:"16-lurk",level:2},{value:"17. Piecrust",id:"17-piecrust",level:2},{value:"18. Ceno",id:"18-ceno",level:2},{value:"19. Stellar",id:"19-stellar",level:2},{value:"20. NovaNet",id:"20-novanet",level:2},{value:"21. ZkLLVM",id:"21-zkllvm",level:2},{value:"22. ZkMove",id:"22-zkmove",level:2},{value:"23. O1VM",id:"23-o1vm",level:2}],c={toc:p};function u(e){let{components:t,...a}=e;return(0,i.kt)("wrapper",(0,r.Z)({},c,a,{components:t,mdxType:"MDXLayout"}),(0,i.kt)("h1",{id:"introduction"},"Introduction"),(0,i.kt)("p",null,'The blockchain space is rapidly evolving, and with it, new technologies are emerging that promise enhanced privacy, scalability, and security.\nAs decentralized systems grow in complexity and usage, the need for secure and private computation has never been greater.\nZero-knowledge virtual machines (zkVMs) are one such innovation, allowing for computations to be proven correct without revealing the underlying data.\nZkVMs have enormous implications for privacy-preserving applications, decentralized finance (DeFi), and other blockchain-based use cases.\nHowever, as the term "zkVM" becomes more widely adopted, it is critical to distinguish between projects that truly satisfy the stringent requirements of a zkVM and those that do not.'),(0,i.kt)("h1",{id:"what-is-a-zkvm"},"What is a zkVM?"),(0,i.kt)("p",null,"A zkVM is a virtual machine that combines the principles of cryptographic proof generation and privacy preservation with the computational model\nof traditional virtual machines. Essentially, a zkVM enables the execution of arbitrary programs while generating cryptographic proofs\u2014specifically, zero-knowledge proofs (ZKPs)\u2014that\ncan verify the correctness of these computations without revealing any sensitive information. This ensures that computations can be trusted while protecting the privacy of the data involved.\nThe key characteristics of a zkVM include:"),(0,i.kt)("ul",null,(0,i.kt)("li",{parentName:"ul"},"Proof generation: The ability to produce ZKPs that verify the correct execution of programs. There are several types of cryptographic techniques used in zkVMs to\ngenerate these proofs, such as zk-SNARKs, zk-STARKs, and recursive proofs. A zkVM\u2019s ability to generate these proofs determines how effectively it can ensure the integrity of computations\nin a privacy-preserving manner."),(0,i.kt)("li",{parentName:"ul"},"Privacy preservation: The system must maintain privacy, ensuring that only the proof is revealed, not the underlying computation or data. Privacy-preserving zkVMs allow users to maintain\nconfidentiality without compromising the security or verifiability of their operations. However, not all zkVMs achieve the same level of privacy. Some may focus more on proof generation\nand scalability while deprioritizing privacy features, which can limit their use in certain privacy-sensitive applications."),(0,i.kt)("li",{parentName:"ul"},"Scalability and performance: zkVMs should offer scalable and efficient computation, leveraging advanced cryptographic techniques like zk-SNARKs, zk-STARKs, or recursive proofs.\nA zkVM's performance must also be measured in terms of latency (time to generate and verify a proof) and throughput (number of computations processed within a certain time frame)."),(0,i.kt)("li",{parentName:"ul"},"Verifiable computation: The zkVM should be able to prove the execution of arbitrary programs in a secure and verifiable manner. Verifiable computation ensures that zkVMs can be deployed\nacross a wide range of applications, from DeFi to private data-sharing platforms and more.")),(0,i.kt)("h1",{id:"why-zkvms-matter"},"Why zkVMs matter"),(0,i.kt)("p",null,"The rise of zkVMs is a crucial development for the future of blockchain and decentralized technologies. As more systems require the ability to scale while maintaining privacy and trust,\nzkVMs provide a powerful solution. They offer the potential to reshape the way decentralized applications (dapps) handle sensitive information, enabling them to be both efficient and private."),(0,i.kt)("p",null,"It is essential to distinguish between projects that fully realize the potential of zkVMs and those that do not. In the remainder of this post, we evaluate several zkVM projects, analyzing\nwhether they satisfy the criteria for being classified as zkVMs based on our research."),(0,i.kt)("h1",{id:"our-methodology"},"Our methodology"),(0,i.kt)("p",null,"We analyzed each project\u2019s documentation, source code, and available benchmarks to determine whether they meet the definition of a zkVM.\nOur criteria focus on the key capabilities of zkVMs\u2014proof generation, privacy, scalability, and integration with existing systems."),(0,i.kt)("h1",{id:"zkvm-project-analysis"},"ZkVM project analysis"),(0,i.kt)("h2",{id:"1-sp1"},"1. ","[SP1]"),(0,i.kt)("ul",null,(0,i.kt)("li",{parentName:"ul"},"Overview: SP1 [",(0,i.kt)("a",{parentName:"li",href:"https://blog.succinct.xyz/introducing-sp1/"},"1"),"] is a developer-friendly zkVM designed to enable ZKP execution for LLVM-based languages like C, C++, Rust, and others. It supports a RISC-V-like instruction set architecture (ISA),\nwhich makes it compatible with various programming languages compiled through LLVM."),(0,i.kt)("li",{parentName:"ul"},"Main focus: The main focus of SP1 is scalability, open-source contributions, and accessibility for developers. It prioritizes performance over privacy,\nmaking it a good fit for environments where privacy isn't the primary concern."),(0,i.kt)("li",{parentName:"ul"},"Privacy: Not explicitly mentioned, making it less suitable for privacy-preserving applications."),(0,i.kt)("li",{parentName:"ul"},"Performance: SP1 has demonstrated up to 5.4x better performance than similar zkVMs like RISC0 for specific computations such as Fibonacci sequence generation."),(0,i.kt)("li",{parentName:"ul"},"Integration: SP1 is highly adaptable for rollups, light client verifiers, oracles, and even web2 projects like verifying the originality of images."),(0,i.kt)("li",{parentName:"ul"},"Conclusion: Yes, SP1 is a zkVM, but it does not prioritize zero-knowledge privacy, focusing more on scalability and performance.")),(0,i.kt)("h2",{id:"2-nexus"},"2. ","[Nexus]"),(0,i.kt)("ul",null,(0,i.kt)("li",{parentName:"ul"},"Overview: Nexus [",(0,i.kt)("a",{parentName:"li",href:"https://docs.nexus.xyz/"},"2"),"] is a highly modular zkVM designed to process up to a trillion CPU cycles per second. It relies on RISC-V instructions for computation, making it extensible and scalable.\nHowever, it currently lacks full ZKP capabilities due to its use of Spartan proofs."),(0,i.kt)("li",{parentName:"ul"},"Main focus: Nexus focuses on high performance and scalability, aiming to create an efficient execution environment for computationally intensive tasks."),(0,i.kt)("li",{parentName:"ul"},"Privacy: Although zero-knowledge privacy isn't the primary feature of Nexus, the project hints at potential privacy enhancements in the future."),(0,i.kt)("li",{parentName:"ul"},"Performance: Nexus has a high theoretical throughput, but it has yet to demonstrate benchmarks on zero-knowledge privacy."),(0,i.kt)("li",{parentName:"ul"},"Integration: Nexus is a good fit for high-performance environments that do not necessarily require full privacy."),(0,i.kt)("li",{parentName:"ul"},"Conclusion: Yes, Nexus qualifies as a zkVM in terms of scalability and proof generation, but it does not yet achieve full zero-knowledge privacy.")),(0,i.kt)("h2",{id:"3-risc0"},"3. ","[RISC0]"),(0,i.kt)("ul",null,(0,i.kt)("li",{parentName:"ul"},"Overview: Risc0 [",(0,i.kt)("a",{parentName:"li",href:"https://www.risczero.com/zkvm"},"3"),"] is a general-purpose zkVM with strong developer support. It allows for the execution of Rust and C code on a RISC-V virtual machine\nand generates zk-SNARK and zk-STARK proofs for these computations."),(0,i.kt)("li",{parentName:"ul"},"Main focus: Risc0 is focused on ease of use for developers by abstracting away the complexities of circuit generation, making it accessible for a wide range of use cases."),(0,i.kt)("li",{parentName:"ul"},"Privacy: Full zero-knowledge privacy is supported via zk-SNARK and zk-STARK proofs, with Groth16 used for constant-size proof generation."),(0,i.kt)("li",{parentName:"ul"},"Performance: Risc0 offers strong benchmarks across different hardware setups, making it one of the most versatile zkVMs in terms of performance and scalability."),(0,i.kt)("li",{parentName:"ul"},"Integration: Risc0 integrates with several ecosystems, including Ethereum, and supports verifiable execution of Rust-based programs."),(0,i.kt)("li",{parentName:"ul"},"Conclusion: Yes, Risc0 qualifies as a zkVM, offering a balance of developer usability, scalability, and privacy.")),(0,i.kt)("h2",{id:"4-powdr"},"4. ","[Powdr]"),(0,i.kt)("ul",null,(0,i.kt)("li",{parentName:"ul"},"Overview: Powdr [",(0,i.kt)("a",{parentName:"li",href:"https://docs.powdr.org/"},"4"),"] is a toolkit for creating custom zkVMs. It allows developers to select from various front-end and back-end components to create zkVMs tailored to specific needs."),(0,i.kt)("li",{parentName:"ul"},"Main focus: Powdr is focused on providing a modular architecture for zkVM creation. It enables flexibility by allowing the combination of different ZK-proof backends like Halo2 or Valida."),(0,i.kt)("li",{parentName:"ul"},"Privacy: Powdr itself does not generate ZKPs, but it facilitates the creation of zkVMs that do."),(0,i.kt)("li",{parentName:"ul"},"Performance: The performance depends on the components chosen by the developer, as Powdr itself is more of a framework."),(0,i.kt)("li",{parentName:"ul"},"Integration: Powdr is highly customizable and can integrate with existing zkVM frameworks to extend their capabilities."),(0,i.kt)("li",{parentName:"ul"},"Conclusion: No, Powdr is not a zkVM itself, but it is a powerful tool for building customized zkVMs with different privacy and performance needs.")),(0,i.kt)("h2",{id:"5-zkmips"},"5. ","[ZkMIPS]"),(0,i.kt)("ul",null,(0,i.kt)("li",{parentName:"ul"},"Overview: ZkMIPS [",(0,i.kt)("a",{parentName:"li",href:"https://docs.zkm.io/zkm-architecture"},"5"),"] uses zk-STARKs to ensure privacy during computation, ensuring that private inputs are preserved while still proving correctness."),(0,i.kt)("li",{parentName:"ul"},"Performance: ZkMIPS is built for scalability, though explicit benchmarks are not widely published."),(0,i.kt)("li",{parentName:"ul"},"Integration: ZkMIPS can be integrated into systems that rely on MIPS architecture, making it versatile for legacy codebases that require privacy."),(0,i.kt)("li",{parentName:"ul"},"Conclusion: Yes, zkMIPS is a zkVM focused on scalability and privacy for MIPS-based architectures.")),(0,i.kt)("h2",{id:"6-valida"},"6. ","[Valida]"),(0,i.kt)("ul",null,(0,i.kt)("li",{parentName:"ul"},"Overview: Valida [",(0,i.kt)("a",{parentName:"li",href:"https://delendum.xyz/writings/2023-05-10-zkvm-design.html"},"6"),"] is a performance-oriented zkVM that generates proofs for programs using a custom ISA designed to optimize zkVM implementation.\nIt uses Plonky3 for its proof system."),(0,i.kt)("li",{parentName:"ul"},"Main focus: Valida is centered around optimizing prover performance and extensibility, making it a valuable tool for generating proofs efficiently."),(0,i.kt)("li",{parentName:"ul"},"Privacy: While Valida is focused on performance, it does not prioritize zero-knowledge privacy as much as other zkVMs."),(0,i.kt)("li",{parentName:"ul"},"Performance: Valida has benchmarks indicating its performance advantages in proving computations quickly, particularly through parallel processing."),(0,i.kt)("li",{parentName:"ul"},"Integration: Valida is specialized and may not integrate as seamlessly into general-purpose systems, as it is optimized for performance over broad applicability."),(0,i.kt)("li",{parentName:"ul"},"Conclusion: Yes, Valida qualifies as a zkVM based on proof generation, but its lack of focus on privacy makes it less suitable for privacy-first use cases.")),(0,i.kt)("h2",{id:"7-jolt"},"7. ","[Jolt]"),(0,i.kt)("ul",null,(0,i.kt)("li",{parentName:"ul"},"Overview: Jolt [",(0,i.kt)("a",{parentName:"li",href:"https://a16zcrypto.com/posts/article/building-jolt/"},"7"),"] is a zkVM built to optimize prover performance using a modified Hyrax polynomial commitment system. It relies on RISC-V instructions for computation\nbut falls short of full zero-knowledge capabilities."),(0,i.kt)("li",{parentName:"ul"},"Main focus: Jolt's main goal is to optimize the speed of proving program execution, making it suitable for high-performance applications where privacy isn't the primary concern."),(0,i.kt)("li",{parentName:"ul"},"Privacy: Jolt does not fully achieve zero-knowledge privacy due to the choice of polynomial commitment schemes."),(0,i.kt)("li",{parentName:"ul"},"Performance: Jolt offers strong performance, with benchmarks highlighting its ability to process proofs efficiently."),(0,i.kt)("li",{parentName:"ul"},"Integration: Jolt can be integrated with systems that prioritize speed over privacy, particularly where rapid proof generation is essential."),(0,i.kt)("li",{parentName:"ul"},"Conclusion: Yes, Jolt qualifies as a zkVM based on proof generation, though it does not provide full zero-knowledge privacy.")),(0,i.kt)("h2",{id:"8-zkwasm"},"8. ","[ZkWASM]"),(0,i.kt)("ul",null,(0,i.kt)("li",{parentName:"ul"},"Overview: ZkWASM [",(0,i.kt)("a",{parentName:"li",href:"https://delphinuslab.com/zk-wasm/"},"8"),"] is a zkVM designed to execute WebAssembly (WASM) code in a privacy-preserving and scalable manner. It uses zk-SNARKs to prove the correctness of WASM\nprogram execution while ensuring privacy."),(0,i.kt)("li",{parentName:"ul"},"Main focus: ZkWASM focuses on scalability and privacy for WebAssembly, making it ideal for dapps that require verifiable computation without compromising privacy."),(0,i.kt)("li",{parentName:"ul"},"Privacy: Full zero-knowledge privacy is provided through zk-SNARKs, ensuring that the execution of WASM programs remains confidential."),(0,i.kt)("li",{parentName:"ul"},"Performance: ZkWASM is optimized for running WASM programs efficiently, with offchain computation and onchain verification to enhance performance."),(0,i.kt)("li",{parentName:"ul"},"Integration: ZkWASM is ideal for dapps, particularly those that use WebAssembly and require verifiable execution."),(0,i.kt)("li",{parentName:"ul"},"Conclusion: Yes, zkWASM qualifies as a zkVM, providing strong privacy, scalability, and verifiable execution for WebAssembly code.")),(0,i.kt)("h2",{id:"9-aleo"},"9. ","[Aleo]"),(0,i.kt)("ul",null,(0,i.kt)("li",{parentName:"ul"},"Overview: Aleo's [",(0,i.kt)("a",{parentName:"li",href:"https://aleo.org/blog/"},"9"),"] snarkVM converts code into Aleo instructions, which are then compiled into bytecode executable on its zkVM. Aleo emphasizes building private, scalable dapps."),(0,i.kt)("li",{parentName:"ul"},"Main focus: Aleo prioritizes privacy and scalability for dapps, providing a robust framework for developers building private dapps."),(0,i.kt)("li",{parentName:"ul"},"Privacy: Aleo offers full privacy through zk-SNARK proofs, making it suitable for building fully private applications."),(0,i.kt)("li",{parentName:"ul"},"Performance: Aleo focuses on scalability through efficient proof systems, though detailed performance benchmarks are not widely available."),(0,i.kt)("li",{parentName:"ul"},"Integration: Aleo is built for privacy-first dapps and integrates with other zkVM-based systems."),(0,i.kt)("li",{parentName:"ul"},"Conclusion: Yes, Aleo qualifies as a zkVM, offering a comprehensive solution for private and scalable dapps.")),(0,i.kt)("h2",{id:"10-ola"},"10. ","[Ola]"),(0,i.kt)("ul",null,(0,i.kt)("li",{parentName:"ul"},"Overview: Ola [",(0,i.kt)("a",{parentName:"li",href:"https://github.com/Sin7Y/olavm-whitepaper-v2/tree/master"},"10"),"] is a ZK-friendly, high-performance layer-2 (L2) rollup platform that is still under development. It is designed to execute computations offchain while generating\nvalidity proofs for these computations, ensuring that they are correctly executed without compromising security. "),(0,i.kt)("li",{parentName:"ul"},"Privacy: Ola does not specifically prioritize privacy in the same way that zkVMs do. While it leverages ZKPs for scalability, its focus is on proving the correctness of\ntransactions and computations rather than ensuring that the data remains private."),(0,i.kt)("li",{parentName:"ul"},"Performance: Ola is designed to achieve high performance, particularly in terms of transaction throughput."),(0,i.kt)("li",{parentName:"ul"},"Integration: Ola is designed to be interoperable with various layer-1 blockchains. The platform supports a hybrid ZK-rollup architecture and is expected to include bridges for cross-chain\ninteroperability, enabling assets and data to move seamlessly between the layer-1 blockchain and the Ola rollup."),(0,i.kt)("li",{parentName:"ul"},"Conclusion: No, Ola is not a zkVM. While it leverages ZKPs (in the form of ZK-rollups) to ensure the validity of offchain computations, its primary focus is on scalability and performance\nrather than privacy or verifiable execution of arbitrary programs. Ola is more accurately described as a ZK-rollup platform aimed at improving transaction throughput and reducing transaction costs on\nlayer-1 blockchains. ")),(0,i.kt)("h2",{id:"11-miden"},"11. ","[Miden]"),(0,i.kt)("ul",null,(0,i.kt)("li",{parentName:"ul"},"Overview: Miden zkVM [",(0,i.kt)("a",{parentName:"li",href:"https://0xpolygonmiden.github.io/miden-vm/intro/main.html"},"11"),"] is a zk-STARK-based virtual machine that converts code into Miden VM instructions and proves the execution of these instructions with zero-knowledge privacy."),(0,i.kt)("li",{parentName:"ul"},"Main focus: Miden focuses on scalability and privacy for ZK-rollups, offering efficient proof generation for dapps."),(0,i.kt)("li",{parentName:"ul"},"Privacy: Miden ensures privacy for transactions and programs via zk-STARK proofs, making it suitable for private dapps."),(0,i.kt)("li",{parentName:"ul"},"Performance: Miden is optimized for scalability, with benchmarks showing its ability to handle up to 1,000 transactions per second (TPS)."),(0,i.kt)("li",{parentName:"ul"},"Integration: Miden integrates well with ZK-rollup solutions, making it ideal for L2 scaling solutions on blockchains like Ethereum."),(0,i.kt)("li",{parentName:"ul"},"Conclusion: Yes, Miden qualifies as a zkVM, providing strong privacy and scalability for dapps and ZK-rollups.")),(0,i.kt)("h2",{id:"12-zkos"},"12. ","[ZkOS]"),(0,i.kt)("ul",null,(0,i.kt)("li",{parentName:"ul"},"Overview: ZkOS [",(0,i.kt)("a",{parentName:"li",href:"https://osblog.stephenmarz.com/index.html"},"12"),"] is a verifiable operating system focused on running zkApps in a decentralized manner. It is built on the RISC-V architecture and aims to create\na world computer where all untrusted executions can be verified."),(0,i.kt)("li",{parentName:"ul"},"Main focus: ZkOS is primarily designed to offer a proof-of-concept operating system where all executions can be verified in a trustless manner.\nHowever, its focus is more on the infrastructure for verifiable applications rather than being a traditional zkVM."),(0,i.kt)("li",{parentName:"ul"},"Privacy: ZkOS does not focus on privacy guarantees such as those found in zkVMs that generate ZKPs."),(0,i.kt)("li",{parentName:"ul"},"Performance: ZkOS focuses on the efficient execution of dapps, but performance benchmarks specific to ZKP generation are not provided."),(0,i.kt)("li",{parentName:"ul"},"Integration: ZkOS supports the execution of zkApps, but it is more of a verifiable operating system rather than a zkVM, making it distinct in its functionality."),(0,i.kt)("li",{parentName:"ul"},"Conclusion: No, zkOS is not a zkVM. It is a verifiable operating system focused on the infrastructure to support zkApps but does not directly generate ZKPs or focus on privacy preservation.")),(0,i.kt)("h2",{id:"13-triton"},"13. ","[Triton]"),(0,i.kt)("ul",null,(0,i.kt)("li",{parentName:"ul"},"Overview: Triton [",(0,i.kt)("a",{parentName:"li",href:"https://triton-vm.org/spec/"},"13"),"] is a domain-specific language (DSL) and compiler designed primarily for high-performance GPU kernels, particularly those used in deep learning applications. "),(0,i.kt)("li",{parentName:"ul"},"Main focus: The primary goal of Triton is to optimize computation for machine learning and GPU workloads. It is focused on enhancing performance and efficiency in processing data\nrather than on ZKPs or verifiable computation."),(0,i.kt)("li",{parentName:"ul"},"Privacy: Triton does not provide ZKPs or privacy features typically associated with zkVMs. Its focus is on high-performance computation rather than cryptographic verifiability."),(0,i.kt)("li",{parentName:"ul"},"Performance: Triton is highly optimized for GPU execution, offering significant improvements in performance for computationally intensive tasks such as those found in deep learning."),(0,i.kt)("li",{parentName:"ul"},"Integration: Triton is integrated with GPU-based computation environments and is highly specialized for optimizing low-level operations on hardware rather\nthan being a general-purpose virtual machine."),(0,i.kt)("li",{parentName:"ul"},"Conclusion: No, Triton is not a zkVM. It is a specialized tool for optimizing GPU workloads, focusing on performance rather than privacy or ZKPs.")),(0,i.kt)("h2",{id:"14-cairo"},"14. ","[Cairo]"),(0,i.kt)("ul",null,(0,i.kt)("li",{parentName:"ul"},"Overview: Cairo zkVM [",(0,i.kt)("a",{parentName:"li",href:"https://github.com/lambdaclass/cairo-vm/blob/main/docs/python_vm/README.md"},"14"),"] uses a custom language that compiles to an optimized STARK-based proof system, ensuring verifiable computation. It is primarily used in systems like Starknet."),(0,i.kt)("li",{parentName:"ul"},"Main focus: Cairo focuses on scalability and performance, using zk-STARK proofs to ensure the verifiable and secure execution of programs."),(0,i.kt)("li",{parentName:"ul"},"Privacy: Cairo provides privacy through zk-STARKs, but it focuses more on scalability and performance than privacy-first use cases."),(0,i.kt)("li",{parentName:"ul"},"Performance: Cairo is highly optimized for performance, making it well-suited for scalable applications on Starknet."),(0,i.kt)("li",{parentName:"ul"},"Integration: Cairo integrates deeply with systems like Starknet, supporting verifiable computation in a highly scalable and efficient manner."),(0,i.kt)("li",{parentName:"ul"},"Conclusion: Yes, Cairo qualifies as a zkVM, focusing on performance and verifiable execution while being ZK-friendly.")),(0,i.kt)("h2",{id:"15-snarkos"},"15. ","[SnarkOS]"),(0,i.kt)("ul",null,(0,i.kt)("li",{parentName:"ul"},"Overview: SnarkOS [",(0,i.kt)("a",{parentName:"li",href:"https://aleo.org/post/aleo-completes-security-audits-of-snarkos-and-snarkvm/"},"15"),"] is a decentralized operating system designed to power Aleo's network, enabling secure and private dapps.\nIt manages transactions and consensus, making it a critical infrastructure component for Aleo's zkVM-based ecosystem."),(0,i.kt)("li",{parentName:"ul"},"Main focus: SnarkOS primarily focuses on securing Aleo's network through consensus mechanisms and privacy-preserving transactions rather than acting as a\nzkVM that directly proves program execution."),(0,i.kt)("li",{parentName:"ul"},"Privacy: SnarkOS supports zero-knowledge privacy through its integration with Aleo's zkVM, but the operating system itself does not generate ZKPs for arbitrary computations."),(0,i.kt)("li",{parentName:"ul"},"Performance: SnarkOS is optimized for managing dapps on the Aleo network and handling private transactions, but its focus is more on infrastructure\nand consensus than on proof generation."),(0,i.kt)("li",{parentName:"ul"},"Integration: SnarkOS integrates seamlessly with Aleo's zkVM to support private dapps and transactions, but its primary role is as a consensus layer."),(0,i.kt)("li",{parentName:"ul"},"Conclusion: No, SnarkOS is not a zkVM. It serves as an operating system for Aleo's decentralized network, focusing on privacy and consensus rather than on generating ZKPs for computations.")),(0,i.kt)("h2",{id:"16-lurk"},"16. ","[Lurk]"),(0,i.kt)("ul",null,(0,i.kt)("li",{parentName:"ul"},"Overview: Lurk [",(0,i.kt)("a",{parentName:"li",href:"https://github.com/lurk-lab"},"16"),"] is a Turing-complete programming language designed for recursive zk-SNARKs. It focuses on enabling developers to build complex,\nrecursive ZKPs efficiently through a custom language tailored for verifiable computation."),(0,i.kt)("li",{parentName:"ul"},"Main focus: Lurk is centered around recursive proof generation rather than serving as a traditional virtual machine. Its purpose is to facilitate the creation of complex zk-SNARK-based proofs,\nmaking it a specialized tool for cryptographic proofs rather than general-purpose computation."),(0,i.kt)("li",{parentName:"ul"},"Privacy: Lurk is built for generating zk-SNARKs, which inherently provide privacy. However, Lurk itself is a language and not a zkVM that executes arbitrary programs and generates ZKPs for them."),(0,i.kt)("li",{parentName:"ul"},"Performance: Lurk is optimized for recursive zk-SNARK generation, but specific performance metrics are tied to its proof-generation capabilities rather than traditional execution environments."),(0,i.kt)("li",{parentName:"ul"},"Integration: Lurk is specialized for zk-SNARKs and may not easily integrate with other general-purpose systems, as it focuses on specific cryptographic tasks."),(0,i.kt)("li",{parentName:"ul"},"Conclusion: No, Lurk is not a zkVM. It is a programming language designed for recursive zk-SNARKs and focuses on proof generation rather than program execution in a virtual machine environment.")),(0,i.kt)("h2",{id:"17-piecrust"},"17. ","[Piecrust]"),(0,i.kt)("ul",null,(0,i.kt)("li",{parentName:"ul"},"Overview: Piecrust [",(0,i.kt)("a",{parentName:"li",href:"https://docs.rs/piecrust/latest/piecrust/"},"17"),"] is a WASM-based zkVM designed to run on the Dusk Network. It supports concurrent execution and focuses on providing privacy and scalability for smart contracts."),(0,i.kt)("li",{parentName:"ul"},"Main focus: Piecrust is designed to provide private and efficient execution of smart contracts through the use of ZKPs."),(0,i.kt)("li",{parentName:"ul"},"Privacy: Piecrust supports ZK-friendly computations and enhances privacy through cryptographic primitives such as Merkle trees."),(0,i.kt)("li",{parentName:"ul"},"Performance: Piecrust is designed to be scalable and concurrent, allowing multiple sessions to run simultaneously, which improves overall performance."),(0,i.kt)("li",{parentName:"ul"},"Integration: Piecrust integrates with the Dusk Network and supports private smart contracts, making it ideal for dapps."),(0,i.kt)("li",{parentName:"ul"},"Conclusion: Yes, Piecrust qualifies as a zkVM, offering scalability, privacy, and support for succinct proof generation.")),(0,i.kt)("h2",{id:"18-ceno"},"18. ","[Ceno]"),(0,i.kt)("ul",null,(0,i.kt)("li",{parentName:"ul"},"Overview: Ceno [",(0,i.kt)("a",{parentName:"li",href:"https://eprint.iacr.org/2024/387"},"18"),"] is a zkVM that provides a theoretical framework for reducing proving time by grouping common portions of code together. It uses recursive proofs to enhance prover efficiency."),(0,i.kt)("li",{parentName:"ul"},"Main focus: Ceno aims to optimize prover performance through recursive proofs, making it a powerful tool for handling complex computations efficiently."),(0,i.kt)("li",{parentName:"ul"},"Privacy: Ceno supports zero-knowledge privacy through recursive proofs and is designed to handle large-scale computations securely."),(0,i.kt)("li",{parentName:"ul"},"Performance: Ceno's recursive proof framework ensures that it can efficiently prove the execution of programs, reducing the time required for proof generation."),(0,i.kt)("li",{parentName:"ul"},"Integration: Ceno can be integrated into systems that require high efficiency and privacy, particularly those handling complex, repeated computations."),(0,i.kt)("li",{parentName:"ul"},"Conclusion: Yes, Ceno qualifies as a zkVM, providing efficient and private computation through the use of recursive proofs.")),(0,i.kt)("h2",{id:"19-stellar"},"19. ","[Stellar]"),(0,i.kt)("ul",null,(0,i.kt)("li",{parentName:"ul"},"Overview: Stellar [",(0,i.kt)("a",{parentName:"li",href:"https://stellar.org/blog/developers/zkvm-a-new-design-for-fast-confidential-smart-contracts"},"19"),"] is a decentralized protocol designed to facilitate cross-border transactions between digital and fiat currencies."),(0,i.kt)("li",{parentName:"ul"},"Main focus: Stellar's primary goal is to improve financial transactions by enabling decentralized, low-cost currency transfers. It does not aim to provide ZKPs or run verifiable computations\nlike a zkVM."),(0,i.kt)("li",{parentName:"ul"},"Privacy: Stellar focuses on confidentiality and security for financial transactions, but it does not employ ZKPs in the way zkVMs do for verifying computation without revealing data."),(0,i.kt)("li",{parentName:"ul"},"Performance: Stellar prioritizes the performance of financial transactions, ensuring low latency and high throughput across its decentralized network.\nHowever, this performance focus is specific to transactions rather than general-purpose program execution."),(0,i.kt)("li",{parentName:"ul"},"Integration: Stellar is designed for integration with financial systems, enabling currency conversions and transfers, but it is not built for executing smart contracts or verifiable computations."),(0,i.kt)("li",{parentName:"ul"},"Conclusion: No, Stellar is not a zkVM. It is a decentralized financial protocol focused on facilitating cross-border payments rather than verifiable or privacy-preserving computation.")),(0,i.kt)("h2",{id:"20-novanet"},"20. ","[NovaNet]"),(0,i.kt)("ul",null,(0,i.kt)("li",{parentName:"ul"},"Overview: NovaNet [",(0,i.kt)("a",{parentName:"li",href:"https://www.novanet.xyz/blog"},"20"),"] is an open peer-to-peer network that aims to build upon concepts of non-uniform incremental verifiable computation. "),(0,i.kt)("li",{parentName:"ul"},"Main focus: NovaNet's focus is on peer-to-peer networking and decentralized computing rather than on proving the execution of programs in a zero-knowledge manner."),(0,i.kt)("li",{parentName:"ul"},"Privacy: NovaNet does not provide ZKPs or privacy features typically associated with zkVMs. Its focus is on decentralized networking and computation."),(0,i.kt)("li",{parentName:"ul"},"Performance: NovaNet prioritizes efficient decentralized computation but does not focus on privacy or performance benchmarks related to ZKPs."),(0,i.kt)("li",{parentName:"ul"},"Integration: NovaNet is built for decentralized networks but is not designed to integrate with systems requiring verifiable computation or ZKP generation."),(0,i.kt)("li",{parentName:"ul"},"Conclusion: No, NovaNet is not a zkVM. It is a decentralized peer-to-peer network focused on distributed computing rather than zero-knowledge computation.")),(0,i.kt)("h2",{id:"21-zkllvm"},"21. ","[ZkLLVM]"),(0,i.kt)("ul",null,(0,i.kt)("li",{parentName:"ul"},"Overview: ZkLLVM [",(0,i.kt)("a",{parentName:"li",href:"https://github.com/NilFoundation/zkLLVM"},"21"),"] is a compiler that transforms C++ or Rust code into circuits for use in zk-SNARK or zk-STARK systems. Its primary purpose is to bridge high-level programming\nlanguages with ZKP systems by compiling code into arithmetic circuits that can be used to generate and verify proofs."),(0,i.kt)("li",{parentName:"ul"},"Main focus: ZkLLVM focuses on making ZKPs accessible to developers by enabling them to write code in familiar languages (C++, Rust) and then compile that code into ZK circuits."),(0,i.kt)("li",{parentName:"ul"},"Privacy: ZkLLVM enables the generation of ZKPs by compiling high-level code into ZK-compatible circuits. It plays a crucial role in privacy-preserving applications but does not act\nas a zkVM itself."),(0,i.kt)("li",{parentName:"ul"},"Performance: ZkLLVM allows for the performance of ZKPs to be closely tied to the complexity of the compiled circuits. The performance depends on the underlying\nzk-SNARK or zk-STARK system used."),(0,i.kt)("li",{parentName:"ul"},"Integration: ZkLLVM integrates with zk-SNARK and zk-STARK proof systems, making it useful for a variety of privacy-focused applications, but it does not serve as a zkVM\nfor general-purpose computation."),(0,i.kt)("li",{parentName:"ul"},"Conclusion: No, zkLLVM is not a zkVM. It is a compiler that transforms high-level code into ZK circuits, enabling ZKPs but not acting as a virtual machine for executing and proving programs.")),(0,i.kt)("h2",{id:"22-zkmove"},"22. ","[ZkMove]"),(0,i.kt)("ul",null,(0,i.kt)("li",{parentName:"ul"},"Overview: ZkMove [",(0,i.kt)("a",{parentName:"li",href:"https://www.zkmove.net/2023-06-20-zkMove-0.2.0-Achieving-Full-Bytecode-Compatibility-with-Move/"},"22"),"] is a zkVM designed to execute smart contracts written in the Move language. It utilizes ZKPs to ensure that the execution of these contracts remains verifiable and secure."),(0,i.kt)("li",{parentName:"ul"},"Main focus: ZkMove focuses on privacy and verifiable execution for Move-based smart contracts, providing a framework for ZK-friendly computation."),(0,i.kt)("li",{parentName:"ul"},"Privacy: ZkMove ensures that smart contract execution remains private through ZKPs, making it suitable for privacy-preserving applications."),(0,i.kt)("li",{parentName:"ul"},"Performance: ZkMove is optimized for verifiable execution, ensuring that contracts can be proven correct while preserving privacy."),(0,i.kt)("li",{parentName:"ul"},"Integration: ZkMove integrates well with systems that use the Move language, particularly in environments that require private smart contract execution."),(0,i.kt)("li",{parentName:"ul"},"Conclusion: Yes, zkMove qualifies as a zkVM, offering ZK-friendly execution and privacy for smart contracts written in the Move language.")),(0,i.kt)("h2",{id:"23-o1vm"},"23. ","[O1VM]"),(0,i.kt)("ul",null,(0,i.kt)("li",{parentName:"ul"},"Overview: O1VM [",(0,i.kt)("a",{parentName:"li",href:"https://github.com/o1-labs/proof-systems/tree/master/o1vm"},"23"),"] is a general-purpose zkVM developed by o1Labs. It is designed to prove the execution of MIPS programs efficiently through a combination of zk-SNARKs\nand specialized techniques like folding schemes and RAMLookups."),(0,i.kt)("li",{parentName:"ul"},"Main focus: O1VM focuses on scalability and verifiable computation for MIPS-based programs, making it a strong contender for executing and proving complex programs efficiently."),(0,i.kt)("li",{parentName:"ul"},"Privacy: O1VM ensures privacy through zk-SNARK proofs, keeping the details of the computation private while proving its correctness."),(0,i.kt)("li",{parentName:"ul"},"Performance: O1VM is optimized for handling long execution traces and complex computations, making it highly scalable."),(0,i.kt)("li",{parentName:"ul"},"Integration: O1VM integrates well with MIPS-based architectures and systems that require privacy-preserving computation."),(0,i.kt)("li",{parentName:"ul"},"Conclusion: Yes, o1VM qualifies as a zkVM, providing privacy, scalability, and strong proof generation for MIPS programs.")),(0,i.kt)("h1",{id:"summary-of-findings"},"Summary of findings"),(0,i.kt)("table",null,(0,i.kt)("thead",{parentName:"table"},(0,i.kt)("tr",{parentName:"thead"},(0,i.kt)("th",{parentName:"tr",align:null},"Project name"),(0,i.kt)("th",{parentName:"tr",align:null},"ZkVM status"),(0,i.kt)("th",{parentName:"tr",align:null},"Zero knowledge"),(0,i.kt)("th",{parentName:"tr",align:null},"Reasoning/comments"))),(0,i.kt)("tbody",{parentName:"table"},(0,i.kt)("tr",{parentName:"tbody"},(0,i.kt)("td",{parentName:"tr",align:null},(0,i.kt)("strong",{parentName:"td"},"SP1")),(0,i.kt)("td",{parentName:"tr",align:null},"Yes"),(0,i.kt)("td",{parentName:"tr",align:null},"No"),(0,i.kt)("td",{parentName:"tr",align:null},"Proves execution of LLVM-based programs but lacks privacy features.")),(0,i.kt)("tr",{parentName:"tbody"},(0,i.kt)("td",{parentName:"tr",align:null},(0,i.kt)("strong",{parentName:"td"},"Nexus")),(0,i.kt)("td",{parentName:"tr",align:null},"Yes"),(0,i.kt)("td",{parentName:"tr",align:null},"No"),(0,i.kt)("td",{parentName:"tr",align:null},"Strong proof generation but lacks zero-knowledge privacy due to Spartan.")),(0,i.kt)("tr",{parentName:"tbody"},(0,i.kt)("td",{parentName:"tr",align:null},(0,i.kt)("strong",{parentName:"td"},"Risc0")),(0,i.kt)("td",{parentName:"tr",align:null},"Yes"),(0,i.kt)("td",{parentName:"tr",align:null},"Yes"),(0,i.kt)("td",{parentName:"tr",align:null},"Supports full ZKP generation for Rust programs.")),(0,i.kt)("tr",{parentName:"tbody"},(0,i.kt)("td",{parentName:"tr",align:null},(0,i.kt)("strong",{parentName:"td"},"Powdr")),(0,i.kt)("td",{parentName:"tr",align:null},"No"),(0,i.kt)("td",{parentName:"tr",align:null},"Yes"),(0,i.kt)("td",{parentName:"tr",align:null},"Toolkit for creating custom zkVMs, not a zkVM itself.")),(0,i.kt)("tr",{parentName:"tbody"},(0,i.kt)("td",{parentName:"tr",align:null},(0,i.kt)("strong",{parentName:"td"},"ZkMIPS")),(0,i.kt)("td",{parentName:"tr",align:null},"Yes"),(0,i.kt)("td",{parentName:"tr",align:null},"Yes"),(0,i.kt)("td",{parentName:"tr",align:null},"Supports MIPS-like architecture with full zero-knowledge and proof generation.")),(0,i.kt)("tr",{parentName:"tbody"},(0,i.kt)("td",{parentName:"tr",align:null},(0,i.kt)("strong",{parentName:"td"},"Valida")),(0,i.kt)("td",{parentName:"tr",align:null},"Yes"),(0,i.kt)("td",{parentName:"tr",align:null},"No"),(0,i.kt)("td",{parentName:"tr",align:null},"Performance-focused zkVM, lacks privacy guarantees.")),(0,i.kt)("tr",{parentName:"tbody"},(0,i.kt)("td",{parentName:"tr",align:null},(0,i.kt)("strong",{parentName:"td"},"Jolt")),(0,i.kt)("td",{parentName:"tr",align:null},"Yes"),(0,i.kt)("td",{parentName:"tr",align:null},"No"),(0,i.kt)("td",{parentName:"tr",align:null},"Performance-focused zkVM, does not achieve zero-knowledge privacy.")),(0,i.kt)("tr",{parentName:"tbody"},(0,i.kt)("td",{parentName:"tr",align:null},(0,i.kt)("strong",{parentName:"td"},"ZkWASM")),(0,i.kt)("td",{parentName:"tr",align:null},"Yes"),(0,i.kt)("td",{parentName:"tr",align:null},"Yes"),(0,i.kt)("td",{parentName:"tr",align:null},"Full zero-knowledge and verifiable execution of WebAssembly code.")),(0,i.kt)("tr",{parentName:"tbody"},(0,i.kt)("td",{parentName:"tr",align:null},(0,i.kt)("strong",{parentName:"td"},"Aleo")),(0,i.kt)("td",{parentName:"tr",align:null},"Yes"),(0,i.kt)("td",{parentName:"tr",align:null},"Yes"),(0,i.kt)("td",{parentName:"tr",align:null},"Fully private and scalable dapps.")),(0,i.kt)("tr",{parentName:"tbody"},(0,i.kt)("td",{parentName:"tr",align:null},(0,i.kt)("strong",{parentName:"td"},"Ola")),(0,i.kt)("td",{parentName:"tr",align:null},"No"),(0,i.kt)("td",{parentName:"tr",align:null},"No"),(0,i.kt)("td",{parentName:"tr",align:null},"Primarily a ZK-rollup platform, not a zkVM, focusing on scalability and performance rather than privacy.")),(0,i.kt)("tr",{parentName:"tbody"},(0,i.kt)("td",{parentName:"tr",align:null},(0,i.kt)("strong",{parentName:"td"},"Miden")),(0,i.kt)("td",{parentName:"tr",align:null},"Yes"),(0,i.kt)("td",{parentName:"tr",align:null},"Yes"),(0,i.kt)("td",{parentName:"tr",align:null},"Zk-STARK-based zkVM with strong privacy and scalability.")),(0,i.kt)("tr",{parentName:"tbody"},(0,i.kt)("td",{parentName:"tr",align:null},(0,i.kt)("strong",{parentName:"td"},"ZkOS")),(0,i.kt)("td",{parentName:"tr",align:null},"No"),(0,i.kt)("td",{parentName:"tr",align:null},"No"),(0,i.kt)("td",{parentName:"tr",align:null},"Verifiable operating system focused on zkApps, not a zkVM.")),(0,i.kt)("tr",{parentName:"tbody"},(0,i.kt)("td",{parentName:"tr",align:null},(0,i.kt)("strong",{parentName:"td"},"Triton")),(0,i.kt)("td",{parentName:"tr",align:null},"No"),(0,i.kt)("td",{parentName:"tr",align:null},"No"),(0,i.kt)("td",{parentName:"tr",align:null},"Optimizes GPU workloads but not designed for ZKPs.")),(0,i.kt)("tr",{parentName:"tbody"},(0,i.kt)("td",{parentName:"tr",align:null},(0,i.kt)("strong",{parentName:"td"},"Cairo")),(0,i.kt)("td",{parentName:"tr",align:null},"Yes"),(0,i.kt)("td",{parentName:"tr",align:null},"ZK-friendly"),(0,i.kt)("td",{parentName:"tr",align:null},"Custom Rust-based language with zk-STARK proof generation.")),(0,i.kt)("tr",{parentName:"tbody"},(0,i.kt)("td",{parentName:"tr",align:null},(0,i.kt)("strong",{parentName:"td"},"SnarkOS")),(0,i.kt)("td",{parentName:"tr",align:null},"No"),(0,i.kt)("td",{parentName:"tr",align:null},"Yes"),(0,i.kt)("td",{parentName:"tr",align:null},"Decentralized OS for Aleo's network, focuses on consensus rather than verifiable computation.")),(0,i.kt)("tr",{parentName:"tbody"},(0,i.kt)("td",{parentName:"tr",align:null},(0,i.kt)("strong",{parentName:"td"},"Lurk")),(0,i.kt)("td",{parentName:"tr",align:null},"No"),(0,i.kt)("td",{parentName:"tr",align:null},"No"),(0,i.kt)("td",{parentName:"tr",align:null},"Programming language for recursive zk-SNARKs, not a zkVM.")),(0,i.kt)("tr",{parentName:"tbody"},(0,i.kt)("td",{parentName:"tr",align:null},(0,i.kt)("strong",{parentName:"td"},"Piecrust")),(0,i.kt)("td",{parentName:"tr",align:null},"Yes"),(0,i.kt)("td",{parentName:"tr",align:null},"ZK-friendly"),(0,i.kt)("td",{parentName:"tr",align:null},"ZkVM with recursive SNARK capabilities, focused on succinct proof generation.")),(0,i.kt)("tr",{parentName:"tbody"},(0,i.kt)("td",{parentName:"tr",align:null},(0,i.kt)("strong",{parentName:"td"},"Ceno")),(0,i.kt)("td",{parentName:"tr",align:null},"Yes"),(0,i.kt)("td",{parentName:"tr",align:null},"Yes"),(0,i.kt)("td",{parentName:"tr",align:null},"Theoretical zkVM improving prover efficiency through recursive proofs.")),(0,i.kt)("tr",{parentName:"tbody"},(0,i.kt)("td",{parentName:"tr",align:null},(0,i.kt)("strong",{parentName:"td"},"Stellar")),(0,i.kt)("td",{parentName:"tr",align:null},"No"),(0,i.kt)("td",{parentName:"tr",align:null},"No"),(0,i.kt)("td",{parentName:"tr",align:null},"Focuses on cross-border transactions, not ZK-proof generation or verifiable computation.")),(0,i.kt)("tr",{parentName:"tbody"},(0,i.kt)("td",{parentName:"tr",align:null},(0,i.kt)("strong",{parentName:"td"},"NovaNet")),(0,i.kt)("td",{parentName:"tr",align:null},"No"),(0,i.kt)("td",{parentName:"tr",align:null},"No"),(0,i.kt)("td",{parentName:"tr",align:null},"Peer-to-peer network focused on distributed computing, not zero-knowledge computation.")),(0,i.kt)("tr",{parentName:"tbody"},(0,i.kt)("td",{parentName:"tr",align:null},(0,i.kt)("strong",{parentName:"td"},"ZkLLVM")),(0,i.kt)("td",{parentName:"tr",align:null},"No"),(0,i.kt)("td",{parentName:"tr",align:null},"Yes, in some cases"),(0,i.kt)("td",{parentName:"tr",align:null},"Compiler for generating ZK-circuits, not a zkVM.")),(0,i.kt)("tr",{parentName:"tbody"},(0,i.kt)("td",{parentName:"tr",align:null},(0,i.kt)("strong",{parentName:"td"},"ZkMove")),(0,i.kt)("td",{parentName:"tr",align:null},"Yes"),(0,i.kt)("td",{parentName:"tr",align:null},"ZK-friendly"),(0,i.kt)("td",{parentName:"tr",align:null},"ZkVM supporting Move language with ZKP execution.")),(0,i.kt)("tr",{parentName:"tbody"},(0,i.kt)("td",{parentName:"tr",align:null},(0,i.kt)("strong",{parentName:"td"},"O1VM")),(0,i.kt)("td",{parentName:"tr",align:null},"Yes"),(0,i.kt)("td",{parentName:"tr",align:null},"Yes"),(0,i.kt)("td",{parentName:"tr",align:null},"MIPS-based zkVM with strong privacy, scalability, and proof generation.")))),(0,i.kt)("h1",{id:"insights-and-conclusions"},"Insights and conclusions"),(0,i.kt)("p",null,"Our analysis reveals that many of the projects labeled as zkVMs do meet the core criteria for zkVMs, offering verifiable computation and proof generation\nas foundational features. However, a number of these projects fall short of delivering full zero-knowledge privacy. Projects like Risc0, Aleo, and Miden stand out as leading zkVM frameworks\nthat balance proof generation, privacy, and scalability, offering strong platforms for developers seeking to build privacy-preserving applications."),(0,i.kt)("p",null,"Conversely, projects like SP1 and Nexus excel in generating verifiable proofs but currently lack comprehensive zero-knowledge privacy mechanisms. These platforms are excellent for\nscenarios where proof generation and scalability are paramount, but privacy is not a primary concern."),(0,i.kt)("p",null,"As zkVM technology continues to evolve, we expect to see more projects integrating enhanced privacy-preserving mechanisms while simultaneously improving performance and scalability.\nThis ongoing development will likely broaden the application of zkVMs across the blockchain ecosystem, particularly in privacy-sensitive sectors such as finance, data security,\nand decentralized applications."),(0,i.kt)("p",null,"What are your thoughts on our zkVM analysis? Do you agree with our findings, or do you know of other zkVM projects that should be on our radar? We would love to hear your insights, questions,\nor suggestions! Feel free to join the ",(0,i.kt)("a",{parentName:"p",href:"https://forum.vac.dev/t/exploring-zkvms-which-projects-truly-qualify-as-zero-knowledge-virtual-machines/317"},"discussion")," on our forum."),(0,i.kt)("h1",{id:"references"},"References"),(0,i.kt)("p",null,"[1]"," Introducing SP1: A performant, 100% open-source, contributor-friendly zkVM. Retrieved from ",(0,i.kt)("a",{parentName:"p",href:"https://blog.succinct.xyz/introducing-sp1/"},"https://blog.succinct.xyz/introducing-sp1/")),(0,i.kt)("p",null,"[2]"," The Nexus 2.0 zkVM. Retrieved from ",(0,i.kt)("a",{parentName:"p",href:"https://docs.nexus.xyz/"},"https://docs.nexus.xyz/")),(0,i.kt)("p",null,"[3]"," The first general purpose zkVM. Retrieved from ",(0,i.kt)("a",{parentName:"p",href:"https://www.risczero.com/zkvm"},"https://www.risczero.com/zkvm")),(0,i.kt)("p",null,"[4]"," Powdr. Retrieved from ",(0,i.kt)("a",{parentName:"p",href:"https://docs.powdr.org/"},"https://docs.powdr.org/")),(0,i.kt)("p",null,"[5]"," ZKM Architecture. Retrieved from ",(0,i.kt)("a",{parentName:"p",href:"https://docs.zkm.io/zkm-architecture"},"https://docs.zkm.io/zkm-architecture")),(0,i.kt)("p",null,"[6]"," Valida zkVM Design. Retrieved from ",(0,i.kt)("a",{parentName:"p",href:"https://delendum.xyz/writings/2023-05-10-zkvm-design.html"},"https://delendum.xyz/writings/2023-05-10-zkvm-design.html")),(0,i.kt)("p",null,"[7]"," Building Jolt: A fast, easy-to-use zkVM. Retrieved from ",(0,i.kt)("a",{parentName:"p",href:"https://a16zcrypto.com/posts/article/building-jolt/"},"https://a16zcrypto.com/posts/article/building-jolt/")),(0,i.kt)("p",null,"[8]"," ZK-WASM. Retrieved from ",(0,i.kt)("a",{parentName:"p",href:"https://delphinuslab.com/zk-wasm/"},"https://delphinuslab.com/zk-wasm/")),(0,i.kt)("p",null,"[9]"," Aleo. Retrieved from ",(0,i.kt)("a",{parentName:"p",href:"https://aleo.org/blog/"},"https://aleo.org/blog/")),(0,i.kt)("p",null,"[10]"," OlaVM Whitepaper V2. Retrieved from ",(0,i.kt)("a",{parentName:"p",href:"https://github.com/Sin7Y/olavm-whitepaper-v2/tree/master"},"https://github.com/Sin7Y/olavm-whitepaper-v2/tree/master")),(0,i.kt)("p",null,"[11]"," Polygon Miden VM. Retrieved from ",(0,i.kt)("a",{parentName:"p",href:"https://0xpolygonmiden.github.io/miden-vm/intro/main.html"},"https://0xpolygonmiden.github.io/miden-vm/intro/main.html")),(0,i.kt)("p",null,"[12]"," The Adventures of OS: Making a RISC-V Operating System using Rust. Retrieved from ",(0,i.kt)("a",{parentName:"p",href:"https://osblog.stephenmarz.com/index.html"},"https://osblog.stephenmarz.com/index.html")),(0,i.kt)("p",null,"[13]"," Triton VM. Retrieved from ",(0,i.kt)("a",{parentName:"p",href:"https://triton-vm.org/spec/"},"https://triton-vm.org/spec/")),(0,i.kt)("p",null,"[14]"," How does the original Cairo VM work?. Retrieved from ",(0,i.kt)("a",{parentName:"p",href:"https://github.com/lambdaclass/cairo-vm/blob/main/docs/python_vm/README.md"},"https://github.com/lambdaclass/cairo-vm/blob/main/docs/python_vm/README.md")),(0,i.kt)("p",null,"[15]"," Aleo completes security audits of snarkOS & snarkVM. Retrieved from ",(0,i.kt)("a",{parentName:"p",href:"https://aleo.org/post/aleo-completes-security-audits-of-snarkos-and-snarkvm/"},"https://aleo.org/post/aleo-completes-security-audits-of-snarkos-and-snarkvm/")),(0,i.kt)("p",null,"[16]"," Lurk zkVM. Retrieved from ",(0,i.kt)("a",{parentName:"p",href:"https://github.com/lurk-lab"},"https://github.com/lurk-lab")),(0,i.kt)("p",null,"[17]"," Piecrust VM. Retrieved from ",(0,i.kt)("a",{parentName:"p",href:"https://docs.rs/piecrust/latest/piecrust/"},"https://docs.rs/piecrust/latest/piecrust/")),(0,i.kt)("p",null,"[18]"," Ceno: Non-uniform, Segment and Parallel Zero-knowledge Virtual Machine. Retrieved from ",(0,i.kt)("a",{parentName:"p",href:"https://eprint.iacr.org/2024/387"},"https://eprint.iacr.org/2024/387")),(0,i.kt)("p",null,"[19]"," ZkVM: a new design for fast, confidential smart contracts. Retrieved from ",(0,i.kt)("a",{parentName:"p",href:"https://stellar.org/blog/developers/zkvm-a-new-design-for-fast-confidential-smart-contracts"},"https://stellar.org/blog/developers/zkvm-a-new-design-for-fast-confidential-smart-contracts")),(0,i.kt)("p",null,"[20]"," Novanet. Retrieved from ",(0,i.kt)("a",{parentName:"p",href:"https://www.novanet.xyz/blog"},"https://www.novanet.xyz/blog")),(0,i.kt)("p",null,"[21]"," ZKLLVM. Retrieved from ",(0,i.kt)("a",{parentName:"p",href:"https://github.com/NilFoundation/zkLLVM"},"https://github.com/NilFoundation/zkLLVM")),(0,i.kt)("p",null,"[22]"," zkMove 0.2.0 - Achieving Full Bytecode Compatibility with Move. Retrieved from ",(0,i.kt)("a",{parentName:"p",href:"https://www.zkmove.net/2023-06-20-zkMove-0.2.0-Achieving-Full-Bytecode-Compatibility-with-Move/"},"https://www.zkmove.net/2023-06-20-zkMove-0.2.0-Achieving-Full-Bytecode-Compatibility-with-Move/")),(0,i.kt)("p",null,"[23]"," O1VM. Retrieved from ",(0,i.kt)("a",{parentName:"p",href:"https://github.com/o1-labs/proof-systems/tree/master/o1vm"},"https://github.com/o1-labs/proof-systems/tree/master/o1vm")))}u.isMDXComponent=!0},3905:(e,t,a)=>{a.d(t,{Zo:()=>c,kt:()=>d});var r=a(67294);function i(e,t,a){return t in e?Object.defineProperty(e,t,{value:a,enumerable:!0,configurable:!0,writable:!0}):e[t]=a,e}function n(e,t){var a=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),a.push.apply(a,r)}return a}function o(e){for(var t=1;t=0||(i[a]=e[a]);return i}(e,t);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,a)&&(i[a]=e[a])}return i}var s=r.createContext({}),p=function(e){var t=r.useContext(s),a=t;return e&&(a="function"==typeof e?e(t):o(o({},t),e)),a},c=function(e){var t=p(e.components);return r.createElement(s.Provider,{value:t},e.children)},u={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},m=r.forwardRef((function(e,t){var a=e.components,i=e.mdxType,n=e.originalType,s=e.parentName,c=l(e,["components","mdxType","originalType","parentName"]),m=p(a),d=i,k=m["".concat(s,".").concat(d)]||m[d]||u[d]||n;return a?r.createElement(k,o(o({ref:t},c),{},{components:a})):r.createElement(k,o({ref:t},c))}));function d(e,t){var a=arguments,i=t&&t.mdxType;if("string"==typeof e||i){var n=a.length,o=new Array(n);o[0]=m;var l={};for(var s in t)hasOwnProperty.call(t,s)&&(l[s]=t[s]);l.originalType=e,l.mdxType="string"==typeof e?e:i,o[1]=l;for(var p=2;p{e.exports=JSON.parse('{"permalink":"/rlog/page/2","page":2,"postsPerPage":10,"totalPages":4,"totalCount":34,"previousPage":"/rlog","nextPage":"/rlog/page/3","blogDescription":"Blog","blogTitle":"Research Blog"}')}}]); \ No newline at end of file +"use strict";(self.webpackChunkvac_dev=self.webpackChunkvac_dev||[]).push([[1969],{44041:e=>{e.exports=JSON.parse('{"permalink":"/rlog/page/2","page":2,"postsPerPage":10,"totalPages":4,"totalCount":35,"previousPage":"/rlog","nextPage":"/rlog/page/3","blogDescription":"Blog","blogTitle":"Research Blog"}')}}]); \ No newline at end of file diff --git a/assets/js/d758c4b4.2e4cb6f0.js b/assets/js/d758c4b4.2e4cb6f0.js new file mode 100644 index 00000000..b6fa1db7 --- /dev/null +++ b/assets/js/d758c4b4.2e4cb6f0.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkvac_dev=self.webpackChunkvac_dev||[]).push([[1033],{62849:(e,t,r)=>{r.r(t),r.d(t,{assets:()=>l,contentTitle:()=>i,default:()=>p,frontMatter:()=>a,metadata:()=>c,toc:()=>s});var n=r(87462),o=(r(67294),r(3905));const a={title:"zkVM Testing Report: Evaluating Zero-Knowledge Virtual Machines for Nescience",date:new Date("2024-09-26T12:00:00.000Z"),authors:"moudy",published:!0,slug:"zkVM-testing",categories:"research",discuss:"https://forum.vac.dev/t/zkvm-testing-report-evaluating-zero-knowledge-virtual-machines-for-nescience/",toc_min_heading_level:2,toc_max_heading_level:5},i=void 0,c={permalink:"/rlog/zkVM-testing",source:"@site/rlog/2024-09-26-Zkvm-testing.mdx",title:"zkVM Testing Report: Evaluating Zero-Knowledge Virtual Machines for Nescience",description:"Following our initial exploration of zkVMs in our previous blog post [1],",date:"2024-09-26T12:00:00.000Z",formattedDate:"September 26, 2024",tags:[],readingTime:11.625,hasTruncateMarker:!0,authors:[{name:"Moudy",github:"moudyellaz",key:"moudy"}],frontMatter:{title:"zkVM Testing Report: Evaluating Zero-Knowledge Virtual Machines for Nescience",date:"2024-09-26T12:00:00.000Z",authors:"moudy",published:!0,slug:"zkVM-testing",categories:"research",discuss:"https://forum.vac.dev/t/zkvm-testing-report-evaluating-zero-knowledge-virtual-machines-for-nescience/",toc_min_heading_level:2,toc_max_heading_level:5},nextItem:{title:"Exploring zkVMs: Which Projects Truly Qualify as Zero-Knowledge Virtual Machines?",permalink:"/rlog/zkVM-explorations"}},l={authorsImageUrls:[void 0]},s=[],u={toc:s};function p(e){let{components:t,...r}=e;return(0,o.kt)("wrapper",(0,n.Z)({},u,r,{components:t,mdxType:"MDXLayout"}))}p.isMDXComponent=!0},3905:(e,t,r)=>{r.d(t,{Zo:()=>u,kt:()=>f});var n=r(67294);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 l=n.createContext({}),s=function(e){var t=n.useContext(l),r=t;return e&&(r="function"==typeof e?e(t):i(i({},t),e)),r},u=function(e){var t=s(e.components);return n.createElement(l.Provider,{value:t},e.children)},p={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},g=n.forwardRef((function(e,t){var r=e.components,o=e.mdxType,a=e.originalType,l=e.parentName,u=c(e,["components","mdxType","originalType","parentName"]),g=s(r),f=o,m=g["".concat(l,".").concat(f)]||g[f]||p[f]||a;return r?n.createElement(m,i(i({ref:t},u),{},{components:r})):n.createElement(m,i({ref:t},u))}));function f(e,t){var r=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var a=r.length,i=new Array(a);i[0]=g;var c={};for(var l in t)hasOwnProperty.call(t,l)&&(c[l]=t[l]);c.originalType=e,c.mdxType="string"==typeof e?e:o,i[1]=c;for(var s=2;s{"use strict";Object.defineProperty(t,Symbol.toStringTag,{value:"Module"});const r=n(67294),o=n(73935),a=n(70917);function i(e){const t=Object.create(null,{[Symbol.toStringTag]:{value:"Module"}});if(e)for(const n in e)if("default"!==n){const r=Object.getOwnPropertyDescriptor(e,n);Object.defineProperty(t,n,r.get?r:{enumerable:!0,get:()=>e[n]})}return t.default=e,Object.freeze(t)}const l=i(r);var s=function(){function e(e){var t=this;this._insertTag=function(e){var n;n=0===t.tags.length?t.insertionPoint?t.insertionPoint.nextSibling:t.prepend?t.container.firstChild:t.before:t.tags[t.tags.length-1].nextSibling,t.container.insertBefore(e,n),t.tags.push(e)},this.isSpeedy=void 0===e.speedy||e.speedy,this.tags=[],this.ctr=0,this.nonce=e.nonce,this.key=e.key,this.container=e.container,this.prepend=e.prepend,this.insertionPoint=e.insertionPoint,this.before=null}var t=e.prototype;return t.hydrate=function(e){e.forEach(this._insertTag)},t.insert=function(e){this.ctr%(this.isSpeedy?65e3:1)==0&&this._insertTag(function(e){var t=document.createElement("style");return t.setAttribute("data-emotion",e.key),void 0!==e.nonce&&t.setAttribute("nonce",e.nonce),t.appendChild(document.createTextNode("")),t.setAttribute("data-s",""),t}(this));var t=this.tags[this.tags.length-1];if(this.isSpeedy){var n=function(e){if(e.sheet)return e.sheet;for(var t=0;t2||B(N)>3?"":" "}function V(e,t){for(;--t&&R()&&!(N<48||N>102||N>57&&N<65||N>70&&N<97););return F(e,M()+(t<6&&32==j()&&32==R()))}function q(e){for(;R();)switch(N){case e:return P;case 34:case 39:34!==e&&39!==e&&q(N);break;case 40:41===e&&q(e);break;case 92:R()}return P}function G(e,t){for(;R()&&e+N!==57&&(e+N!==84||47!==j()););return"/*"+F(t,P-1)+"*"+v(47===e?e:R())}function W(e){for(;!B(j());)R();return F(e,P)}function Z(e){return $(Q("",null,null,null,[""],e=z(e),0,[0],e))}function Q(e,t,n,r,o,a,i,l,s){for(var u=0,c=0,d=i,f=0,p=0,h=0,m=1,g=1,b=1,y=0,k="",S=o,D=a,I=r,L=k;g;)switch(h=y,y=R()){case 40:if(108!=h&&58==_(L,d-1)){-1!=x(L+=w(U(y),"&","&\f"),"&\f")&&(b=-1);break}case 34:case 39:case 91:L+=U(y);break;case 9:case 10:case 13:case 32:L+=H(h);break;case 92:L+=V(M()-1,7);continue;case 47:switch(j()){case 42:case 47:C(X(G(R(),M()),t,n),s);break;default:L+="/"}break;case 123*m:l[u++]=E(L)*b;case 125*m:case 59:case 0:switch(y){case 0:case 125:g=0;case 59+c:p>0&&E(L)-d&&C(p>32?K(L+";",r,n,d-1):K(w(L," ","")+";",r,n,d-2),s);break;case 59:L+=";";default:if(C(I=Y(L,t,n,u,c,o,l,k,S=[],D=[],d),a),123===y)if(0===c)Q(L,t,I,I,S,a,d,l,D);else switch(99===f&&110===_(L,3)?100:f){case 100:case 109:case 115:Q(e,I,I,r&&C(Y(e,I,I,0,0,o,l,k,o,S=[],d),D),o,D,d,l,r?S:D);break;default:Q(L,I,I,I,[""],D,0,l,D)}}u=c=p=0,m=b=1,k=L="",d=i;break;case 58:d=1+E(L),p=h;default:if(m<1)if(123==y)--m;else if(125==y&&0==m++&&125==(N=P>0?_(A,--P):0,O--,10===N&&(O=1,T--),N))continue;switch(L+=v(y),y*m){case 38:b=c>0?1:(L+="\f",-1);break;case 44:l[u++]=(E(L)-1)*b,b=1;break;case 64:45===j()&&(L+=U(R())),f=j(),c=d=E(k=L+=W(M())),y++;break;case 45:45===h&&2==E(L)&&(m=0)}}return a}function Y(e,t,n,r,o,a,i,l,s,u,c){for(var d=o-1,f=0===o?a:[""],h=S(f),m=0,v=0,b=0;m0?f[x]+" "+_:w(_,/&\f/g,f[x])))&&(s[b++]=E);return I(e,t,n,0===o?p:l,s,u,c)}function X(e,t,n){return I(e,t,n,f,v(N),k(e,2,-2),0)}function K(e,t,n,r){return I(e,t,n,h,k(e,0,r),k(e,r+1,-1),r)}function J(e,t){for(var n="",r=S(e),o=0;o6)switch(_(e,t+1)){case 109:if(45!==_(e,t+4))break;case 102:return w(e,/(.+:)(.+)-([^]+)/,"$1-webkit-$2-$3$1"+c+(108==_(e,t+3)?"$3":"$2-$3"))+e;case 115:return~x(e,"stretch")?le(w(e,"stretch","fill-available"),t)+e:e}break;case 4949:if(115!==_(e,t+1))break;case 6444:switch(_(e,E(e)-3-(~x(e,"!important")&&10))){case 107:return w(e,":",":"+d)+e;case 101:return w(e,/(.+:)([^;!]+)(;|!.+)?/,"$1"+d+(45===_(e,14)?"inline-":"")+"box$3$1"+d+"$2$3$1"+u+"$2box$3")+e}break;case 5936:switch(_(e,t+11)){case 114:return d+e+u+w(e,/[svh]\w+-[tblr]{2}/,"tb")+e;case 108:return d+e+u+w(e,/[svh]\w+-[tblr]{2}/,"tb-rl")+e;case 45:return d+e+u+w(e,/[svh]\w+-[tblr]{2}/,"lr")+e}return d+e+u+e+e}return e}var se,ue=[function(e,t,n,r){if(e.length>-1&&!e.return)switch(e.type){case h:e.return=le(e.value,e.length);break;case m:return J([L(e,{value:w(e.value,"@","@"+d)})],r);case p:if(e.length)return function(e,t){return e.map(t).join("")}(e.props,(function(t){switch(function(e,t){return(e=t.exec(e))?e[0]:e}(t,/(::plac\w+|:read-\w+)/)){case":read-only":case":read-write":return J([L(e,{props:[w(t,/:(read-\w+)/,":-moz-$1")]})],r);case"::placeholder":return J([L(e,{props:[w(t,/:(plac\w+)/,":-webkit-input-$1")]}),L(e,{props:[w(t,/:(plac\w+)/,":-moz-$1")]}),L(e,{props:[w(t,/:(plac\w+)/,u+"input-$1")]})],r)}return""}))}}],ce=function(e){var t=e.key;if("css"===t){var n=document.querySelectorAll("style[data-emotion]:not([data-s])");Array.prototype.forEach.call(n,(function(e){-1!==e.getAttribute("data-emotion").indexOf(" ")&&(document.head.appendChild(e),e.setAttribute("data-s",""))}))}var r=e.stylisPlugins||ue;var o,a,i={},l=[];o=e.container||document.head,Array.prototype.forEach.call(document.querySelectorAll('style[data-emotion^="'+t+' "]'),(function(e){for(var t=e.getAttribute("data-emotion").split(" "),n=1;n=4;++r,o-=4)t=1540483477*(65535&(t=255&e.charCodeAt(r)|(255&e.charCodeAt(++r))<<8|(255&e.charCodeAt(++r))<<16|(255&e.charCodeAt(++r))<<24))+(59797*(t>>>16)<<16),n=1540483477*(65535&(t^=t>>>24))+(59797*(t>>>16)<<16)^1540483477*(65535&n)+(59797*(n>>>16)<<16);switch(o){case 3:n^=(255&e.charCodeAt(r+2))<<16;case 2:n^=(255&e.charCodeAt(r+1))<<8;case 1:n=1540483477*(65535&(n^=255&e.charCodeAt(r)))+(59797*(n>>>16)<<16)}return(((n=1540483477*(65535&(n^=n>>>13))+(59797*(n>>>16)<<16))^n>>>15)>>>0).toString(36)}(o)+s;return{name:u,styles:o,next:Se}}(i,void 0,r.useContext(Ne));l+=t.key+"-"+s.name;var u={};for(var c in e)Oe.call(e,c)&&"css"!==c&&c!==Ae&&(u[c]=e[c]);return u.ref=n,u.className=l,r.createElement(r.Fragment,null,r.createElement(Le,{cache:t,serialized:s,isStringTag:"string"==typeof a}),r.createElement(a,u))}));var je,Me,Fe,Be={},ze={};function $e(){if(Fe)return ze;Fe=1,function(){if(Me)return je;Me=1;var e=Object.getOwnPropertySymbols,t=Object.prototype.hasOwnProperty,n=Object.prototype.propertyIsEnumerable;function r(e){if(null==e)throw new TypeError("Object.assign cannot be called with null or undefined");return Object(e)}je=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(o){return!1}}()?Object.assign:function(o,a){for(var i,l,s=r(o),u=1;u{const[t,n]=r.useState(e.value??e.defaultValue),o=void 0===e.value,a=void 0!==t&&("string"==typeof t?t.length>0:t.toString().length>0);return r.useEffect((()=>{!o&&n(e.value)}),[o,e.value]),{value:t,filled:a,onChange:t=>{if(o){const e=t.target.type,r=t.target["checkbox"===e||"radio"===e?"checked":"value"];n(r)}e.onChange&&e.onChange(t)},setValue:t=>{var n,r,o,a;const i=(null==(n=null==e?void 0:e.ref)?void 0:n.current)??("function"==typeof e.getInput&&e.getInput());if(!i)return;const l=new Event("input",{bubbles:!0});null==(a=null==(o=null==(r=Object.getOwnPropertyDescriptor(window.HTMLInputElement.prototype,"value"))?void 0:r.set)?void 0:o.call)||a.call(o,i,t),i.dispatchEvent(l)}}};var Xe=function(e,t){for(var n=-1,r=null==e?0:e.length,o=Array(r);++n-1},dt=function(e,t){var n=this.__data__,r=it(n,e);return r<0?(++this.size,n.push([e,t])):n[r][1]=t,this};function ft(e){var t=-1,n=null==e?0:e.length;for(this.clear();++t-1&&e%1==0&&e-1&&e%1==0&&e<=9007199254740991},kr=Lt,Er=_r,Sr=sr,Cr={};Cr["[object Float32Array]"]=Cr["[object Float64Array]"]=Cr["[object Int8Array]"]=Cr["[object Int16Array]"]=Cr["[object Int32Array]"]=Cr["[object Uint8Array]"]=Cr["[object Uint8ClampedArray]"]=Cr["[object Uint16Array]"]=Cr["[object Uint32Array]"]=!0,Cr["[object Arguments]"]=Cr["[object Array]"]=Cr["[object ArrayBuffer]"]=Cr["[object Boolean]"]=Cr["[object DataView]"]=Cr["[object Date]"]=Cr["[object Error]"]=Cr["[object Function]"]=Cr["[object Map]"]=Cr["[object Number]"]=Cr["[object Object]"]=Cr["[object RegExp]"]=Cr["[object Set]"]=Cr["[object String]"]=Cr["[object WeakMap]"]=!1;var Tr=function(e){return Sr(e)&&Er(e.length)&&!!Cr[kr(e)]};var Or=function(e){return function(t){return e(t)}},Dr={};!function(e,t){var n=yt,r=t&&!t.nodeType&&t,o=r&&e&&!e.nodeType&&e,a=o&&o.exports===r&&n.process,i=function(){try{var e=o&&o.require&&o.require("util").types;return e||a&&a.binding&&a.binding("util")}catch(t){}}();e.exports=i}({get exports(){return Dr},set exports(e){Dr=e}},Dr);var Pr=Tr,Nr=Or,Ar=Dr&&Dr.isTypedArray,Ir=Ar?Nr(Ar):Pr,Lr=lr,Rr=gr,jr=vr,Mr=br,Fr=xr,Br=Ir,zr=Object.prototype.hasOwnProperty;var $r=function(e,t){var n=jr(e),r=!n&&Rr(e),o=!n&&!r&&Mr(e),a=!n&&!r&&!o&&Br(e),i=n||r||o||a,l=i?Lr(e.length,String):[],s=l.length;for(var u in e)!t&&!zr.call(e,u)||i&&("length"==u||o&&("offset"==u||"parent"==u)||a&&("buffer"==u||"byteLength"==u||"byteOffset"==u)||Fr(u,s))||l.push(u);return l},Ur=Object.prototype;var Hr=function(e){var t=e&&e.constructor;return e===("function"==typeof t&&t.prototype||Ur)};var Vr=function(e,t){return function(n){return e(t(n))}},qr=Vr(Object.keys,Object),Gr=Hr,Wr=qr,Zr=Object.prototype.hasOwnProperty;var Qr=Bt,Yr=_r;var Xr=function(e){return null!=e&&Yr(e.length)&&!Qr(e)},Kr=$r,Jr=function(e){if(!Gr(e))return Wr(e);var t=[];for(var n in Object(e))Zr.call(e,n)&&"constructor"!=n&&t.push(n);return t},eo=Xr;var to=function(e){return eo(e)?Kr(e):Jr(e)},no=ir,ro=to;var oo=function(e,t){return e&&no(t,ro(t),e)};var ao=Rt,io=Hr,lo=function(e){var t=[];if(null!=e)for(var n in Object(e))t.push(n);return t},so=Object.prototype.hasOwnProperty;var uo=$r,co=function(e){if(!ao(e))return lo(e);var t=io(e),n=[];for(var r in e)("constructor"!=r||!t&&so.call(e,r))&&n.push(r);return n},fo=Xr;var po=function(e){return fo(e)?uo(e,!0):co(e)},ho=ir,mo=po;var go=function(e,t){return e&&ho(t,mo(t),e)},vo={};!function(e,t){var n=_t,r=t&&!t.nodeType&&t,o=r&&e&&!e.nodeType&&e,a=o&&o.exports===r?n.Buffer:void 0,i=a?a.allocUnsafe:void 0;e.exports=function(e,t){if(t)return e.slice();var n=e.length,r=i?i(n):new e.constructor(n);return e.copy(r),r}}({get exports(){return vo},set exports(e){vo=e}},vo);var bo=function(e,t){var n=-1,r=e.length;for(t||(t=Array(r));++no?0:o+t),(n=n>o?o:n)<0&&(n+=o),o=t>n?0:n-t>>>0,t>>>=0;for(var a=Array(o);++r0&&r(s)?n>1?e(s,n-1,r,o,a):wl(a,s):o||(a[a.length]=s)}return a},kl=_l;var El=function(e){return(null==e?0:e.length)?kl(e,1):[]};var Sl=function(e,t,n){switch(n.length){case 0:return e.call(t);case 1:return e.call(t,n[0]);case 2:return e.call(t,n[0],n[1]);case 3:return e.call(t,n[0],n[1],n[2])}return e.apply(t,n)},Cl=Math.max;var Tl=function(e,t,n){return t=Cl(void 0===t?e.length-1:t,0),function(){for(var r=arguments,o=-1,a=Cl(r.length-t,0),i=Array(a);++o0){if(++t>=800)return arguments[0]}else t=0;return e.apply(void 0,arguments)}}(Pl),Il=El,Ll=Tl,Rl=Al;var jl=function(e){return Rl(Ll(e,void 0,Il),e+"")},Ml=Xe,Fl=xi,Bl=il,zl=Zi,$l=ir,Ul=gl,Hl=Zo,Vl=jl((function(e,t){var n={};if(null==e)return n;var r=!1;t=Ml(t,(function(t){return t=zl(t,e),r||(r=t.length>1),t})),$l(e,Hl(e),n),r&&(n=Fl(n,7,Ul));for(var o=t.length;o--;)Bl(n,t[o]);return n})),ql=rr,Gl=Zi,Wl=xr,Zl=Rt,Ql=Yi;var Yl=Ji,Xl=function(e,t,n,r){if(!Zl(e))return e;for(var o=-1,a=(t=Gl(t,e)).length,i=a-1,l=e;null!=l&&++oObject.fromEntries((Array.isArray(e)?e:Object.keys(e)).map(((e,n)=>[e,t(e,n)]))),fs=["xs","sm","md","lg","xl"],ps=["display1","display2","display3","display4","h1","h2","h3","h4","h5","h6","subtitle1","subtitle2","subtitle3","subtitle4","body1","body2","body3","label1","label2"],hs={h1:["h1"],h2:["h2"],h3:["h3"],h4:["h4"],h5:["h5"],h6:["h6"],body1:["body"],label1:["label"]},ms=["fontSize","fontWeight","lineHeight"],gs={...ds(ps,(e=>`lsd-typography--${e}`)),root:"lsd-typography",primary:"lsd-typography--primary",secondary:"lsd-typography--secondary",serif:"lsd-typography--serif",sansSerif:"lsd-typography--sans-serif",monospace:"lsd-typography--monospace"},vs=["genericFontFamily"],bs=({genericFontFamily:e})=>({className:Qe("serif"===e&&gs.serif,"monospace"===e&&gs.monospace,"sans-serif"===e&&gs.sansSerif)}),ys=e=>cs(e,vs),ws=e=>Vl(e,vs),xs={root:"lsd-icon",small:"lsd-icon--small",filled:"lsd-icon--filled",stroked:"lsd-icon--stroked",primary:"lsd-icon--primary",secondary:"lsd-icon--secondary"},_s=(e,t)=>{const n=({color:n,size:r="small",className:o,...a})=>{const i=bs(a);return Ge(e,{className:Qe(i.className,o,xs.root,xs[r],n&&xs[n],(null==t?void 0:t.filled)&&xs.filled,(null==t?void 0:t.stroked)&&xs.stroked),...ws(a)})};return n.displayName=e.displayName,n.classes=xs,n},ks=_s((e=>Ge("svg",{width:"14",height:"14",viewBox:"0 0 14 14",fill:"none",xmlns:"http://www.w3.org/2000/svg",...e,children:Ge("path",{d:"M11.6666 7.58334H7.58325V11.6667H6.41659V7.58334H2.33325V6.41668H6.41659V2.33334H7.58325V6.41668H11.6666V7.58334Z",fill:"black"})})),{filled:!0}),Es=_s((e=>Ge("svg",{width:"14",height:"14",viewBox:"0 0 14 14",fill:"none",xmlns:"http://www.w3.org/2000/svg",...e,children:Ge("path",{d:"M10.5 5.66125L9.6775 4.83875L7 7.51041L4.3225 4.83874L3.5 5.66125L7 9.16125L10.5 5.66125Z",fill:"black"})})),{filled:!0}),Ss=_s((e=>Ge("svg",{width:"14",height:"14",viewBox:"0 0 14 14",fill:"none",xmlns:"http://www.w3.org/2000/svg",...e,children:Ge("path",{d:"M6.99992 2.33334L6.17742 3.15584L9.43242 6.41668H2.33325V7.58334H9.43242L6.17742 10.8442L6.99992 11.6667L11.6666 7.00001L6.99992 2.33334Z",fill:"black"})})),{filled:!0}),Cs=_s((e=>Ge("svg",{width:"14",height:"14",viewBox:"0 0 14 14",fill:"none",xmlns:"http://www.w3.org/2000/svg",...e,children:Ge("path",{d:"M3.5 8.33875L4.3225 9.16125L7 6.48959L9.6775 9.16125L10.5 8.33875L7 4.83875L3.5 8.33875Z",fill:"black"})})),{filled:!0}),Ts=_s((e=>Ge("svg",{width:"14",height:"14",viewBox:"0 0 14 14",fill:"none",xmlns:"http://www.w3.org/2000/svg",...e,children:Ge("path",{fillRule:"evenodd",clipRule:"evenodd",d:"M2.91667 1.75H11.0833C11.725 1.75 12.25 2.275 12.25 2.91667V11.0833C12.25 11.725 11.725 12.25 11.0833 12.25H2.91667C2.275 12.25 1.75 11.725 1.75 11.0833V2.91667C1.75 2.275 2.275 1.75 2.91667 1.75ZM9.68333 4.43333L10.5 5.25L5.83333 9.91667L3.5 7.58333L4.31667 6.76667L5.83333 8.28333L9.68333 4.43333Z",fill:"black"})})),{filled:!0}),Os=_s((e=>Ge("svg",{width:"14",height:"14",viewBox:"0 0 14 14",fill:"none",xmlns:"http://www.w3.org/2000/svg",...e,children:Ge("path",{d:"M11.0833 2.91667V11.0833H2.91667V2.91667H11.0833ZM11.0833 1.75H2.91667C2.275 1.75 1.75 2.275 1.75 2.91667V11.0833C1.75 11.725 2.275 12.25 2.91667 12.25H11.0833C11.725 12.25 12.25 11.725 12.25 11.0833V2.91667C12.25 2.275 11.725 1.75 11.0833 1.75Z",fill:"black"})})),{filled:!0}),Ds=_s((e=>Ge("svg",{width:"14",height:"14",viewBox:"0 0 14 14",fill:"none",xmlns:"http://www.w3.org/2000/svg",...e,children:Ge("path",{d:"M5.25009 9.43247L2.81759 6.99997L1.98926 7.82247L5.25009 11.0833L12.2501 4.0833L11.4276 3.2608L5.25009 9.43247Z",fill:"black"})})),{filled:!0}),Ps=_s((e=>Ge("svg",{width:"14",height:"14",viewBox:"0 0 14 14",fill:"none",xmlns:"http://www.w3.org/2000/svg",...e,children:Ge("path",{d:"M11.0834 3.73916L10.2609 2.91666L7.00008 6.17749L3.73925 2.91666L2.91675 3.73916L6.17758 6.99999L2.91675 10.2608L3.73925 11.0833L7.00008 7.82249L10.2609 11.0833L11.0834 10.2608L7.82258 6.99999L11.0834 3.73916Z",fill:"black"})})),{filled:!0}),Ns=_s((e=>Ge("svg",{width:"14",height:"14",viewBox:"0 0 14 14",fill:"none",xmlns:"http://www.w3.org/2000/svg",...e,children:Ge("path",{fillRule:"evenodd",clipRule:"evenodd",d:"M7.00008 1.16666C3.78008 1.16666 1.16675 3.77999 1.16675 6.99999C1.16675 10.22 3.78008 12.8333 7.00008 12.8333C10.2201 12.8333 12.8334 10.22 12.8334 6.99999C12.8334 3.77999 10.2201 1.16666 7.00008 1.16666ZM6.41675 9.91666V8.74999H7.58342V9.91666H6.41675ZM6.41675 4.08332V7.58332H7.58342V4.08332H6.41675Z",fill:"black"})})),{filled:!0}),As=_s((e=>Ge("svg",{width:"14",height:"14",viewBox:"0 0 14 14",fill:"none",xmlns:"http://www.w3.org/2000/svg",...e,children:Ge("path",{d:"M5.34925 3.50001L6.51591 4.66668H11.6667V10.5H2.33341V3.50001H5.34925ZM5.83341 2.33334H2.33341C1.69175 2.33334 1.17258 2.85834 1.17258 3.50001L1.16675 10.5C1.16675 11.1417 1.69175 11.6667 2.33341 11.6667H11.6667C12.3084 11.6667 12.8334 11.1417 12.8334 10.5V4.66668C12.8334 4.02501 12.3084 3.50001 11.6667 3.50001H7.00008L5.83341 2.33334Z",fill:"black"})})),{filled:!0}),Is=_s((e=>Ge("svg",{width:"14",height:"14",viewBox:"0 0 14 14",fill:"none",xmlns:"http://www.w3.org/2000/svg",...e,children:Ge("path",{d:"M11.0833 4.08333V6.41667H3.98417L6.0725 4.3225L5.25 3.5L1.75 7L5.25 10.5L6.0725 9.6775L3.98417 7.58333H12.25V4.08333H11.0833Z",fill:"black"})})),{filled:!0}),Ls=_s((e=>Ge("svg",{width:"14",height:"14",viewBox:"0 0 14 14",fill:"none",xmlns:"http://www.w3.org/2000/svg",...e,children:Ge("path",{fillRule:"evenodd",clipRule:"evenodd",d:"M1.75 4.66667V3.5H12.25V4.66667H1.75ZM1.75 7.58333H12.25V6.41667H1.75V7.58333ZM1.75 10.5H12.25V9.33333H1.75V10.5Z",fill:"black"})})),{filled:!0}),Rs=_s((e=>Ge("svg",{width:"14",height:"14",viewBox:"0 0 14 14",fill:"none",xmlns:"http://www.w3.org/2000/svg",...e,children:Ge("path",{fillRule:"evenodd",clipRule:"evenodd",d:"M3.49992 5.83334C2.85825 5.83334 2.33325 6.35834 2.33325 7.00001C2.33325 7.64168 2.85825 8.16668 3.49992 8.16668C4.14159 8.16668 4.66659 7.64168 4.66659 7.00001C4.66659 6.35834 4.14159 5.83334 3.49992 5.83334ZM10.4999 5.83334C9.85825 5.83334 9.33325 6.35834 9.33325 7.00001C9.33325 7.64168 9.85825 8.16668 10.4999 8.16668C11.1416 8.16668 11.6666 7.64168 11.6666 7.00001C11.6666 6.35834 11.1416 5.83334 10.4999 5.83334ZM5.83325 7.00001C5.83325 6.35834 6.35825 5.83334 6.99992 5.83334C7.64159 5.83334 8.16659 6.35834 8.16659 7.00001C8.16659 7.64168 7.64159 8.16668 6.99992 8.16668C6.35825 8.16668 5.83325 7.64168 5.83325 7.00001Z",fill:"black"})})),{filled:!0}),js=_s((e=>Ge("svg",{width:"14",height:"14",viewBox:"0 0 14 14",fill:"none",xmlns:"http://www.w3.org/2000/svg",...e,children:Ge("path",{d:"M9.16137 4.3225L8.33887 3.5L4.83887 7L8.33887 10.5L9.16137 9.6775L6.4897 7L9.16137 4.3225Z",fill:"black"})})),{filled:!0}),Ms=_s((e=>Ge("svg",{width:"14",height:"14",viewBox:"0 0 14 14",fill:"none",xmlns:"http://www.w3.org/2000/svg",...e,children:Ge("path",{d:"M5.66137 3.5L4.83887 4.3225L7.51053 7L4.83887 9.6775L5.66137 10.5L9.16137 7L5.66137 3.5Z",fill:"black"})})),{filled:!0}),Fs=_s((e=>Ge("svg",{width:"14",height:"14",viewBox:"0 0 14 14",fill:"none",xmlns:"http://www.w3.org/2000/svg",...e,children:Ge("path",{fillRule:"evenodd",clipRule:"evenodd",d:"M8.61 7.74083L11.9525 11.0833L11.0833 11.9525L7.74083 8.61C7.11667 9.05917 6.36417 9.33333 5.54167 9.33333C3.4475 9.33333 1.75 7.63583 1.75 5.54167C1.75 3.4475 3.4475 1.75 5.54167 1.75C7.63583 1.75 9.33333 3.4475 9.33333 5.54167C9.33333 6.36417 9.05917 7.11667 8.61 7.74083ZM5.54167 2.91667C4.08917 2.91667 2.91667 4.08917 2.91667 5.54167C2.91667 6.99417 4.08917 8.16667 5.54167 8.16667C6.99417 8.16667 8.16667 6.99417 8.16667 5.54167C8.16667 4.08917 6.99417 2.91667 5.54167 2.91667Z",fill:"black"})})),{filled:!0}),Bs=_s((e=>Ge("svg",{width:"14",height:"14",viewBox:"0 0 14 14",fill:"none",xmlns:"http://www.w3.org/2000/svg",...e,children:Ge("path",{fillRule:"evenodd",clipRule:"evenodd",d:"M9.79287 3.5H2.99998V2.5H11.5V11H10.5V4.20711L3.35353 11.3536L2.64642 10.6464L9.79287 3.5Z",fill:"black"})})),{filled:!0}),zs=_s((e=>Ge("svg",{width:"14",height:"14",viewBox:"0 0 14 14",fill:"none",xmlns:"http://www.w3.org/2000/svg",...e,children:Ge("path",{d:"M7.0013 1.16669C3.7813 1.16669 1.16797 3.78002 1.16797 7.00002C1.16797 10.22 3.7813 12.8334 7.0013 12.8334C10.2213 12.8334 12.8346 10.22 12.8346 7.00002C12.8346 3.78002 10.2213 1.16669 7.0013 1.16669ZM7.0013 11.6667C4.42297 11.6667 2.33464 9.57835 2.33464 7.00002C2.33464 4.42169 4.42297 2.33335 7.0013 2.33335C9.57964 2.33335 11.668 4.42169 11.668 7.00002C11.668 9.57835 9.57964 11.6667 7.0013 11.6667Z",fill:"black"})})),{filled:!0}),$s=_s((e=>We("svg",{width:"14",height:"14",viewBox:"0 0 14 14",fill:"none",xmlns:"http://www.w3.org/2000/svg",...e,children:[Ge("path",{d:"M7.0013 1.16669C3.7813 1.16669 1.16797 3.78002 1.16797 7.00002C1.16797 10.22 3.7813 12.8334 7.0013 12.8334C10.2213 12.8334 12.8346 10.22 12.8346 7.00002C12.8346 3.78002 10.2213 1.16669 7.0013 1.16669ZM7.0013 11.6667C4.42297 11.6667 2.33464 9.57835 2.33464 7.00002C2.33464 4.42169 4.42297 2.33335 7.0013 2.33335C9.57964 2.33335 11.668 4.42169 11.668 7.00002C11.668 9.57835 9.57964 11.6667 7.0013 11.6667Z",fill:"black"}),Ge("path",{d:"M7.0013 9.91669C8.61213 9.91669 9.91797 8.61085 9.91797 7.00002C9.91797 5.38919 8.61213 4.08335 7.0013 4.08335C5.39047 4.08335 4.08464 5.38919 4.08464 7.00002C4.08464 8.61085 5.39047 9.91669 7.0013 9.91669Z",fill:"black"})]})),{filled:!0}),Us=_s((e=>Ge("svg",{width:"14",height:"14",viewBox:"0 0 14 14",fill:"none",xmlns:"http://www.w3.org/2000/svg",...e,children:Ge("path",{"fill-rule":"evenodd","clip-rule":"evenodd",d:"M11.0833 2.33332H10.5V1.16666H9.33333V2.33332H4.66667V1.16666H3.5V2.33332H2.91667C2.26917 2.33332 1.75 2.85832 1.75 3.49999V11.6667C1.75 12.3083 2.26917 12.8333 2.91667 12.8333H11.0833C11.725 12.8333 12.25 12.3083 12.25 11.6667V3.49999C12.25 2.85832 11.725 2.33332 11.0833 2.33332ZM11.0833 11.6667H2.91667V5.24999H11.0833V11.6667ZM3.79167 7.58332C3.79167 6.77832 4.445 6.12499 5.25 6.12499C6.055 6.12499 6.70833 6.77832 6.70833 7.58332C6.70833 8.38832 6.055 9.04166 5.25 9.04166C4.445 9.04166 3.79167 8.38832 3.79167 7.58332Z",fill:"black"})})),{filled:!0}),Hs=_s((e=>Ge("svg",{width:"14",height:"14",viewBox:"0 0 14 14",fill:"none",xmlns:"http://www.w3.org/2000/svg",...e,children:Ge("path",{d:"M2.32812 7.58329V6.41663H11.6581V7.58329H2.32812Z",fill:"black"})})),{filled:!0}),Vs=({color:e,variant:t="body1",component:n,className:r,children:o,...a})=>{const i=bs(a);return Ge(n??{h1:"h1",h2:"h2",h3:"h3",h4:"h4",h5:"h5",h6:"h6",label1:"label",label2:"label"}[t]??"span",{className:Qe(i.className,gs.root,gs[t],e&&gs[e],r),...ws(a),children:o})};Vs.classes=gs;const qs={root:"lsd-dropdown-item",icon:"lsd-dropdown-item__icon",label:"lsd-dropdown-item__label",error:"lsd-dropdown-item--error",disabled:"lsd-dropdown-item--disabled",selected:"lsd-dropdown-item--selected",withIcon:"lsd-dropdown-item--with-icon",small:"lsd-dropdown-item--small",medium:"lsd-dropdown-item--medium",large:"lsd-dropdown-item--large"},Gs=({label:e,size:t="large",withIcon:n,selected:r,disabled:o,className:a,...i})=>{const l=bs(i),s={color:"primary",className:qs.icon};return We("div",{role:"option","aria-selected":r?"true":"false",...ws(i),className:Qe(l.className,a,qs.root,qs[t],n&&qs.withIcon,o&&qs.disabled),children:[n&&Ge(r?Ts:Os,{...s}),Ge(Vs,{variant:"large"===t?"label1":"label2",component:"span",className:qs.label,children:e})]})};function Ws(e){for(var t=[],n=1;n{const[n,o]=r.useState({});return r.useEffect((()=>{const{width:t,height:n,top:r,left:a}=e.current.getBoundingClientRect();o({left:a+window.scrollX,width:t,top:r+n+window.scrollY})}),[t]),n},ru=({size:e="large",open:t,label:n,handleRef:o,onClose:a,children:i,...l})=>{const s=bs(l),u=r.useRef(null);Ys(u,(e=>{t&&!e.composedPath().includes(o.current)&&a&&a()}));const c=nu(o,t);return Ge("ul",{...ws(l),ref:u,role:"listbox","aria-label":n,style:{...c,...l.style??{}},className:Qe(s.className,l.className,tu.root,tu[e],t&&tu.open),children:i})};ru.classes=tu;const ou=r.createContext({initialized:!1}),au=({id:e,children:t})=>{var n;return(null==(n=r.useContext(ou))?void 0:n.initialized)??!1?Ge(iu,{id:e,children:t}):Ge(qe,{})},iu=({id:e,children:t})=>{const n=(({parentId:e})=>{const t=r.useRef();return"undefined"==typeof window||t.current||(t.current=document.createElement("div")),r.useEffect((()=>{var n;if("undefined"==typeof window||!t.current)return;const r=document.querySelectorAll(`#${e}`);return null==(n=r[r.length-1])||n.appendChild(t.current),()=>{var n;try{null==(n=document.getElementById(e))||n.removeChild(t.current)}catch(r){}}}),[e,t.current]),t.current})({parentId:"lsd-presentation"});return n?o.createPortal(t,n,e):Ge(qe,{})},lu={root:"lsd-autocomplete",label:"lsd-autocomplete__label",inputContainer:"lsd-autocomplete__input-container",input:"lsd-autocomplete__input",icon:"lsd-autocomplete__icon",dropdownItemPlaceholder:"lsd-autocomplete__dropdown-item-placeholder",disabled:"lsd-autocomplete--disabled",error:"lsd-autocomplete--error",large:"lsd-autocomplete--large",medium:"lsd-autocomplete--medium",small:"lsd-autocomplete--small",withIcon:"lsd-autocomplete--with-icon",outlined:"lsd-autocomplete--outlined",underlined:"lsd-autocomplete--underlined"},su=({label:e,size:t="large",withIcon:n=!1,error:o=!1,disabled:a=!1,children:i,value:l,defaultValue:s,placeholder:u,onChange:c,options:d=[],inputProps:f={},variant:p="outlined",...h})=>{const m=bs(h),g=r.useRef(null),v=r.useRef(null),b=Ye({defaultValue:s,value:l,onChange:c,ref:g}),y=b.value,[w,x]=r.useState(!1),[_,k]=r.useState(),E=e=>{x(!1),k(e),b.setValue(e)},S=r.useMemo((()=>b.filled?d.filter((e=>new RegExp(`^${b.value}.+`,"i").test(e))).map((e=>[e,e.slice(0,y.length),e.slice(y.length)])):d),[b.value,d]);r.useEffect((()=>{!_&&b.filled&&!w&&x(!0)}),[b.value,_,w]);const C=!a&&w&&S.length>0&&b.filled,T=(null==f?void 0:f.id)??(h.id||"autocomplete")+"-input";return We("div",{ref:v,...ws(h),className:Qe(h.className,m.className,lu.root,lu[t],a&&lu.disabled,n&&lu.withIcon,"outlined"===p?lu.outlined:lu.underlined),children:[e&&Ge(Vs,{htmlFor:T,className:lu.label,variant:"label2",component:"label",children:e}),We("div",{className:lu.inputContainer,children:[Ge("input",{id:T,ref:g,value:b.value,placeholder:u,onChange:b.onChange,disabled:a,onFocus:()=>x(!0),...f,className:Qe(f.className,lu.input,o&&lu.error)}),n&&b.value?Ge("span",{className:lu.icon,onClick:()=>b.setValue(""),children:Ge(Ps,{color:"primary"})}):n&&!b.value?Ge("span",{className:lu.icon,children:Ge(Fs,{color:"primary"})}):null]}),Ge(au,{id:"autocomplete",children:Ge(ru,{handleRef:v,open:C,onClose:()=>x(!1),size:t,...ys(h),children:S.map(((e,n)=>Ge(Gs,{size:t,tabIndex:0,label:We(qe,{children:[e[1],Ge("span",{className:lu.dropdownItemPlaceholder,children:e[2]})]}),onClick:()=>E(e[0]),onKeyDown:t=>"Enter"===t.key&&E(e[0])},n)))})})]})};su.classes=lu;const uu={root:"lsd-badge",label:"lsd-badge__label",outlined:"lsd-badge--outlined",filled:"lsd-badge--filled",disabled:"lsd-badge--disabled",small:"lsd-badge--small",large:"lsd-badge--large"},cu=({variant:e="outlined",disabled:t,size:n="large",icon:r,iconDirection:o="left",children:a,...i})=>{const l=bs(i);return We("div",{"aria-label":a,...ws(i),className:Qe(i.className,l.className,uu.root,uu[e],t&&uu.disabled,uu[n]),children:["left"===o&&r,Ge(Vs,{component:"span",variant:"small"===n?"label2":"label1",className:uu.label,children:a}),"right"===o&&r]})};cu.classes=uu;const du={root:"lsd-breadcrumb-item",outlined:"lsd-breadcrumb-item--outlined",itemLink:"lsd-breadcrumb-item__link",large:"lsd-breadcrumb-item--large",small:"lsd-breadcrumb-item--small"},fu=({size:e="large",label:t,link:n,linkComponent:r=(e=>Ge("a",{...e,children:e.children})),outlined:o,selected:a,ellipsisRef:i,onClick:l,className:s,...u})=>{const c=bs(u);return Ge("li",{...ws(u),className:Qe(c.className,du.root,du[e],s),"aria-selected":a?"true":"false",onClick:l,ref:i,children:Ge(r,{href:n,className:Qe(du.itemLink,o&&du.outlined),children:Ge(Vs,{color:"primary",component:"span",variant:"large"===e?"label1":"label2",children:t})})})};fu.classes=du;const pu={root:"lsd-breadcrumb",list:"lsd-breadcrumb__list",listBox:"lsd-breadcrumb__dropdown-menu",open:"lsd-breadcrumb--open",disabled:"lsd-breadcrumb--disabled"},hu=({size:e="large",disabled:t=!1,ellipsis:n=!1,maxItems:o,value:a=[],onChange:i,options:l=[],...s})=>{const u=bs(s),c=r.useRef(null),[d,f]=r.useState(!1);o=Math.max(2,Math.min(o||2,l.length));const[p,...h]=l,[m,g]=n?[h.slice(0,h.length-o+1),h.slice(h.length-o+1)]:[[],h],v=t=>t.map(((t,n)=>Ge(fu,{outlined:n===g.length-1&&t!==p,label:t.value,link:t.link,linkComponent:null==t?void 0:t.linkComponent,size:e},n)));return r.useEffect((()=>{t&&d&&f(!1)}),[d,t]),We("div",{...ws(s),className:Qe(s.className,u.className,pu.root,t&&pu.disabled,d&&pu.open),children:[We("ul",{className:pu.list,children:[p&&v([p]),m.length>0&&Ge(fu,{ellipsisRef:c,label:"...",onClick:()=>{!t&&f((e=>!e))},size:e,...ys(s)}),v(g)]}),null!=(null==c?void 0:c.current)&&n&&o&&Ge(au,{id:"breadcrumb",children:Ge(ru,{handleRef:c,open:d,onClose:()=>f(!1),className:Qe(pu.listBox),size:e,genericFontFamily:s.genericFontFamily,...ys(s),children:m.map(((e,t)=>Ge(fu,{label:e.value,link:e.link,className:du.itemLink,linkComponent:null==e?void 0:e.linkComponent},t)))})})]})};hu.classes=pu;const mu=r.createContext(null),gu={root:"lsd-button",disabled:"lsd-button--disabled",large:"lsd-button--large",medium:"lsd-button--medium",small:"lsd-button--small",withIcon:"lsd-button--with-icon",outlined:"lsd-button--outlined",filled:"lsd-button--filled",text:"lsd-button__text",icon:"lsd-button__icon"},vu=({size:e,variant:t,disabled:n,icon:o,children:a,...i})=>{const l=r.useContext(mu),s=bs(i),u=bs(l||{}),c=s.className||u.className,d=e??(null==l?void 0:l.size)??"medium",f=t??(null==l?void 0:l.variant)??"outlined",p=n??(null==l?void 0:l.disabled)??!1;return Ge(qe,{children:We("button",{...ws(i),className:Qe(c,i.className,gu.root,gu[d],gu[f],p&&gu.disabled,o&&gu.withIcon),children:[Ge(Vs,{component:"span",className:gu.text,variant:"small"===d?"label2":"label1",children:a}),o&&Ge("span",{className:gu.icon,children:o})]})})};vu.classes=gu;const bu={root:"lsd-card",small:"lsd-card--small",medium:"lsd-card--medium",large:"lsd-card--large"},yu=r.createContext(null),wu=({size:e="large",children:t,...n})=>{const r=bs(n);return Ge(yu.Provider,{value:{size:e},children:Ge("div",{...ws(n),className:Qe(r.className,bu.root,bu[e]),children:t})})};wu.classes=bu;const xu={root:"lsd-card-body"},_u=({children:e,...t})=>{const n=bs(t);return Ge("div",{...ws(t),className:Qe(n.className,t.className,xu.root),children:e})};_u.classes=xu;const ku={root:"lsd-card-header",title:"lsd-card-header__title",small:"lsd-card-header--small",medium:"lsd-card-header--medium",large:"lsd-card-header--large"},Eu=({size:e="large",children:t,...n})=>{const o=bs(n),a=r.useContext(yu),i=(null==a?void 0:a.size)??e;return Ge("div",{...ws(n),className:Qe(o.className,n.className,ku.root,ku[i]),children:Ge(Vs,{className:ku.title,component:"div",variant:"large"===i?"label1":"label2",children:t})})};Eu.classes=ku;const Su=r.createContext(null),Cu=_s((e=>Ge("svg",{width:"14",height:"14",viewBox:"0 0 14 14",fill:"none",xmlns:"http://www.w3.org/2000/svg",...e,children:Ge("path",{fillRule:"evenodd",clipRule:"evenodd",d:"M2.91667 1.75C2.27233 1.75 1.75 2.27233 1.75 2.91667V11.0833C1.75 11.7277 2.27233 12.25 2.91667 12.25H11.0833C11.7277 12.25 12.25 11.7277 12.25 11.0833V2.91667C12.25 2.27233 11.7277 1.75 11.0833 1.75H2.91667ZM9.91667 6.41667H4.08333V7.58333H9.91667V6.41667Z",fill:"black"})})),{filled:!0}),Tu={root:"lsd-checkbox",input:"lsd-checkbox__input",icon:"lsd-checkbox__icon",label:"lsd-checkbox__label",focused:"lsd-checkbox--focused",disabled:"lsd-checkbox--disabled",indeterminate:"lsd-checkbox--indeterminate",large:"lsd-checkbox--large",medium:"lsd-checkbox--medium",small:"lsd-checkbox--small"},Ou=({name:e,size:t="large",onChange:n,checked:o,defaultChecked:a,disabled:i=!1,indeterminate:l=!1,inputProps:s={},children:u,...c})=>{const d=bs(c),f=r.useRef(null),[p,h]=r.useState(!1),m=Ye({value:o,defaultValue:a??!1,onChange:n,ref:f}),g=r.useContext(Su),v=(null==g?void 0:g.size)??t;return r.useEffect((()=>{if(!f.current)return;const e=()=>h(!0),t=()=>h(!1);return f.current.addEventListener("focus",e),f.current.addEventListener("blur",t),()=>{var n,r;null==(n=f.current)||n.removeEventListener("focus",e),null==(r=f.current)||r.removeEventListener("blur",t)}}),[f.current]),We(Vs,{color:"primary",variant:"large"===v?"label1":"label2",component:"label","aria-disabled":i?"true":"false",...ws(c),className:Qe(d.className,c.className,Tu.root,Tu[v],p&&Tu.focused,i&&Tu.disabled,l&&Tu.indeterminate),children:[Ge("input",{ref:f,name:e,type:"checkbox",disabled:i,checked:m.value,onChange:m.onChange,defaultChecked:a,className:Qe(s.className,Tu.input),...s}),l?Ge(Cu,{color:"primary",focusable:!1}):m.value?Ge(Ts,{color:"primary",focusable:!1}):Ge(Os,{color:"primary",focusable:!1}),Ge("span",{className:Tu.label,children:u})]})};Ou.classes=Tu;const Du={root:"lsd-checkbox-group",label:"lsd-checkbox-group__label"},Pu=({size:e="large",label:t,children:n,...r})=>{const o=bs(r);return Ge(Su.Provider,{value:{size:e},children:We("div",{...ws(r),className:Qe(o.className,r.className,Du.root),children:[Ge(Vs,{component:"span",variant:"small"===e?"label2":"label1",className:Du.label,...ys(r),children:t}),n]})})};Pu.classes=Du;const Nu={root:"lsd-collapse-header",trigger:"lsd-collapse-header__trigger",label:"lsd-collapse-header__label",icons:"lsd-collapse-header__icons",icon:"lsd-collapse-header__icon",menuIcon:"lsd-collapse-header__menu-icon",open:"lsd-collapse-header--open",disabled:"lsd-collapse-header--disabled",small:"lsd-collapse-header--small",medium:"lsd-collapse-header--medium",large:"lsd-collapse-header--large"},Au=({label:e,disabled:t=!1,open:n,setOpen:r,size:o="large",onTrigger:a,...i})=>{const l=bs(i);return Ge("div",{...ws(i),className:Qe(l.className,i.className,Nu.root,Nu[o],t&&Nu.disabled,n&&Nu.open),children:We("button",{className:Qe(Nu.trigger),onClick:a,children:[Ge(Vs,{color:"primary",component:"label",variant:"small"===o?"label2":"label1",className:Nu.label,children:e}),Ge("div",{className:Nu.icons,children:Ge(n?Cs:Es,{color:"primary",className:Nu.menuIcon})})]})})};Au.classes=Nu;const Iu={root:"lsd-collapse",content:"lsd-collapse__content",open:"lsd-collapse--open",disabled:"lsd-collapse--disabled"},Lu=({label:e,disabled:t=!1,size:n="large",open:o,children:a,...i})=>{const l=bs(i),s=r.useRef(null),[u,c]=r.useState(o??!1),d=e=>{if(void 0===o)return c(e);i.onChange&&i.onChange(e)};return r.useEffect((()=>{t&&u&&d(!1)}),[t,u,d]),r.useEffect((()=>{void 0!==o&&c(o)}),[o]),We("div",{...ws(i),ref:s,className:Qe(l.className,i.className,Iu.root,t&&Iu.disabled,u&&Iu.open),children:[Ge(Au,{label:e,open:u,setOpen:c,size:n,onTrigger:()=>!t&&d(!u),disabled:t,...ys(i)}),u&&Ge("div",{className:Iu.content,children:a})]})};Lu.classes=Iu;const Ru={root:"lsd-dropdown",label:"lsd-dropdown__label",buttonContainer:"lsd-dropdown__button-container",trigger:"lsd-dropdown__trigger",optionLabel:"lsd-dropdown__option-label",icons:"lsd-dropdown__icons",icon:"lsd-dropdown__icon",menuIcon:"lsd-dropdown__menu-icon",supportingText:"lsd-dropdown__supporting-text",open:"lsd-dropdown--open",error:"lsd-dropdown--error",disabled:"lsd-dropdown--disabled",small:"lsd-dropdown--small",medium:"lsd-dropdown--medium",large:"lsd-dropdown--large",outlined:"lsd-dropdown--outlined",underlined:"lsd-dropdown--underlined"},ju=({label:e,size:t="large",error:n=!1,disabled:o=!1,supportingText:a,triggerLabel:i,value:l=[],onChange:s,options:u=[],multi:c=!1,variant:d="outlined",isOpen:f,onToggle:p,menuProps:h={},...m})=>{const g=bs(m),v=r.useRef(null),b=void 0!==f,[y,w]=r.useState(!1);b&&f!==y&&w(f);const{select:x,isSelected:_,selected:k}=((e,t,{onDone:n,onChange:o,multi:a=!1}={})=>{const i=r.useMemo((()=>Object.fromEntries(e.map((e=>[e.value,e])))),[e]),[l,s]=r.useState(Array.isArray(t)?t:t?[t]:[]),u=r.useMemo((()=>ds(l,(()=>!0))),[l]),c=r.useMemo((()=>l.map((e=>i[e]))),[l,i]);r.useEffect((()=>{o&&s(Array.isArray(t)?t:t?[t]:[])}),[t,o]);const d=e=>"string"==typeof e?e:e.value;return{selected:c,isSelected:e=>!!u[d(e)],select:e=>{const t=d(e),r=a?u[t]?l.filter((e=>e!==t)):[...l,t]:[t];o?o(a?r:r[0]):s(r),!a&&n&&n(a?r:r[0])}}})(u,l,{multi:c,onChange:s,onDone:()=>{w(!1)}}),E=e=>{b?p&&p(e):w(e)};r.useEffect((()=>{o&&y&&!b&&w(!1)}),[y,o,b]);const S=(null==m?void 0:m.id)??(m.id||"dropdown")+"-input";return We("div",{ref:v,...ws(m),className:Qe(g.className,m.className,Ru.root,Ru[t],n&&Ru.error,o&&Ru.disabled,y&&Ru.open,"outlined"===d?Ru.outlined:Ru.underlined),children:[e&&Ge(Vs,{htmlFor:S,className:Ru.label,variant:"label2",component:"label",children:e}),Ge("div",{className:Ru.buttonContainer,children:We("button",{id:S,className:Qe(Ru.trigger),onClick:()=>{o||E(!y)},children:[Ge(Vs,{color:"primary",component:"label",variant:"large"===t?"label1":"label2",className:Ru.optionLabel,children:k.length>0?k.map((e=>e.name)).join(", "):i}),We("div",{className:Ru.icons,children:[n&&Ge(Ns,{color:"primary",className:Ru.icon}),Ge(y?Cs:Es,{color:"primary",className:Ru.menuIcon})]})]})}),a&&Ge(Vs,{variant:"large"===t?"label1":"label2",component:"p",className:Ru.supportingText,children:a}),Ge(au,{id:"dropdown",children:Ge(ru,{handleRef:v,open:y,onClose:()=>E(!1),size:t,genericFontFamily:m.genericFontFamily,...h,children:u.map((e=>Ge(Gs,{size:t,tabIndex:0,onClick:x.bind(null,e),withIcon:c,label:e.name,selected:_(e),onKeyDown:t=>"Enter"===t.key&&x(e)},e.value)))})})]})};ju.classes=Ru;const Mu=r.createContext(null),Fu={root:"lsd-icon-button",outlined:"lsd-icon-button--outlined",filled:"lsd-icon-button--filled",disabled:"lsd-icon-button--disabled",small:"lsd-icon-button--small",medium:"lsd-icon-button--medium",large:"lsd-icon-button--large"},Bu=({size:e,disabled:t,variant:n,children:o,...a})=>{const i=bs(a),l=r.useContext(Mu),s=e??(null==l?void 0:l.size)??"large",u=n??(null==l?void 0:l.variant)??"outlined",c=t??(null==l?void 0:l.disabled)??!1;return Ge("button",{...ws(a),className:Qe(i.className,a.className,Fu.root,Fu[s],Fu[u],c&&Fu.disabled),children:o})};Bu.classes=Fu;const zu={root:"lsd-icon-button-group",outlined:"lsd-icon-button-group--outlined",filled:"lsd-icon-button-group--filled",disabled:"lsd-icon-button-group--disabled",small:"lsd-icon-button-group--small",medium:"lsd-icon-button-group--medium",large:"lsd-icon-button-group--large"},$u=({size:e="large",disabled:t,variant:n="outlined",children:r,...o})=>{const a=bs(o);return Ge("div",{...ws(o),className:Qe(a.className,o.className,zu.root,zu[e],zu[n],t&&zu.disabled),children:Ge(Mu.Provider,{value:{size:e,variant:n,disabled:t},children:r})})};$u.classes=zu;const Uu={root:"lsd-quote",indentedInline:"lsd-quote--indented-inline",parentheses:"lsd-quote--parentheses",text:"lsd-quote__text"},Hu=({mode:e="indented-line",children:t,...n})=>{const r=bs(n);return Ge(qe,{children:Ge("div",{...ws(n),className:Qe(r.className,n.className,Uu.root,e&&"parentheses"===e?Uu.parentheses:Uu.indentedInline),children:Ge(Vs,{color:"primary",component:"label",variant:"label1",children:t})})})};Hu.classes=Uu;const Vu=r.createContext(null),qu={root:"lsd-radio-button",input:"lsd-radio-button__input",label:"lsd-radio-button__label",disabled:"lsd-radio-button--disabled",large:"lsd-radio-button--large",medium:"lsd-radio-button--medium",small:"lsd-radio-button--small"},Gu=({size:e="large",onChange:t,checked:n,defaultChecked:o,disabled:a=!1,value:i,name:l,inputProps:s={},children:u,...c})=>{const d=bs(c),f=r.useRef(null),p=r.useContext(Vu),h=(null==p?void 0:p.size)??e,m=(null==p?void 0:p.name)??l??"",g=p?p.value===i:n,v=Ye({value:g,defaultValue:o??!1,onChange:t,ref:f});return We(Vs,{color:"primary",variant:"large"===h?"label1":"label2",component:"label","aria-disabled":a?"true":"false",...ws(c),className:Qe(d.className,c.className,qu.root,qu[h],a&&qu.disabled),children:[Ge("input",{ref:f,name:m,value:i,type:"radio",checked:v.value,onChange:e=>{p?p.setActiveRadioButton(e.target.value):v.onChange(e)},defaultChecked:o,className:Qe(s.className,qu.input),...s}),v.value?Ge($s,{color:"primary",focusable:!1}):Ge(zs,{color:"primary",focusable:!1}),Ge("span",{className:qu.label,children:u})]})};Gu.classes=qu;const Wu={root:"lsd-radio-button-group",label:"lsd-radio-button-group__label"},Zu=({size:e="large",label:t,value:n,name:o,onChange:a,children:i,...l})=>{const s=bs(l),u=r.useRef(null),[c,d]=r.useState(n);return r.useEffect((()=>d(n)),[n]),Ge(Vu.Provider,{value:{value:c,setActiveRadioButton:e=>{a?a(e):d(e)},name:o,size:e},children:We("div",{ref:u,...ws(l),className:Qe(s.className,l.className,Wu.root),children:[Ge(Vs,{component:"span",variant:"small"===e?"label2":"label1",className:Wu.label,children:t&&t}),i]})})};Zu.classes=Wu;const Qu=r.createContext(null),Yu={root:"lsd-tab-item",text:"lsd-tab-item--text",icon:"lsd-tab-item--icon",disabled:"lsd-tab-item--disabled",selected:"lsd-tab-item--selected",small:"lsd-tab-item--small",medium:"lsd-tab-item--medium",large:"lsd-tab-item--large",withIcon:"lsd-tab-item--with-icon"},Xu=({name:e,size:t="large",selected:n=!1,inactive:o=!1,icon:a,children:i,...l})=>{const s=bs(l),u=r.useContext(Qu),c=(null==u?void 0:u.size)??t,d=u?u.activeTab===e:n;return We("button",{...ws(l),className:Qe(s.className,l.className,Yu.root,Yu[c],d&&Yu.selected,l.disabled&&Yu.disabled,!!a&&Yu.withIcon),onClick:t=>{l.onClick&&l.onClick(t),o||(null==u?void 0:u.setActiveTab)&&u.setActiveTab(e)},children:[Ge(Vs,{component:"span",className:Yu.text,variant:"small"===c?"label2":"label1",children:i}),a&&Ge("span",{className:Yu.icon,children:a})]})};Xu.classes=Yu;const Ku={root:"lsd-table-body",toolbar:"lsd-table-body__toolbar",row:"lsd-table-body__row"},Ju=({options:e=[],size:t="large",buttonLabel:n="Button",toolbar:r,children:o,...a})=>{const i=bs(a);return We("div",{...ws(a),className:Qe(i.className,a.className,Ku.root),children:[r&&Ge("div",{className:Qe(Ku.toolbar),children:r}),Ge("table",{children:o})]})};Ju.classes=Ku;const ec={root:"lsd-table-header"},tc=({size:e="large",children:t,...n})=>{const r=bs(n);return Ge("div",{...ws(n),className:Qe(r.className,n.className,ec.root),children:t})};tc.classes=ec;const nc={root:"lsd-table",small:"lsd-table--small",medium:"lsd-table--medium",large:"lsd-table--large"},rc=r.createContext(null),oc=()=>r.useContext(rc),ac=({size:e="large",type:t="default",headerOptions:n,header:r,toolbar:o,children:a,...i})=>{const l=bs(i);return Ge(rc.Provider,{value:{size:e,type:t,headerOptions:n},children:We("div",{...ws(i),className:Qe(l.className,nc.root,nc[e]),children:[Ge(tc,{children:r}),Ge(Ju,{toolbar:o,options:n,children:a})]})})};ac.classes=nc;const ic={root:"lsd-table-item",large:"lsd-table-item--large",medium:"lsd-table-item--medium",small:"lsd-table-item--small"},lc=({size:e="large",children:t,...n})=>{const r=bs(n),o=oc(),a=(null==o?void 0:o.size)??e;return Ge("td",{...ws(n),className:Qe(r.className,n.className,ic.root,ic[a]),children:t})};lc.classes=ic;const sc={root:"lsd-table-row"},uc=({size:e="large",type:t="default",children:n,...r})=>{const o=bs(r),a=oc(),i=(null==a?void 0:a.type)??t;return We("tr",{...ws(r),className:Qe(o.className,r.className,sc.root),children:["checkbox"===i&&Ge("td",{className:ic.root,children:Ge(Ou,{})}),"radio"===i&&Ge("td",{className:ic.root,children:Ge(Gu,{value:"1"})}),n]})};uc.classes=sc;const cc=r.createContext(null),dc=(e=0)=>{let t=e-1;return()=>(t++,t)},fc="undefined"==typeof DOMRectReadOnly?null:new DOMRectReadOnly(0,0,0,0),pc=dc(),hc=(e,t)=>{const n=(()=>{const{observe:e,unobserve:t,ready:n}=r.useContext(cc)??{};return r.useMemo((()=>({observe:e,unobserve:t,ready:n})),[e,t,n])})(),o=r.useMemo((()=>t??pc().toString()),[t]),a=((e,t)=>{var n;const o=r.useContext(cc);return(null==(n=null==o?void 0:o.rect)?void 0:n[e])??t})(o)??fc;return r.useEffect((()=>{if(n&&n.ready)return e.current&&n.observe(o,e),()=>{n.unobserve(o)}}),[n.ready,e.current]),a},mc=(e,t,n,r)=>-1===e?t:n-(r+t),gc=(e,t)=>{var n;const o=hc(e),[a,i]=r.useState((null==(n=null==e?void 0:e.current)?void 0:n.scrollLeft)??0),[l,s]=r.useState(0),[u,c]=r.useState(0),d=r.useRef(null);((e,t,n,o,a)=>{const i=r.useMemo((()=>"string"==typeof e?e:e()),[]),l=r.useMemo((()=>"function"==typeof t?t():t),[t]);r.useEffect((()=>{if((null==l?void 0:l.addEventListener)&&(null==l?void 0:l.removeEventListener))return l.addEventListener(i,n,o),()=>{l.removeEventListener(i,n,o)}}),[i,l])})("scroll",e.current,(e=>{i(e.target.scrollLeft)}),{passive:!0});r.useEffect((()=>{if(d.current&&clearTimeout(d.current),!e.current)return;const{scrollLeft:t,scrollWidth:n,clientWidth:r}=e.current;c(mc(1,t,n,r)),s(mc(-1,t,n,r))}),[o,a,null==t?void 0:t.deps]);const f=(n,r)=>{const{clientWidth:o,scrollLeft:a}=e.current,i=Array.from(e.current.childNodes).find((e=>e.getBoundingClientRect().x>=0)),l=Math.max(r??o/3,i?i.clientWidth:0);e.current.scrollTo({behavior:(null==t?void 0:t.scrollBehavior)??"smooth",left:a+l*n})};return r.useMemo((()=>({right:u,left:l,toRight:f.bind(null,1),toLeft:f.bind(null,-1)})),[u,l])},vc={root:"lsd-tabs",fullWidth:"lsd-tabs--full-width",withScrollControls:"lsd-tabs--with-scroll-controls",leftScrollControl:"lsd-tabs__left-scroll-control",rightScrollControl:"lsd-tabs__right-scroll-control"},bc=({size:e="large",fullWidth:t=!1,scrollControls:n=!1,onChange:o,activeTab:a,children:i,...l})=>{const s=bs(l),u=r.useRef(null),[c,d]=r.useState(a);r.useEffect((()=>d(a)),[a]);const f=gc(u,{scrollBehavior:"smooth",deps:[i]}),p=0!==f.left||0!==f.right;return Ge(Qu.Provider,{value:{activeTab:c,setActiveTab:e=>{o?o(e):d(e)},size:e},children:We("div",{ref:u,...ws(l),className:Qe(s.className,l.className,vc.root,t&&vc.fullWidth,n&&p&&vc.withScrollControls),children:[n&&p&&Ge(Xu,{inactive:!0,name:"Prev",disabled:0===f.left,onClick:()=>f.toLeft(),className:vc.leftScrollControl,children:Ge(js,{color:"primary"})}),i,n&&p&&Ge(Xu,{inactive:!0,name:"Next",disabled:0===f.right,onClick:()=>f.toRight(),className:vc.rightScrollControl,children:Ge(Ms,{color:"primary"})})]})})};bc.classes=vc;const yc={root:"lsd-tag",label:"lsd-tag__label",outlined:"lsd-tag--outlined",filled:"lsd-tag--filled",disabled:"lsd-tag--disabled",small:"lsd-badge--small",large:"lsd-badge--large"},wc=({variant:e="outlined",disabled:t,icon:n,iconDirection:r="left",children:o,size:a="large",...i})=>{const l=bs(i);return We("div",{"aria-label":o,...ws(i),className:Qe(l.className,i.className,yc.root,yc[e],t&&yc.disabled,yc[a]),children:["left"===r&&n,Ge(Vs,{variant:"small"===a?"label2":"label1",className:yc.label,component:"span",children:o}),"right"===r&&n]})};wc.classes=yc;var xc=Hi,_c=0;var kc=function(e){var t=++_c;return xc(e)+t};const Ec={root:"lsd-text-field",inputContainer:"lsd-text-field__input-container",label:"lsd-text-field__label",input:"lsd-text-field__input",icon:"lsd-text-field__icon",clearButton:"lsd-text-field__clear-button",supportingText:"lsd-text-field__supporting-text",disabled:"lsd-text-field--disabled",error:"lsd-text-field--error",large:"lsd-text-field--large",medium:"lsd-text-field--medium",small:"lsd-text-field--small",outlined:"lsd-text-field--outlined",underlined:"lsd-text-field--underlined"},Sc=({size:e="large",label:t,icon:n,error:o=!1,errorIcon:a=!1,clearButton:i,supportingText:l,children:s,value:u,placeholder:c,defaultValue:d,disabled:f,onChange:p,inputProps:h={},labelProps:m={},variant:g="underlined",...v})=>{const b=bs(v),y=r.useRef(null),w=Ye({defaultValue:d,value:u,onChange:p,ref:y}),x=h.id||kc("TextField-");return We("div",{"aria-disabled":f?"true":"false",...ws(v),className:Qe(b.className,v.className,Ec.root,Ec[e],f&&Ec.disabled,o&&Ec.error,"outlined"===g?Ec.outlined:Ec.underlined),children:[t&&Ge(Vs,{variant:"label2",component:"label",htmlFor:x,...m,className:Qe(Ec.label,m.className),children:t}),We("div",{className:Ec.inputContainer,children:[Ge("input",{id:x,placeholder:c,ref:y,value:w.value,onChange:w.onChange,...h,className:Qe(h.className,Ec.input)}),o&&a?Ge(Ns,{color:"primary",className:Ec.icon}):i&&w.filled?Ge(Bu,{disabled:f,onClick:()=>!f&&w.setValue(""),"aria-label":"clear",className:Ec.clearButton,children:Ge(Ps,{color:"primary",className:Ec.icon})}):n]}),l&&Ge("div",{className:Qe(Ec.supportingText),children:Ge(Vs,{variant:"large"===e?"label1":"label2",component:"p",children:l})})]})};Sc.classes=Ec;const Cc={vars:{lsd:(...e)=>`--${["lsd",...e].join("-")}`,typography:(e,t)=>Cc.vars.lsd(e,t),color:(e,t)=>Cc.vars.lsd(e,t),wrap:e=>`var(${e})`},define:(e,t)=>`${e}: ${t};`},Tc=(()=>{const e={};return t=>{const n=t.name;return e[n]&&"undefined"!=typeof window||(e[n]=(e=>{const t=[],n=[],r=fs.map((()=>[])),o=fs.map((()=>[]));ps.forEach((n=>{ms.forEach((r=>{var o;const a=(null==(o=e.typography[n][r])?void 0:o.toString())??"unset";t.push(Cc.define(Cc.vars.typography(n,r),a))}))})),t.push(Cc.define(Cc.vars.lsd("typography","generic-font-family"),e.typographyGlobal.genericFontFamily)),fs.forEach(((t,n)=>{ps.forEach((r=>{ms.forEach((a=>{var i,l,s,u;const c=e.breakpoints[t].typography[r][a],d=n>0?null==(u=null==(s=null==(l=null==(i=e.breakpoints)?void 0:i[fs[n-1]])?void 0:l.typography)?void 0:s[r])?void 0:u[a]:e.typography[r][a];c&&c!==d&&o[n].push(Cc.define(Cc.vars.typography(r,a),c.toString()))}))}))}));{const{primary:n,secondary:r,...o}=e.palette,a=o;t.push(Cc.define(Cc.vars.color("theme","primary"),n),Cc.define(Cc.vars.color("theme","secondary"),r),...Object.keys(a).flatMap((e=>Object.keys(a[e]).map((t=>Cc.define(Cc.vars.color(e,t),a[e][t]))))))}e.spacing.map((e=>{const n=Cc.vars.lsd("spacing",e.toString());t.push(Cc.define(n,`${e}px`))})),fs.map(((t,a)=>{n.push(`@media (min-width: ${e.breakpoints[t].width}px) {\n :root {\n ${o[a].join("\n")}\n }\n\n ${r[a]}\n }`)}));const i=`\n ${t.join("\n")} \n\n ${n.join("\n")}\n `;return{cssVars:i,globalStyles:a.css(":root{",i,";}","")}})(t)),e[n]}})(),Oc={name:"LSD",breakpoints:{xs:{width:0,typography:{display1:{},display2:{},display3:{},display4:{},h1:{},h2:{},h3:{},h4:{},h5:{},h6:{},body1:{},body2:{},body3:{},label1:{},label2:{},subtitle1:{},subtitle2:{},subtitle3:{},subtitle4:{}}},sm:{width:400,typography:{display1:{},display2:{},display3:{},display4:{},h1:{},h2:{},h3:{},h4:{},h5:{},h6:{},body1:{},body2:{},body3:{},label1:{},subtitle4:{},subtitle3:{},label2:{},subtitle1:{},subtitle2:{}}},md:{width:768,typography:{display1:{},display2:{},display3:{},display4:{},h1:{},h2:{},h3:{},h4:{},h5:{},h6:{},body1:{},body2:{},body3:{},label1:{},subtitle4:{},subtitle3:{},label2:{},subtitle1:{},subtitle2:{}}},lg:{width:1024,typography:{display1:{},display2:{},display3:{},display4:{},h1:{},h2:{},h3:{},h4:{},h5:{},h6:{},body1:{},body2:{},body3:{},label1:{},subtitle4:{},subtitle3:{},label2:{},subtitle1:{},subtitle2:{}}},xl:{width:1205,typography:{display1:{},display2:{},display3:{},display4:{},h1:{},h2:{},h3:{},h4:{},h5:{},h6:{},body1:{},body2:{},body3:{},label1:{},subtitle4:{},subtitle3:{},label2:{},subtitle1:{},subtitle2:{}}}},typography:{display1:{fontSize:"5.5rem",fontWeight:"normal",lineHeight:"6rem"},display2:{fontSize:"4rem",fontWeight:"normal",lineHeight:"4.5rem"},display3:{fontSize:"3.5rem",fontWeight:"normal",lineHeight:"4rem"},display4:{fontSize:"3rem",fontWeight:"normal",lineHeight:"3.5rem"},h1:{fontSize:"2.5rem",fontWeight:"normal",lineHeight:"3rem"},h2:{fontSize:"2rem",fontWeight:"normal",lineHeight:"2.5rem"},h3:{fontSize:"1.75rem",fontWeight:"normal",lineHeight:"2.25rem"},h4:{fontSize:"1.5rem",fontWeight:"normal",lineHeight:"2rem"},h5:{fontSize:"1.25rem",fontWeight:"normal",lineHeight:"1.75rem"},h6:{fontSize:"1rem",fontWeight:"normal",lineHeight:"1.5rem"},subtitle1:{fontSize:"1.125rem",fontWeight:"normal",lineHeight:"1.5rem"},subtitle2:{fontSize:"1rem",fontWeight:"normal",lineHeight:"1.5rem"},subtitle3:{fontSize:"0.875rem",fontWeight:"normal",lineHeight:"1.25rem"},subtitle4:{fontSize:"0.75rem",fontWeight:"normal",lineHeight:"1rem"},body1:{fontSize:"1rem",fontWeight:"normal",lineHeight:"1.5rem"},body2:{fontSize:"0.875rem",fontWeight:"normal",lineHeight:"1.25rem"},body3:{fontSize:"0.75rem",fontWeight:"normal",lineHeight:"1rem"},label1:{fontSize:"0.875rem",fontWeight:"normal",lineHeight:"1.25rem"},label2:{fontSize:"0.75rem",fontWeight:"normal",lineHeight:"1rem"}},typographyGlobal:{genericFontFamily:"sans-serif"},palette:{primary:"0, 0, 0",secondary:"255, 255, 255",surface:{primary:"255, 255, 255",secondary:"0, 0, 0"},text:{primary:"0, 0, 0",secondary:"255, 255, 255",tertiary:"0, 0, 0, 0.34"},border:{primary:"0, 0, 0",secondary:"255, 255, 255"},icon:{primary:"0, 0, 0",secondary:"255, 255, 255"}},spacing:[4,8,16,24,32,40,64,80,96,120],globalStyles:a.css("",""),cssVars:""},{cssVars:Dc,globalStyles:Pc}=Tc(Oc);Oc.cssVars=Dc,Oc.globalStyles=Pc;const Nc=dc(),Ac=(e,t)=>ds(ps,(n=>({...t.typography[n],...e.typography[n]??{}}))),Ic=(e,t)=>({...t.typographyGlobal,...e.typographyGlobal}),Lc=(e,t)=>{const n=new Map;return Object.fromEntries(fs.reduce(((r,o,a)=>[...r,{...t.breakpoints[o],...e.breakpoints[o],...ds(["typography"],(o=>((e,t,n,r,o,a)=>"typography"===e?ds(o[e],(i=>{var l,s,u,c,d,f,p,h,m,g,v;const b=`${e}.${i}`,y=!0===a.get(b);return Object.keys((null==(u=null==(s=null==(l=r.breakpoints)?void 0:l[fs[n]])?void 0:s[e])?void 0:u[i])??{}).length>0&&a.set(b,!0),{...o[e][i],...r[e][i],...y?(null==(d=null==(c=null==t?void 0:t[n-1])?void 0:c[e])?void 0:d[i])??{}:null==(h=null==(p=null==(f=o.breakpoints)?void 0:f[fs[n]])?void 0:p[e])?void 0:h[i],...(null==(v=null==(g=null==(m=r.breakpoints)?void 0:m[fs[n]])?void 0:g[e])?void 0:v[i])??{}}})):{})(o,r,a,e,t,n)))}]),[]).map(((e,t)=>[fs[t],e])))},Rc=(e,t)=>{var n,r,o,a,i,l,s,u,c;const d=e.palette.primary??t.palette.primary,f=e.palette.secondary??t.palette.secondary;return{primary:d,secondary:f,surface:{primary:(null==(n=e.palette.surface)?void 0:n.primary)??f,secondary:(null==(r=e.palette.surface)?void 0:r.secondary)??d},border:{primary:(null==(o=e.palette.border)?void 0:o.primary)??d,secondary:(null==(a=e.palette.border)?void 0:a.secondary)??f},icon:{primary:(null==(i=e.palette.icon)?void 0:i.primary)??d,secondary:(null==(l=e.palette.icon)?void 0:l.secondary)??f},text:{primary:(null==(s=e.palette.text)?void 0:s.primary)??d,secondary:(null==(u=e.palette.text)?void 0:u.secondary)??f,tertiary:(null==(c=e.palette.text)?void 0:c.tertiary)??`${d}, 0.34`}}},jc=(e,t=Oc)=>{const n={name:e.name??(r=t.name,`${r}-${Nc()}`),typography:Ac(e,t),typographyGlobal:Ic(e,t),breakpoints:Lc(e,t),palette:Rc(e,t),globalStyles:a.css("",""),cssVars:"",spacing:e.spacing.length?e.spacing:t.spacing};var r;const{cssVars:o,globalStyles:i}=Tc(n);return n.cssVars=o,n.globalStyles=i,n},Mc=jc({name:"Light",breakpoints:{},typography:{},typographyGlobal:{},palette:{},spacing:[]},Oc),Fc={light:Mc,dark:jc({name:"Dark",breakpoints:{},typography:{},typographyGlobal:{},palette:{primary:"255, 255, 255",secondary:"0, 0, 0"},spacing:[]},Mc)},Bc=a.css(".",lu.root,"{box-sizing:border-box;}.",lu.label,"{display:block;}.",lu.inputContainer,"{display:flex;justify-content:space-between;}.",lu.disabled,"{opacity:0.34;}.",lu.input,"{border:none;outline:none;font-size:14px;color:rgb(var(--lsd-text-primary));background:none;width:100%;}.",lu.input,":hover{outline:none;}.",lu.input,"::placeholder{color:rgb(var(--lsd-text-primary));opacity:0.3;}.",lu.icon,"{cursor:pointer;display:flex;align-items:center;}.",lu.error,"{text-decoration:line-through;}.",lu.large,"{width:208px;.",lu.label,"{margin:0 0 6px 18px;}.",lu.inputContainer,"{height:40px;}.",lu.input,"{padding:9px 17px;}.",lu.icon,"{padding:12px 13px;}}.",lu.medium,"{width:188px;.",lu.label,"{margin:0 0 6px 14px;}.",lu.inputContainer,"{height:32px;}.",lu.input,"{padding:5px 13px;}.",lu.icon,"{padding:8px 11px;}}.",lu.small,"{width:164px;.",lu.label,"{margin:0 0 6px 12px;}.",lu.inputContainer,"{height:28px;}.",lu.input,"{padding:5px 11px;}.",lu.icon,"{padding:6px 9px;}}.",lu.withIcon,"{}.",lu.outlined," .",lu.inputContainer,"{border:1px solid rgb(var(--lsd-border-primary));}.",lu.underlined," .",lu.inputContainer,"{border:1px solid transparent;border-bottom:1px solid rgb(var(--lsd-border-primary));}.",lu.dropdownItemPlaceholder,"{opacity:0.5;white-space:pre;}",""),zc=a.css(".",uu.root,"{width:fit-content;box-sizing:border-box;display:flex;flex-direction:row;align-items:center;justify-content:center;border:1px solid rgb(var(--lsd-icon-primary));border-radius:20px;&:hover,&:focus{text-decoration:underline;cursor:pointer;}}.",uu.large,"{padding:3px 11px;gap:12px;height:28px;}.",uu.small,"{padding:3px 7px;gap:8px;height:24px;}.",uu.filled,"{background-color:rgb(var(--lsd-icon-primary));.",uu.label,"{color:rgb(var(--lsd-text-secondary));}svg{--lsd-icon-primary:var(--lsd-icon-secondary);}}.",uu.outlined,"{color:rgb(var(--lsd-text-primary));}.",uu.disabled,"{opacity:0.3;cursor:initial;pointer-events:none;}",""),$c=a.css(".",pu.root,"{}.",pu.list,"{display:flex;flex-direction:row;align-items:center;list-style-type:none;margin:0;padding:0;}.",pu.disabled,"{.",pu.list,"{opacity:0.34;cursor:initial;pointer-events:none;}}.",pu.listBox,"{display:flex;flex-direction:column;overflow:auto;border:1px solid rgb(var(--lsd-border-primary));margin-top:10px;position:absolute;width:auto!important;}.",pu.listBox,">li{cursor:pointer;&:not(:last-child){border-bottom:1px solid rgb(var(--lsd-border-primary));}&:hover,&:focus{text-decoration:underline;text-decoration-color:rgb(var(--lsd-border-primary));}}.",pu.listBox," li>a{width:164px;padding:5px 11px;}",""),Uc=a.css(".",du.root,"{list-style-type:none;display:flex;align-items:center;}.",pu.list,">li:not(:last-child)::after{display:inline-block;margin-inline:12px;content:'/';}.",du.itemLink,"{text-decoration:none;cursor:pointer;}.",du.outlined,"{padding:3px 11px;border:1px solid rgb(var(--lsd-border-primary));}",du.large,"{}",du.small,"{}.",pu.root,":not(.",pu.disabled,"){.",du.itemLink,"{&:hover,&:focus{text-decoration:underline;text-decoration-color:rgb(var(--lsd-border-primary));}}}",""),Hc=a.css(".",gu.root,"{width:auto;cursor:pointer;padding:6px 24px;}.",gu.disabled,"{cursor:default;opacity:0.34;}.",gu.large,"{padding:10px 40px;}.",gu.medium,"{padding:6px 24px;}.",gu.small,"{padding:6px 12px;}.",gu.root,":hover{&:not(.",gu.disabled,"){.",gu.text,"{text-decoration:underline;}}}.",gu.withIcon,"{display:flex;align-items:center;}.",gu.icon,"{display:flex;justify-content:center;align-items:center;height:100%;}.",gu.large,".",gu.withIcon,"{padding:10px 0px 10px 18px;.",gu.icon,"{width:42px;}}.",gu.medium,".",gu.withIcon,"{padding:6px 0px 6px 14px;.",gu.icon,"{width:38px;}}.",gu.small,".",gu.withIcon,"{padding:6px 0px 6px 12px;.",gu.icon,"{width:34px;}}.",gu.outlined,"{background:none;border:1px solid rgb(var(--lsd-border-primary));.",gu.text,"{color:rgb(var(--lsd-text-primary));}}.",gu.filled,"{background:rgb(var(--lsd-surface-secondary));border:1px solid rgb(var(--lsd-border-primary));.",gu.text,"{color:rgb(var(--lsd-text-secondary));}}",""),Vc={root:"lsd-calendar",container:"lsd-calendar-container",small:"lsd-calendar--small",medium:"lsd-calendar--medium",large:"lsd-calendar--large",open:"lsd-calendar--open",disabled:"lsd-calendar--disabled",header:"lsd-calendar-header",weekDay:"lsd-calendar__week_day",button:"lsd-calendar__button",changeYear:"lsd-calendar__change-year",changeYearActive:"lsd-calendar__change-year--active",changeYearIconContainer:"lsd-calendar__change-year-icon-container",year:"lsd-calendar-year",month:"lsd-calendar-month",day:"lsd-calendar-day",yearAndIcon:"lsd-calendar__year-and-icon",monthAndYear:"lsd-calendar__month-and-year",dayContainer:"lsd-calendar-day__container",dayRange:"lsd-calendar-day--range",daySelected:"lsd-calendar-day--selected",dayDisabled:"lsd-calendar-day--disabled",dayIsToday:"lsd-calendar-day--today",dayBorderLeft:"lsd-calendar-day--border-left",dayBorderRight:"lsd-calendar-day--border-right",dayBorderLeftAndRight:"lsd-calendar-day--border-left-and-right",dayBorderTopAndBottom:"lsd-calendar-day--border-top-and-bottom",todayIndicator:"lsd-calendar-day__today_indicator",monthTable:"lsd-calendar__month-table",nextMonthButton:"lsd-calendar__next-month-button",previousMonthButton:"lsd-calendar__previous-month-button",yearDropdown:"lsd-calendar__year-dropdown",yearDropdownHidden:"lsd-calendar__year-dropdown--hidden"},qc=a.css(".",Vc.root,"{border:1px solid rgb(var(--lsd-border-primary));visibility:hidden;position:absolute!important;top:0;left:0;opacity:0;visibility:hidden;margin:0;padding:0;box-sizing:border-box;background:rgb(var(--lsd-surface-primary));user-select:none;}.",Vc.container,"{display:flex;flex-direction:column;padding:8px;}.",Vc.open,"{opacity:1;visibility:visible;}.",Vc.header,"{display:flex;justify-content:center;align-items:center;height:32px;margin-bottom:8px;}.",Vc.weekDay,"{display:flex;justify-content:center;align-items:center;aspect-ratio:1/1;margin-bottom:4px;}.",Vc.changeYear,"{position:relative;display:flex;justify-content:center;align-items:center;padding:2px 0xp 2px 8px;gap:6px;border:1px solid transparent;}.",Vc.changeYearActive,"{.",Vc.yearAndIcon,"{border:1px solid rgb(var(--lsd-border-primary));}}.",Vc.changeYearIconContainer,"{display:flex;justify-content:center;align-items:center;cursor:pointer;border:none;}.",Vc.month,"{margin-right:8px;}.",Vc.monthAndYear,"{display:flex;align-items:center;justify-content:center;}.",Vc.dayContainer,"{cursor:pointer;background:transparent;position:relative;box-sizing:border-box;border:1px solid transparent;}.",Vc.day,"{aspect-ratio:1/1;display:flex;justify-content:center;align-items:center;}.",Vc.day,":hover{cursor:pointer;text-decoration:underline;text-decoration-color:rgb(var(--lsd-border-primary));}.",Vc.day," label:hover{cursor:pointer;}.",Vc.daySelected,"{border:1px solid rgb(var(--lsd-border-primary));}.",Vc.dayDisabled,"{opacity:0.3;cursor:default;}.",Vc.todayIndicator,"{position:absolute;left:50%;transform:translateX(-50%);bottom:2px;}.",Vc.disabled,"{pointer-events:none;border:1px solid rgba(var(--lsd-border-primary), 0.3);label{opacity:0.3;}.",Vc.button,"{opacity:0.3;}.",Vc.daySelected,"{opacity:0.3;}}.",Vc.button,"{border:1px solid rgb(var(--lsd-border-primary));cursor:pointer;background:transparent;width:32px;height:32px;display:flex;align-items:center;justify-content:center;position:absolute;}.",Vc.nextMonthButton,"{top:8px;right:8px;}.",Vc.previousMonthButton,"{top:8px;left:8px;}.",Vc.dayBorderLeft,"{border-left:1px double rgb(var(--lsd-border-primary));}.",Vc.dayBorderRight,"{border-right:1px double rgb(var(--lsd-border-primary));}.",Vc.dayBorderLeftAndRight,"{border-left:1px double rgb(var(--lsd-border-primary));border-right:1px double rgb(var(--lsd-border-primary));}.",Vc.dayBorderTopAndBottom,"{border-top:1px double rgb(var(--lsd-border-primary));border-bottom:1px double rgb(var(--lsd-border-primary));}.",Vc.monthTable,"{border-collapse:collapse;}.",Vc.yearDropdown,"{box-sizing:border-box;position:absolute;top:100%;left:0;max-height:200px;overflow-y:auto;width:100%;border:1px solid rgb(var(--lsd-border-primary));border-top:none;z-index:1;.",Vc.year,"{border-bottom:1px solid rgb(var(--lsd-border-primary));}}.",Vc.yearDropdownHidden,"{visibility:hidden;}.",Vc.year,"{display:flex;cursor:pointer;transition:background-color 0.2s;align-items:center;background:rgb(var(--lsd-surface-primary));:hover{text-decoration:underline;}}.",Vc.yearAndIcon,"{border:1px solid rgb(var(--lsd-border-primary));}.",Vc.large,"{.",Vc.year,"{padding:6px 0px 6px 14px;}.",Vc.changeYearIconContainer,"{width:32px;}}.",Vc.medium,"{.",Vc.year,"{padding:6px 0px 6px 12px;}.",Vc.changeYearIconContainer,"{width:28px;}}.",Vc.small,"{.",Vc.year,"{padding:6px 0px 6px 12px;}.",Vc.changeYearIconContainer,"{width:28px;}}",""),Gc=a.css(".",bu.root,"{box-sizing:border-box;display:flex;flex-direction:column;}.",bu.root,">.",ku.root,"{margin-bottom:-1px;}.",bu.large,"{}.",bu.medium,"{}.",bu.small,"{}",""),Wc=a.css(".",xu.root,"{box-sizing:border-box;padding:14px 22px;border:1px solid rgb(var(--lsd-border-primary));}",""),Zc=a.css(".",ku.root,"{box-sizing:border-box;padding:10px 18px;text-align:center;border:1px solid rgb(var(--lsd-border-primary));}.",ku.title,"{overflow:hidden;word-break:break-all;}.",ku.large,"{padding:10px 18px;}.",ku.medium,"{padding:6px 14px;}.",ku.small,"{padding:6px 12px;}",""),Qc=a.css(".",Tu.root,"{position:relative;display:flex;flex-direction:row;align-items:center;}.",Tu.input,"{opacity:0;position:absolute;left:0;top:0;padding:0;margin:0;width:100%;height:100%;}.",Tu.root,":not(.",Tu.disabled,"){&:hover,&.",Tu.focused,"{text-decoration:underline;}.",Tu.input,"{cursor:pointer;}}.",Tu.disabled,"{opacity:0.34;}.",Tu.label,"{margin-left:18px;}.",Tu.large,"{.",Tu.label,"{margin-left:18px;}}.",Tu.medium,"{.",Tu.label,"{margin-left:14px;}}.",Tu.small,"{.",Tu.label,"{margin-left:12px;}}",""),Yc=a.css(".",Du.root,"{display:flex;flex-direction:column;gap:6px;width:fit-content;}.",Du.label,"{margin-bottom:6px;}",""),Xc=a.css(".",Iu.root,"{box-sizing:border-box;display:flex;flex-direction:column;}.",Iu.open,"{.",Iu.content,"{border-top:1px solid transparent;}}.",Iu.content,"{border:1px solid rgb(var(--lsd-border-primary));}",""),Kc=a.css(".",Nu.root,"{box-sizing:border-box;}.",Nu.root,":not(.",Nu.disabled,"){.",Nu.trigger,"{&:hover{.",Nu.label,"{text-decoration:underline;}}}}.",Nu.trigger,"{width:100%;display:flex;flex-direction:row;align-items:center;justify-content:space-between;cursor:pointer;background:none;border:1px solid rgb(var(--lsd-border-primary));&:focus{outline:none;}}.",Nu.label,"{cursor:inherit;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;margin:auto;}.",Nu.icons,"{display:flex;flex-direction:row;align-items:center;justify-content:flex-end;}.",Nu.icon,"{margin-right:8px;}.",Nu.menuIcon,"{}.",Nu.disabled,"{.",Nu.trigger,"{opacity:0.34;cursor:initial;}}.",Nu.large,"{.",Nu.trigger,"{width:299px;height:40px;padding:9px 17px;}}.",Nu.medium,"{.",Nu.trigger,"{width:270px;height:32px;padding:5px 13px;}}.",Nu.small,"{.",Nu.trigger,"{width:235px;height:28px;padding:5px 11px;}}",""),Jc={root:"lsd-date-field",label:"lsd-date-field__label",inputContainer:"lsd-date-field__input-container",input:"lsd-date-field__input-container__input",inputFilled:"lsd-date-field__input-container__input--filled",icon:"lsd-date-field__input-container__icon",noIcon:"lsd-date-field__input-container__no-icon",iconButton:"lsd-date-field__input-container__icon-button",supportingText:"lsd-date-field__supporting-text",disabled:"lsd-date-field--disabled",error:"lsd-date-field--error",large:"lsd-date-field--large",medium:"lsd-date-field--medium",small:"lsd-date-field--small",outlined:"lsd-date-field--outlined",underlined:"lsd-date-field--underlined"},ed=a.css(".",Jc.root,"{width:auto;box-sizing:border-box;}.",Jc.label,"{display:block;}.",Jc.icon,"{position:absolute;right:0;cursor:pointer;display:flex;align-items:center;background-color:rgb(var(--lsd-surface-primary));}.",Jc.icon,":focus{background:blue;background-color:pink;border:1px solid rgb(var(--lsd-border-primary));}.",Jc.noIcon,"{position:absolute;right:0;background-color:rgb(var(--lsd-surface-primary));padding:12px;}.",Jc.outlined,"{border:1px solid rgb(var(--lsd-border-primary));}.",Jc.underlined,"{border-bottom:1px solid rgb(var(--lsd-border-primary));}.",Jc.inputContainer,"{position:relative;display:flex;align-items:center;justify-content:space-between;}.",Jc.disabled,"{opacity:0.34;}.",Jc.input,"{border:none;outline:none;font-size:14px;color:rgb(var(--lsd-text-primary));background:none;width:100%;opacity:0.4;transition:opacity 0.2s ease-in-out;}.",Jc.input,"::-webkit-inner-spin-button,.",Jc.input,"::-webkit-calendar-picker-indicator{display:none;-webkit-appearance:none;}.",Jc.input,":hover{outline:none;}.",Jc.supportingText,"{position:absolute;}.",Jc.large,"{width:208px;.",Jc.label,"{margin:0 0 6px 18px;}.",Jc.inputContainer,"{height:40px;}.",Jc.input,"{padding:9px 0px 9px 17px;}.",Jc.icon,"{padding:12px 13px;}.",Jc.supportingText,"{margin:6px 18px 0 18px;}}.",Jc.medium,"{width:188px;.",Jc.label,"{margin:0 0 6px 14px;}.",Jc.inputContainer,"{height:32px;}.",Jc.input,"{padding:5px 11px 5px 13px;}.",Jc.icon,"{padding:8px 11px;}.",Jc.supportingText,"{margin:6px 14px 0 14px;}}.",Jc.small,"{width:164px;.",Jc.label,"{margin:0 0 6px 12px;}.",Jc.inputContainer,"{height:28px;}.",Jc.input,"{padding:5px 9px 5px 11px;font-size:12px;}.",Jc.icon,"{padding:6px 9px;}.",Jc.supportingText,"{margin:6px 12px 0 12px;}}.",Jc.input,":invalid,.",Jc.inputFilled,"{color:rgb(var(--lsd-border-primary));opacity:1;}.",Jc.error," .",Jc.input,"::-webkit-datetime-edit-year-field,.",Jc.error," .",Jc.input,"::-webkit-datetime-edit-month-field,.",Jc.error," .",Jc.input,"::-webkit-datetime-edit-day-field{text-decoration:line-through;}@supports not selector(::-webkit-datetime-edit-day-field){.",Jc.error," .",Jc.input,"{text-decoration:line-through;}}",""),td={root:"lsd-date-picker",calendar:"lsd-date-picker__calendar",large:"lsd-date-picker--large",medium:"lsd-date-picker--medium",small:"lsd-date-picker--small"},nd=a.css(".",td.root,"{width:fit-content;}.",td.calendar,"{border-top:none!important;}.",td.large,"{.",Jc.large,"{width:318px;}}.",td.medium,"{.",Jc.medium,"{width:290px;}}.",td.small,"{.",Jc.small,"{width:262px;}}",""),rd=a.css(".",Ru.root,"{}.",Ru.root,":not(.",Ru.disabled,"):not(\n .",Ru.error,"\n ){.",Ru.trigger,"{&:hover,&:focus{.",Ru.optionLabel,"{text-decoration:underline;}}}}.",Ru.label,"{display:block;}.",Ru.buttonContainer,"{display:flex;justify-content:space-between;}.",Ru.trigger,"{width:100%;display:flex;flex-direction:row;align-items:center;justify-content:space-between;border:none;cursor:pointer;background:none;&:focus{outline:none;}}.",Ru.optionLabel,"{cursor:inherit;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;}.",Ru.icons,"{display:flex;flex-direction:row;align-items:center;justify-content:center;gap:8px;}.",Ru.icon,"{display:flex;align-items:center;}.",Ru.menuIcon,"{}.",Ru.supportingText,"{margin:6px 14px;}.",Ru.error,"{.",Ru.optionLabel,"{text-decoration:line-through;}}.",Ru.disabled,"{opacity:0.34;cursor:initial;}.",Ru.large,"{width:208px;&.",Ru.error,"{width:230px;}.",Ru.label,"{margin:0 0 6px 18px;}.",Ru.buttonContainer,"{height:40px;}.",Ru.trigger,"{padding:10px 0px 10px 18px;}.",Ru.icons,"{padding:0px 14px;}}.",Ru.medium,"{width:188px;&.",Ru.error,"{width:210px;}.",Ru.label,"{margin:0 0 6px 14px;}.",Ru.buttonContainer,"{height:32px;}.",Ru.trigger,"{padding:6px 0px 6px 14px;}.",Ru.icons,"{padding:0px 12px;}}.",Ru.small,"{width:164px;&.",Ru.error,"{width:186px;}.",Ru.label,"{margin:0 0 6px 12px;}.",Ru.buttonContainer,"{height:28px;}.",Ru.trigger,"{padding:6px 0px 6px 12px;}.",Ru.icons,"{padding:0px 10px;}}.",Ru.outlined,"{.",Ru.buttonContainer,"{border:1px solid rgb(var(--lsd-border-primary));}}.",Ru.underlined,"{.",Ru.buttonContainer,"{border:1px solid transparent;border-bottom:1px solid rgb(var(--lsd-border-primary));}}",""),od=a.css(".",qs.root,"{width:100%;box-sizing:border-box;display:flex;flex-direction:row;align-items:center;border:1px solid rgb(var(--lsd-border-primary));:not(.",qs.disabled,"){cursor:pointer;&:hover,&:focus{outline:none;.",qs.label,"{text-decoration:underline;}}}}.",qs.label,"{display:block;overflow:hidden;white-space:nowrap;text-overflow:ellipsis;}.",qs.disabled,"{opacity:0.34;}.",qs.icon,"{margin-right:18px;flex-shrink:0;}.",qs.small,"{padding:5px 9px;height:28px;}.",qs.medium,"{padding:5px 11px;height:32px;}.",qs.large,"{padding:5px 13px;height:40px;}",""),ad=a.css(".",Fu.root,"{display:flex;flex-direction:row;align-items:center;justify-content:center;cursor:pointer;background:none;padding:0;border:1px solid rgb(var(--lsd-border-primary));}.",Fu.filled,"{background-color:rgb(var(--lsd-icon-primary));svg{--lsd-icon-primary:var(--lsd-icon-secondary);}}.",Fu.outlined,"{}.",Fu.disabled,"{opacity:0.34;cursor:default;}.",Fu.large,"{width:40px;height:40px;}.",Fu.medium,"{width:32px;height:32px;}.",Fu.small,"{width:28px;height:28px;}",""),id=a.css(".",zu.root,"{display:flex;flex-direction:row;}.",zu.outlined," .",Fu.root,":not(:last-child){border-right:none;}",""),ld=a.css(".",xs.root,"{}.",xs.primary,"{&.",xs.filled,"{&,*{fill:rgb(var(--lsd-icon-primary));}}$.",xs.stroked,"{&,*{fill:rgb(var(--lsd-icon-primary));}}}.",xs.secondary,"{&.",xs.filled,"{&,*{fill:rgb(var(--lsd-icon-secondary));}}$.",xs.stroked,"{&,*{fill:rgb(var(--lsd-icon-secondary));}}}",""),sd=a.css(".",tu.root,"{position:absolute;top:0;left:0;opacity:0;visibility:hidden;margin:0;padding:0;box-sizing:border-box;background:rgb(var(--lsd-surface-primary));overflow:auto;border:1px solid rgb(var(--lsd-border-primary));border-top:0;}.",tu.root,">div{border:0;&:not(:last-child){border-bottom:1px solid rgb(var(--lsd-border-primary));}}.",tu.open,"{opacity:1;visibility:visible;}.",tu.large,"{max-height:220px;}.",tu.medium,"{max-height:176px;}.",tu.small,"{max-height:154px;}",""),ud=a.css(".",Uu.root,"{color:rgb(var(--lsd-text-primary));white-space:pre-wrap;}.",Uu.indentedInline,"{border-left:1px solid rgb(var(--lsd-border-primary));padding:4px 8px 4px 28px;}.",Uu.parentheses,"{padding:0px;text-align:center;}.",Uu.parentheses,"::before{content:'***';}.",Uu.parentheses,"::after{content:'***';}",""),cd=a.css(".",qu.root,"{position:relative;display:flex;flex-direction:row;align-items:center;}.",qu.input,"{opacity:0;position:absolute;left:0;top:0;padding:0;margin:0;width:100%;height:100%;}.",qu.root,":not(.",qu.disabled,"){&:hover{text-decoration:underline;}.",qu.input,"{cursor:pointer;}}.",qu.disabled,"{opacity:0.34;}.",qu.label,"{margin-left:18px;}.",qu.large,"{.",qu.label,"{margin-left:18px;}}.",qu.medium,"{.",qu.label,"{margin-left:14px;}}.",qu.small,"{.",qu.label,"{margin-left:12px;}}",""),dd=a.css(".",Wu.root,"{display:flex;flex-direction:column;gap:6px;width:fit-content;}.",Wu.label,"{margin-bottom:6px;}",""),fd=a.css(".",Yu.root,"{background:rgb(var(--lsd-surface-primary));border:1px solid transparent;cursor:pointer;display:flex;flex-direction:row;align-items:center;justify-content:center;box-sizing:border-box;&:hover{text-decoration:underline;}&:not(",Yu.selected,"){border-bottom:1px solid rgb(var(--lsd-border-primary));}}.",Yu.text,"{overflow:hidden;white-space:nowrap;text-overflow:ellipsis;}.",Yu.icon,"{margin-left:14px;}.",Yu.selected,"{border:1px solid rgb(var(--lsd-border-primary));&:hover{text-decoration:none;}}.",Yu.withIcon,"{justify-content:space-between;}.",Yu.disabled,"{cursor:default;opacity:0.34;&:hover{text-decoration:none;}}.",Yu.small,"{padding:6px 12px;.",Yu.icon,"{margin-left:10px;}}.",Yu.medium,"{padding:6px 14px;.",Yu.icon,"{margin-left:12px;}}.",Yu.large,"{padding:10px 18px;.",Yu.icon,"{margin-left:14px;}}",""),pd=a.css(".",nc.root,"{box-sizing:border-box;display:flex;flex-direction:column;}.",nc.root,">.",ec.root,"{margin-bottom:-1px;}.",nc.large,"{}.",nc.medium,"{}.",nc.small,"{}",""),hd=a.css(".",Ku.root,"{table{border-collapse:collapse;text-align:center;table-layout:fixed;width:100%;height:auto;}table tr:first-of-type td label:has(input[type='radio']){display:none;}}.",Ku.toolbar,"{box-sizing:border-box;padding:10px;border:1px solid rgb(var(--lsd-border-primary));border-bottom:none;display:flex;justify-content:space-between;}",""),md=a.css(".",ec.root,"{box-sizing:border-box;border:1px solid rgb(var(--lsd-border-primary));}",""),gd=a.css(".",ic.root,"{border:1px solid rgb(var(--lsd-border-primary));}.",ic.root,":has(> label){width:40px;input{position:relative;width:14px;height:14px;margin:auto;}span{margin-left:14px!important;}}.",ic.large,"{padding:10px;}.",ic.medium,"{padding:6px 8px;}.",ic.small,"{padding:6px;}",""),vd=a.css(".",sc.root,"{align-items:center;}",""),bd=a.css(".",vc.root,"{display:flex;flex-direction:row;overflow:auto;width:fit-content;max-width:100%;border-bottom:1px solid rgb(var(--lsd-border-primary));&>*{flex-shrink:0;}.",Yu.root,"{border-bottom:none;}}.",vc.fullWidth,"{width:100%;justify-content:stretch;&>*{width:100%;flex:1 0;}}.",vc.root,"{-ms-overflow-style:none;scrollbar-width:none;&::-webkit-scrollbar{display:none;}}.",vc.leftScrollControl,"{left:0;}.",vc.rightScrollControl,"{right:0;}.",vc.rightScrollControl,",.",vc.leftScrollControl,"{top:0;flex:0 1;position:sticky;}",""),yd=a.css(".",yc.root,"{width:fit-content;display:flex;flex-direction:row;align-items:center;justify-content:center;box-sizing:border-box;border:1px solid rgb(var(--lsd-icon-primary));&:hover,&:focus{text-decoration:underline;cursor:pointer;}}.",yc.large,"{padding:3px 11px;gap:12px;height:28px;}.",yc.small,"{padding:3px 7px;gap:8px;height:24px;}.",yc.filled,"{background-color:rgb(var(--lsd-icon-primary));.",yc.label,"{color:rgb(var(--lsd-text-secondary));}svg{--lsd-icon-primary:var(--lsd-icon-secondary);}}.",yc.outlined,"{color:rgb(var(--lsd-text-primary));}.",yc.disabled,"{opacity:0.3;cursor:initial;pointer-events:none;}",""),wd=a.css(".",Ec.root,"{box-sizing:border-box;display:flex;flex-direction:column;}.",Ec.inputContainer,"{display:flex;align-items:center;justify-content:space-between;}.",Ec.disabled,"{opacity:0.34;}.",Ec.input,"{border:none;outline:none;font-size:14px;color:rgb(var(--lsd-text-primary));background:none;width:100%;}.",Ec.input,":hover{outline:none;}.",Ec.input,"::placeholder{color:rgb(var(--lsd-text-primary));opacity:0.3;}.",Ec.error," .",Ec.input,"{text-decoration:line-through;}.",Ec.supportingText,"{width:fit-content;}.",Ec.large,"{width:208px;&>*{padding:10px 14px 10px 18px;}}.",Ec.medium,"{width:188px;&>*{padding:6px 12px 6px 14px;}}.",Ec.small,"{width:164px;&>*{padding:6px 10px 6px 12px;}}.",Ec.label,"{padding-top:0;padding-bottom:6px;}.",Ec.supportingText,"{padding-bottom:0;padding-top:6px;}.",Ec.outlined," .",Ec.inputContainer,"{border:1px solid rgb(var(--lsd-border-primary));}.",Ec.underlined," .",Ec.inputContainer,"{border:1px solid transparent;border-bottom:1px solid rgb(var(--lsd-border-primary));}.",Ec.clearButton,"{padding:0;width:auto;height:auto;margin:0;border:0;}.",Ec.icon,"{}",""),xd=a.css("body *{font-family:var(--lsd-typography-generic-font-family);}.",gs.root,"{color:rgb(var(--lsd-text-primary));}.",gs.sansSerif,"{&,*{font-family:sans-serif;}}.",gs.serif,"{&,*{font-family:serif;}}.",gs.monospace,"{&,*{font-family:monospace;}}",ps.map((e=>a.css((e=>[...hs[e]??[],`.${gs[e]}`].join(", "))(e),"{color:rgb(var(--lsd-text-primary));font-weight:var(--lsd-",e,"-fontWeight);font-size:var(--lsd-",e,"-fontSize);line-height:var(--lsd-",e,"-lineHeight);}","")))," .",gs.primary,"{color:rgb(var(--lsd-text-primary));}.",gs.secondary,"{color:rgb(var(--lsd-text-secondary));}input{color:rgb(var(--lsd-text-primary));font-size:var(--lsd-body1-fontSize);font-weight:var(--lsd-body1-fontWeight);}h1,h2,h3,h4,h5,h6,p,span{margin:0;}",""),_d={root:"lsd-number-input",label:"lsd-number-input__label",mainContainer:"lsd-number-input__main-container",inputContainer:"lsd-number-input__input-container",input:"lsd-number-input__input",errorIcon:"lsd-number-input__error-icon",plusMinusIcons:"lsd-number-input__plus-minus-icons",supportingText:"lsd-number-input__supporting-text",disabled:"lsd-number-input--disabled",error:"lsd-number-input--error",large:"lsd-number-input--large",medium:"lsd-number-input--medium",small:"lsd-number-input--small"},kd={root:"lsd-modal",small:"lsd-modal--small",medium:"lsd-modal--medium",large:"lsd-modal--large",xsmall:"lsd-modal--extra-small",modalContainer:"lsd-modal__container",header:"lsd-modal__header",title:"lsd-modal__title",subtitle:"lsd-modal__subtitle",titleAndSubtitleContainer:"lsd-modal__title-and-subtitle-container",closeIcon:"lsd-modal__close-icon"},Ed={root:"lsd-modal-footer"},Sd={root:"lsd-modal-body"},Cd={root:"lsd-toast",inlineContainer:"lsd-toast__inline-container",columnContainer:"lsd-toast__column-container",large:"lsd-toast--large",medium:"lsd-toast--medium",small:"lsd-toast--small",icon:"lsd-toast__icon",textContainer:"lsd-toast__text-container",columnIconContainer:"lsd-toast__column-icon-container",inlineIconContainer:"lsd-toast__inline-icon-container",title:"lsd-toast__title",information:"lsd-toast__information",inlineButtonContainer:"lsd-toast__inline-button-container",columnButtonContainer:"lsd-toast__column-button-container",buttonContainer:"lsd-toast__button-container",closeButton:"lsd-toast__close-button"},Td={toastContainer:"lsd-toast-provider__toast-container",topLeft:"lsd-toast-provider__toast--top-left",topCenter:"lsd-toast-provider__toast--top-center",topRight:"lsd-toast-provider__toast--top-right",bottomLeft:"lsd-toast-provider__toast--bottom-left",bottomCenter:"lsd-toast-provider__toast--bottom-center",bottomRight:"lsd-toast-provider__toast--bottom-right"},Od={root:"lsd-button-group",outlined:"lsd-button-group--outlined",filled:"lsd-button-group--filled",disabled:"lsd-button-group--disabled",small:"lsd-button-group--small",medium:"lsd-button-group--medium",large:"lsd-button-group--large"},Dd={root:"lsd-date-range-picker",calendar:"lsd-date-picker__calendar",withCalendar:"lsd-date-range-picker--with-calendar",openCalendar:"lsd-date-range-picker--calendar-open",disabled:"lsd-date-range-picker--disabled",inputContainer:"lsd-date-range-picker__input-container",icon:"lsd-date-range-picker__icon",large:"lsd-date-range-picker--large",medium:"lsd-date-range-picker--medium",small:"lsd-date-range-picker--small",label:"lsd-date-range-picker__label",supportingText:"lsd-date-range-picker__supporting-text",outlined:"lsd-date-range-picker--outlined",separator:"lsd-date-range-picker__separator"},Pd={root:"lsd-tooltip-base",arrowTip:"lsd-tooltip-base__arrow-tip",content:"lsd-tooltip-base__content"},Nd=[Hc,ad,id,xd,ld,fd,bd,sd,rd,od,$c,Uc,Gc,Zc,Wc,yd,wd,Qc,Bc,ud,Xc,Kc,Yc,zc,cd,dd,pd,md,hd,gd,vd,a.css(".",_d.root,"{width:auto;box-sizing:border-box;}.",_d.mainContainer,":hover{text-decoration:underline;}.",_d.error,"{.",_d.mainContainer,"{text-decoration:line-through;}}.",_d.label,"{display:block;}.",_d.plusMinusIcons,"{display:flex;flex-shrink:0;}.",_d.inputContainer,"{box-sizing:border-box;border:1px solid rgb(var(--lsd-border-primary));border-left:0px;border-right:0px;}.",_d.errorIcon,"{cursor:pointer;display:flex;align-items:center;padding:10px 8px;}.",_d.inputContainer,"{display:flex;align-items:center;justify-content:space-between;}.",_d.disabled,"{opacity:0.34;}.",_d.mainContainer,"{display:flex;align-items:center;}.",_d.input,"{border:none;outline:none;font-size:14px;color:rgb(var(--lsd-text-primary));background:none;text-align:center;padding:0 4px;}.",_d.input,"::-webkit-inner-spin-button{display:none;-webkit-appearance:none;}.",_d.input,":hover{outline:none;}.",_d.supportingText,"{position:absolute;}.",_d.large,"{.",_d.label,"{margin:0 0 6px 18px;}.",_d.inputContainer,"{height:40px;}.",_d.input,"{width:62px;}.",_d.plusMinusIcons,"{height:40px;width:40px;}.",_d.supportingText,"{margin:6px 18px 0 18px;}}.",_d.medium,"{.",_d.label,"{margin:0 0 6px 14px;}.",_d.inputContainer,"{height:32px;}.",_d.input,"{width:58px;}.",_d.plusMinusIcons,"{height:32px;width:32px;}.",_d.supportingText,"{margin:6px 14px 0 14px;}}.",_d.small,"{.",_d.label,"{margin:0 0 6px 12px;}.",_d.inputContainer,"{height:28px;}.",_d.input,"{width:50px;}.",_d.plusMinusIcons,"{height:28px;width:28px;}.",_d.supportingText,"{margin:6px 12px 0 12px;}}",""),a.css(".",kd.root,"{box-sizing:border-box;display:flex;flex-direction:column;position:fixed;top:0;left:0;right:0;bottom:0;background-color:rgba(0, 0, 0, 0.5);display:flex;justify-content:center;align-items:center;z-index:9999;}.",kd.modalContainer,"{position:relative;background:rgb(var(--lsd-surface-primary));padding:20px;max-width:90%;box-sizing:border-box;border:1px solid rgb(var(--lsd-border-primary));}.",kd.header,"{display:flex;justify-content:space-between;align-items:center;}.",kd.title,"{}.",kd.subtitle,"{}.",kd.closeIcon,"{position:absolute;top:8px;right:8px;cursor:pointer;}.",kd.titleAndSubtitleContainer,"{display:flex;flex-direction:column;}.",kd.large,"{.",kd.modalContainer,"{min-width:960px;}}.",kd.medium,"{.",kd.modalContainer,"{min-width:768px;}}.",kd.small,"{.",kd.modalContainer,"{min-width:614px;}}.",kd.xsmall,"{.",kd.modalContainer,"{min-width:490px;}}",""),a.css(".",Ed.root,"{display:flex;}",""),a.css(".",Sd.root,"{margin:18px 0;}",""),nd,ed,qc,a.css(".",Cd.root,"{box-sizing:border-box;display:inline-flex;align-items:center;background:rgb(var(--lsd-surface-primary));border:1px solid rgb(var(--lsd-border-primary));padding:8px;height:fit-content;}.",Cd.inlineButtonContainer,"{flex-shrink:0;}.",Cd.columnButtonContainer,"{margin-top:18px;margin-bottom:6px;}.",Cd.inlineContainer,"{display:flex;align-items:center;justify-content:space-between;flex-grow:1;}.",Cd.columnContainer,"{display:flex;flex-direction:column;justify-content:space-between;}.",Cd.textContainer,"{display:flex;flex-direction:column;color:rgb(var(--lsd-text-secondary));padding-left:12px;}.",Cd.title,"{position:relative;}.",Cd.information,"{margin-top:4px;}.",Cd.buttonContainer,"{min-height:28px;min-width:60px;width:fit-content;padding:0px 12px;}.",Cd.closeButton,"{margin-bottom:auto;flex-shrink:0;height:28px;width:28px;margin-left:auto;}.",Cd.columnIconContainer,"{display:flex;justify-content:center;margin-bottom:auto;position:relative;top:4px;padding-left:4px;}.",Cd.inlineIconContainer,"{display:flex;align-items:center;justify-content:center;padding-left:4px;}.",Cd.icon,"{position:relative;}.",Cd.large,"{width:364px;}.",Cd.medium,"{width:336px;}.",Cd.small,"{width:296px;.",Cd.icon,"{top:0px;}}",""),a.css(".",Td.toastContainer,"{position:fixed;transition:all 230ms cubic-bezier(0.21, 1.02, 0.73, 1);z-index:9999;}.",Td.topLeft,",.",Td.topCenter,",.",Td.topRight,"{top:0;}.",Td.bottomLeft,",.",Td.bottomCenter,",.",Td.bottomRight,"{bottom:0;}.",Td.topCenter,",.",Td.bottomCenter,"{left:50%;}.",Td.topRight,",.",Td.bottomRight,"{right:0;}",""),a.css(".",Od.root,"{display:flex;flex-direction:row;>*:not(:last-child){&.",gu.outlined,",.",gu.outlined,"{border-right:none;}}}",""),a.css(".",Dd.root,"{box-sizing:border-box;.",Jc.outlined,"{border:none;}.",Jc.icon,"{padding:8px;}}.",Dd.label,"{display:block;}.",Dd.inputContainer,"{box-sizing:border-box;display:flex;align-items:center;border:1px solid transparent;}.",Dd.calendar,"{border-top:none!important;.",Pd.arrowTip,"{transition:left 0.2s ease-in-out;}}.",Dd.openCalendar,"{.",Dd.inputContainer,"{border-bottom:1px solid rgb(var(--lsd-border-primary));}}.",Dd.icon,"{cursor:pointer;display:flex;align-items:center;justify-content:center;flex-grow:1;padding:0 10px;}.",Dd.disabled,"{opacity:0.3;}.",Dd.supportingText,"{position:absolute;}.",Dd.large,"{width:318px;.",Jc.large,"{width:156px;}.",Jc.input,"{padding-right:0;}.",Jc.icon,"{padding:11px 12px;}.",Dd.label,"{margin:0 0 6px 18px;}.",Dd.inputContainer,"{height:40px;}.",Dd.supportingText,"{margin:6px 18px 0 18px;}}.",Dd.medium,"{width:290px;.",Jc.medium,"{width:142px;}.",Jc.input,"{padding-right:0;}.",Jc.icon,"{padding:7px 8px;}.",Dd.label,"{margin:0 0 6px 14px;}.",Dd.inputContainer,"{height:32px;}.",Dd.supportingText,"{margin:6px 14px 0 14px;}}.",Dd.small,"{width:262px;.",Jc.small,"{width:128px;}.",Jc.input,"{padding-right:0;}.",Jc.icon,"{padding:5px 7px;}.",Dd.label,"{margin:0 0 6px 12px;}.",Dd.inputContainer,"{height:28px;}.",Dd.supportingText,"{margin:6px 12px 0 12px;}}.",Dd.separator,"{margin-left:3px;width:1px;height:100%;}.",Dd.separator,"{border-left:1px solid transparent;}.",Dd.outlined,"{border:1px solid rgb(var(--lsd-border-primary));.",Dd.separator,"{border-left:1px solid rgb(var(--lsd-border-primary));}}",""),a.css(".",Pd.root,"{border:1px solid rgb(var(--lsd-border-primary));position:relative;}.",Pd.arrowTip,"{border:1px solid rgb(var(--lsd-border-primary));position:absolute;background:rgb(var(--lsd-surface-primary));}.",Pd.content,"{background:rgb(var(--lsd-surface-primary));width:100%;height:100%;position:relative;z-index:1;}","")],Ad=({theme:e=Fc.light})=>{const t=r.useMemo((()=>Nd.map((t=>"function"==typeof t?t(e):t)).map((e=>Ge(a.Global,{styles:e},e.name)))),[e]);return Ge(qe,{children:t})},Id=e=>{try{return[e(),void 0]}catch(t){return[void 0,t]}},Ld=({children:e})=>{const[t,n]=r.useState(!1);return r.useEffect((()=>{if("undefined"==typeof window)return;const e=document.querySelector("body");let t=e.querySelector("#lsd-presentation");return t||(t=document.createElement("div"),t.id="lsd-presentation"),e.appendChild(t),n(!0),()=>{Id((()=>e.removeChild(t)))}}),[]),Ge(ou.Provider,{value:{initialized:t},children:e})},Rd=({children:e})=>{const t=r.useRef(),n=r.useRef({}),[o,a]=r.useState({}),[i,l]=r.useState(!1),s=e=>{const t=n.current[e];t&&t.current&&Id((()=>{a((n=>({...n,[e]:t.current.getBoundingClientRect()})))}))};r.useEffect((()=>{if("undefined"!=typeof window&&"undefined"!=typeof ResizeObserver)return t.current=new ResizeObserver((e=>{Id((()=>{const t=Object.entries(n.current);e.map((e=>t.find((([t,n])=>n.current===e.target)))).forEach((e=>{if(e&&2===e.length){const[t]=e;s(t)}}))}))})),l(!0),()=>{var e;null==(e=t.current)||e.disconnect()}}),[]);return Ge(cc.Provider,{value:{observe:(e,r)=>{t.current&&(n.current[e]=r,s(e),r.current instanceof Element&&t.current.observe(r.current))},unobserve:e=>{if(!t.current)return;const r=n.current[e];r&&(r.current instanceof Element&&t.current.unobserve(r.current),delete n.current[e],a((t=>Vl(t,e))))},rect:o,ready:i},children:e})},jd=r.createContext({theme:null}),Md=({label:e,size:t="large",error:n=!1,errorIcon:o=!1,supportingText:a,value:i,placeholder:l,defaultValue:s,disabled:u,onChange:c,icon:d,inputProps:f={},id:p="number-input",min:h=Number.MIN_SAFE_INTEGER,max:m=Number.MAX_SAFE_INTEGER,step:g=1,...v})=>{const b=r.useRef(null),y=bs(v),w=Ye({defaultValue:s,value:i,onChange:c,ref:b});return We("div",{"aria-disabled":u?"true":"false",...ws(v),className:Qe(v.className,y.className,_d.root,_d[t],u&&_d.disabled,n&&_d.error),children:[e&&Ge(Vs,{htmlFor:p,className:_d.label,variant:"label2",component:"label",children:e}),We("div",{className:_d.mainContainer,children:[Ge(Bu,{onClick:()=>{if(u)return;const e=Math.max(h,Number(w.value||"0")-g);w.setValue(e.toString())},className:_d.plusMinusIcons,children:Ge(Hs,{color:"primary"})}),We("div",{className:_d.inputContainer,children:[Ge("input",{id:p,type:"number",placeholder:l,ref:b,className:Qe(f.className,_d.input),value:w.value||"",onChange:w.onChange,min:h,max:m,step:g,disabled:u,...f}),n&&!!o&&Ge("span",{className:_d.errorIcon,children:Ge(Ns,{color:"primary"})})]}),Ge(Bu,{onClick:()=>{if(u)return;const e=Math.min(m,Number(w.value||"0")+g);w.setValue(e.toString())},className:_d.plusMinusIcons,children:Ge(ks,{color:"primary"})})]}),a&&Ge("div",{className:Qe(_d.supportingText),children:Ge(Vs,{variant:"label2",component:"p",children:a})})]})};Md.classes=_d;const Fd=({isOpen:e,size:t="large",title:n,subtitle:r,onClose:o,children:a,...i})=>{const l=bs(i);return e?Ge("div",{...ws(i),className:Qe(l.className,kd.root,kd[t]),onClick:e=>{e.target===e.currentTarget&&o&&o()},children:We("div",{className:Qe(kd.modalContainer),children:[We("div",{className:kd.header,children:[We("div",{className:kd.titleAndSubtitleContainer,children:[!!n&&Ge(Vs,{className:kd.title,component:"div",variant:"small"===t?"h6":"h5",children:n}),!!r&&Ge(Vs,{className:kd.subtitle,variant:"small"===t?"label2":"label1",component:"div",children:r})]}),Ge(Bu,{onClick:o,className:kd.closeIcon,size:"medium",children:Ge(Ps,{color:"primary"})})]}),a]})}):null};Fd.classes=kd;const Bd=({children:e,...t})=>{const n=bs(t);return Ge("div",{...ws(t),className:Qe(n.className,Sd.root),children:e})};Bd.classes=Sd;const zd=({children:e,...t})=>{const n=bs(t);return Ge("div",{...ws(t),className:Qe(n.className,Ed.root),children:e})};zd.classes=Ed;const $d=({label:e,size:t="large",error:n=!1,errorIcon:o=!1,clearButton:a,supportingText:i,children:l,value:s,placeholder:u,defaultValue:c,disabled:d,onChange:f,icon:p,onIconClick:h,inputProps:m={},calendarIconRef:g,variant:v="underlined",...b})=>{const y=bs(b),w=r.useRef(null),x=Ye({defaultValue:c,value:s,onChange:f,ref:w}),_=(null==m?void 0:m.id)??(b.id||"date-field")+"-input";return We("div",{"aria-disabled":d?"true":"false",...b,className:Qe({...ws(b)},b.className,y.className,Jc.root,Jc[t],d&&Jc.disabled,n&&Jc.error),children:[e&&Ge(Vs,{htmlFor:_,className:Jc.label,variant:"label2",component:"label",children:e}),We("div",{className:Qe(Jc.inputContainer,"outlined"===v?Jc.outlined:Jc.underlined),children:[Ge("input",{id:_,type:"date",placeholder:u,...m,ref:w,value:x.value||"",onChange:x.onChange,className:Qe(m.className,Jc.input,x.filled&&Jc.inputFilled),max:m.max||"9999-12-31"}),p?Ge("span",{className:Jc.icon,onClick:()=>!d&&h&&h(),ref:g,children:p}):n&&o?Ge("span",{className:Jc.icon,children:Ge(Ns,{color:"primary"})}):a&&x.filled?Ge("span",{onClick:()=>!d&&x.setValue(""),className:Jc.icon,children:Ge(Ps,{color:"primary"})}):Ge("span",{className:Jc.noIcon})]}),i&&Ge("div",{className:Qe(Jc.supportingText),children:Ge(Vs,{variant:"label2",component:"p",children:i})}),l]})};$d.classes=Jc;const Ud=(e,t,n)=>{if(!e)return{isValid:!1,date:null};const r=new Date(e+"T00:00:00");return{isValid:!Number.isNaN(+r)&&r>=t&&r<=n,date:r}},Hd=e=>new Date(e.getTime()-6e4*e.getTimezoneOffset()).toISOString().split("T")[0],Vd=e=>e.setHours(0,0,0,0),qd=(e,t,n)=>!!(e&&t&&n)&&(Vd(t)<=Vd(e)&&Vd(n)>=Vd(e)),Gd=(e,t)=>{if(!e||!t)return!1;return Hd(e)===Hd(t)},Wd=e=>{const t=(e=>{const t=e.find((e=>"number"!=typeof e));return t?new Date(t.date):new Date})(e),n=new Date(t);n.setDate(n.getDate()-t.getDay());const r=[];for(let o=0;o<42;o++){const e=new Date(n);e.setDate(e.getDate()+o),r.push(e)}return r},Zd=(e,t)=>e&&e===t?null:t;function Qd(e,t){if(!e||!t)return!0;let n=new Date(Hd(new Date(e)));return new Date(Hd(new Date(t)))>n}const Yd=(e,t)=>"large"===t?"startDate"===e?130:291:"medium"===t?"startDate"===e?120:267:"small"===t?"startDate"===e?107:239:0;var Xd={lessThanXSeconds:{one:"less than a second",other:"less than {{count}} seconds"},xSeconds:{one:"1 second",other:"{{count}} seconds"},halfAMinute:"half a minute",lessThanXMinutes:{one:"less than a minute",other:"less than {{count}} minutes"},xMinutes:{one:"1 minute",other:"{{count}} minutes"},aboutXHours:{one:"about 1 hour",other:"about {{count}} hours"},xHours:{one:"1 hour",other:"{{count}} hours"},xDays:{one:"1 day",other:"{{count}} days"},aboutXWeeks:{one:"about 1 week",other:"about {{count}} weeks"},xWeeks:{one:"1 week",other:"{{count}} weeks"},aboutXMonths:{one:"about 1 month",other:"about {{count}} months"},xMonths:{one:"1 month",other:"{{count}} months"},aboutXYears:{one:"about 1 year",other:"about {{count}} years"},xYears:{one:"1 year",other:"{{count}} years"},overXYears:{one:"over 1 year",other:"over {{count}} years"},almostXYears:{one:"almost 1 year",other:"almost {{count}} years"}};function Kd(e){return function(t){var n=t||{},r=n.width?String(n.width):e.defaultWidth;return e.formats[r]||e.formats[e.defaultWidth]}}var Jd={date:Kd({formats:{full:"EEEE, MMMM do, y",long:"MMMM do, y",medium:"MMM d, y",short:"MM/dd/yyyy"},defaultWidth:"full"}),time:Kd({formats:{full:"h:mm:ss a zzzz",long:"h:mm:ss a z",medium:"h:mm:ss a",short:"h:mm a"},defaultWidth:"full"}),dateTime:Kd({formats:{full:"{{date}} 'at' {{time}}",long:"{{date}} 'at' {{time}}",medium:"{{date}}, {{time}}",short:"{{date}}, {{time}}"},defaultWidth:"full"})},ef={lastWeek:"'last' eeee 'at' p",yesterday:"'yesterday at' p",today:"'today at' p",tomorrow:"'tomorrow at' p",nextWeek:"eeee 'at' p",other:"P"};function tf(e){return function(t,n){var r,o=n||{};if("formatting"===(o.context?String(o.context):"standalone")&&e.formattingValues){var a=e.defaultFormattingWidth||e.defaultWidth,i=o.width?String(o.width):a;r=e.formattingValues[i]||e.formattingValues[a]}else{var l=e.defaultWidth,s=o.width?String(o.width):e.defaultWidth;r=e.values[s]||e.values[l]}return r[e.argumentCallback?e.argumentCallback(t):t]}}function nf(e){return function(t,n){var r=String(t),o=n||{},a=o.width,i=a&&e.matchPatterns[a]||e.matchPatterns[e.defaultMatchWidth],l=r.match(i);if(!l)return null;var s,u=l[0],c=a&&e.parsePatterns[a]||e.parsePatterns[e.defaultParseWidth];return s="[object Array]"===Object.prototype.toString.call(c)?function(e,t){for(var n=0;n0?"in "+r:r+" ago":r},formatLong:Jd,formatRelative:function(e,t,n,r){return ef[e]},localize:{ordinalNumber:function(e,t){var n=Number(e),r=n%100;if(r>20||r<10)switch(r%10){case 1:return n+"st";case 2:return n+"nd";case 3:return n+"rd"}return n+"th"},era:tf({values:{narrow:["B","A"],abbreviated:["BC","AD"],wide:["Before Christ","Anno Domini"]},defaultWidth:"wide"}),quarter:tf({values:{narrow:["1","2","3","4"],abbreviated:["Q1","Q2","Q3","Q4"],wide:["1st quarter","2nd quarter","3rd quarter","4th quarter"]},defaultWidth:"wide",argumentCallback:function(e){return Number(e)-1}}),month:tf({values:{narrow:["J","F","M","A","M","J","J","A","S","O","N","D"],abbreviated:["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"],wide:["January","February","March","April","May","June","July","August","September","October","November","December"]},defaultWidth:"wide"}),day:tf({values:{narrow:["S","M","T","W","T","F","S"],short:["Su","Mo","Tu","We","Th","Fr","Sa"],abbreviated:["Sun","Mon","Tue","Wed","Thu","Fri","Sat"],wide:["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"]},defaultWidth:"wide"}),dayPeriod:tf({values:{narrow:{am:"a",pm:"p",midnight:"mi",noon:"n",morning:"morning",afternoon:"afternoon",evening:"evening",night:"night"},abbreviated:{am:"AM",pm:"PM",midnight:"midnight",noon:"noon",morning:"morning",afternoon:"afternoon",evening:"evening",night:"night"},wide:{am:"a.m.",pm:"p.m.",midnight:"midnight",noon:"noon",morning:"morning",afternoon:"afternoon",evening:"evening",night:"night"}},defaultWidth:"wide",formattingValues:{narrow:{am:"a",pm:"p",midnight:"mi",noon:"n",morning:"in the morning",afternoon:"in the afternoon",evening:"in the evening",night:"at night"},abbreviated:{am:"AM",pm:"PM",midnight:"midnight",noon:"noon",morning:"in the morning",afternoon:"in the afternoon",evening:"in the evening",night:"at night"},wide:{am:"a.m.",pm:"p.m.",midnight:"midnight",noon:"noon",morning:"in the morning",afternoon:"in the afternoon",evening:"in the evening",night:"at night"}},defaultFormattingWidth:"wide"})},match:{ordinalNumber:(rf={matchPattern:/^(\d+)(th|st|nd|rd)?/i,parsePattern:/\d+/i,valueCallback:function(e){return parseInt(e,10)}},function(e,t){var n=String(e),r=t||{},o=n.match(rf.matchPattern);if(!o)return null;var a=o[0],i=n.match(rf.parsePattern);if(!i)return null;var l=rf.valueCallback?rf.valueCallback(i[0]):i[0];return{value:l=r.valueCallback?r.valueCallback(l):l,rest:n.slice(a.length)}}),era:nf({matchPatterns:{narrow:/^(b|a)/i,abbreviated:/^(b\.?\s?c\.?|b\.?\s?c\.?\s?e\.?|a\.?\s?d\.?|c\.?\s?e\.?)/i,wide:/^(before christ|before common era|anno domini|common era)/i},defaultMatchWidth:"wide",parsePatterns:{any:[/^b/i,/^(a|c)/i]},defaultParseWidth:"any"}),quarter:nf({matchPatterns:{narrow:/^[1234]/i,abbreviated:/^q[1234]/i,wide:/^[1234](th|st|nd|rd)? quarter/i},defaultMatchWidth:"wide",parsePatterns:{any:[/1/i,/2/i,/3/i,/4/i]},defaultParseWidth:"any",valueCallback:function(e){return e+1}}),month:nf({matchPatterns:{narrow:/^[jfmasond]/i,abbreviated:/^(jan|feb|mar|apr|may|jun|jul|aug|sep|oct|nov|dec)/i,wide:/^(january|february|march|april|may|june|july|august|september|october|november|december)/i},defaultMatchWidth:"wide",parsePatterns:{narrow:[/^j/i,/^f/i,/^m/i,/^a/i,/^m/i,/^j/i,/^j/i,/^a/i,/^s/i,/^o/i,/^n/i,/^d/i],any:[/^ja/i,/^f/i,/^mar/i,/^ap/i,/^may/i,/^jun/i,/^jul/i,/^au/i,/^s/i,/^o/i,/^n/i,/^d/i]},defaultParseWidth:"any"}),day:nf({matchPatterns:{narrow:/^[smtwf]/i,short:/^(su|mo|tu|we|th|fr|sa)/i,abbreviated:/^(sun|mon|tue|wed|thu|fri|sat)/i,wide:/^(sunday|monday|tuesday|wednesday|thursday|friday|saturday)/i},defaultMatchWidth:"wide",parsePatterns:{narrow:[/^s/i,/^m/i,/^t/i,/^w/i,/^t/i,/^f/i,/^s/i],any:[/^su/i,/^m/i,/^tu/i,/^w/i,/^th/i,/^f/i,/^sa/i]},defaultParseWidth:"any"}),dayPeriod:nf({matchPatterns:{narrow:/^(a|p|mi|n|(in the|at) (morning|afternoon|evening|night))/i,any:/^([ap]\.?\s?m\.?|midnight|noon|(in the|at) (morning|afternoon|evening|night))/i},defaultMatchWidth:"any",parsePatterns:{any:{am:/^a/i,pm:/^p/i,midnight:/^mi/i,noon:/^no/i,morning:/morning/i,afternoon:/afternoon/i,evening:/evening/i,night:/night/i}},defaultParseWidth:"any"})},options:{weekStartsOn:0,firstWeekContainsDate:1}};function af(e){if(null===e||!0===e||!1===e)return NaN;var t=Number(e);return isNaN(t)?t:t<0?Math.ceil(t):Math.floor(t)}function lf(e,t){if(t.length1?"s":"")+" required, but only "+t.length+" present")}function sf(e){lf(1,arguments);var t=Object.prototype.toString.call(e);return e instanceof Date||"object"==typeof e&&"[object Date]"===t?new Date(e.getTime()):"number"==typeof e||"[object Number]"===t?new Date(e):("string"!=typeof e&&"[object String]"!==t||"undefined"==typeof console||(console.warn("Starting with v2.0.0-beta.1 date-fns doesn't accept strings as arguments. Please use `parseISO` to parse strings. See: https://git.io/fjule"),console.warn((new Error).stack)),new Date(NaN))}function uf(e,t){lf(2,arguments);var n=sf(e).getTime(),r=af(t);return new Date(n+r)}function cf(e,t){lf(2,arguments);var n=af(t);return uf(e,-n)}function df(e,t){switch(e){case"P":return t.date({width:"short"});case"PP":return t.date({width:"medium"});case"PPP":return t.date({width:"long"});default:return t.date({width:"full"})}}function ff(e,t){switch(e){case"p":return t.time({width:"short"});case"pp":return t.time({width:"medium"});case"ppp":return t.time({width:"long"});default:return t.time({width:"full"})}}var pf={p:ff,P:function(e,t){var n,r=e.match(/(P+)(p+)?/),o=r[1],a=r[2];if(!a)return df(e,t);switch(o){case"P":n=t.dateTime({width:"short"});break;case"PP":n=t.dateTime({width:"medium"});break;case"PPP":n=t.dateTime({width:"long"});break;default:n=t.dateTime({width:"full"})}return n.replace("{{date}}",df(o,t)).replace("{{time}}",ff(a,t))}};function hf(e){return e.getTime()%6e4}function mf(e){var t=new Date(e.getTime()),n=Math.ceil(t.getTimezoneOffset());return t.setSeconds(0,0),6e4*n+(n>0?(6e4+hf(t))%6e4:hf(t))}var gf=["D","DD"],vf=["YY","YYYY"];function bf(e){return-1!==gf.indexOf(e)}function yf(e){return-1!==vf.indexOf(e)}function wf(e){if("YYYY"===e)throw new RangeError("Use `yyyy` instead of `YYYY` for formatting years; see: https://git.io/fxCyr");if("YY"===e)throw new RangeError("Use `yy` instead of `YY` for formatting years; see: https://git.io/fxCyr");if("D"===e)throw new RangeError("Use `d` instead of `D` for formatting days of the month; see: https://git.io/fxCyr");if("DD"===e)throw new RangeError("Use `dd` instead of `DD` for formatting days of the month; see: https://git.io/fxCyr")}function xf(e,t){lf(1,arguments);var n=t||{},r=n.locale,o=r&&r.options&&r.options.weekStartsOn,a=null==o?0:af(o),i=null==n.weekStartsOn?a:af(n.weekStartsOn);if(!(i>=0&&i<=6))throw new RangeError("weekStartsOn must be between 0 and 6 inclusively");var l=sf(e),s=l.getUTCDay(),u=(s=1&&s<=7))throw new RangeError("firstWeekContainsDate must be between 1 and 7 inclusively");var u=new Date(0);u.setUTCFullYear(r+1,0,s),u.setUTCHours(0,0,0,0);var c=xf(u,t),d=new Date(0);d.setUTCFullYear(r,0,s),d.setUTCHours(0,0,0,0);var f=xf(d,t);return n.getTime()>=c.getTime()?r+1:n.getTime()>=f.getTime()?r:r-1}function kf(e){lf(1,arguments);var t=1,n=sf(e),r=n.getUTCDay(),o=(r=o.getTime()?n+1:t.getTime()>=i.getTime()?n:n-1}function Sf(e){lf(1,arguments);var t=Ef(e),n=new Date(0);n.setUTCFullYear(t,0,4),n.setUTCHours(0,0,0,0);var r=kf(n);return r}function Cf(e,t){lf(1,arguments);var n=t||{},r=n.locale,o=r&&r.options&&r.options.firstWeekContainsDate,a=null==o?1:af(o),i=null==n.firstWeekContainsDate?a:af(n.firstWeekContainsDate),l=_f(e,t),s=new Date(0);s.setUTCFullYear(l,0,i),s.setUTCHours(0,0,0,0);var u=xf(s,t);return u}function Tf(e){lf(1,arguments);var t=sf(e);return!isNaN(t)}function Of(e,t){for(var n=e<0?"-":"",r=Math.abs(e).toString();r.length0?1:0;switch(t){case"G":case"GG":case"GGG":return n.era(r,{width:"abbreviated"});case"GGGGG":return n.era(r,{width:"narrow"});default:return n.era(r,{width:"wide"})}},y:function(e,t,n){if("yo"===t){var r=e.getUTCFullYear(),o=r>0?r:1-r;return n.ordinalNumber(o,{unit:"year"})}return function(e,t){var n=e.getUTCFullYear(),r=n>0?n:1-n;return Of("yy"===t?r%100:r,t.length)}(e,t)},Y:function(e,t,n,r){var o=_f(e,r),a=o>0?o:1-o;return"YY"===t?Of(a%100,2):"Yo"===t?n.ordinalNumber(a,{unit:"year"}):Of(a,t.length)},R:function(e,t){return Of(Ef(e),t.length)},u:function(e,t){return Of(e.getUTCFullYear(),t.length)},Q:function(e,t,n){var r=Math.ceil((e.getUTCMonth()+1)/3);switch(t){case"Q":return String(r);case"QQ":return Of(r,2);case"Qo":return n.ordinalNumber(r,{unit:"quarter"});case"QQQ":return n.quarter(r,{width:"abbreviated",context:"formatting"});case"QQQQQ":return n.quarter(r,{width:"narrow",context:"formatting"});default:return n.quarter(r,{width:"wide",context:"formatting"})}},q:function(e,t,n){var r=Math.ceil((e.getUTCMonth()+1)/3);switch(t){case"q":return String(r);case"qq":return Of(r,2);case"qo":return n.ordinalNumber(r,{unit:"quarter"});case"qqq":return n.quarter(r,{width:"abbreviated",context:"standalone"});case"qqqqq":return n.quarter(r,{width:"narrow",context:"standalone"});default:return n.quarter(r,{width:"wide",context:"standalone"})}},M:function(e,t,n){var r=e.getUTCMonth();switch(t){case"M":case"MM":return function(e,t){var n=e.getUTCMonth();return"M"===t?String(n+1):Of(n+1,2)}(e,t);case"Mo":return n.ordinalNumber(r+1,{unit:"month"});case"MMM":return n.month(r,{width:"abbreviated",context:"formatting"});case"MMMMM":return n.month(r,{width:"narrow",context:"formatting"});default:return n.month(r,{width:"wide",context:"formatting"})}},L:function(e,t,n){var r=e.getUTCMonth();switch(t){case"L":return String(r+1);case"LL":return Of(r+1,2);case"Lo":return n.ordinalNumber(r+1,{unit:"month"});case"LLL":return n.month(r,{width:"abbreviated",context:"standalone"});case"LLLLL":return n.month(r,{width:"narrow",context:"standalone"});default:return n.month(r,{width:"wide",context:"standalone"})}},w:function(e,t,n,r){var o=function(e,t){lf(1,arguments);var n=sf(e),r=xf(n,t).getTime()-Cf(n,t).getTime();return Math.round(r/6048e5)+1}(e,r);return"wo"===t?n.ordinalNumber(o,{unit:"week"}):Of(o,t.length)},I:function(e,t,n){var r=function(e){lf(1,arguments);var t=sf(e),n=kf(t).getTime()-Sf(t).getTime();return Math.round(n/6048e5)+1}(e);return"Io"===t?n.ordinalNumber(r,{unit:"week"}):Of(r,t.length)},d:function(e,t,n){return"do"===t?n.ordinalNumber(e.getUTCDate(),{unit:"date"}):function(e,t){return Of(e.getUTCDate(),t.length)}(e,t)},D:function(e,t,n){var r=function(e){lf(1,arguments);var t=sf(e),n=t.getTime();t.setUTCMonth(0,1),t.setUTCHours(0,0,0,0);var r=t.getTime(),o=n-r;return Math.floor(o/864e5)+1}(e);return"Do"===t?n.ordinalNumber(r,{unit:"dayOfYear"}):Of(r,t.length)},E:function(e,t,n){var r=e.getUTCDay();switch(t){case"E":case"EE":case"EEE":return n.day(r,{width:"abbreviated",context:"formatting"});case"EEEEE":return n.day(r,{width:"narrow",context:"formatting"});case"EEEEEE":return n.day(r,{width:"short",context:"formatting"});default:return n.day(r,{width:"wide",context:"formatting"})}},e:function(e,t,n,r){var o=e.getUTCDay(),a=(o-r.weekStartsOn+8)%7||7;switch(t){case"e":return String(a);case"ee":return Of(a,2);case"eo":return n.ordinalNumber(a,{unit:"day"});case"eee":return n.day(o,{width:"abbreviated",context:"formatting"});case"eeeee":return n.day(o,{width:"narrow",context:"formatting"});case"eeeeee":return n.day(o,{width:"short",context:"formatting"});default:return n.day(o,{width:"wide",context:"formatting"})}},c:function(e,t,n,r){var o=e.getUTCDay(),a=(o-r.weekStartsOn+8)%7||7;switch(t){case"c":return String(a);case"cc":return Of(a,t.length);case"co":return n.ordinalNumber(a,{unit:"day"});case"ccc":return n.day(o,{width:"abbreviated",context:"standalone"});case"ccccc":return n.day(o,{width:"narrow",context:"standalone"});case"cccccc":return n.day(o,{width:"short",context:"standalone"});default:return n.day(o,{width:"wide",context:"standalone"})}},i:function(e,t,n){var r=e.getUTCDay(),o=0===r?7:r;switch(t){case"i":return String(o);case"ii":return Of(o,t.length);case"io":return n.ordinalNumber(o,{unit:"day"});case"iii":return n.day(r,{width:"abbreviated",context:"formatting"});case"iiiii":return n.day(r,{width:"narrow",context:"formatting"});case"iiiiii":return n.day(r,{width:"short",context:"formatting"});default:return n.day(r,{width:"wide",context:"formatting"})}},a:function(e,t,n){var r=e.getUTCHours()/12>=1?"pm":"am";switch(t){case"a":case"aa":case"aaa":return n.dayPeriod(r,{width:"abbreviated",context:"formatting"});case"aaaaa":return n.dayPeriod(r,{width:"narrow",context:"formatting"});default:return n.dayPeriod(r,{width:"wide",context:"formatting"})}},b:function(e,t,n){var r,o=e.getUTCHours();switch(r=12===o?"noon":0===o?"midnight":o/12>=1?"pm":"am",t){case"b":case"bb":case"bbb":return n.dayPeriod(r,{width:"abbreviated",context:"formatting"});case"bbbbb":return n.dayPeriod(r,{width:"narrow",context:"formatting"});default:return n.dayPeriod(r,{width:"wide",context:"formatting"})}},B:function(e,t,n){var r,o=e.getUTCHours();switch(r=o>=17?"evening":o>=12?"afternoon":o>=4?"morning":"night",t){case"B":case"BB":case"BBB":return n.dayPeriod(r,{width:"abbreviated",context:"formatting"});case"BBBBB":return n.dayPeriod(r,{width:"narrow",context:"formatting"});default:return n.dayPeriod(r,{width:"wide",context:"formatting"})}},h:function(e,t,n){if("ho"===t){var r=e.getUTCHours()%12;return 0===r&&(r=12),n.ordinalNumber(r,{unit:"hour"})}return function(e,t){return Of(e.getUTCHours()%12||12,t.length)}(e,t)},H:function(e,t,n){return"Ho"===t?n.ordinalNumber(e.getUTCHours(),{unit:"hour"}):function(e,t){return Of(e.getUTCHours(),t.length)}(e,t)},K:function(e,t,n){var r=e.getUTCHours()%12;return"Ko"===t?n.ordinalNumber(r,{unit:"hour"}):Of(r,t.length)},k:function(e,t,n){var r=e.getUTCHours();return 0===r&&(r=24),"ko"===t?n.ordinalNumber(r,{unit:"hour"}):Of(r,t.length)},m:function(e,t,n){return"mo"===t?n.ordinalNumber(e.getUTCMinutes(),{unit:"minute"}):function(e,t){return Of(e.getUTCMinutes(),t.length)}(e,t)},s:function(e,t,n){return"so"===t?n.ordinalNumber(e.getUTCSeconds(),{unit:"second"}):function(e,t){return Of(e.getUTCSeconds(),t.length)}(e,t)},S:function(e,t){return function(e,t){var n=t.length,r=e.getUTCMilliseconds();return Of(Math.floor(r*Math.pow(10,n-3)),t.length)}(e,t)},X:function(e,t,n,r){var o=(r._originalDate||e).getTimezoneOffset();if(0===o)return"Z";switch(t){case"X":return Nf(o);case"XXXX":case"XX":return Af(o);default:return Af(o,":")}},x:function(e,t,n,r){var o=(r._originalDate||e).getTimezoneOffset();switch(t){case"x":return Nf(o);case"xxxx":case"xx":return Af(o);default:return Af(o,":")}},O:function(e,t,n,r){var o=(r._originalDate||e).getTimezoneOffset();switch(t){case"O":case"OO":case"OOO":return"GMT"+Pf(o,":");default:return"GMT"+Af(o,":")}},z:function(e,t,n,r){var o=(r._originalDate||e).getTimezoneOffset();switch(t){case"z":case"zz":case"zzz":return"GMT"+Pf(o,":");default:return"GMT"+Af(o,":")}},t:function(e,t,n,r){var o=r._originalDate||e;return Of(Math.floor(o.getTime()/1e3),t.length)},T:function(e,t,n,r){return Of((r._originalDate||e).getTime(),t.length)}};function Pf(e,t){var n=e>0?"-":"+",r=Math.abs(e),o=Math.floor(r/60),a=r%60;if(0===a)return n+String(o);var i=t||"";return n+String(o)+i+Of(a,2)}function Nf(e,t){return e%60==0?(e>0?"-":"+")+Of(Math.abs(e)/60,2):Af(e,t)}function Af(e,t){var n=t||"",r=e>0?"-":"+",o=Math.abs(e);return r+Of(Math.floor(o/60),2)+n+Of(o%60,2)}var If=/[yYQqMLwIdDecihHKkms]o|(\w)\1*|''|'(''|[^'])+('|$)|./g,Lf=/P+p+|P+|p+|''|'(''|[^'])+('|$)|./g,Rf=/^'([^]*?)'?$/,jf=/''/g,Mf=/[a-zA-Z]/;function Ff(e,t,n){lf(2,arguments);var r=String(t),o=n||{},a=o.locale||of,i=a.options&&a.options.firstWeekContainsDate,l=null==i?1:af(i),s=null==o.firstWeekContainsDate?l:af(o.firstWeekContainsDate);if(!(s>=1&&s<=7))throw new RangeError("firstWeekContainsDate must be between 1 and 7 inclusively");var u=a.options&&a.options.weekStartsOn,c=null==u?0:af(u),d=null==o.weekStartsOn?c:af(o.weekStartsOn);if(!(d>=0&&d<=6))throw new RangeError("weekStartsOn must be between 0 and 6 inclusively");if(!a.localize)throw new RangeError("locale must contain localize property");if(!a.formatLong)throw new RangeError("locale must contain formatLong property");var f=sf(e);if(!Tf(f))throw new RangeError("Invalid time value");var p=mf(f),h=cf(f,p),m={firstWeekContainsDate:s,weekStartsOn:d,locale:a,_originalDate:f},g=r.match(Lf).map((function(e){var t=e[0];return"p"===t||"P"===t?(0,pf[t])(e,a.formatLong,m):e})).join("").match(If).map((function(e){if("''"===e)return"'";var t=e[0];if("'"===t)return Bf(e);var n=Df[t];if(n)return!o.useAdditionalWeekYearTokens&&yf(e)&&wf(e),!o.useAdditionalDayOfYearTokens&&bf(e)&&wf(e),n(h,e,a.localize,m);if(t.match(Mf))throw new RangeError("Format string contains an unescaped latin alphabet character `"+t+"`");return e})).join("");return g}function Bf(e){return e.match(Rf)[1].replace(jf,"'")}function zf(e,t){lf(2,arguments);var n=sf(e),r=af(t);return isNaN(r)?new Date(NaN):r?(n.setDate(n.getDate()+r),n):n}function $f(e,t){lf(1,arguments);var n=e||{},r=sf(n.start),o=sf(n.end),a=o.getTime();if(!(r.getTime()<=a))throw new RangeError("Invalid interval");var i=[],l=r;l.setHours(0,0,0,0);var s=t&&"step"in t?Number(t.step):1;if(s<1||isNaN(s))throw new RangeError("`options.step` must be a number greater than 1");for(;l.getTime()<=a;)i.push(sf(l)),l.setDate(l.getDate()+s),l.setHours(0,0,0,0);return i}function Uf(e,t){lf(1,arguments);var n=t||{},r=n.locale,o=r&&r.options&&r.options.weekStartsOn,a=null==o?0:af(o),i=null==n.weekStartsOn?a:af(n.weekStartsOn);if(!(i>=0&&i<=6))throw new RangeError("weekStartsOn must be between 0 and 6 inclusively");var l=sf(e),s=l.getDay(),u=6+(s=0&&i<=6))throw new RangeError("weekStartsOn must be between 0 and 6 inclusively");var l=sf(e),s=l.getDay(),u=(s=o?u-o:6-o+u+1).keys()).fill(0),$f({start:s,end:c}).map((function(e){return{date:e,dayLabel:i(e)}})))}({year:t,month:n,firstDayOfWeek:a,dayLabelFormat:l})}),[t,n,a,l]),weekdayLabels:r.useMemo((function(){return function(e){var t=void 0===e?{}:e,n=t.firstDayOfWeek,r=void 0===n?1:n,o=t.weekdayLabelFormat,a=void 0===o?function(e){return Ff(e,"iiiiii")}:o,i=new Date;return $f({start:zf(Vf(i),r),end:zf(Uf(i),r)}).reduce((function(e,t){return e.push(a(t)),e}),[])}({firstDayOfWeek:a,weekdayLabelFormat:u})}),[a,u]),monthLabel:d(new Date(t,n))}}function Qf(e,t){lf(2,arguments);var n=sf(e),r=sf(t);return n.getTime()r.getTime()}function Xf(e,t){lf(2,arguments);var n=t||{},r=sf(e).getTime(),o=sf(n.start).getTime(),a=sf(n.end).getTime();if(!(o<=a))throw new RangeError("Invalid interval");return r>=o&&r<=a}function Kf(e){lf(1,arguments);var t=sf(e);return t.setHours(0,0,0,0),t}function Jf(e,t){lf(2,arguments);var n=Kf(e),r=Kf(t);return n.getTime()===r.getTime()}function ep(e,t){lf(2,arguments);var n=sf(e),r=af(t);if(isNaN(r))return new Date(NaN);if(!r)return n;var o=n.getDate(),a=new Date(n.getTime());a.setMonth(n.getMonth()+r+1,0);var i=a.getDate();return o>=i?a:(n.setFullYear(a.getFullYear(),a.getMonth(),o),n)}var tp=function(e,t){return void 0===e&&(e=[]),e.some((function(e){return Jf(t,e)}))};function np(e){var t=Hf(e);return{year:function(e){lf(1,arguments);var t=sf(e),n=t.getFullYear();return n}(t),month:function(e){lf(1,arguments);var t=sf(e),n=t.getMonth();return n}(t),date:t}}function rp(e,t){var n=np(t||Kf(Date.now())),r=n.date,o=[n];return e>1&&(o=Array.from(Array(e-1).keys()).reduce((function(e){return r=ep(e[e.length-1].date,1),e.concat([np(r)])}),o)),o}function op(e,t,n,r){var o=e[r?n>0?0:e.length-r:n>0?e.length-1:0].date;return Array.from(Array(t).keys()).reduce((function(e){return o=0===e.length?ep(o,n):ep(o,n>=0?1:-1),n>0?e.concat([np(o)]):[np(o)].concat(e)}),[])}function ap(e){var t=e.startDate,n=e.endDate,r=e.isDateBlocked,o=e.minBookingDays,a=e.exactMinBookingDays,i=e.minBookingDate,l=e.maxBookingDate,s=!i||!Qf(t,zf(i,-1)),u=!l||!Yf(zf(t,o-1),l);return!((!t||1!==o||n||r(t))&&(t&&o>1&&!n&&!a||t&&o>0&&a&&s&&u||t&&o>0&&a&&!i&&!l?$f({start:t,end:zf(t,o-1)}).some((function(e){return r(e)})):!t||!n||a||Qf(n,zf(t,o-1))||$f({start:t,end:n}).some((function(e){return r(e)}))))}function ip(e){var t=e.startDate,n=e.endDate,o=e.focusedInput,a=e.minBookingDate,i=e.maxBookingDate,l=e.onDatesChange,s=e.initialVisibleMonth,u=e.exactMinBookingDays,c=void 0!==u&&u,d=e.minBookingDays,f=void 0===d?1:d,p=e.numberOfMonths,h=void 0===p?2:p,m=e.firstDayOfWeek,g=void 0===m?1:m,v=e.isDateBlocked,b=void 0===v?function(){return!1}:v,y=e.unavailableDates,w=void 0===y?[]:y,x=e.changeActiveMonthOnSelect,_=void 0===x||x,k=r.useState((function(){return rp(h,t||s||null)})),E=k[0],S=k[1],C=r.useState(null),T=C[0],O=C[1],D=r.useState(t),P=D[0],N=D[1];r.useEffect((function(){return"undefined"!=typeof window&&window.addEventListener&&window.addEventListener("keydown",R),function(){window.removeEventListener&&window.removeEventListener("keydown",R)}}));var A=function(e){return tp(w,e)||b(e)},I=function(e){N(e),(!P||P&&!Jf(e,P))&&S(rp(h,e))},L=function(e){return function(e){var t=e.date,n=e.minBookingDate,r=e.maxBookingDate,o=e.isDateBlockedFn,a=e.startDate,i=e.endDate,l=e.minBookingDays,s=void 0===l?1:l,u=e.unavailableDates,c=void 0===u?[]:u,d=n?new Date(n.getFullYear(),n.getMonth(),n.getDate(),0,0,0):n,f=r?new Date(r.getFullYear(),r.getMonth(),r.getDate(),0,0,0):r;return!!(tp(c,t)||d&&Qf(t,d)||f&&Yf(t,f)||a&&!i&&s>1&&Xf(t,{start:a,end:zf(a,s-2)})||o&&o(t))}({date:e,minBookingDate:a,maxBookingDate:i,startDate:t,endDate:n,minBookingDays:f,isDateBlockedFn:A})};function R(e){if(("ArrowRight"===e.key||"ArrowLeft"===e.key||"ArrowDown"===e.key||"ArrowUp"===e.key)&&!P){var t=E[0];I(t.date),S(rp(h,t.date))}}var j=r.useCallback((function(){S(op(E,h,-1)),N(null)}),[E,h]),M=r.useCallback((function(){S(op(E,h,-1,1)),N(null)}),[E,h]),F=r.useCallback((function(){S(op(E,h,1)),N(null)}),[E,h]),B=r.useCallback((function(){S(op(E,h,1,1)),N(null)}),[E,h]),z=r.useCallback((function(e){S(rp(h,e)),N(null)}),[h]),$=r.useCallback((function(e){void 0===e&&(e=1),S(op(E,h,-(12*e-h+1))),N(null)}),[E,h]),U=r.useCallback((function(e){void 0===e&&(e=1),S(op(E,h,12*e-h+1)),N(null)}),[E,h]);return{firstDayOfWeek:g,activeMonths:E,isDateSelected:function(e){return function(e,t,n){return!(!t||!n)&&Xf(e,{start:t,end:n})}(e,t,n)},isDateHovered:function(e){return o=(r={date:e,hoveredDate:T,startDate:t,endDate:n,minBookingDays:f,exactMinBookingDays:c,isDateBlocked:A}).date,a=r.startDate,i=r.endDate,l=r.isDateBlocked,u=r.minBookingDays,(s=r.hoveredDate)&&u>1&&r.exactMinBookingDays&&Xf(o,{start:s,end:zf(s,u-1)})?!$f({start:s,end:zf(s,u-1)}).some((function(e){return l(e)})):a&&!i&&s&&Xf(o,{start:a,end:zf(a,u-1)})&&Jf(a,s)&&u>1?!$f({start:a,end:zf(a,u-1)}).some((function(e){return l(e)})):!(!a||i||!s||Qf(s,a)||!Xf(o,{start:a,end:s})||$f({start:a,end:s}).some((function(e){return l(e)})));var r,o,a,i,l,s,u},isFirstOrLastSelectedDate:function(e){return function(e,t,n){return!!(t&&Jf(e,t)||n&&Jf(e,n))}(e,t,n)},isStartDate:function(e){return function(e,t){return!(!t||!Jf(e,t))}(e,t)},isEndDate:function(e){return function(e,t){return!(!t||!Jf(e,t))}(e,n)},isDateBlocked:L,numberOfMonths:h,isDateFocused:function(e){return!!P&&Jf(e,P)},focusedDate:P,hoveredDate:T,onResetDates:function(){l({startDate:null,endDate:null,focusedInput:"startDate"})},onDateHover:function(e){if(e){if(e){var r=!L(e)||t&&Jf(e,t),o=!a||!Qf(e,zf(a,-1)),l=!i||!Yf(e,i),s=zf(e,f-1),u=!a||!Qf(s,a),d=!i||!Yf(s,i),p=c&&f>1&&o&&l&&u&&d,h=t&&!n&&!c&&o&&l,m=!(f>1&&t)||Xf(e,{start:t,end:zf(t,f-2)}),g=t&&Jf(e,t)&&m;r&&(p||h||g)?O(e):null!==T&&O(null)}}else O(null)},onDateSelect:function(e){("endDate"===o||"startDate"===o)&&f>0&&c&&ap({minBookingDays:f,exactMinBookingDays:c,minBookingDate:a,maxBookingDate:i,isDateBlocked:A,startDate:e,endDate:null})?l({startDate:e,endDate:zf(e,f-1),focusedInput:null}):("endDate"===o&&t&&Qf(e,t)||"startDate"===o&&n&&Yf(e,n))&&!c&&ap({minBookingDays:f,isDateBlocked:A,startDate:e,endDate:null})?l({endDate:null,startDate:e,focusedInput:"endDate"}):"startDate"===o&&!c&&ap({minBookingDays:f,isDateBlocked:A,endDate:n,startDate:e})?l({endDate:n,startDate:e,focusedInput:"endDate"}):"startDate"===o&&!c&&ap({minBookingDays:f,isDateBlocked:A,endDate:null,startDate:e})?l({endDate:null,startDate:e,focusedInput:"endDate"}):"endDate"===o&&t&&!Qf(e,t)&&!c&&ap({minBookingDays:f,isDateBlocked:A,startDate:t,endDate:e})&&l({startDate:t,endDate:e,focusedInput:null}),"endDate"!==o&&(!P||P&&!Jf(e,P))&&_&&S(rp(h,e))},onDateFocus:I,goToPreviousMonths:j,goToPreviousMonthsByOneMonth:M,goToNextMonths:F,goToNextMonthsByOneMonth:B,goToDate:z,goToPreviousYear:$,goToNextYear:U}}const lp=r.createContext(null),sp=()=>r.useContext(lp),up=({day:e,index:t,fullMonthDays:n,disabled:o=!1})=>{const a=n[t],{mode:i,startDate:l,endDate:s,onDateSelect:u}=sp(),c=r.useRef(null),d=Vd(a)===Vd(new Date),f="range"===i&&qd(a,l,s),p=r.useCallback((()=>u(a)),[a,u]),h=Gd(a,l),m="range"===i&&Gd(a,s),g=h||m||f;if(!e)return null;const v=((e,t,n,r,o)=>{if(!n)return"";if(!r||!o)return Vc.dayBorderLeftAndRight;const{prevIndex:a,nextIndex:i}=((e,t)=>{const n=e-1,r=e+1;return{prevIndex:n>=0?n:null,nextIndex:r{const a=r.useRef(null),i=r.useRef(null),{goToDate:l,changeYearMode:s,setChangeYearMode:u}=sp(),c=r.useRef(null),{y:d}=eu(c),[f,p]=r.useState((()=>parseInt(e)-o)),[h,m]=r.useState((()=>parseInt(e)+o)),g=Array.from({length:h-f+1},((e,t)=>f+t));Ys(a,(()=>{u(!1)}));return r.useEffect((()=>{if(s&&i.current&&c.current){const e=i.current.offsetTop,t=i.current.offsetHeight,n=e-c.current.clientHeight/2+t/2;c.current.scrollTop=n}}),[s]),r.useEffect((()=>{var e,t;const n=null==(e=null==c?void 0:c.current)?void 0:e.scrollHeight,r=null==(t=null==c?void 0:c.current)?void 0:t.clientHeight;if(!n||!r)return;const a=d/(n-r)*100;a>90&&m((e=>Math.min(e+o,bp))),a<10&&p((e=>Math.max(e-o,vp)))}),[d,o]),We("div",{ref:a,className:Qe(Vc.changeYear,s&&Vc.changeYearActive),onClick:()=>{u(!s)},children:[We("div",{className:Qe(Vc.year,Vc.yearAndIcon),children:[Ge(Vs,{component:"span",variant:"large"===n?"label1":"label2",children:e}),Ge("div",{className:Vc.changeYearIconContainer,children:Ge(s?Cs:Es,{color:"primary"})})]}),Ge("div",{className:Qe(Vc.yearDropdown,!s&&Vc.yearDropdownHidden),ref:c,children:g.map((r=>Ge("div",{className:Vc.year,onClick:()=>(e=>{const n=new Date(e,t,1);l(n),u(!1)})(r),ref:r===parseInt(e)?i:null,children:Ge(Vs,{component:"span",variant:"large"===n?"label1":"label2",children:r})},r)))})]})},dp=({direction:e,onClick:t,className:n})=>{const r="previous"===e?js:Ms;return Ge("button",{className:Qe(Vc.button,n),type:"button",onClick:t,children:Ge(r,{color:"primary"})})},fp=({monthLabel:e,monthNumber:t,size:n})=>{const{goToPreviousMonths:r,goToNextMonths:o}=sp(),[a,i]=e.split(" ");return We("div",{className:Vc.header,children:[Ge(dp,{direction:"previous",onClick:r,className:Vc.previousMonthButton}),We("div",{className:Vc.monthAndYear,children:[Ge(Vs,{className:Vc.month,component:"span",variant:"large"===n?"label1":"label2",children:a}),Ge(cp,{year:i,monthNumber:t,size:n})]}),Ge(dp,{direction:"next",onClick:o,className:Vc.nextMonthButton})]})},pp=({weekdayLabels:e})=>Ge("tr",{children:e.map(((e,t)=>Ge("th",{children:Ge("div",{className:Vc.weekDay,children:Ge(Vs,{variant:"label2",children:e[0]})})},t)))}),hp=({days:e})=>{const t=Wd(e),n=new Date(t[15]).getMonth();return Ge(qe,{children:Array.from({length:6}).map(((e,r)=>Ge("tr",{children:Array.from({length:7}).map(((e,o)=>{const a=7*r+o,i=t[a];return Ge(up,{index:a,day:i.getDate().toString(),fullMonthDays:t,disabled:i.getMonth()!==n},`day-${a}`)}))},`week-${r}`)))})},mp=({size:e="large",year:t,month:n,firstDayOfWeek:r})=>{const o=sp(),a=(null==o?void 0:o.size)??e,{days:i,weekdayLabels:l,monthLabel:s}=Zf({year:t,month:n,firstDayOfWeek:r});return We(qe,{children:[Ge(fp,{monthLabel:s,monthNumber:n,size:a}),We("table",{className:Vc.monthTable,children:[Ge("thead",{children:Ge(pp,{weekdayLabels:l})}),Ge("tbody",{children:Ge(hp,{days:i})})]})]})},gp=({children:e,arrowOffset:t,arrowPosition:n="top",arrowSize:r=10,rootRef:o,...a})=>{const i=bs(a),l={width:`${r}px`,height:`${r}px`,transform:"rotate(45deg)"};return["top","bottom"].includes(n)?(l.left=`${t}px`,l[n]=`-${r/2}px`):(l.top=`${t}px`,l[n]=`-${r/2}px`),Ge("div",{ref:o,...ws(a),className:Qe(i.className,a.className,Pd.root),children:t?We(qe,{children:[Ge("div",{className:Pd.arrowTip,style:l}),Ge("div",{className:Pd.content,children:e})]}):e})};gp.classes=Pd;const vp=1850,bp=2100,yp=({open:e,handleRef:t,size:n="large",mode:o="date",disabled:a=!1,onStartDateChange:i,onEndDateChange:l,onClose:s,onCalendarClickaway:u,startDate:c,endDate:d,calendarType:f="startDate",minDate:p=new Date(vp,0,1),maxDate:h=new Date(bp,0,1),tooltipArrowOffset:m,...g})=>{const v=bs(g),b=r.useRef(null),[y,w]=r.useState(c?Ud(c,p,h).date:null),[x,_]=r.useState(d?Ud(d,p,h).date:null),[k,E]=r.useState(!1);Ys(b,(t=>{e&&(u&&u(t),void 0===e&&s&&s())}));const{activeMonths:S,onDateFocus:C,onDateSelect:T,goToPreviousMonths:O,goToNextMonths:D,goToDate:P}=ip({startDate:y,endDate:x,focusedInput:"startDate",onDatesChange:e=>{const t=((e,t,n,r)=>{let o=t,a=n;const i=r.startDate;return i?("startDate"===e?(!a||a&&i.getTime()<=a.getTime())&&(o=i):"endDate"===e&&(!o||o&&i.getTime()>=o.getTime())&&(a=i),{newStartDate:o,newEndDate:a}):{newStartDate:o,newEndDate:a}})(f,y,x,e),{newStartDate:n,newEndDate:r}=t;n!==y&&(null==i||i(n??new Date),w(n)),r!==x&&"range"===o&&(null==l||l(r??new Date),_(r))},numberOfMonths:1});r.useEffect((()=>{const e=Ud(c,p,h);if(Gd(e.date,y)||w(e.isValid?e.date:null),"range"===o){const e=Ud(d,p,h);Gd(e.date,x)||_(e.isValid?e.date:null)}}),[c,d,o,p,h,y,x]),r.useEffect((()=>{y&&C(y)}),[y]),r.useEffect((()=>{x&&C(x)}),[x]);const N=nu(t,e);return Ge(lp.Provider,{value:{size:n,mode:o,startDate:y,endDate:x,onDateFocus:C,onDateSelect:T,goToPreviousMonths:O,goToNextMonths:D,goToDate:P,changeYearMode:k,setChangeYearMode:E},children:Ge(gp,{...g,className:Qe({...ws(g)},v.className,g.className,Vc.root,Vc[n],e&&Vc.open,a&&Vc.disabled),rootRef:b,style:{...N,...g.style??{}},arrowOffset:m,children:Ge("div",{className:Qe(Vc.container),children:S.map(((e,t)=>Ge(mp,{year:e.year,month:e.month,firstDayOfWeek:0,size:n},`${e.year}-${e.month}-${t}`)))})})})};yp.classes=Vc;const wp=(e,t)=>t&&(null==e?void 0:e.composedPath().includes(t))||!1,xp=({label:e,size:t="large",value:n,onChange:o,withCalendar:a=!0,variant:i="underlined",...l})=>{const s=bs(l),u=r.useRef(null),c=r.useRef(null),[d,f]=r.useState(!1),p=void 0!==n,h=Ye({value:n,defaultValue:"",onChange:o,getInput:()=>{var e;return null==(e=u.current)?void 0:e.querySelector(`input.${$d.classes.input}`)}});return Ge("div",{id:(l.id||"date-picker")+"-input",ref:u,className:Qe({...ws(l)},l.className,s.className,td.root,td[t]),children:Ge($d,{label:e,size:t,variant:i,icon:a&&Ge(Us,{color:"primary"}),onIconClick:()=>f((e=>!e)),value:p||d?h.value:void 0,onChange:h.onChange,calendarIconRef:c,...l,children:Ge(au,{id:"calendar",children:a&&Ge(yp,{...ys(l),onStartDateChange:e=>(e=>h.setValue(Hd(e)))(e),open:d,onCalendarClickaway:e=>{wp(e,c.current)||f(!1)},handleRef:u,startDate:h.value,disabled:l.disabled,className:td.calendar})})})})};xp.classes=td;const _p=({title:e,information:t,onClose:n,size:r="large",toastRef:o,children:a,icon:i,actions:l,...s})=>{const u=bs(s),c=!t,d=void 0===i?Ns:i;return We("div",{ref:o,...ws(s),className:Qe(s.className,u.className,Cd.root,Cd[r]),children:[Ge("div",{className:Qe(c?Cd.inlineIconContainer:Cd.columnIconContainer),children:d&&Ge(d,{color:"primary",className:Cd.icon})}),We("div",{className:c?Cd.inlineContainer:Cd.columnContainer,children:[We("div",{className:Qe(Cd.textContainer),children:[!!e&&Ge(Vs,{className:Cd.title,component:"div",variant:"small"===r?"label2":"label1",children:e}),!!t&&Ge(Vs,{className:Cd.information,component:"div",variant:"small"===r?"label2":"label1",children:t})]}),!!l&&Ge("div",{className:Qe(Cd.buttonContainer,c?Cd.inlineButtonContainer:Cd.columnButtonContainer),children:l})]}),Ge(Bu,{onClick:n,className:Cd.closeButton,size:"medium",children:Ge(Ps,{color:"primary"})})]})};_p.classes=Cd;var kp=(e,t)=>(e=>"function"==typeof e)(e)?e(t):e,Ep=(()=>{let e=0;return()=>(++e).toString()})(),Sp=new Map,Cp=e=>{if(Sp.has(e))return;let t=setTimeout((()=>{Sp.delete(e),Pp({type:4,toastId:e})}),1e3);Sp.set(e,t)},Tp=(e,t)=>{switch(t.type){case 0:return{...e,toasts:[t.toast,...e.toasts].slice(0,20)};case 1:return t.toast.id&&(e=>{let t=Sp.get(e);t&&clearTimeout(t)})(t.toast.id),{...e,toasts:e.toasts.map((e=>e.id===t.toast.id?{...e,...t.toast}:e))};case 2:let{toast:n}=t;return e.toasts.find((e=>e.id===n.id))?Tp(e,{type:1,toast:n}):Tp(e,{type:0,toast:n});case 3:let{toastId:r}=t;return r?Cp(r):e.toasts.forEach((e=>{Cp(e.id)})),{...e,toasts:e.toasts.map((e=>e.id===r||void 0===r?{...e,visible:!1}:e))};case 4:return void 0===t.toastId?{...e,toasts:[]}:{...e,toasts:e.toasts.filter((e=>e.id!==t.toastId))};case 5:return{...e,pausedAt:t.time};case 6:let o=t.time-(e.pausedAt||0);return{...e,pausedAt:void 0,toasts:e.toasts.map((e=>({...e,pauseDuration:e.pauseDuration+o})))}}},Op=[],Dp={toasts:[],pausedAt:void 0},Pp=e=>{Dp=Tp(Dp,e),Op.forEach((e=>{e(Dp)}))},Np={blank:4e3,error:4e3,success:2e3,loading:1/0,custom:4e3},Ap=e=>(t,n)=>{let r=((e,t="blank",n)=>({createdAt:Date.now(),visible:!0,type:t,ariaProps:{role:"status","aria-live":"polite"},message:e,pauseDuration:0,...n,id:(null==n?void 0:n.id)||Ep()}))(t,e,n);return Pp({type:2,toast:r}),r.id},Ip=(e,t)=>Ap("blank")(e,t);Ip.error=Ap("error"),Ip.success=Ap("success"),Ip.loading=Ap("loading"),Ip.custom=Ap("custom"),Ip.dismiss=e=>{Pp({type:3,toastId:e})},Ip.remove=e=>Pp({type:4,toastId:e}),Ip.promise=(e,t,n)=>{let r=Ip.loading(t.loading,{...n,...null==n?void 0:n.loading});return e.then((e=>(Ip.success(kp(t.success,e),{id:r,...n,...null==n?void 0:n.success}),e))).catch((e=>{Ip.error(kp(t.error,e),{id:r,...n,...null==n?void 0:n.error})})),e};var Lp=(e,t)=>{Pp({type:1,toast:{id:e,height:t}})},Rp=()=>{Pp({type:5,time:Date.now()})},jp=e=>{let{toasts:t,pausedAt:n}=((e={})=>{let[t,n]=r.useState(Dp);r.useEffect((()=>(Op.push(n),()=>{let e=Op.indexOf(n);e>-1&&Op.splice(e,1)})),[t]);let o=t.toasts.map((t=>{var n,r;return{...e,...e[t.type],...t,duration:t.duration||(null==(n=e[t.type])?void 0:n.duration)||(null==e?void 0:e.duration)||Np[t.type],style:{...e.style,...null==(r=e[t.type])?void 0:r.style,...t.style}}}));return{...t,toasts:o}})(e);r.useEffect((()=>{if(n)return;let e=Date.now(),r=t.map((t=>{if(t.duration===1/0)return;let n=(t.duration||0)+t.pauseDuration-(e-t.createdAt);if(!(n<0))return setTimeout((()=>Ip.dismiss(t.id)),n);t.visible&&Ip.dismiss(t.id)}));return()=>{r.forEach((e=>e&&clearTimeout(e)))}}),[t,n]);let o=r.useCallback((()=>{n&&Pp({type:6,time:Date.now()})}),[n]),a=r.useCallback(((e,n)=>{let{reverseOrder:r=!1,gutter:o=8,defaultPosition:a}=n||{},i=t.filter((t=>(t.position||a)===(e.position||a)&&t.height)),l=i.findIndex((t=>t.id===e.id)),s=i.filter(((e,t)=>te.visible)).slice(...r?[s+1]:[0,s]).reduce(((e,t)=>e+(t.height||0)+o),0)}),[t]);return{toasts:t,handlers:{updateHeight:Lp,startPause:Rp,endPause:o,calculateOffset:a}}};const Mp=r.createContext(null),Fp=({toastsPropsMap:e,className:t,...n})=>{const{toasts:r,handlers:o}=jp(),{startPause:a,endPause:i,calculateOffset:l,updateHeight:s}=o;return Ge(au,{id:"toast",children:r.map((r=>{const o=e.get(r.id);if(!o)return console.warn("Could not find toast with id",r.id),null;const{position:u,duration:c,...d}=o,f=l(r,{reverseOrder:!1,gutter:8,defaultPosition:u}),{transform:p,positionClassName:h}=((e,t)=>{if(!e)return{positionClassName:"",transform:`translateY(${t}px)`};let n="";const r=e.includes("center"),o=e.includes("bottom");return"top-left"===e?n=Td.topLeft:"top-center"===e?n=Td.topCenter:"top-right"===e?n=Td.topRight:"bottom-left"===e?n=Td.bottomLeft:"bottom-center"===e?n=Td.bottomCenter:"bottom-right"===e&&(n=Td.bottomRight),{positionClassName:n,transform:`translateY(${o?-t:t}px) translateX(${r?"-50%":"0"})`}})(u,f);return Ge("div",{onMouseEnter:a,onMouseLeave:i,...n,className:Qe(Td.toastContainer,h,t),style:{transform:p,...n.style},children:Ge(_p,{className:Qe(d.className),toastRef:e=>{if(e&&"number"!=typeof r.height){const t=e.getBoundingClientRect().height;s(r.id,t)}},...d,style:{opacity:r.visible?1:0,...d.style},onClose:()=>{var e;Ip.dismiss(r.id),null==(e=d.onClose)||e.call(d)}},r.id)},`container-${r.id}`)}))})};const Bp=({size:e="large",disabled:t,variant:n="outlined",children:r,...o})=>{const a=bs(o);return Ge("div",{...ws(o),className:Qe(a.className,o.className,Od.root,Od[e],Od[n],t&&Od.disabled),children:Ge(mu.Provider,{value:{size:e,variant:n,disabled:t},children:r})})};Bp.classes=Od;const zp=({startValue:e,endValue:t,onStartDateChange:n,onEndDateChange:o,size:a="large",variant:i="underlined",withCalendar:l=!0,label:s,supportingText:u,disabled:c,...d})=>{const f=bs(d),p=r.useRef(null),h=r.useRef(null),m=r.useRef(null),[g,v]=r.useState(null),b=void 0!==e,y=void 0!==t,w=Ye({value:e,defaultValue:"",onChange:n,getInput:()=>{var e;return null==(e=p.current)?void 0:e.querySelectorAll(`input.${$d.classes.input}`)[0]}}),x=Ye({value:t,defaultValue:"",onChange:o,getInput:()=>{var e;return null==(e=p.current)?void 0:e.querySelectorAll(`input.${$d.classes.input}`)[1]}}),_={...d,size:a,label:void 0,supportingText:void 0},k="startDate"===g||"endDate"===g;return We("div",{ref:p,className:Qe({...ws(d)},f.className,d.className,Dd.root,Dd[a],l&&Dd.withCalendar,k&&Dd.openCalendar,c&&Dd.disabled),children:[s&&Ge(Vs,{className:Dd.label,variant:"label2",component:"label",children:s}),We("div",{className:Qe(d.className,Dd.inputContainer,"outlined"===i&&Dd.outlined),children:[Ge($d,{variant:i,calendarIconRef:m,icon:l&&Ge(Us,{color:"primary"}),value:b||k?w.value:void 0,onIconClick:()=>v((e=>Zd(e,"startDate"))),onChange:e=>{x.value&&!Qd(e.target.value,x.value)||w.onChange(e)},..._}),Ge("div",{className:Dd.separator}),Ge($d,{variant:i,calendarIconRef:h,icon:l&&Ge(Us,{color:"primary"}),value:y||k?x.value:void 0,onIconClick:()=>v((e=>Zd(e,"endDate"))),onChange:e=>{w.value&&!Qd(w.value,e.target.value)||x.onChange(e)},..._})]}),u&&Ge("div",{className:Qe(Dd.supportingText),children:Ge(Vs,{variant:"label2",component:"p",children:u})}),l&&Ge(au,{id:"calendar",children:Ge(yp,{...ys(d),onStartDateChange:e=>{w.setValue(Hd(e)),v("endDate")},onEndDateChange:e=>x.setValue(Hd(e)),onCalendarClickaway:e=>{wp(e,h.current)||wp(e,m.current)||v(null)},calendarType:g,open:k,onClose:()=>v(null),handleRef:p,mode:"range",disabled:c,startDate:w.value,endDate:x.value,className:Dd.calendar,tooltipArrowOffset:Yd(g,a),size:a})})]})};zp.classes=Dd,t.AddIcon=ks,t.ArrowForwardIcon=Ss,t.Autocomplete=su,t.Badge=cu,t.Breadcrumb=hu,t.BreadcrumbItem=fu,t.Button=vu,t.ButtonGroup=Bp,t.CALENDAR_MAX_YEAR=bp,t.CALENDAR_MIN_YEAR=vp,t.Calendar=yp,t.CalendarIcon=Us,t.Card=wu,t.CardBody=_u,t.CardHeader=Eu,t.CheckIcon=Ds,t.Checkbox=Ou,t.CheckboxGroup=Pu,t.CheckboxIcon=Ts,t.CheckboxOutlineBlankIcon=Os,t.ChevronDownIcon=Es,t.ChevronLeftIcon=js,t.ChevronRightIcon=Ms,t.ChevronUpIcon=Cs,t.CloseIcon=Ps,t.Collapse=Lu,t.CollapseHeader=Au,t.DateField=$d,t.DatePicker=xp,t.DateRangePicker=zp,t.Dropdown=ju,t.DropdownItem=Gs,t.DropdownMenu=ru,t.ErrorIcon=Ns,t.FolderIcon=As,t.IconButton=Bu,t.IconButtonGroup=$u,t.KeyboardReturnIcon=Is,t.LSD_NAMESPACE="lsd",t.LsdIcon=_s,t.MenuIcon=Ls,t.Modal=Fd,t.ModalBody=Bd,t.ModalFooter=zd,t.MoreIcon=Rs,t.NumberInput=Md,t.PickIcon=Bs,t.Quote=Hu,t.RadioButton=Gu,t.RadioButtonCheckedIcon=$s,t.RadioButtonGroup=Zu,t.RadioButtonIcon=zs,t.RemoveIcon=Hs,t.SearchIcon=Fs,t.THEME_BREAKPOINTS=fs,t.THEME_TYPOGRAPHY_PROPERTIES=ms,t.THEME_TYPOGRAPHY_VARIANTS=ps,t.THEME_VARIANT_PROPERTIES=["typography"],t.TabItem=Xu,t.Table=ac,t.TableBody=Ju,t.TableHeader=tc,t.TableItem=lc,t.TableRow=uc,t.Tabs=bc,t.Tag=wc,t.TextField=Sc,t.ThemeProvider=({theme:e,children:t,injectCssVars:n=!0})=>Ge(Rd,{children:Ge(Ld,{children:We(jd.Provider,{value:{theme:e},children:[Ge(Ad,{theme:e}),n&&Ge(a.Global,{styles:e.globalStyles}),Ge(a.ThemeProvider,{theme:e,children:t})]})})}),t.Toast=_p,t.ToastContext=Mp,t.ToastProvider=({providerToastOptions:e,children:t,...n})=>{const[o,a]=r.useState(new Map);return We(Mp.Provider,{value:(t,n)=>{const r={...e,...n},o=Ip("",{duration:null==r?void 0:r.duration});t&&a((e=>{const n=new Map(e);return n.set(o,{...t,...r}),n}))},children:[t,Ge(Fp,{toastsPropsMap:o,...n})]})},t.TooltipBase=gp,t.Typography=Vs,t.createTheme=jc,t.createThemeGlobalStyles=Tc,t.defaultThemes=Fc,t.useTheme=()=>r.useContext(jd).theme??Fc.light,t.useToast=function(){const e=r.useContext(Mp);if(!e)throw new Error("useToast must be used within a ToastProvider");return e},t.withTheme=e=>t=>e(t)},21204:(e,t,n)=>{"use strict";n.d(t,{Z:()=>p});var r=n(67294),o=n(87462),a=n(68356),i=n.n(a),l=n(16887);const s={"0b46e8e7":[()=>n.e(5387).then(n.bind(n,94644)),"@site/docs/publications.md",94644],"0d54ff0d":[()=>n.e(4248).then(n.bind(n,36733)),"@site/rlog/2022-04-12-introducing-nwaku.mdx?truncated=true",36733],"124805df":[()=>n.e(2206).then(n.t.bind(n,9935,19)),"~blog/blog/rlog-12b.json",9935],"12da0170":[()=>n.e(8056).then(n.bind(n,16486)),"@site/rlog/2021-06-04-presenting-js-waku.mdx",16486],"13a255f1":[()=>n.e(3415).then(n.bind(n,94866)),"@site/rlog/2022-05-17-noise.mdx?truncated=true",94866],"158719ed":[()=>n.e(4763).then(n.bind(n,53590)),"@site/rlog/2020-02-7-dns-based-discovery.mdx?truncated=true",53590],"15a93281":[()=>n.e(2594).then(n.bind(n,32788)),"@site/rlog/2020-02-7-dns-based-discovery.mdx",32788],17896441:[()=>Promise.all([n.e(532),n.e(219),n.e(7918)]).then(n.bind(n,59047)),"@theme/DocItem",59047],"18961ce6":[()=>n.e(7975).then(n.bind(n,63941)),"@site/rlog/2021-10-25-waku-v1-vs-waku-v2.mdx?truncated=true",63941],"18a94246":[()=>n.e(5543).then(n.bind(n,37553)),"@site/rlog/2024-08-23-state-separation.mdx",37553],"191d05a9":[()=>n.e(14).then(n.bind(n,89670)),"@site/rlog/2022-11-08-waku-for-all-decentralize-applications.mdx",89670],"1be78505":[()=>Promise.all([n.e(532),n.e(9514)]).then(n.bind(n,93687)),"@theme/DocPage",93687],"1e4c069f":[()=>n.e(6424).then(n.t.bind(n,85804,19)),"/home/jenkins/workspace/website/vac.dev/.docusaurus/docusaurus-plugin-content-blog/blog/plugin-route-context-module-100.json",85804],"1e7f5ce0":[()=>n.e(6297).then(n.bind(n,91652)),"@site/rlog/2022-05-17-noise.mdx",91652],"1f3523a7":[()=>n.e(8648).then(n.t.bind(n,79749,19)),"~docs/Docs/version-current-metadata-prop-751.json",79749],"2056d17e":[()=>n.e(819).then(n.bind(n,30780)),"@site/rlog/2019-12-03-fixing-whisper-with-waku.mdx",30780],"2858c6ff":[()=>n.e(7604).then(n.bind(n,87233)),"@site/rlog/2024-05-13-rln-v3.mdx?truncated=true",87233],"29ae586d":[()=>n.e(1158).then(n.bind(n,99327)),"@site/rlog/2021-03-03-rln-relay.mdx",99327],"2c2dd814":[()=>Promise.all([n.e(532),n.e(1755),n.e(5035)]).then(n.bind(n,58693)),"@site/docs/community.mdx",58693],"2d6b2291":[()=>n.e(5524).then(n.bind(n,37818)),"@site/rlog/2019-07-19-p2p-data-sync-for-mobile.mdx?truncated=true",37818],"2e8c87b8":[()=>n.e(2585).then(n.bind(n,93605)),"@site/rlog/2024-08-27-Zkvm.mdx?truncated=true",93605],"2ef0cd56":[()=>n.e(7972).then(n.t.bind(n,54910,19)),"~blog/blog/rlog-page-4-205.json",54910],"382fdf29":[()=>n.e(5077).then(n.bind(n,37497)),"@site/rlog/2023-11-07-rln-relay.mdx?truncated=true",37497],"384035e2":[()=>n.e(305).then(n.bind(n,66729)),"@site/rlog/2020-09-28-waku-v2-update.mdx",66729],"38dc9501":[()=>n.e(4441).then(n.bind(n,58510)),"@site/rlog/2023-04-24-device-pairing-in-js-waku-and-go-waku.mdx?truncated=true",58510],"39f27fb8":[()=>n.e(3171).then(n.bind(n,98488)),"@site/rlog/2023-09-27-gossipimprovements.mdx?truncated=true",98488],"3b467599":[()=>n.e(5601).then(n.bind(n,4956)),"@site/rlog/2023-08-28-Nescience.mdx",4956],"3ec022cb":[()=>n.e(3607).then(n.bind(n,41412)),"@site/rlog/2020-07-01-waku-v2-pitch.mdx",41412],"3f082616":[()=>n.e(2819).then(n.bind(n,97507)),"@site/rlog/2020-02-14-waku-update.mdx?truncated=true",97507],"3f64d9a3":[()=>n.e(2282).then(n.bind(n,81283)),"@site/rlog/2021-06-04-presenting-js-waku.mdx?truncated=true",81283],"3f781295":[()=>n.e(1599).then(n.bind(n,67691)),"@site/docs/vips.md",67691],"4a8210e4":[()=>n.e(959).then(n.bind(n,76926)),"@site/rlog/2019-10-04-remote-log.mdx?truncated=true",76926],"4ba7e5a3":[()=>n.e(9735).then(n.bind(n,10238)),"@site/docs/contribute.md",10238],"4f94ff0f":[()=>n.e(1569).then(n.bind(n,80724)),"@site/docs/deepresearch.md",80724],"500a151f":[()=>n.e(4545).then(n.bind(n,40536)),"@site/docs/terms.md",40536],"544f54cc":[()=>n.e(5705).then(n.bind(n,33879)),"@site/rlog/2023-04-03-waku-as-a-network.mdx?truncated=true",33879],"5a7c4f09":[()=>n.e(5417).then(n.bind(n,33861)),"@site/rlog/2019-08-02-vac-overview.mdx",33861],"67b45d3c":[()=>n.e(8161).then(n.bind(n,40100)),"@site/rlog/2023-04-24-device-pairing-in-js-waku-and-go-waku.mdx",40100],"6abf00de":[()=>n.e(5025).then(n.bind(n,95643)),"@site/rlog/2020-07-01-waku-v2-pitch.mdx?truncated=true",95643],"6f1f8c5f":[()=>n.e(7495).then(n.bind(n,2358)),"@site/rlog/2019-12-03-fixing-whisper-with-waku.mdx?truncated=true",2358],"6f6bcf93":[()=>n.e(242).then(n.bind(n,81470)),"@site/rlog/2020-09-28-waku-v2-update.mdx?truncated=true",81470],"6facda94":[()=>n.e(6125).then(n.bind(n,27500)),"@site/rlog/2022-11-08-waku-for-all-decentralize-applications.mdx?truncated=true",27500],"74c00f84":[()=>n.e(6676).then(n.bind(n,12008)),"@site/rlog/2020-11-10-waku-v2-ethereum-messaging.mdx?truncated=true",12008],"7af80316":[()=>n.e(8761).then(n.bind(n,60129)),"@site/rlog/2020-04-9-kademlia-to-discv5.mdx?truncated=true",60129],"7b019678":[()=>n.e(3854).then(n.bind(n,51694)),"@site/rlog/2021-12-03-ethics-surveillance-tech.mdx",51694],"7b0e1478":[()=>n.e(3877).then(n.bind(n,73475)),"@site/rlog/2024-07-19-bloomfilter.mdx",73475],"7d3f2fdb":[()=>n.e(7969).then(n.bind(n,98190)),"@site/rlog/2022-11-04-building-privacy-protecting-infrastructure.mdx?truncated=true",98190],"8161b354":[()=>n.e(8398).then(n.bind(n,2978)),"@site/docs/rfcprocess.md",2978],83575890:[()=>n.e(1525).then(n.bind(n,93938)),"@site/rlog/2020-04-27-feasibility-discv5.mdx?truncated=true",93938],"84dd0cf8":[()=>n.e(6149).then(n.bind(n,63282)),"@site/rlog/2023-08-28-Nescience.mdx?truncated=true",63282],"84f8336a":[()=>n.e(1742).then(n.bind(n,6411)),"@site/rlog/2020-04-16-wechat-replacement-need.mdx?truncated=true",6411],"8779ed83":[()=>n.e(7562).then(n.bind(n,87481)),"@site/rlog/2023-11-07-rln-relay.mdx",87481],"8c1443cc":[()=>n.e(5302).then(n.t.bind(n,47407,19)),"~blog/blog/rlog-page-3-95d.json",47407],"8c5da4da":[()=>n.e(1923).then(n.bind(n,65641)),"@site/docs/privacy-policy.md",65641],"8e79cc52":[()=>n.e(3274).then(n.bind(n,68350)),"@site/docs/media.md",68350],"91ce8bda":[()=>n.e(7467).then(n.bind(n,52051)),"@site/rlog/2023-04-03-waku-as-a-network.mdx",52051],"93541fc5":[()=>n.e(1773).then(n.bind(n,76944)),"@site/rlog/2024-09-26-Zkvm-testing.mdx",76944],"95b96bb9":[()=>n.e(3561).then(n.t.bind(n,24577,19)),"~blog/blog/blog-post-list-prop-blog.json",24577],96524732:[()=>n.e(2982).then(n.bind(n,23877)),"@site/rlog/2019-11-08-feasibility-semaphore-rate-limiting-zksnarks.mdx",23877],"99c49682":[()=>n.e(6807).then(n.t.bind(n,10319,19)),"~blog/blog/rlog-archive-cb2.json",10319],"99f69f8e":[()=>n.e(865).then(n.bind(n,96058)),"@site/rlog/2022-05-09-ambient-peer-discovery.mdx",96058],"9e34dc04":[()=>n.e(9924).then(n.bind(n,26810)),"@site/rlog/2022-04-12-introducing-nwaku.mdx",26810],"9e396004":[()=>n.e(5328).then(n.bind(n,12134)),"@site/rlog/2020-11-10-waku-v2-ethereum-messaging.mdx",12134],"9e4087bc":[()=>n.e(3608).then(n.bind(n,8387)),"@theme/BlogArchivePage",8387],"9fb2a6b1":[()=>n.e(8381).then(n.bind(n,84428)),"@site/rlog/2021-08-06-coscup-waku-ethereum.mdx?truncated=true",84428],a413eb42:[()=>Promise.all([n.e(532),n.e(1755),n.e(9834)]).then(n.bind(n,73673)),"@site/docs/join-us.mdx",73673],a6aa9e1f:[()=>Promise.all([n.e(532),n.e(219),n.e(5253),n.e(3089)]).then(n.bind(n,68854)),"@theme/BlogListPage",68854],a71c3513:[()=>n.e(7791).then(n.bind(n,18966)),"@site/rlog/2024-05-03-rln-light-verifiers.mdx",18966],ad3e391a:[()=>n.e(2276).then(n.bind(n,27221)),"@site/docs/vsus.md",27221],b0a36ee8:[()=>n.e(1618).then(n.bind(n,46643)),"@site/rlog/2021-10-25-waku-v1-vs-waku-v2.mdx",46643],b6f6cb50:[()=>n.e(1327).then(n.bind(n,72932)),"@site/rlog/2022-07-22-relay-anonymity.mdx",72932],b8fd8041:[()=>n.e(4588).then(n.bind(n,61357)),"@site/rlog/2024-08-27-Zkvm.mdx",61357],bd3d84fb:[()=>n.e(7746).then(n.bind(n,58968)),"@site/rlog/2023-09-27-gossipimprovements.mdx",58968],bfd2a918:[()=>n.e(689).then(n.t.bind(n,12342,19)),"/home/jenkins/workspace/website/vac.dev/.docusaurus/docusaurus-plugin-content-docs/Docs/plugin-route-context-module-100.json",12342],c2965f87:[()=>n.e(4991).then(n.bind(n,61356)),"@site/rlog/2021-03-03-rln-relay.mdx?truncated=true",61356],c377a04b:[()=>n.e(6971).then(n.bind(n,42206)),"@site/docs/index.md",42206],c7770090:[()=>n.e(2702).then(n.bind(n,4304)),"@site/rlog/2019-08-02-vac-overview.mdx?truncated=true",4304],c8894de3:[()=>n.e(1869).then(n.bind(n,87608)),"@site/rlog/2022-05-09-ambient-peer-discovery.mdx?truncated=true",87608],cbf8cf19:[()=>n.e(3231).then(n.bind(n,22584)),"@site/rlog/2024-08-23-state-separation.mdx?truncated=true",22584],ccc49370:[()=>Promise.all([n.e(532),n.e(219),n.e(5253),n.e(6103)]).then(n.bind(n,4297)),"@theme/BlogPostPage",4297],cde6c892:[()=>n.e(1969).then(n.t.bind(n,44041,19)),"~blog/blog/rlog-page-2-639.json",44041],d0c5fcac:[()=>n.e(9313).then(n.bind(n,37148)),"@site/rlog/2020-02-14-waku-update.mdx",37148],d758c4b4:[()=>n.e(1033).then(n.bind(n,62849)),"@site/rlog/2024-09-26-Zkvm-testing.mdx?truncated=true",62849],db32d859:[()=>n.e(6653).then(n.bind(n,79307)),"@site/docs/security.md",79307],db40b3a8:[()=>n.e(5089).then(n.bind(n,50170)),"@site/rlog/2024-05-13-rln-v3.mdx",50170],db970d56:[()=>n.e(1221).then(n.bind(n,55941)),"@site/rlog/2019-11-08-feasibility-semaphore-rate-limiting-zksnarks.mdx?truncated=true",55941],e22c7a04:[()=>n.e(1750).then(n.bind(n,98071)),"@site/rlog/2022-11-04-building-privacy-protecting-infrastructure.mdx",98071],e6b418ad:[()=>n.e(2614).then(n.bind(n,5923)),"@site/rlog/2020-04-16-wechat-replacement-need.mdx",5923],e954d700:[()=>n.e(7120).then(n.bind(n,85498)),"@site/rlog/2019-07-19-p2p-data-sync-for-mobile.mdx",85498],ec8fd1ee:[()=>n.e(7070).then(n.bind(n,91723)),"@site/rlog/2022-07-22-relay-anonymity.mdx?truncated=true",91723],f1787e6d:[()=>n.e(2223).then(n.bind(n,85790)),"@site/rlog/2019-10-04-remote-log.mdx",85790],f3c329e5:[()=>n.e(4633).then(n.bind(n,72897)),"@site/rlog/2021-08-06-coscup-waku-ethereum.mdx",72897],f40b13b8:[()=>n.e(7846).then(n.bind(n,16732)),"@site/rlog/2020-04-9-kademlia-to-discv5.mdx",16732],f643ab5d:[()=>n.e(4046).then(n.bind(n,86269)),"@site/rlog/2021-12-03-ethics-surveillance-tech.mdx?truncated=true",86269],f7ba2fd8:[()=>n.e(3228).then(n.bind(n,94433)),"@site/rlog/2020-04-27-feasibility-discv5.mdx",94433],f8d84f88:[()=>n.e(4733).then(n.bind(n,74826)),"@site/docs/principles.md",74826],fdd3b45a:[()=>n.e(8581).then(n.bind(n,67486)),"@site/rlog/2024-05-03-rln-light-verifiers.mdx?truncated=true",67486],feda84cd:[()=>n.e(1016).then(n.bind(n,45751)),"@site/rlog/2024-07-19-bloomfilter.mdx?truncated=true",45751]};function u(e){let{error:t,retry:n,pastDelay:o}=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"))):o?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 c=n(66916),d=n(66041);function f(e,t){if("*"===e)return i()({loading:u,loader:()=>Promise.all([n.e(532),n.e(9481)]).then(n.bind(n,89481)),modules:["@theme/NotFound"],webpack:()=>[89481],render(e,t){const n=e.default;return r.createElement(d.z,{value:{plugin:{name:"native",id:"default"}}},r.createElement(n,t))}});const a=l[`${e}-${t}`],f={},p=[],h=[],m=(0,c.Z)(a);return Object.entries(m).forEach((e=>{let[t,n]=e;const r=s[n];r&&(f[t]=r[0],p.push(r[1]),h.push(r[2]))})),i().Map({loading:u,loader:f,modules:p,webpack:()=>h,render(t,n){const i=JSON.parse(JSON.stringify(a));Object.entries(t).forEach((t=>{let[n,r]=t;const o=r.default;if(!o)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 o&&"function"!=typeof o||Object.keys(r).filter((e=>"default"!==e)).forEach((e=>{o[e]=r[e]}));let a=i;const l=n.split(".");l.slice(0,-1).forEach((e=>{a=a[e]})),a[l[l.length-1]]=o}));const l=i.__comp;delete i.__comp;const s=i.__context;return delete i.__context,r.createElement(d.z,{value:s},r.createElement(l,(0,o.Z)({},i,n)))}})}const p=[{path:"/rlog",component:f("/rlog","20f"),exact:!0},{path:"/rlog/archive",component:f("/rlog/archive","242"),exact:!0},{path:"/rlog/building-privacy-protecting-infrastructure",component:f("/rlog/building-privacy-protecting-infrastructure","b52"),exact:!0},{path:"/rlog/device-pairing-in-js-waku-and-go-waku",component:f("/rlog/device-pairing-in-js-waku-and-go-waku","6e6"),exact:!0},{path:"/rlog/dns-based-discovery",component:f("/rlog/dns-based-discovery","f9b"),exact:!0},{path:"/rlog/ethics-surveillance-tech",component:f("/rlog/ethics-surveillance-tech","872"),exact:!0},{path:"/rlog/feasibility-discv5",component:f("/rlog/feasibility-discv5","2c3"),exact:!0},{path:"/rlog/feasibility-semaphore-rate-limiting-zksnarks",component:f("/rlog/feasibility-semaphore-rate-limiting-zksnarks","cff"),exact:!0},{path:"/rlog/fixing-whisper-with-waku",component:f("/rlog/fixing-whisper-with-waku","4ec"),exact:!0},{path:"/rlog/future-of-waku-network",component:f("/rlog/future-of-waku-network","100"),exact:!0},{path:"/rlog/GossipSub Improvements",component:f("/rlog/GossipSub Improvements","4fc"),exact:!0},{path:"/rlog/introducing-nwaku",component:f("/rlog/introducing-nwaku","9eb"),exact:!0},{path:"/rlog/kademlia-to-discv5",component:f("/rlog/kademlia-to-discv5","2d3"),exact:!0},{path:"/rlog/membership-with-bloom-filters-and-cuckoo-filters",component:f("/rlog/membership-with-bloom-filters-and-cuckoo-filters","b1b"),exact:!0},{path:"/rlog/Nescience-A-zkVM-leveraging-hiding-properties",component:f("/rlog/Nescience-A-zkVM-leveraging-hiding-properties","605"),exact:!0},{path:"/rlog/Nescience-state-separation-architecture",component:f("/rlog/Nescience-state-separation-architecture","72d"),exact:!0},{path:"/rlog/p2p-data-sync-for-mobile",component:f("/rlog/p2p-data-sync-for-mobile","8e8"),exact:!0},{path:"/rlog/page/2",component:f("/rlog/page/2","de8"),exact:!0},{path:"/rlog/page/3",component:f("/rlog/page/3","a57"),exact:!0},{path:"/rlog/page/4",component:f("/rlog/page/4","917"),exact:!0},{path:"/rlog/presenting-js-waku",component:f("/rlog/presenting-js-waku","380"),exact:!0},{path:"/rlog/remote-log",component:f("/rlog/remote-log","5c3"),exact:!0},{path:"/rlog/rln-anonymous-dos-prevention",component:f("/rlog/rln-anonymous-dos-prevention","535"),exact:!0},{path:"/rlog/rln-light-verifiers",component:f("/rlog/rln-light-verifiers","657"),exact:!0},{path:"/rlog/rln-relay",component:f("/rlog/rln-relay","2b7"),exact:!0},{path:"/rlog/rln-v3",component:f("/rlog/rln-v3","f91"),exact:!0},{path:"/rlog/vac-overview",component:f("/rlog/vac-overview","13b"),exact:!0},{path:"/rlog/waku-for-all",component:f("/rlog/waku-for-all","8f7"),exact:!0},{path:"/rlog/waku-update",component:f("/rlog/waku-update","7bc"),exact:!0},{path:"/rlog/waku-v1-v2-bandwidth-comparison",component:f("/rlog/waku-v1-v2-bandwidth-comparison","a00"),exact:!0},{path:"/rlog/waku-v2-ethereum-coscup",component:f("/rlog/waku-v2-ethereum-coscup","f86"),exact:!0},{path:"/rlog/waku-v2-ethereum-messaging",component:f("/rlog/waku-v2-ethereum-messaging","d5b"),exact:!0},{path:"/rlog/waku-v2-plan",component:f("/rlog/waku-v2-plan","943"),exact:!0},{path:"/rlog/waku-v2-update",component:f("/rlog/waku-v2-update","73e"),exact:!0},{path:"/rlog/wakuv2-apd",component:f("/rlog/wakuv2-apd","f04"),exact:!0},{path:"/rlog/wakuv2-noise",component:f("/rlog/wakuv2-noise","6d7"),exact:!0},{path:"/rlog/wakuv2-relay-anon",component:f("/rlog/wakuv2-relay-anon","dc8"),exact:!0},{path:"/rlog/wechat-replacement-need",component:f("/rlog/wechat-replacement-need","4e9"),exact:!0},{path:"/rlog/zkVM-explorations",component:f("/rlog/zkVM-explorations","337"),exact:!0},{path:"/rlog/zkVM-testing",component:f("/rlog/zkVM-testing","dc5"),exact:!0},{path:"/",component:f("/","4d6"),routes:[{path:"/",component:f("/","d22"),exact:!0,sidebar:"main"},{path:"/community",component:f("/community","051"),exact:!0},{path:"/contribute",component:f("/contribute","00f"),exact:!0,sidebar:"main"},{path:"/deepresearch",component:f("/deepresearch","40e"),exact:!0,sidebar:"main"},{path:"/join-us",component:f("/join-us","63f"),exact:!0},{path:"/media",component:f("/media","895"),exact:!0},{path:"/principles",component:f("/principles","ef3"),exact:!0,sidebar:"main"},{path:"/privacy-policy",component:f("/privacy-policy","4cd"),exact:!0},{path:"/publications",component:f("/publications","be1"),exact:!0},{path:"/rfcprocess",component:f("/rfcprocess","d12"),exact:!0},{path:"/security",component:f("/security","2fb"),exact:!0},{path:"/terms",component:f("/terms","37d"),exact:!0},{path:"/vips",component:f("/vips","fef"),exact:!0,sidebar:"main"},{path:"/vsus",component:f("/vsus","e2a"),exact:!0,sidebar:"main"}]},{path:"*",component:f("*")}]},79578:(e,t,n)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.createPromise=t.ResultType=void 0;const r=n(70655),o=n(78007),a=n(84647),i=n(32438),l=n(58263),s=r.__importStar(n(96059)),u=e=>{let{versionUrl:t,searchContextByPaths:n}=e,r=window.location.pathname;if(r=r.endsWith("/")?r:r+"/",!Array.isArray(n)||!r.startsWith(t))return"";const o=r.substring(t.length);return n.find((e=>o===e||o.startsWith(`${e}/`)))??""};class c{constructor(e){this.config=e,this.loading=!1,this.source=null,this.init=async()=>{this.loading=!0;const{wrappedIndexes:e,zhDictionary:t}=await(async e=>{const{wrappedIndexes:t,zhDictionary:n}=await(0,o.fetchIndexes)(e.versionUrl,e.searchContext);return{wrappedIndexes:t,zhDictionary:n}})({versionUrl:this.baseUrl,searchContext:u({versionUrl:this.baseUrl,searchContextByPaths:this.searchContextByPaths})});this.source=(0,l.SearchSourceFactory)(e,t,this.config.resultsLimit)},this.query=async e=>{if(!this.source)throw new Error("Not initialized");const{promise:n,callback:r}=(0,t.createPromise)();return this.source&&this.source(e,r),{results:(await n).map((e=>this.formatResult(e)))}},this.formatResult=e=>({...e,type:this.resultTypeToString(e.type),page:e.page?this.formatDocument(e.page):null,document:e.document?this.formatDocument(e.document):null,highlighted:(0,i.highlightStemmed)(e.document.t,(0,a.getStemmedPositions)(e.metadata,"t"),e.tokens)}),this.resultTypeToString=e=>({0:d.Title,1:d.Heading,2:d.Paragraph}[e]),this.formatDocument=e=>({id:e.i,title:e.t,url:e.u,hash:e.h,parentId:e.p,breadcrumb:e.b,sectionTitle:e.s}),this.baseUrl=e.preferredVersionPath,this.searchContextByPaths=e.searchContextByPaths??""}}var d;!function(e){e.Title="title",e.Heading="heading",e.Paragraph="paragraph"}(d=t.ResultType||(t.ResultType={}));t.createPromise=()=>{let e,t;const n=new Promise(((n,r)=>{e=n,t=r}));return{reject:t,resolve:e,promise:n,callback:(n,r)=>{r?t(r):e(n)}}};(async()=>{if("undefined"==typeof window)return;const e=window;e.getProxiedGeneratedData=()=>s,e.createSearchInstance=async e=>new c(e)})()},22197:(e,t,n)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.IconRemove=t.IconAdd=t.IconDownload=t.IconAvatar=t.IconX=t.IconTelegramWhite=t.IconDiscordWhite=t.IconExternalLink=t.IconFullscreenExit=t.IconFullscreen=t.IconEdit=t.IconClose=t.IconHistory=t.IconCopy=t.IconGScholar=t.IconDropdown=t.IconSearch=t.IconFolderFilled=t.IconDot=t.IconLinkedin=t.IconDiscourse=t.IconTelegram=t.IconTwitter=t.IconStatus=t.IconDiscord=t.IconGithub=t.IconFolder=t.IconArrowLeft=t.IconArrowRight=t.IconArrowLeftCircle=t.IconArrowRightCircle=t.Icon=void 0;const r=n(70655),o=n(86010),a=r.__importDefault(n(67294)),i=r.__importDefault(n(27861)),l=r.__importDefault(n(19044)),s=r.__importDefault(n(80255)),u=r.__importDefault(n(67146)),c=r.__importDefault(n(68425)),d=r.__importDefault(n(88121)),f=r.__importDefault(n(62082)),p=r.__importDefault(n(80469)),h=r.__importDefault(n(94793)),m=r.__importDefault(n(14607)),g=r.__importDefault(n(50437)),v=r.__importDefault(n(23179)),b=r.__importDefault(n(19818)),y=r.__importDefault(n(38981)),w=r.__importDefault(n(28487)),x=r.__importDefault(n(94177)),_=r.__importDefault(n(58611)),k=r.__importDefault(n(13042)),E=r.__importDefault(n(96367)),S=r.__importDefault(n(6907)),C=r.__importDefault(n(59570)),T=r.__importDefault(n(26890)),O=r.__importDefault(n(74297)),D=r.__importDefault(n(33336)),P=r.__importDefault(n(78951)),N=r.__importDefault(n(84629)),A=r.__importDefault(n(23816)),I=r.__importDefault(n(35245)),L=r.__importDefault(n(68902)),R=r.__importDefault(n(86089)),j=r.__importDefault(n(92358));t.Icon=e=>{const{children:t,size:n="m"}=e;return a.default.createElement("div",{className:(0,o.clsx)(i.default.icon,i.default[n],e.stroke&&i.default.stroke,e.fill&&i.default.fill,e.className&&e.className)},t)};t.IconArrowRightCircle=e=>a.default.createElement(t.Icon,{...e},a.default.createElement(c.default,null));t.IconArrowLeftCircle=e=>a.default.createElement(t.Icon,null,a.default.createElement(s.default,null));t.IconArrowRight=e=>a.default.createElement(t.Icon,{...e},a.default.createElement(d.default,null));t.IconArrowLeft=e=>a.default.createElement(t.Icon,null,a.default.createElement(u.default,null));t.IconFolder=e=>a.default.createElement(t.Icon,{...e},a.default.createElement(k.default,null));t.IconGithub=e=>a.default.createElement(t.Icon,{...e},a.default.createElement(C.default,null));t.IconDiscord=e=>a.default.createElement(t.Icon,{...e},a.default.createElement(g.default,null));t.IconStatus=e=>a.default.createElement(t.Icon,{...e},a.default.createElement(A.default,null));t.IconTwitter=e=>a.default.createElement(t.Icon,{...e},a.default.createElement(R.default,null));t.IconTelegram=e=>a.default.createElement(t.Icon,{...e},a.default.createElement(L.default,null));t.IconDiscourse=e=>a.default.createElement(t.Icon,{...e},a.default.createElement(v.default,null));t.IconLinkedin=e=>a.default.createElement(t.Icon,{...e},a.default.createElement(D.default,null));t.IconDot=e=>a.default.createElement(t.Icon,{...e},a.default.createElement(b.default,null));t.IconFolderFilled=e=>a.default.createElement(t.Icon,{...e},a.default.createElement(k.default,null));t.IconSearch=e=>a.default.createElement(t.Icon,{...e},a.default.createElement(N.default,null));t.IconDropdown=e=>a.default.createElement(t.Icon,{...e},a.default.createElement(w.default,null));t.IconGScholar=e=>a.default.createElement(t.Icon,{...e},a.default.createElement(T.default,null));t.IconCopy=e=>a.default.createElement(t.Icon,{...e},a.default.createElement(h.default,null));t.IconHistory=e=>a.default.createElement(t.Icon,{...e},a.default.createElement(O.default,null));t.IconClose=e=>a.default.createElement(t.Icon,{...e},a.default.createElement(p.default,null));t.IconEdit=e=>a.default.createElement(t.Icon,{...e},a.default.createElement(x.default,null));t.IconFullscreen=e=>a.default.createElement(t.Icon,{...e},a.default.createElement(S.default,null));t.IconFullscreenExit=e=>a.default.createElement(t.Icon,{...e},a.default.createElement(E.default,null));t.IconExternalLink=e=>a.default.createElement(t.Icon,{...e},a.default.createElement(_.default,null));t.IconDiscordWhite=e=>a.default.createElement(t.Icon,{...e},a.default.createElement(m.default,null));t.IconTelegramWhite=e=>a.default.createElement(t.Icon,{...e},a.default.createElement(I.default,null));t.IconX=e=>a.default.createElement(t.Icon,{...e},a.default.createElement(j.default,null));t.IconAvatar=e=>a.default.createElement(t.Icon,{...e},a.default.createElement(f.default,null));t.IconDownload=e=>a.default.createElement(t.Icon,{...e},a.default.createElement(y.default,null));t.IconAdd=e=>a.default.createElement(t.Icon,{...e,stroke:!0},a.default.createElement(l.default,null));t.IconRemove=e=>a.default.createElement(t.Icon,{...e,stroke:!0},a.default.createElement(P.default,null))},6980:(e,t,n)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0});n(70655).__exportStar(n(22197),t)},81575:(e,t,n)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.Modal=void 0;const r=n(70655),o=r.__importDefault(n(86010)),a=r.__importDefault(n(67294)),i=n(89164),l=n(67713),s=n(54920);n(22473);t.Modal=e=>{let{open:t=!1,onClose:n,keepMounted:r=!1,className:u,children:c,...d}=e;const f=(0,l.useHydrated)(),p=()=>{n&&n()};return(0,i.useKeyPressEvent)((e=>"Escape"===e.code),(e=>{p()})),f&&(t||r)?a.default.createElement(s.Portal,{containerId:"lsd-presentation",id:d.id},a.default.createElement("div",{className:(0,o.default)(u,"l-modal",t&&"l-modal--open"),...d},a.default.createElement("div",{className:"l-modal__container"},a.default.createElement("div",{className:"l-modal__content"},c),a.default.createElement("div",{className:"l-modal__backdrop",onClick:p})))):a.default.createElement(a.default.Fragment,null)}},54920:(e,t,n)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.Portal=void 0;const r=n(70655).__importDefault(n(67294)),o=n(73935),a=n(72777);t.Portal=e=>{let{children:t,containerId:n,id:i}=e;if("undefined"==typeof window)return r.default.createElement(r.default.Fragment,null);const l=(0,a.usePortal)({parentId:n});return(0,o.createPortal)(t,l,i)}},72777:(e,t,n)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.usePortal=void 0;const r=n(67294),o=n(32833);t.usePortal=e=>{let{parentId:t}=e;const n=(0,r.useRef)();return n.current||(n.current=document.createElement("div")),(0,r.useEffect)((()=>{var e;if(n.current)return null==(e=document.getElementById(t))||e.appendChild(n.current),()=>{const e=n.current;e&&(0,o.settleSync)((()=>{var n;return null==(n=document.getElementById(t))?void 0:n.removeChild(e)}))}}),[t,n.current]),n.current}},91866:(e,t,n)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.LightBoxWrapper=t.useLightBox=t.LightBoxContext=t.LightBoxProvider=void 0;const r=n(70655),o=n(31665),a=r.__importDefault(n(56306)),i=r.__importDefault(n(86010)),l=r.__importStar(n(67294)),s=r.__importStar(n(33199)),u=n(89164),c=n(22197),d=n(54920),f=n(67713),p=n(52606),h=r.__importDefault(n(10153));t.LightBoxProvider=e=>{let{children:n}=e;const r=(0,f.useHydrated)(),s=(0,u.useWindowScroll)(),[m,g]=(0,l.useState)(null),[v,b]=(0,l.useState)({opacity:"0.5"}),y=(0,p.useIsMobile)(),w=(0,l.useMemo)((()=>({opacity:1,transform:"scale(1) translate(0px, 0px)",transition:"0.3s"})),[m]),x=e=>{g(e);const t=document.body.clientWidth,n=window.innerHeight,r=window.innerWidth>768?.9375*t:t-32,o=n-128,a=e.getBoundingClientRect(),i=Math.min(o/a.height,r/a.width),l=[a.left+a.width/2,a.top+a.height/2],s=[t/2,n/2].map(((e,t)=>(e-l[t])/i));b({zIndex:202,transform:`scale(${i}) translate(${s[0]}px, ${s[1]}px)`,position:"relative"})},_=()=>{g(null)};return(0,l.useEffect)((()=>{m&&window.innerWidth>768&&_()}),[s]),(0,l.useEffect)((()=>{if(y&&m){document.querySelector("html").style.overflow="hidden"}else{document.querySelector("html").style.overflow="initial"}}),[y,m]),l.default.createElement(t.LightBoxContext.Provider,{value:{active:m,style:w,activeStyle:v,display:x,close:_,toggle:e=>{const t=m;_(),t!==e&&x(e)}}},n,r&&l.default.createElement(d.Portal,{containerId:"lsd-presentation"},l.default.createElement(l.default.Fragment,null,l.default.createElement("div",{className:(0,i.default)(h.default.backdrop,m&&h.default.visible)}),l.default.createElement("div",{className:(0,i.default)(h.default.navWrapper,m&&h.default.visible)},l.default.createElement("nav",{className:(0,i.default)(h.default.nav,"navbar",m&&h.default.visible)},l.default.createElement(a.default,null),l.default.createElement(o.IconButton,{size:"medium",onClick:_},l.default.createElement(c.IconFullscreenExit,null)))))))},t.LightBoxContext=l.default.createContext({style:{},activeStyle:{},active:null,close:null,toggle:null,display:null});t.useLightBox=()=>{const e=(0,l.useContext)(t.LightBoxContext);return{getStyle:t=>({...e.style,...t===e.active?e.activeStyle:{}}),style:e.style,activeStyle:e.activeStyle,active:e.active,isActive:!!e.active,close:e.close,toggle:e.toggle,display:e.display,isActiveElement:t=>e.active===t}};t.LightBoxWrapper=e=>{let{children:n}=e;const r=(0,l.useRef)(null),a=(0,l.useRef)(null),{getStyle:u,display:d,isActiveElement:f}=(0,t.useLightBox)(),m=(0,p.useIsMobile)(),g=(0,l.useCallback)((e=>{let{x:t,y:n,scale:r}=e;const{current:o}=a;if(o){const e=(0,s.make3dTransformValue)({x:t,y:n,scale:r});o.style.setProperty("transform",e)}}),[]),v=m&&r.current&&f(r.current)?l.default.createElement(s.default,{onUpdate:g,doubleTapZoomOutOnMaxScale:!0,maxZoom:3},l.default.createElement("div",{ref:a},n)):l.default.createElement(l.default.Fragment,null,n,l.default.createElement(o.IconButton,{className:h.default.fullscreenButton,size:"medium",onClick:()=>r.current&&d(r.current)},l.default.createElement(c.IconFullscreen,null)));return l.default.createElement(l.default.Fragment,null,l.default.createElement("div",{className:(0,i.default)(h.default.wrapper,f(r.current)&&h.default.active),ref:r,style:r.current?u(r.current):{}},v))}},30091:(e,t,n)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.ThemeProvider=void 0;const r=n(70655),o=n(31665),a=n(70917),i=r.__importDefault(n(67294)),l=n(51509);t.ThemeProvider=e=>{let{children:t}=e;const n=(0,l.useTheme)();return i.default.createElement(o.ThemeProvider,{theme:n.current,injectCssVars:!1},i.default.createElement(a.Global,{styles:n.darkCssVars}),i.default.createElement(a.Global,{styles:n.lightCssVars}),t)}},84138:(e,t,n)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0});n(70655).__exportStar(n(30091),t)},32833:(e,t)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.settleSync=t.settle=void 0;t.settle=async e=>{try{return["function"==typeof e?await e():await e,void 0]}catch(t){return[void 0,t]}};t.settleSync=e=>{try{return[e(),void 0]}catch(t){return[void 0,t]}}},68347:(e,t)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.ensureTrailingSlash=t.ensureTrailingString=void 0;t.ensureTrailingString=(e,t)=>e.endsWith(t)?e:e+t;t.ensureTrailingSlash=e=>(0,t.ensureTrailingString)(e,"/")},51509:(e,t,n)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.useTheme=void 0;const r=n(31665),o=n(93945),a=n(70917),i=n(67294),l=n(38840),s=(e,t)=>(0,i.useMemo)((()=>a.css` + [data-theme=${t}] { + ${e.cssVars} + } + `),[e]);t.useTheme=()=>{const e=(0,o.useColorMode)(),{typography:t}=(0,l.useThemeOptions)(),n=(null==t?void 0:t.genericFontFamily)??"sans-serif",a=r.defaultThemes,u=(0,i.useMemo)((()=>{const e={breakpoints:{},palette:{},typography:{},typographyGlobal:{genericFontFamily:n},spacing:[]};return{light:(0,r.createTheme)(e,a.light),dark:(0,r.createTheme)(e,a.dark)}}),[a,n]);return{dark:u.dark,light:u.light,current:u[e.colorMode],colorMode:e.colorMode,lightCssVars:s(u.light,"light"),darkCssVars:s(u.dark,"dark")}}},17648:(e,t,n)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.useEventListener=void 0;const r=n(67294);t.useEventListener=(e,t,n,o,a)=>{const i=(0,r.useMemo)((()=>"string"==typeof e?e:e()),[]),l=(0,r.useMemo)((()=>"function"==typeof t?t():t),[t]);(0,r.useEffect)((()=>{if(null!=l&&l.addEventListener&&null!=l&&l.removeEventListener)return l.addEventListener(i,n,o),()=>{l.removeEventListener(i,n,o)}}),[i,l])}},67713:(e,t,n)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.useHydrated=void 0;const r=n(67294);t.useHydrated=()=>{const[e,t]=(0,r.useState)(!1);return(0,r.useEffect)((()=>{t(!0)}),[]),e}},52606:(e,t,n)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.useIsMobile=void 0;const r=n(89164);t.useIsMobile=()=>(0,r.useMedia)("(max-width: 1199px)")},59213:(e,t,n)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.usePersistedHistory=void 0;const r=n(89164);t.usePersistedHistory=(e,t)=>{const n=(null==t?void 0:t.unique)??!1,o=(null==t?void 0:t.equals)??((e,t)=>e===t),a=(null==t?void 0:t.maxItems)??null,[i,l]=(0,r.useLocalStorage)("logos-docusaurus-theme-"+e,[]),s=e=>{l((i??[]).filter(((t,n)=>!e(t,n))))};return{add:e=>{const t=i??[],r=[e,...n?t.filter((t=>!o(t,e))):t];l(a?r.slice(0,a):r)},clear:()=>{l([])},remove:s,removeByIndex:e=>{s(((t,n)=>n===e))},list:i}}},38840:(e,t,n)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.useDocThemeOptions=t.useThemeOptions=void 0;const r=n(70655),o=n(4452),a=r.__importDefault(n(6832));t.useThemeOptions=()=>{const{siteConfig:{customFields:e={}}}=(0,a.default)();return e["logos-docusaurus-theme"]??{}};t.useDocThemeOptions=()=>{var e;const n=(0,o.useActivePlugin)(),r=(0,t.useThemeOptions)();return n?(null==r||null==(e=r.docs)?void 0:e[null==n?void 0:n.pluginId])??{}:{}}},21457:(e,t,n)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.useWindowEventListener=void 0;const r=n(17648);t.useWindowEventListener=function(e,t,n,o){void 0===o&&(o=[]),(0,r.useEventListener)(e,(()=>"undefined"!=typeof window&&window),t,n,o)}},61818:(e,t,n)=>{"use strict";const r=n(70655),o=n(31665),a=n(11614),i=r.__importDefault(n(5730)),l=r.__importDefault(n(5574)),s=r.__importDefault(n(60388)),u=r.__importDefault(n(86010)),c=r.__importDefault(n(67294)),d=r.__importDefault(n(8633));t.Z=c.default.memo((function(e){let{className:t,buttonClassName:n,value:r,onChange:f}=e;const p=(0,i.default)(),h=(0,a.translate)({message:"Switch between dark and light mode (currently {mode})",id:"theme.colorToggle.ariaLabel",description:"The ARIA label for the navbar color mode toggle"},{mode:"dark"===r?(0,a.translate)({message:"dark mode",id:"theme.colorToggle.ariaLabel.mode.dark",description:"The name for the dark color mode"}):(0,a.translate)({message:"light mode",id:"theme.colorToggle.ariaLabel.mode.light",description:"The name for the light color mode"})});return c.default.createElement(o.IconButton,{className:(0,u.default)("clean-btn",d.default.toggle,t,!p&&d.default.toggleButtonDisabled,n),type:"button",onClick:()=>f("dark"===r?"light":"dark"),disabled:!p,title:h,"aria-label":h,"aria-live":"polite"},c.default.createElement(s.default,{className:(0,u.default)(d.default.toggleIcon,d.default.lightToggleIcon)}),c.default.createElement(l.default,{className:(0,u.default)(d.default.toggleIcon,d.default.darkToggleIcon)}))}))},72726:(e,t,n)=>{"use strict";const r=n(70655),o=n(31665),a=r.__importDefault(n(86010)),i=r.__importDefault(n(67294)),l=r.__importDefault(n(79762));t.Z=function(e){let{style:t,links:n,logo:r,copyright:s}=e;const[u,c]=(e=>{const t=[],n=[];for(const r of e)"title"in r&&"string"==typeof r.title&&r.title.startsWith("shared:")?n.push({...r,title:r.title.slice(7)}):t.push(r);return[t,n]})(n.props.links);return i.default.createElement("footer",{className:(0,a.default)("footer",{"footer--dark":"dark"===t})},i.default.createElement("div",{className:(0,a.default)("container","container-fluid",l.default.firstRow)},(r||s)&&i.default.createElement(i.default.Fragment,null,i.default.createElement("div",{className:"footer__bottom text--center"},r&&i.default.createElement("div",{className:"margin-bottom--sm"},r),s)),i.default.cloneElement(n,{links:u})),i.default.createElement("div",{className:l.default.secondRow},i.default.createElement("div",{className:"footer__bottom text--center"},"Logos Collective"),i.default.cloneElement(n,{links:c})),i.default.createElement(o.Button,{className:l.default.backToTop,size:"small",onClick:()=>{window.scrollTo({top:0,behavior:"smooth"})}},"Back to top \u2191"))}},10211:(e,t,n)=>{"use strict";const r=n(70655).__importDefault(n(67294)),o=n(93945),a=n(13616),i=(0,o.composeProviders)([a.AnnouncementBarProvider,a.ScrollControllerProvider,a.DocsPreferredVersionContextProvider,a.PluginHtmlClassNameProvider,a.NavbarProvider]);t.Z=function(e){let{children:t}=e;return r.default.createElement(i,null,t)}},60969:(e,t,n)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0});const r=n(70655),o=r.__importDefault(n(67294)),a=r.__importDefault(n(88746)),i=r.__importDefault(n(51402)),l=r.__importDefault(n(6832)),s=n(93945),u=r.__importDefault(n(47002));function c(e){let{logo:t,alt:n,imageClassName:r}=e;const a={light:(0,i.default)(t.src),dark:(0,i.default)(t.srcDark||t.src)},l=o.default.createElement(u.default,{className:t.className,sources:a,height:t.height,width:t.width,alt:n,style:t.style});return r?o.default.createElement("div",{className:r},l):l}t.default=function(e){const{siteConfig:{title:t}}=(0,l.default)(),{navbar:{title:n,logo:r}}=(0,s.useThemeConfig)(),{imageClassName:u,titleClassName:d,...f}=e,p=(0,i.default)((null==r?void 0:r.href)||"/"),h=n?"":t,m=(null==r?void 0:r.alt)??h;return o.default.createElement(a.default,{to:p,...f,...(null==r?void 0:r.target)&&{target:r.target}},r&&o.default.createElement(c,{logo:r,alt:m,imageClassName:u}),null!=n&&o.default.createElement("b",{className:d},n))}},27882:(e,t,n)=>{"use strict";const r=n(70655),o=n(31665),a=n(93945),i=n(13616),l=r.__importDefault(n(17662)),s=r.__importDefault(n(56306)),u=r.__importDefault(n(60543)),c=r.__importDefault(n(93496)),d=r.__importDefault(n(20130)),f=r.__importDefault(n(86010)),p=r.__importDefault(n(67294)),h=n(67713),m=r.__importDefault(n(90826));function g(e){let{items:t}=e;return p.default.createElement(p.default.Fragment,null,t.map(((e,t)=>p.default.createElement(a.ErrorCauseBoundary,{key:t,onError:t=>new Error(`A theme navbar item failed to render.\nPlease double-check the following navbar item (themeConfig.navbar.items) of your Docusaurus config:\n${JSON.stringify(e,null,2)}`,{cause:t})},p.default.createElement(c.default,{...e})))))}t.Z=function(){const e=(0,h.useHydrated)(),t=(0,i.useNavbarMobileSidebar)(),n=(0,a.useThemeConfig)().navbar.items,[r,c]=(0,i.splitNavbarItems)(n.filter((e=>!["search"].includes(e.type??"")))),v=n.find((e=>"search"===e.type));return p.default.createElement("div",{className:"navbar__inner"},p.default.createElement("div",{className:"navbar__left"},p.default.createElement(s.default,null)),p.default.createElement("div",{className:"navbar__left-items"},p.default.createElement(g,{items:r})),p.default.createElement("div",{className:"navbar__right-items"},p.default.createElement(g,{items:c}),p.default.createElement(o.IconButtonGroup,{className:m.default.iconButtonGroup,size:"medium"},p.default.createElement(l.default,{key:"color-toggle",className:(0,f.default)(m.default.colorModeToggle,"navbar__color-mode-toggle")}),e&&p.default.createElement(p.default.Fragment,{key:"search"},v&&p.default.createElement(d.default,null)),p.default.createElement(p.default.Fragment,{key:"mobile-sidebar-toggle"},!t.disabled&&p.default.createElement(u.default,null)))))}},26558:(e,t,n)=>{"use strict";const r=n(70655),o=r.__importDefault(n(67294)),a=r.__importDefault(n(86010)),i=n(93945),l=n(13616),s=n(11614),u=r.__importDefault(n(44488)),c=r.__importDefault(n(97087));function d(e){return o.default.createElement("div",{role:"presentation",...e,className:(0,a.default)("navbar-sidebar__backdrop",e.className)})}t.Z=function(e){let{children:t}=e;const{navbar:{hideOnScroll:n,style:r}}=(0,i.useThemeConfig)(),f=(0,l.useNavbarMobileSidebar)(),{navbarRef:p,isNavbarVisible:h}=(0,l.useHideableNavbar)(n);return o.default.createElement("nav",{ref:p,"aria-label":(0,s.translate)({id:"theme.NavBar.navAriaLabel",message:"Main",description:"The ARIA label for the main navigation"}),className:(0,a.default)("navbar","navbar--fixed-top",n&&[c.default.navbarHideable,!h&&c.default.navbarHidden],{"navbar--dark":"dark"===r,"navbar--primary":"primary"===r,"navbar-sidebar--show":f.shown})},t,o.default.createElement(d,{onClick:f.toggle}),o.default.createElement(u.default,null))}},56306:(e,t,n)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0});const r=n(70655),o=r.__importDefault(n(67294)),a=r.__importDefault(n(60969));t.default=function(){return o.default.createElement(a.default,{className:"navbar__brand",imageClassName:"navbar__logo",titleClassName:"navbar__title text--truncate"})}},20080:(e,t,n)=>{"use strict";const r=n(70655),o=r.__importDefault(n(67294)),a=n(13616),i=n(11614),l=r.__importDefault(n(17662)),s=r.__importDefault(n(56306)),u=n(31665),c=r.__importDefault(n(20130));function d(){const e=(0,a.useNavbarMobileSidebar)();return o.default.createElement("button",{type:"button","aria-label":(0,i.translate)({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()},o.default.createElement(u.CloseIcon,null))}t.Z=function(){return o.default.createElement("div",{className:"navbar-sidebar__brand"},o.default.createElement(s.default,null),o.default.createElement(l.default,{className:"margin-right--md"}),o.default.createElement(c.default,null),o.default.createElement(d,null))}},64644:(e,t,n)=>{"use strict";const r=n(70655),o=r.__importDefault(n(67294)),a=r.__importDefault(n(86010)),i=n(13616),l=r.__importDefault(n(10510));t.Z=function(e){let{header:t,primaryMenu:n,secondaryMenu:r}=e;const{shown:s}=(0,i.useNavbarSecondaryMenu)();return o.default.createElement("div",{className:(0,a.default)("navbar-sidebar",s&&"navbar-sidebar--show-secondary")},t,o.default.createElement("div",{className:(0,a.default)("navbar-sidebar__items",{"navbar-sidebar__items--show-secondary":s})},o.default.createElement("div",{className:"navbar-sidebar__item menu"},n,!s&&o.default.createElement(l.default,null)),o.default.createElement("div",{className:"navbar-sidebar__item menu"},r)))}},29843:(e,t,n)=>{"use strict";const r=n(70655),o=n(31665),a=n(93945),i=n(13616),l=r.__importDefault(n(11614)),s=n(6980),u=r.__importDefault(n(67294));function c(e){return u.default.createElement("button",{...e,type:"button",className:"clean-btn navbar-sidebar__back"},u.default.createElement(s.IconArrowLeft,null),u.default.createElement(o.Typography,null,u.default.createElement(l.default,{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)"},"Back to main menu")))}t.Z=function(){const e=0===(0,a.useThemeConfig)().navbar.items.length,t=(0,i.useNavbarSecondaryMenu)();return u.default.createElement(u.default.Fragment,null,!e&&u.default.createElement(c,{onClick:()=>t.hide()}),t.content)}},71003:(e,t,n)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0});const r=n(70655),o=n(31665),a=n(93945),i=n(13616),l=r.__importDefault(n(93496)),s=r.__importDefault(n(83112)),u=r.__importDefault(n(86010)),c=r.__importStar(n(67294)),d=r.__importDefault(n(83244));function f(e,t){return e.some((e=>function(e,t){return!!(0,i.isSamePath)(e.to,t)||!!(0,a.isRegexpStringMatch)(e.activeBaseRegex,t)||!(!e.activeBasePath||!t.startsWith(e.activeBasePath))}(e,t)))}function p(e){let{items:t,position:n,className:r,onClick:a,...i}=e;const f=(0,c.useRef)(null),[p,h]=(0,c.useState)(!1);return(0,c.useEffect)((()=>{const e=e=>{f.current&&!f.current.contains(e.target)&&h(!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)}}),[f]),c.default.createElement("div",{ref:f,className:(0,u.default)("navbar__item",d.default.dropdownNavbarItem,"dropdown","dropdown--hoverable",{"dropdown--right":"right"===n,"dropdown--show":p})},c.default.createElement(s.default,{"aria-haspopup":"true","aria-expanded":p,role:"button",href:i.to?void 0:"#",className:(0,u.default)("navbar__link",r),...i,onClick:i.to?void 0:e=>e.preventDefault(),onKeyDown:e=>{"Enter"===e.key&&(e.preventDefault(),h(!p))}},i.children??i.label),c.default.createElement(o.ChevronDownIcon,{className:(0,u.default)("margin-left-8","cursor-pointer")}),c.default.createElement("ul",{className:"dropdown__menu"},t.map(((e,t)=>c.default.createElement(l.default,{isDropdownItem:!0,activeClassName:"dropdown__link--active",...e,key:t})))))}function h(e){let{items:t,className:n,position:r,onClick:d,...p}=e;const h=(0,i.useLocalPathname)(),m=f(t,h),{collapsed:g,toggleCollapsed:v,setCollapsed:b}=(0,a.useCollapsible)({initialState:()=>!m});return(0,c.useEffect)((()=>{m&&b(!m)}),[h,m,b]),c.default.createElement("li",{className:(0,u.default)("menu__list-item",{"menu__list-item--collapsed":g})},c.default.createElement(s.default,{role:"button",className:(0,u.default)("menu__link menu__link--sublist menu__link--sublist-caret",n),...p,onClick:e=>{e.preventDefault(),v()}},c.default.createElement(o.Typography,{variant:"body1"},p.children??p.label)),c.default.createElement(a.Collapsible,{lazy:!0,as:"ul",className:"menu__list",collapsed:g},t.map(((e,t)=>c.default.createElement(l.default,{mobile:!0,isDropdownItem:!0,onClick:d,activeClassName:"menu__link--active",...e,key:t})))))}t.default=function(e){let{mobile:t=!1,...n}=e;const r=t?h:p;return c.default.createElement(r,{...n})}},23247:(e,t,n)=>{"use strict";const r=n(70655),o=r.__importDefault(n(67294)),a=r.__importDefault(n(6832)),i=n(13616),l=n(11614),s=n(7154),u=r.__importDefault(n(71003));t.Z=function(e){var t;let{mobile:n,dropdownItemsBefore:r,dropdownItemsAfter:c,...d}=e;const{i18n:{currentLocale:f,locales:p,localeConfigs:h}}=(0,a.default)(),m=(0,i.useAlternatePageUtils)(),{search:g,hash:v}=(0,s.useLocation)(),b=[...r,...p.map((e=>{var t,r;const o=`${`pathname://${m.createUrl({locale:e,fullyQualified:!1})}`}${g}${v}`;return{label:null==(t=h[e])?void 0:t.label,lang:null==(r=h[e])?void 0:r.htmlLang,to:o,target:"_self",autoAddBaseUrl:!1,className:e===f?n?"menu__link--active":"dropdown__link--active":""}})),...c],y=n?(0,l.translate)({message:"Languages",id:"theme.navbar.mobileLanguageDropdown.label",description:"The label for the mobile language switcher dropdown"}):null==(t=h[f])?void 0:t.label.substring(0,2).toUpperCase();return o.default.createElement(u.default,{...d,mobile:n,label:o.default.createElement(o.default.Fragment,null,y),items:b})}},83112:(e,t,n)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0});const r=n(70655),o=n(31665),a=r.__importDefault(n(71699)),i=r.__importDefault(n(88746)),l=n(93945),s=r.__importDefault(n(51402)),u=r.__importDefault(n(67294)),c=n(22197),d=r.__importDefault(n(88822));t.default=function(e){let{activeBasePath:t,activeBaseRegex:n,to:r,href:f,label:p,html:h,isDropdownLink:m,prependBaseUrlToHref:g,...v}=e;const b=(0,s.default)(r),y=(0,s.default)(t),w=(0,s.default)(f,{forcePrependBaseUrl:!0}),x=p&&f&&!(0,a.default)(f),_=h?{dangerouslySetInnerHTML:{__html:h}}:{children:u.default.createElement(o.Typography,{component:"div",variant:"body2",className:d.default.linkContent},p,x&&u.default.createElement(c.IconExternalLink,{className:d.default.externalLinkIcon}))};return f?u.default.createElement(i.default,{href:g?w:f,...v,..._}):u.default.createElement(i.default,{to:b,isNavLink:!0,...(t||n)&&{isActive:(e,t)=>n?(0,l.isRegexpStringMatch)(n,t.pathname):t.pathname.startsWith(y)},...v,..._})}},28511:(e,t,n)=>{"use strict";const r=n(70655),o=n(13616),a=r.__importDefault(n(67294)),i=n(91866),l=n(84138),s=n(38840),u=r.__importDefault(n(36459));t.Z=function(e){var t;let{children:n}=e;const r=(0,s.useDocThemeOptions)(),c=null==r||null==(t=r.sidebar)?void 0:t.hide;return a.default.createElement(o.ColorModeProvider,null,a.default.createElement(l.ThemeProvider,null,a.default.createElement(i.LightBoxProvider,null,a.default.createElement("div",{className:u.default.root,"data-hidden-doc-sidebar":c},n))))}},56051:(e,t,n)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.SearchBar=void 0;const r=n(70655),o=n(31665),a=r.__importStar(n(67294)),i=n(81575),l=n(59213),s=n(21457),u=n(41310),c=r.__importDefault(n(31259)),d=n(55634),f=n(16991),p=n(44334);t.SearchBar=e=>{let{}=e;const t=(0,l.usePersistedHistory)("search",{unique:!0,equals:(e,t)=>e.title===t.title&&e.href===t.href,maxItems:10}),n=(0,u.useSearch)(),r=(0,a.useRef)(null),[h,m]=(0,a.useState)(""),[g,v]=(0,a.useState)([]),[b,y]=(0,a.useState)(!1);(0,a.useEffect)((()=>{h.length>0?(async e=>{const{results:t}=await n.query(e);v(t)})(h):v([])}),[h]),(0,a.useEffect)((()=>{b?(()=>{const e=r.current;if(!e)return;const t=e.querySelector("input");t&&setTimeout((()=>{t.focus()}),50)})():m("")}),[b]);return(0,s.useWindowEventListener)("keydown",(e=>{(e.ctrlKey||e.metaKey)&&"KeyK"===e.code&&(e.preventDefault(),y(!0))}),{},[]),a.default.createElement(a.default.Fragment,null,a.default.createElement(o.IconButton,{onClick:()=>y(!0),size:"medium"},a.default.createElement(o.SearchIcon,null)),a.default.createElement(i.Modal,{keepMounted:!0,id:"search-modal",open:b,onClose:()=>y(!1),className:c.default.modal},a.default.createElement("div",{className:c.default.header},a.default.createElement(f.SearchInput,{containerRef:r,onClear:()=>{m("")},value:h,onChange:e=>{m(e.target.value)}}),a.default.createElement(o.IconButton,{className:c.default.closeButton,size:"medium",onClick:()=>y(!1)},a.default.createElement(o.CloseIcon,{color:"primary"}))),h.length>0&&a.default.createElement(p.SearchResults,{results:g,onNavigate:(e,n)=>{e.preventDefault(),y(!1),t.add(n),window.location.href=n.href}}),0===h.length&&a.default.createElement(d.SearchHistory,{history:t.list??[],onRemove:t.removeByIndex,onClose:()=>y(!1)})))}},55634:(e,t,n)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.SearchHistory=void 0;const r=n(70655),o=n(31665),a=r.__importDefault(n(86010)),i=r.__importDefault(n(67294)),l=n(22197),s=n(42130),u=r.__importDefault(n(61699));t.SearchHistory=e=>{let{history:t=[],onRemove:n,onClose:r,className:c,children:d,...f}=e;return i.default.createElement("div",{className:(0,a.default)(c,u.default.root,0===t.length&&u.default.empty),...f},0===t.length?i.default.createElement(s.SearchResultMessage,null,"No recent searches"):i.default.createElement(i.default.Fragment,null,i.default.createElement(o.Typography,{className:u.default.title,variant:"subtitle2",component:"div"},"Recent"),t.map(((e,t)=>i.default.createElement("div",{key:t,className:u.default.item},i.default.createElement(l.IconHistory,null),i.default.createElement(o.Typography,{variant:"subtitle2",component:"a",href:e.href,className:u.default.itemTitle,dangerouslySetInnerHTML:{__html:e.title},onClick:()=>r&&r()}),i.default.createElement("button",{className:"clean-btn",onClick:()=>n(t)},i.default.createElement(l.IconClose,null)))))))}},16991:(e,t,n)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.SearchInput=void 0;const r=n(70655),o=n(31665),a=r.__importDefault(n(86010)),i=r.__importDefault(n(67294)),l=n(89164),s=r.__importDefault(n(9592));t.SearchInput=e=>{let{value:t="",active:n,onChange:r,onClear:u,onFocus:c,onCancel:d,className:f,inputProps:{ref:p,...h}={placeholder:""},containerRef:m,...g}=e;const v=(0,l.useMedia)("(max-width: 996px)"),b=n||(null==t?void 0:t.length)>0;return i.default.createElement("div",{ref:m,className:(0,a.default)(s.default.root,b&&s.default.expanded,f),onKeyDown:e=>{"Escape"===e.code&&t.length>0&&(e.stopPropagation(),u&&u())},...g},i.default.createElement(o.TextField,{className:s.default.textField,value:t,placeholder:b||v?h.placeholder:"",onChange:r,onFocus:e=>{c&&c()},clearButton:!0,icon:i.default.createElement(o.SearchIcon,{color:"primary"}),...h}))}},537:(e,t,n)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.SearchResultGroup=void 0;const r=n(70655),o=n(31665),a=r.__importDefault(n(86010)),i=r.__importDefault(n(67294)),l=r.__importDefault(n(1443));t.SearchResultGroup=e=>{let{className:t,title:n="",children:r,...s}=e;return i.default.createElement("div",{className:(0,a.default)(l.default.root,t),...s},i.default.createElement("div",null,i.default.createElement(o.Typography,{variant:"subtitle2"},n)),i.default.createElement("ul",null,r))}},16183:(e,t,n)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0});n(70655).__exportStar(n(537),t)},78447:(e,t,n)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.SearchResultItem=void 0;const r=n(70655),o=r.__importDefault(n(88746)),a=r.__importDefault(n(86010)),i=r.__importDefault(n(67294)),l=r.__importDefault(n(7744)),s=r.__importDefault(n(42924)),u=n(55459),c=n(79587),d=r.__importDefault(n(18589)),f={[c.SearchDocumentType.Title]:i.default.createElement(l.default,{className:(0,a.default)(d.default.icon,d.default.fill)}),[c.SearchDocumentType.Heading]:i.default.createElement(s.default,{className:(0,a.default)(d.default.icon,d.default.fill)}),[c.SearchDocumentType.Paragraph]:i.default.createElement(s.default,{className:(0,a.default)(d.default.icon,d.default.fill)})};t.SearchResultItem=e=>{let{type:t,level:n=0,href:r,title:l,content:s,className:c,linkProps:{className:p,...h}={},...m}=e;const g=f[t];return i.default.createElement(o.default,{href:r,className:(0,a.default)(d.default.root,d.default[`level${n}`],p),...h},i.default.createElement(u.SearchResultItemBase,{title:l,content:s,icon:g,...m}))}},98028:(e,t,n)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0});n(70655).__exportStar(n(78447),t)},8655:(e,t,n)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.SearchResultItemBase=void 0;const r=n(70655),o=n(31665),a=r.__importDefault(n(86010)),i=r.__importDefault(n(67294)),l=r.__importDefault(n(86620));t.SearchResultItemBase=e=>{let{icon:t,title:n,content:r,className:s,...u}=e;return i.default.createElement("li",{className:(0,a.default)(l.default.root,s),...u},i.default.createElement("span",null,t),i.default.createElement("div",null,n&&i.default.createElement(o.Typography,{variant:"subtitle2",component:"span",dangerouslySetInnerHTML:{__html:n}})))}},55459:(e,t,n)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0});n(70655).__exportStar(n(8655),t)},42130:(e,t,n)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.SearchResultMessage=void 0;const r=n(70655),o=n(31665),a=r.__importDefault(n(86010)),i=r.__importDefault(n(67294)),l=r.__importDefault(n(38076));t.SearchResultMessage=e=>{let{className:t,children:n,...r}=e;return i.default.createElement(o.Typography,{className:(0,a.default)(t,l.default.root),variant:"subtitle2",component:"div",...r},i.default.createElement("span",null,n))}},44334:(e,t,n)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.SearchResults=void 0;const r=n(70655),o=r.__importDefault(n(86010)),a=r.__importStar(n(67294)),i=n(16183),l=n(98028),s=n(42130),u=n(36570),c=r.__importDefault(n(20550));t.SearchResults=e=>{let{results:t,className:n,onNavigate:r,...d}=e;const f=t.length,p=(0,a.useMemo)((()=>(0,u.groupSearchResult)(t)),[t]);return a.default.createElement("div",{className:(0,o.default)(c.default.root,0===f&&c.default.noResults)},0===f&&a.default.createElement(s.SearchResultMessage,null,"No result."),a.default.createElement("div",{className:(0,o.default)(c.default.groups)},p.map(((e,t)=>{let[n,o]=e;return a.default.createElement(a.default.Fragment,{key:t},a.default.createElement(i.SearchResultGroup,{className:c.default.group,title:n},o.map(((e,t)=>a.default.createElement(l.SearchResultItem,{key:t,type:e.type,level:e.level,href:e.href,title:e.title,content:e.content,linkProps:r?{onClick:t=>r(t,e)}:{}})))))}))))}},41310:(e,t,n)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.useSearch=void 0;const r=n(67294),o=n(8675);t.useSearch=()=>{const{createSearchInstance:e}=window,t=(0,o.useSearchContextPath)(),[n,a]=(0,r.useState)(!1),i=(0,r.useRef)(null);return(0,r.useEffect)((()=>{a(!1),(async()=>{i.current=await e({resultsLimit:50,preferredVersionPath:t[0],searchContextByPaths:t[1]}),await i.current.init(),a(!0)})()}),[t[0],t[1]]),{loaded:n,query:async e=>await i.current.query(e)}}},8675:(e,t,n)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.useSearchContextPath=void 0;const r=n(4452),o=n(68347),a=()=>window.getProxiedGeneratedData().searchContextByPaths;t.useSearchContextPath=()=>{const e=a(),t=(0,r.useActivePluginAndVersion)();if(!t)return["/",""];const{activePlugin:{pluginData:{path:n}},activeVersion:i}=t;return i?[n!==i.path?(0,o.ensureTrailingSlash)(i.path):"/",e]:["/",""]}},20130:(e,t,n)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0});const r=n(70655),o=r.__importDefault(n(24649)),a=r.__importDefault(n(67294)),i=n(56051);t.default=()=>"undefined"==typeof window?a.default.createElement(a.default.Fragment,null):a.default.createElement(o.default,{fallback:()=>a.default.createElement(a.default.Fragment,null)},a.default.createElement(i.SearchBar,null))},79587:(e,t)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.SearchDocumentType=void 0,function(e){e.Title="title",e.Heading="heading",e.Paragraph="paragraph"}(t.SearchDocumentType||(t.SearchDocumentType={}))},36570:(e,t,n)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.groupSearchResult=void 0;const r=n(70655),o=r.__importDefault(n(7739)),a=r.__importDefault(n(57557)),i=n(79587);t.groupSearchResult=e=>Object.entries((0,o.default)(e.map((e=>(e=>{const{type:t,document:n,page:r,highlighted:o,score:a}=e,{url:l,hash:s=""}=n,u=l+s;switch(t){case i.SearchDocumentType.Title:var c;return{type:t,level:0,url:l,hash:s,href:u,score:a,title:o,content:"",category:(null==(c=n.breadcrumb)?void 0:c[1])??n.title};case i.SearchDocumentType.Heading:{var d;const e=r;return{type:t,level:1,url:l,hash:s,href:u,score:a,title:o,content:"",category:(null==e||null==(d=e.breadcrumb)?void 0:d[1])??(null==e?void 0:e.title)??""}}case i.SearchDocumentType.Paragraph:{var f;const e=r;return{type:t,level:2,url:l,hash:s,href:u,score:a,title:n.sectionTitle||n.title||"",content:o,category:(null==e||null==(f=e.breadcrumb)?void 0:f[1])??(null==e?void 0:e.title)??""}}}})(e))),"category")).map((e=>{let[t,n]=e;return[t,n.map((e=>(0,a.default)(e,"category"))).sort(((e,t)=>e.score>t.score?-1:1))]})).sort(((e,t)=>{var n,r;return((null==(n=e[1][0])?void 0:n.score)??0)>((null==(r=t[1][0])?void 0:r.score)??0)?-1:1})).map((e=>{let[t,n]=e;return[t,Object.entries((0,o.default)(n,"url")).map((e=>{var t;let[n,r]=e,o=[...r].sort(((e,t)=>e.type===i.SearchDocumentType.Title||e.score>t.score?-1:1));const a=(null==(t=o[0])?void 0:t.type)===i.SearchDocumentType.Title;return o=a?o.filter((e=>!(e.type===i.SearchDocumentType.Heading&&""===e.hash))):o,o=o.map(((e,t)=>({...e,level:a?0===t?0:1:0}))),[n,o]})).sort(((e,t)=>{var n,r;return((null==(n=e[1][0])?void 0:n.score)??0)>((null==(r=t[1][0])?void 0:r.score)??0)?-1:1})).flatMap((e=>{let[t,n]=e;return n}))]}))},74058:(e,t,n)=>{"use strict";n.d(t,{_:()=>o,t:()=>a});var r=n(67294);const o=r.createContext(!1);function a(e){let{children:t}=e;const[n,a]=(0,r.useState)(!1);return(0,r.useEffect)((()=>{a(!0)}),[]),r.createElement(o.Provider,{value:n},t)}},3364:(e,t,n)=>{"use strict";var r=n(67294),o=n(73935),a=n(73727),i=n(70405),l=n(19901);const s=[n(79578),n(32497),n(25529),n(26126),n(11057),n(93878)];var u=n(21204),c=n(16550),d=n(18790),f=n(28511),p=n(87462),h=n(32411),m=n(6832),g=n(51402),v=n(96793),b=n(44873),y=n(13156),w=n(22768),x=n(39105),_=n(26145);function k(){const{i18n:{defaultLocale:e,localeConfigs:t}}=(0,m.default)(),n=(0,y.l)();return r.createElement(h.Z,null,Object.entries(t).map((e=>{let[t,{htmlLang:o}]=e;return r.createElement("link",{key:t,rel:"alternate",href:n.createUrl({locale:t,fullyQualified:!0}),hrefLang:o})})),r.createElement("link",{rel:"alternate",href:n.createUrl({locale:e,fullyQualified:!0}),hrefLang:"x-default"}))}function E(e){let{permalink:t}=e;const{siteConfig:{url:n}}=(0,m.default)(),o=function(){const{siteConfig:{url:e}}=(0,m.default)(),{pathname:t}=(0,c.TH)();return e+(0,g.default)(t)}(),a=t?`${n}${t}`:o;return r.createElement(h.Z,null,r.createElement("meta",{property:"og:url",content:a}),r.createElement("link",{rel:"canonical",href:a}))}function S(){const{i18n:{currentLocale:e}}=(0,m.default)(),{metadata:t,image:n}=(0,v.L)();return r.createElement(r.Fragment,null,r.createElement(h.Z,null,r.createElement("meta",{name:"twitter:card",content:"summary_large_image"}),r.createElement("body",{className:w.h})),n&&r.createElement(b.d,{image:n}),r.createElement(E,null),r.createElement(k,null),r.createElement(_.Z,{tag:x.HX,locale:e}),r.createElement(h.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)(u.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 O=n(74058),D=n(56725);function P(e){for(var t=arguments.length,n=new Array(t>1?t-1:0),r=1;r{var r;const o=(null==(r=t.default)?void 0:r[e])??t[e];return null==o?void 0:o(...n)}));return()=>o.forEach((e=>null==e?void 0:e()))}const N=function(e){let{children:t,location:n,previousLocation:o}=e;return(0,r.useLayoutEffect)((()=>{o!==n&&(!function(e){let{location:t,previousLocation:n}=e;if(!n)return;const r=t.pathname===n.pathname,o=t.hash===n.hash,a=t.search===n.search;if(r&&o&&!a)return;const{hash:i}=t;if(i){const e=decodeURIComponent(i.substring(1)),t=document.getElementById(e);null==t||t.scrollIntoView()}else window.scrollTo(0,0)}({location:n,previousLocation:o}),P("onRouteDidUpdate",{previousLocation:o,location:n}))}),[o,n]),t};function A(e){const t=Array.from(new Set([e,decodeURI(e)])).map((e=>(0,d.f)(u.Z,e))).flat();return Promise.all(t.map((e=>null==e.route.component.preload?void 0:e.route.component.preload())))}class I extends r.Component{constructor(e){super(e),this.previousLocation=void 0,this.routeUpdateCleanupCb=void 0,this.previousLocation=null,this.routeUpdateCleanupCb=l.Z.canUseDOM?P("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=P("onRouteUpdate",{previousLocation:this.previousLocation,location:n}),A(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(N,{previousLocation:this.previousLocation,location:t},r.createElement(c.AW,{location:t,render:()=>e}))}}const L=I,R="__docusaurus-base-url-issue-banner-container",j="__docusaurus-base-url-issue-banner-suggestion-container",M="__DOCUSAURUS_INSERT_BASEURL_BANNER";function F(e){return`\nwindow['${M}'] = true;\n\ndocument.addEventListener('DOMContentLoaded', maybeInsertBanner);\n\nfunction maybeInsertBanner() {\n var shouldInsert = window['${M}'];\n shouldInsert && insertBanner();\n}\n\nfunction insertBanner() {\n var bannerContainer = document.getElementById('${R}');\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[M]=!1}),[]),r.createElement(r.Fragment,null,!l.Z.canUseDOM&&r.createElement(h.Z,null,r.createElement("script",null,F(e))),r.createElement("div",{id:R}))}function z(){const{siteConfig:{baseUrl:e,baseUrlIssueBanner:t}}=(0,m.default)(),{pathname:n}=(0,c.TH)();return t&&n===e?r.createElement(B,null):null}function $(){const{siteConfig:{favicon:e,title:t,noIndex:n},i18n:{currentLocale:o,localeConfigs:a}}=(0,m.default)(),i=(0,g.default)(e),{htmlLang:l,direction:s}=a[o];return r.createElement(h.Z,null,r.createElement("html",{lang:l,dir:s}),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 U=n(24649);function H(){const e=(0,d.H)(u.Z),t=(0,c.TH)();return r.createElement(U.default,null,r.createElement(D.M,null,r.createElement(O.t,null,r.createElement(f.Z,null,r.createElement($,null),r.createElement(S,null),r.createElement(z,null),r.createElement(L,{location:T(t)},e)))))}var V=n(16887);const q=function(e){try{return document.createElement("link").relList.supports(e)}catch{return!1}}("prefetch")?function(e){return new Promise(((t,n)=>{var r;if("undefined"==typeof document)return void n();const o=document.createElement("link");o.setAttribute("rel","prefetch"),o.setAttribute("href",e),o.onload=()=>t(),o.onerror=()=>n();const a=document.getElementsByTagName("head")[0]??(null==(r=document.getElementsByName("script")[0])?void 0:r.parentNode);null==a||a.appendChild(o)}))}: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 G=n(66916);const W=new Set,Z=new Set,Q=()=>{var e,t;return(null==(e=navigator.connection)?void 0:e.effectiveType.includes("2g"))||(null==(t=navigator.connection)?void 0:t.saveData)},Y={prefetch(e){if(!(e=>!Q()&&!Z.has(e)&&!W.has(e))(e))return!1;W.add(e);const t=(0,d.f)(u.Z,e).flatMap((e=>{return t=e.route.path,Object.entries(V).filter((e=>{let[n]=e;return n.replace(/-[^-]+$/,"")===t})).flatMap((e=>{let[,t]=e;return Object.values((0,G.Z)(t))}));var t}));return Promise.all(t.map((e=>{const t=n.gca(e);return t&&!t.includes("undefined")?q(t).catch((()=>{})):Promise.resolve()})))},preload:e=>!!(e=>!Q()&&!Z.has(e))(e)&&(Z.add(e),A(e))},X=Object.freeze(Y);if(l.Z.canUseDOM){window.docusaurus=X;const e=o.hydrate;A(window.location.pathname).then((()=>{e(r.createElement(i.B6,null,r.createElement(a.VK,null,r.createElement(H,null))),document.getElementById("__docusaurus"))}))}},56725:(e,t,n)=>{"use strict";n.d(t,{_:()=>c,M:()=>d});var r=n(67294),o=n(36809);const a=JSON.parse('{"docusaurus-plugin-content-docs":{"Docs":{"path":"/","versions":[{"name":"current","label":"Next","isLast":true,"path":"/","mainDocId":"index","docs":[{"id":"community","path":"/community"},{"id":"contribute","path":"/contribute","sidebar":"main"},{"id":"deepresearch","path":"/deepresearch","sidebar":"main"},{"id":"index","path":"/","sidebar":"main"},{"id":"join-us","path":"/join-us"},{"id":"media","path":"/media"},{"id":"principles","path":"/principles","sidebar":"main"},{"id":"privacy-policy","path":"/privacy-policy"},{"id":"publications","path":"/publications"},{"id":"rfcprocess","path":"/rfcprocess"},{"id":"security","path":"/security"},{"id":"terms","path":"/terms"},{"id":"vips","path":"/vips","sidebar":"main"},{"id":"vsus","path":"/vsus","sidebar":"main"}],"draftIds":[],"sidebars":{"main":{"link":{"path":"/","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 l=n(57529);const s=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-plugin-sass":{"type":"package","name":"docusaurus-plugin-sass","version":"0.2.3"},"logos-docusaurus-search-local":{"type":"package","name":"@acid-info/logos-docusaurus-search-local","version":"1.0.0-alpha.111"},"logos-data-plugin":{"type":"local"},"docusaurus-theme-classic":{"type":"package","name":"@docusaurus/theme-classic","version":"2.4.1"},"docusaurus-theme-mermaid":{"type":"package","name":"@docusaurus/theme-mermaid","version":"2.4.1"},"logos-docusaurus-theme":{"type":"package","name":"@acid-info/logos-docusaurus-theme","version":"1.0.0-alpha.133"},"docusaurus-plugin-client-redirects":{"type":"package","name":"@docusaurus/plugin-client-redirects","version":"2.4.1"},"docusaurus-og":{"type":"package","name":"@acid-info/docusaurus-og","version":"1.0.0-alpha.131"}}}'),u={siteConfig:o.Z,siteMetadata:s,globalData:a,i18n:i,codeTranslations:l},c=r.createContext(u);function d(e){let{children:t}=e;return r.createElement(c.Provider,{value:u},t)}},24649:(e,t,n)=>{"use strict";n.r(t),n.d(t,{default:()=>f});var r=n(67294),o=n(19901),a=n(32411),i=n(79861),l=n(66867);function s(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(u,{error:t}))}function u(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 c(e){let{error:t,tryAgain:n}=e;return r.createElement(f,{fallback:()=>r.createElement(s,{error:t,tryAgain:n})},r.createElement(a.Z,null,r.createElement("title",null,"Page Error")),r.createElement(l.default,null,r.createElement(s,{error:t,tryAgain:n})))}const d=e=>r.createElement(c,e);class f extends r.Component{constructor(e){super(e),this.state={error:null}}componentDidCatch(e){o.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}}},19901:(e,t,n)=>{"use strict";n.d(t,{Z:()=>o});const r="undefined"!=typeof window&&"document"in window&&"createElement"in window.document,o={canUseDOM:r,canUseEventListeners:r&&("addEventListener"in window||"attachEvent"in window),canUseIntersectionObserver:r&&"IntersectionObserver"in window,canUseViewport:r&&"screen"in window}},32411:(e,t,n)=>{"use strict";n.d(t,{Z:()=>a});var r=n(67294),o=n(70405);function a(e){return r.createElement(o.ql,e)}},88746:(e,t,n)=>{"use strict";n.r(t),n.d(t,{default:()=>p});var r=n(87462),o=n(67294),a=n(73727),i=n(79861),l=n(6832),s=n(71699),u=n(19901);const c=o.createContext({collectLink:()=>{}});var d=n(51402);function f(e,t){var n;let{isNavLink:f,to:p,href:h,activeClassName:m,isActive:g,"data-noBrokenLinkCheck":v,autoAddBaseUrl:b=!0,...y}=e;const{siteConfig:{trailingSlash:w,baseUrl:x}}=(0,l.default)(),{withBaseUrl:_}=(0,d.useBaseUrlUtils)(),k=(0,o.useContext)(c),E=(0,o.useRef)(null);(0,o.useImperativeHandle)(t,(()=>E.current));const S=p||h;const C=(0,s.default)(S),T=null==S?void 0:S.replace("pathname://","");let O=void 0!==T?(D=T,b&&(e=>e.startsWith("/"))(D)?_(D):D):void 0;var D;O&&C&&(O=(0,i.applyTrailingSlash)(O,{trailingSlash:w,baseUrl:x}));const P=(0,o.useRef)(!1),N=f?a.OL:a.rU,A=u.Z.canUseIntersectionObserver,I=(0,o.useRef)(),L=()=>{P.current||null==O||(window.docusaurus.preload(O),P.current=!0)};(0,o.useEffect)((()=>(!A&&C&&null!=O&&window.docusaurus.prefetch(O),()=>{A&&I.current&&I.current.disconnect()})),[I,O,A,C]);const R=(null==(n=O)?void 0:n.startsWith("#"))??!1,j=!O||!C||R;return j||v||k.collectLink(O),j?o.createElement("a",(0,r.Z)({ref:E,href:O},S&&!C&&{target:"_blank",rel:"noopener noreferrer"},y)):o.createElement(N,(0,r.Z)({},y,{onMouseEnter:L,onTouchStart:L,innerRef:e=>{E.current=e,A&&e&&C&&(I.current=new window.IntersectionObserver((t=>{t.forEach((t=>{e===t.target&&(t.isIntersecting||t.intersectionRatio>0)&&(I.current.unobserve(e),I.current.disconnect(),null!=O&&window.docusaurus.prefetch(O))}))})),I.current.observe(e))},to:O},f&&{isActive:g,activeClassName:m}))}const p=o.forwardRef(f)},11614:(e,t,n)=>{"use strict";n.r(t),n.d(t,{default:()=>s,translate:()=>l});var r=n(67294);function o(e,t){const n=e.split(/(\{\w+\})/).map(((e,n)=>{if(n%2==1){const n=null==t?void 0: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 a=n(57529);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 a[t??n]??n??t}function l(e,t){let{message:n,id:r}=e;return o(i({message:n,id:r}),t)}function s(e){let{children:t,id:n,values:a}=e;if(t&&"string"!=typeof t)throw console.warn("Illegal children",t),new Error("The Docusaurus component only accept simple string values");const l=i({message:t,id:n});return r.createElement(r.Fragment,null,o(l,a))}},12497:(e,t,n)=>{"use strict";n.d(t,{m:()=>r});const r="default"},71699:(e,t,n)=>{"use strict";function r(e){return/^(?:\w*:|\/\/)/.test(e)}function o(e){return void 0!==e&&!r(e)}n.r(t),n.d(t,{default:()=>o,hasProtocol:()=>r})},7154:(e,t,n)=>{"use strict";n.r(t),n.d(t,{Redirect:()=>r.l_,matchPath:()=>r.LX,useHistory:()=>r.k6,useLocation:()=>r.TH});var r=n(16550)},51402:(e,t,n)=>{"use strict";n.r(t),n.d(t,{default:()=>l,useBaseUrlUtils:()=>i});var r=n(67294),o=n(6832),a=n(71699);function i(){const{siteConfig:{baseUrl:e,url:t}}=(0,o.default)(),n=(0,r.useCallback)(((n,r)=>function(e,t,n,r){let{forcePrependBaseUrl:o=!1,absolute:i=!1}=void 0===r?{}:r;if(!n||n.startsWith("#")||(0,a.hasProtocol)(n))return n;if(o)return t+n.replace(/^\//,"");if(n===t.replace(/\/$/,""))return t;const l=n.startsWith(t)?n:t+n.replace(/^\//,"");return i?e+l:l}(t,e,n,r)),[t,e]);return{withBaseUrl:n}}function l(e,t){void 0===t&&(t={});const{withBaseUrl:n}=i();return n(e,t)}},6832:(e,t,n)=>{"use strict";n.r(t),n.d(t,{default:()=>a});var r=n(67294),o=n(56725);function a(){return(0,r.useContext)(o._)}},5730:(e,t,n)=>{"use strict";n.r(t),n.d(t,{default:()=>a});var r=n(67294),o=n(74058);function a(){return(0,r.useContext)(o._)}},66916:(e,t,n)=>{"use strict";n.d(t,{Z:()=>r});function r(e){const t={};return function e(n,r){Object.entries(n).forEach((n=>{let[o,a]=n;const i=r?`${r}.${o}`:o;var l;"object"==typeof(l=a)&&l&&Object.keys(l).length>0?e(a,i):t[i]=a}))}(e),t}},66041:(e,t,n)=>{"use strict";n.d(t,{_:()=>o,z:()=>a});var r=n(67294);const o=r.createContext(null);function a(e){let{children:t,value:n}=e;const a=r.useContext(o),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,...null==n?void 0:n.data};return{plugin:t.plugin,data:r}}({parent:a,value:n})),[a,n]);return r.createElement(o.Provider,{value:i},t)}},4452:(e,t,n)=>{"use strict";n.r(t),n.d(t,{useActiveDocContext:()=>b,useActivePlugin:()=>p,useActivePluginAndVersion:()=>h,useActiveVersion:()=>v,useAllDocsData:()=>d,useDocVersionSuggestions:()=>y,useDocsData:()=>f,useLatestVersion:()=>g,useVersions:()=>m});var r=n(16550),o=n(6832),a=n(12497);function i(e,t){void 0===t&&(t={});const n=function(){const{globalData:e}=(0,o.default)();return e}()[e];if(!n&&t.failfast)throw new Error(`Docusaurus plugin global data not found for "${e}" plugin.`);return n}const l=e=>e.versions.find((e=>e.isLast));function s(e,t){const n=l(e);return[...e.versions.filter((e=>e!==n)),n].find((e=>!!(0,r.LX)(t,{path:e.path,exact:!1,strict:!1})))}function u(e,t){const n=s(e,t),o=null==n?void 0:n.docs.find((e=>!!(0,r.LX)(t,{path:e.path,exact:!0,strict:!1})));return{activeVersion:n,activeDoc:o,alternateDocVersions:o?function(t){const n={};return e.versions.forEach((e=>{e.docs.forEach((r=>{r.id===t&&(n[e.name]=r)}))})),n}(o.id):{}}}const c={},d=()=>i("docusaurus-plugin-content-docs")??c,f=e=>function(e,t,n){void 0===t&&(t=a.m),void 0===n&&(n={});const r=i(e),o=null==r?void 0:r[t];if(!o&&n.failfast)throw new Error(`Docusaurus plugin global data not found for "${e}" plugin with id "${t}".`);return o}("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 o=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})})),a=o?{pluginId:o[0],pluginData:o[1]}:void 0;if(!a&&n.failfast)throw new Error(`Can't find active docs plugin for "${t}" pathname, while it was expected to be found. Maybe you tried to use a docs feature that can only be used on a docs-related page? Existing docs plugin paths are: ${Object.values(e).map((e=>e.path)).join(", ")}`);return a}(t,n,e)}function h(e){void 0===e&&(e={});const t=p(e),{pathname:n}=(0,r.TH)();if(!t)return;return{activePlugin:t,activeVersion:s(t.pluginData,n)}}function m(e){return f(e).versions}function g(e){const t=f(e);return l(t)}function v(e){const t=f(e),{pathname:n}=(0,r.TH)();return s(t,n)}function b(e){const t=f(e),{pathname:n}=(0,r.TH)();return u(t,n)}function y(e){const t=f(e),{pathname:n}=(0,r.TH)();return function(e,t){const n=l(e);return{latestDocSuggestion:u(e,t).alternateDocVersions[n.name],latestVersionSuggestion:n}}(t,n)}},26126:(e,t,n)=>{"use strict";n.r(t),n.d(t,{default:()=>a});var r=n(74865),o=n.n(r);o().configure({showSpinner:!1});const a={onRouteUpdate(e){let{location:t,previousLocation:n}=e;if(n&&t.pathname!==n.pathname){const e=window.setTimeout((()=>{o().start()}),200);return()=>window.clearTimeout(e)}},onRouteDidUpdate(){o().done()}}},25529:(e,t,n)=>{"use strict";n.r(t);var r=n(87410),o=n(36809);!function(e){const{themeConfig:{prism:t}}=o.Z,{additionalLanguages:r}=t;globalThis.Prism=e,r.forEach((e=>{n(6726)(`./prism-${e}`)})),delete globalThis.Prism}(r.Z)},10510:(e,t,n)=>{"use strict";n.r(t),n.d(t,{default:()=>T});var r=n(67294),o=n(96793),a=n(68211),i=n(87462),l=n(88746),s=n(51402),u=n(71699),c=n(43399);function d(e){let{item:t}=e;const{to:n,href:o,label:a,prependBaseUrlToHref:d,...f}=t,p=(0,s.default)(n),h=(0,s.default)(o,{forcePrependBaseUrl:!0});return r.createElement(l.default,(0,i.Z)({className:"footer__link-item"},o?{href:d?h:o}:{to:p},f),a,o&&!(0,u.default)(o)&&r.createElement(c.Z,null))}function f(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(d,{item:t}))}function p(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(f,{key:t,item:e})))))}function h(e){let{columns:t}=e;return r.createElement("div",{className:"row footer__links"},t.map(((e,t)=>r.createElement(p,{key:t,column:e}))))}function m(){return r.createElement("span",{className:"footer__link-separator"},"\xb7")}function g(e){let{item:t}=e;return t.html?r.createElement("span",{className:"footer__link-item",dangerouslySetInnerHTML:{__html:t.html}}):r.createElement(d,{item:t})}function v(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(g,{item:e}),t.length!==n+1&&r.createElement(m,null))))))}function b(e){let{links:t}=e;return(0,a.a)(t)?r.createElement(h,{columns:t}):r.createElement(v,{links:t})}var y=n(86010),w=n(47002);const x="footerLogoLink_BH7S";function _(e){let{logo:t}=e;const{withBaseUrl:n}=(0,s.useBaseUrlUtils)(),o={light:n(t.src),dark:n(t.srcDark??t.src)};return r.createElement(w.default,{className:(0,y.default)("footer__logo",t.className),alt:t.alt,sources:o,width:t.width,height:t.height,style:t.style})}function k(e){let{logo:t}=e;return t.href?r.createElement(l.default,{href:t.href,className:x,target:t.target},r.createElement(_,{logo:t})):r.createElement(_,{logo:t})}function E(e){let{copyright:t}=e;return r.createElement("div",{className:"footer__copyright",dangerouslySetInnerHTML:{__html:t}})}var S=n(72726);function C(){const{footer:e}=(0,o.L)();if(!e)return null;const{copyright:t,links:n,logo:a,style:i}=e;return r.createElement(S.Z,{style:i,links:n&&n.length>0&&r.createElement(b,{links:n}),logo:a&&r.createElement(k,{logo:a}),copyright:t&&r.createElement(E,{copyright:t})})}const T=r.memo(C)},5574:(e,t,n)=>{"use strict";n.r(t),n.d(t,{default:()=>a});var r=n(87462),o=n(67294);function a(e){return o.createElement("svg",(0,r.Z)({viewBox:"0 0 24 24",width:24,height:24},e),o.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"}))}},43399:(e,t,n)=>{"use strict";n.d(t,{Z:()=>a});var r=n(67294);const o="iconExternalLink_nPIU";function a(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:o},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"}))}},60388:(e,t,n)=>{"use strict";n.r(t),n.d(t,{default:()=>a});var r=n(87462),o=n(67294);function a(e){return o.createElement("svg",(0,r.Z)({viewBox:"0 0 24 24",width:24,height:24},e),o.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"}))}},66867:(e,t,n)=>{"use strict";n.r(t),n.d(t,{default:()=>L});var r=n(67294),o=n(86010),a=n(24649),i=n(44873),l=n(66470),s=n(18015),u=n(22768);const c="skipToContent_fXgn";function d(){return r.createElement(l.l,{className:c})}var f=n(96793),p=n(69061),h=n(87462),m=n(11614);function g(e){let{width:t=21,height:n=21,color:o="currentColor",strokeWidth:a=1.2,className:i,...l}=e;return r.createElement("svg",(0,h.Z)({viewBox:"0 0 15 15",width:t,height:n},l),r.createElement("g",{stroke:o,strokeWidth:a},r.createElement("path",{d:"M.75.75l13.5 13.5M14.25.75L.75 14.25"})))}const v="closeButton_CVFx";function b(e){return r.createElement("button",(0,h.Z)({type:"button","aria-label":(0,m.translate)({id:"theme.AnnouncementBar.closeButtonAriaLabel",message:"Close",description:"The ARIA label for close button of announcement bar"})},e,{className:(0,o.default)("clean-btn close",v,e.className)}),r.createElement(g,{width:14,height:14,strokeWidth:3.1}))}const y="content_knG7";function w(e){const{announcementBar:t}=(0,f.L)(),{content:n}=t;return r.createElement("div",(0,h.Z)({},e,{className:(0,o.default)(y,e.className),dangerouslySetInnerHTML:{__html:n}}))}const x="announcementBar_mb4j",_="announcementBarPlaceholder_vyr4",k="announcementBarClose_gvF7",E="announcementBarContent_xLdY";function S(){const{announcementBar:e}=(0,f.L)(),{isActive:t,close:n}=(0,p.nT)();if(!t)return null;const{backgroundColor:o,textColor:a,isCloseable:i}=e;return r.createElement("div",{className:x,style:{backgroundColor:o,color:a},role:"banner"},i&&r.createElement("div",{className:_}),r.createElement(w,{className:E}),i&&r.createElement(b,{onClick:n,className:k}))}var C=n(26558),T=n(27882);function O(){return r.createElement(C.Z,null,r.createElement(T.Z,null))}var D=n(10510),P=n(10211),N=n(48348);function A(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(m.default,{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(N.Cw,{onClick:n,className:"button button--primary shadow--lw"})),r.createElement("hr",null),r.createElement("div",{className:"margin-vert--md"},r.createElement(N.aG,{error:t})))))}const I="mainWrapper_z2l0";function L(e){const{children:t,noFooter:n,wrapperClassName:c,title:f,description:p}=e;return(0,u.t)(),r.createElement(P.Z,null,r.createElement(i.d,{title:f,description:p}),r.createElement(d,null),r.createElement(S,null),r.createElement(O,null),r.createElement("div",{id:l.u,className:(0,o.default)(s.k.wrapper.main,I,c)},r.createElement(a.default,{fallback:e=>r.createElement(A,e)},t)),!n&&r.createElement(D.default,null))}},17662:(e,t,n)=>{"use strict";n.r(t),n.d(t,{default:()=>s});var r=n(67294),o=n(96793),a=n(70524),i=n(61818);const l="darkNavbarColorModeToggle_X3D1";function s(e){let{className:t}=e;const n=(0,o.L)().navbar.style,s=(0,o.L)().colorMode.disableSwitch,{colorMode:u,setColorMode:c}=(0,a.I)();return s?null:r.createElement(i.Z,{className:t,buttonClassName:"dark"===n?l:void 0,value:u,onChange:c})}},60543:(e,t,n)=>{"use strict";n.r(t),n.d(t,{default:()=>s});var r=n(67294),o=n(35022),a=n(11614),i=n(87462);function l(e){let{width:t=30,height:n=30,className:o,...a}=e;return r.createElement("svg",(0,i.Z)({className:o,width:t,height:n,viewBox:"0 0 30 30","aria-hidden":"true"},a),r.createElement("path",{stroke:"currentColor",strokeLinecap:"round",strokeMiterlimit:"10",strokeWidth:"2",d:"M4 7h22M4 15h22M4 23h22"}))}function s(){const{toggle:e,shown:t}=(0,o.e)();return r.createElement("button",{onClick:e,"aria-label":(0,a.translate)({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(l,null))}},44488:(e,t,n)=>{"use strict";n.r(t),n.d(t,{default:()=>p});var r=n(67294),o=n(35022),a=n(69322),i=n(64644),l=n(20080),s=n(87462),u=n(96793),c=n(93496);function d(){const e=(0,o.e)(),t=(0,u.L)().navbar.items;return r.createElement("ul",{className:"menu__list"},t.map(((t,n)=>r.createElement(c.default,(0,s.Z)({mobile:!0},t,{onClick:()=>e.toggle(),key:n})))))}var f=n(29843);function p(){const e=(0,o.e)();return(0,a.N)(e.shown),e.shouldRender?r.createElement(i.Z,{header:r.createElement(l.Z,null),primaryMenu:r.createElement(d,null),secondaryMenu:r.createElement(f.Z,null)}):null}},93496:(e,t,n)=>{"use strict";n.r(t),n.d(t,{default:()=>_});var r=n(67294),o=n(87462),a=n(86010),i=n(83112);function l(e){let{className:t,isDropdownItem:n=!1,...l}=e;const s=r.createElement(i.default,(0,o.Z)({className:(0,a.default)(n?"dropdown__link":"navbar__item navbar__link",t),isDropdownLink:n},l));return n?r.createElement("li",null,s):s}function s(e){let{className:t,isDropdownItem:n,...l}=e;return r.createElement("li",{className:"menu__list-item"},r.createElement(i.default,(0,o.Z)({className:(0,a.default)("menu__link",t)},l)))}function u(e){let{mobile:t=!1,position:n,...a}=e;const i=t?s:l;return r.createElement(i,(0,o.Z)({},a,{activeClassName:a.activeClassName??(t?"menu__link--active":"navbar__link--active")}))}var c=n(71003),d=n(23247),f=n(20130);const p="searchBox_ZlJk";function h(e){let{children:t,className:n}=e;return r.createElement("div",{className:(0,a.default)(n,p)},t)}var m=n(4452),g=n(85919);var v=n(4049),b=n(11614),y=n(16550);const w=e=>e.docs.find((t=>t.id===e.mainDocId));const x={default:u,localeDropdown:d.Z,search:function(e){let{mobile:t,className:n}=e;return t?null:r.createElement(h,{className:n},r.createElement(f.default,null))},dropdown:c.default,html:function(e){let{value:t,className:n,mobile:o=!1,isDropdownItem:i=!1}=e;const l=i?"li":"div";return r.createElement(l,{className:(0,a.default)({navbar__item:!o&&!i,"menu__list-item":o},n),dangerouslySetInnerHTML:{__html:t}})},doc:function(e){let{docId:t,label:n,docsPluginId:a,...i}=e;const{activeDoc:l}=(0,m.useActiveDocContext)(a),s=(0,g.vY)(t,a);return null===s?null:r.createElement(u,(0,o.Z)({exact:!0},i,{isActive:()=>(null==l?void 0:l.path)===s.path||!(null==l||!l.sidebar)&&l.sidebar===s.sidebar,label:n??s.id,to:s.path}))},docSidebar:function(e){let{sidebarId:t,label:n,docsPluginId:a,...i}=e;const{activeDoc:l}=(0,m.useActiveDocContext)(a),s=(0,g.oz)(t,a).link;if(!s)throw new Error(`DocSidebarNavbarItem: Sidebar with ID "${t}" doesn't have anything to be linked to.`);return r.createElement(u,(0,o.Z)({exact:!0},i,{isActive:()=>(null==l?void 0:l.sidebar)===t,label:n??s.label,to:s.path}))},docsVersion:function(e){let{label:t,to:n,docsPluginId:a,...i}=e;const l=(0,g.lO)(a)[0],s=t??l.label,c=n??(e=>e.docs.find((t=>t.id===e.mainDocId)))(l).path;return r.createElement(u,(0,o.Z)({},i,{label:s,to:c}))},docsVersionDropdown:function(e){let{mobile:t,docsPluginId:n,dropdownActiveClassDisabled:a,dropdownItemsBefore:i,dropdownItemsAfter:l,...s}=e;const{search:d,hash:f}=(0,y.TH)(),p=(0,m.useActiveDocContext)(n),h=(0,m.useVersions)(n),{savePreferredVersionName:x}=(0,v.J)(n),_=[...i,...h.map((e=>{const t=p.alternateDocVersions[e.name]??w(e);return{label:e.label,to:`${t.path}${d}${f}`,isActive:()=>e===p.activeVersion,onClick:()=>x(e.name)}})),...l],k=(0,g.lO)(n)[0],E=t&&_.length>1?(0,b.translate)({id:"theme.navbar.mobileVersionsDropdown.label",message:"Versions",description:"The label for the navbar versions dropdown on mobile view"}):k.label,S=t&&_.length>1?void 0:w(k).path;return _.length<=1?r.createElement(u,(0,o.Z)({},s,{mobile:t,label:E,to:S,isActive:a?()=>!1:void 0})):r.createElement(c.default,(0,o.Z)({},s,{mobile:t,label:E,to:S,items:_,isActive:a?()=>!1:void 0}))}};function _(e){let{type:t,...n}=e;const o=function(e,t){return e&&"default"!==e?e:"items"in t?"dropdown":"default"}(t,n),a=x[o];if(!a)throw new Error(`No NavbarItem component found for type "${t}".`);return r.createElement(a,n)}},26145:(e,t,n)=>{"use strict";n.d(t,{Z:()=>a});var r=n(67294),o=n(32411);function a(e){let{locale:t,version:n,tag:a}=e;const i=t;return r.createElement(o.Z,null,t&&r.createElement("meta",{name:"docusaurus_locale",content:t}),n&&r.createElement("meta",{name:"docusaurus_version",content:n}),a&&r.createElement("meta",{name:"docusaurus_tag",content:a}),i&&r.createElement("meta",{name:"docsearch:language",content:i}),n&&r.createElement("meta",{name:"docsearch:version",content:n}),a&&r.createElement("meta",{name:"docsearch:docusaurus_tag",content:a}))}},47002:(e,t,n)=>{"use strict";n.r(t),n.d(t,{default:()=>u});var r=n(87462),o=n(67294),a=n(86010),i=n(5730),l=n(70524);const s={themedImage:"themedImage_ToTc","themedImage--light":"themedImage--light_HNdA","themedImage--dark":"themedImage--dark_i4oU"};function u(e){const t=(0,i.default)(),{colorMode:n}=(0,l.I)(),{sources:u,className:c,alt:d,...f}=e,p=t?"dark"===n?["dark"]:["light"]:["light","dark"];return o.createElement(o.Fragment,null,p.map((e=>o.createElement("img",(0,r.Z)({key:e,src:u[e],alt:d,className:(0,a.default)(s.themedImage,s[`themedImage--${e}`],c)},f)))))}},69061:(e,t,n)=>{"use strict";n.d(t,{nT:()=>h,pl:()=>p});var r=n(67294),o=n(5730),a=n(99200),i=n(93478),l=n(96793);const s=(0,a.WA)("docusaurus.announcement.dismiss"),u=(0,a.WA)("docusaurus.announcement.id"),c=()=>"true"===s.get(),d=e=>s.set(String(e)),f=r.createContext(null);function p(e){let{children:t}=e;const n=function(){const{announcementBar:e}=(0,l.L)(),t=(0,o.default)(),[n,a]=(0,r.useState)((()=>!!t&&c()));(0,r.useEffect)((()=>{a(c())}),[]);const i=(0,r.useCallback)((()=>{d(!0),a(!0)}),[]);return(0,r.useEffect)((()=>{if(!e)return;const{id:t}=e;let n=u.get();"annoucement-bar"===n&&(n="announcement-bar");const r=t!==n;u.set(t),r&&d(!1),!r&&c()||a(!1)}),[e]),(0,r.useMemo)((()=>({isActive:!!e&&!n,close:i})),[e,n,i])}();return r.createElement(f.Provider,{value:n},t)}function h(){const e=(0,r.useContext)(f);if(!e)throw new i.i6("AnnouncementBarProvider");return e}},17762:(e,t,n)=>{"use strict";n.d(t,{C:()=>l,n:()=>i});var r=n(67294),o=n(93478);const a=r.createContext(null);function i(e){let{children:t,content:n,isBlogPostPage:o=!1}=e;const i=function(e){let{content:t,isBlogPostPage:n}=e;return(0,r.useMemo)((()=>({metadata:t.metadata,frontMatter:t.frontMatter,assets:t.assets,toc:t.toc,isBlogPostPage:n})),[t,n])}({content:n,isBlogPostPage:o});return r.createElement(a.Provider,{value:i},t)}function l(){const e=(0,r.useContext)(a);if(null===e)throw new o.i6("BlogPostProvider");return e}},70524:(e,t,n)=>{"use strict";n.d(t,{I:()=>g,S:()=>m});var r=n(67294),o=n(19901),a=n(93478),i=n(99200),l=n(96793);const s=r.createContext(void 0),u="theme",c=(0,i.WA)(u),d="light",f="dark",p=e=>e===f?f:d;function h(){const{colorMode:{defaultMode:e,disableSwitch:t,respectPrefersColorScheme:n}}=(0,l.L)(),[a,i]=(0,r.useState)((e=>o.Z.canUseDOM?p(document.documentElement.getAttribute("data-theme")):p(e))(e));(0,r.useEffect)((()=>{t&&c.del()}),[t]);const s=(0,r.useCallback)((function(t,r){void 0===r&&(r={});const{persist:o=!0}=r;t?(i(t),o&&(e=>{c.set(p(e))})(t)):(i(n?window.matchMedia("(prefers-color-scheme: dark)").matches?f:d:e),c.del())}),[n,e]);(0,r.useEffect)((()=>{document.documentElement.setAttribute("data-theme",p(a))}),[a]),(0,r.useEffect)((()=>{if(t)return;const e=e=>{if(e.key!==u)return;const t=c.get();null!==t&&s(p(t))};return window.addEventListener("storage",e),()=>window.removeEventListener("storage",e)}),[t,s]);const h=(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||h.current?h.current=window.matchMedia("print").matches:s(null)};return e.addListener(r),()=>e.removeListener(r)}),[s,t,n]),(0,r.useMemo)((()=>({colorMode:a,setColorMode:s,get isDarkTheme(){return a===f},setLightTheme(){s(d)},setDarkTheme(){s(f)}})),[a,s])}function m(e){let{children:t}=e;const n=h();return r.createElement(s.Provider,{value:n},t)}function g(){const e=(0,r.useContext)(s);if(null==e)throw new a.i6("ColorModeProvider","Please see https://docusaurus.io/docs/api/themes/configuration#use-color-mode.");return e}},2791:(e,t,n)=>{"use strict";n.d(t,{b:()=>i,k:()=>l});var r=n(67294),o=n(93478);const a=r.createContext(null);function i(e){let{children:t,content:n}=e;const o=function(e){return(0,r.useMemo)((()=>({metadata:e.metadata,frontMatter:e.frontMatter,assets:e.assets,contentTitle:e.contentTitle,toc:e.toc})),[e])}(n);return r.createElement(a.Provider,{value:o},t)}function l(){const e=(0,r.useContext)(a);if(null===e)throw new o.i6("DocProvider");return e}},55132:(e,t,n)=>{"use strict";n.d(t,{D:()=>l,f:()=>s});var r=n(67294),o=n(93478);const a=Symbol("EmptyContext"),i=r.createContext(a);function l(e){let{children:t}=e;const[n,o]=(0,r.useState)(null),a=(0,r.useMemo)((()=>({expandedItem:n,setExpandedItem:o})),[n]);return r.createElement(i.Provider,{value:a},t)}function s(){const e=(0,r.useContext)(i);if(e===a)throw new o.i6("DocSidebarItemsExpandedStateProvider");return e}},4049:(e,t,n)=>{"use strict";n.d(t,{J:()=>y,L5:()=>v,Oh:()=>w});var r=n(67294),o=n(4452),a=n(12497),i=n(96793),l=n(85919),s=n(93478),u=n(99200);const c=e=>`docs-preferred-version-${e}`,d=(e,t,n)=>{(0,u.WA)(c(e),{persistence:t}).set(n)},f=(e,t)=>(0,u.WA)(c(e),{persistence:t}).get(),p=(e,t)=>{(0,u.WA)(c(e),{persistence:t}).del()};const h=r.createContext(null);function m(){const e=(0,o.useAllDocsData)(),t=(0,i.L)().docs.versionPersistence,n=(0,r.useMemo)((()=>Object.keys(e)),[e]),[a,l]=(0,r.useState)((()=>(e=>Object.fromEntries(e.map((e=>[e,{preferredVersionName:null}]))))(n)));(0,r.useEffect)((()=>{l(function(e){let{pluginIds:t,versionPersistence:n,allDocsData:r}=e;function o(e){const t=f(e,n);return r[e].versions.some((e=>e.name===t))?{preferredVersionName:t}:(p(e,n),{preferredVersionName:null})}return Object.fromEntries(t.map((e=>[e,o(e)])))}({allDocsData:e,versionPersistence:t,pluginIds:n}))}),[e,t,n]);return[a,(0,r.useMemo)((()=>({savePreferredVersion:function(e,n){d(e,t,n),l((t=>({...t,[e]:{preferredVersionName:n}})))}})),[t])]}function g(e){let{children:t}=e;const n=m();return r.createElement(h.Provider,{value:n},t)}function v(e){let{children:t}=e;return l.cE?r.createElement(g,null,t):r.createElement(r.Fragment,null,t)}function b(){const e=(0,r.useContext)(h);if(!e)throw new s.i6("DocsPreferredVersionContextProvider");return e}function y(e){void 0===e&&(e=a.m);const t=(0,o.useDocsData)(e),[n,i]=b(),{preferredVersionName:l}=n[e];return{preferredVersion:t.versions.find((e=>e.name===l))??null,savePreferredVersionName:(0,r.useCallback)((t=>{i.savePreferredVersion(e,t)}),[i,e])}}function w(){const e=(0,o.useAllDocsData)(),[t]=b();function n(n){const r=e[n],{preferredVersionName:o}=t[n];return r.versions.find((e=>e.name===o))??null}const r=Object.keys(e);return Object.fromEntries(r.map((e=>[e,n(e)])))}},50003:(e,t,n)=>{"use strict";n.d(t,{V:()=>s,b:()=>l});var r=n(67294),o=n(93478);const a=Symbol("EmptyContext"),i=r.createContext(a);function l(e){let{children:t,name:n,items:o}=e;const a=(0,r.useMemo)((()=>n&&o?{name:n,items:o}:null),[n,o]);return r.createElement(i.Provider,{value:a},t)}function s(){const e=(0,r.useContext)(i);if(e===a)throw new o.i6("DocsSidebarProvider");return e}},6141:(e,t,n)=>{"use strict";n.d(t,{E:()=>l,q:()=>i});var r=n(67294),o=n(93478);const a=r.createContext(null);function i(e){let{children:t,version:n}=e;return r.createElement(a.Provider,{value:n},t)}function l(){const e=(0,r.useContext)(a);if(null===e)throw new o.i6("DocsVersionProvider");return e}},35022:(e,t,n)=>{"use strict";n.d(t,{M:()=>d,e:()=>f});var r=n(67294),o=n(82306),a=n(94980),i=n(34423),l=n(96793),s=n(93478);const u=r.createContext(void 0);function c(){const e=function(){const e=(0,o.HY)(),{items:t}=(0,l.L)().navbar;return 0===t.length&&!e.component}(),t=(0,a.i)(),n=!e&&"mobile"===t,[s,u]=(0,r.useState)(!1);(0,i.Rb)((()=>{if(s)return u(!1),!1}));const c=(0,r.useCallback)((()=>{u((e=>!e))}),[]);return(0,r.useEffect)((()=>{"desktop"===t&&u(!1)}),[t]),(0,r.useMemo)((()=>({disabled:e,shouldRender:n,toggle:c,shown:s})),[e,n,c,s])}function d(e){let{children:t}=e;const n=c();return r.createElement(u.Provider,{value:n},t)}function f(){const e=r.useContext(u);if(void 0===e)throw new s.i6("NavbarMobileSidebarProvider");return e}},82306:(e,t,n)=>{"use strict";n.d(t,{HY:()=>l,Zo:()=>s,n2:()=>i});var r=n(67294),o=n(93478);const a=r.createContext(null);function i(e){let{children:t}=e;const n=(0,r.useState)({component:null,props:null});return r.createElement(a.Provider,{value:n},t)}function l(){const e=(0,r.useContext)(a);if(!e)throw new o.i6("NavbarSecondaryMenuContentProvider");return e[0]}function s(e){let{component:t,props:n}=e;const i=(0,r.useContext)(a);if(!i)throw new o.i6("NavbarSecondaryMenuContentProvider");const[,l]=i,s=(0,o.Ql)(n);return(0,r.useEffect)((()=>{l({component:t,props:s})}),[l,t,s]),(0,r.useEffect)((()=>()=>l({component:null,props:null})),[l]),null}},20883:(e,t,n)=>{"use strict";n.d(t,{a:()=>i});var r=n(67294),o=n(63735),a=n(68265);function i(e){let{threshold:t}=e;const[n,i]=(0,r.useState)(!1),l=(0,r.useRef)(!1),{startScroll:s,cancelScroll:u}=(0,o.Ct)();return(0,o.RF)(((e,n)=>{let{scrollY:r}=e;const o=null==n?void 0:n.scrollY;o&&(l.current?l.current=!1:r>=o?(u(),i(!1)):r{e.location.hash&&(l.current=!0,i(!1))})),{shown:n,scrollToTop:()=>s(0)}}},22768:(e,t,n)=>{"use strict";n.d(t,{h:()=>o,t:()=>a});var r=n(67294);const o="navigation-with-keyboard";function a(){(0,r.useEffect)((()=>{function e(e){"keydown"===e.type&&"Tab"===e.key&&document.body.classList.add(o),"mousedown"===e.type&&document.body.classList.remove(o)}return document.addEventListener("keydown",e),document.addEventListener("mousedown",e),()=>{document.body.classList.remove(o),document.removeEventListener("keydown",e),document.removeEventListener("mousedown",e)}}),[])}},69322:(e,t,n)=>{"use strict";n.d(t,{N:()=>o});var r=n(67294);function o(e){void 0===e&&(e=!0),(0,r.useEffect)((()=>(document.body.style.overflow=e?"hidden":"visible",()=>{document.body.style.overflow="visible"})),[e])}},99401:(e,t,n)=>{"use strict";n.d(t,{p:()=>a});var r=n(70524),o=n(96793);function a(){const{prism:e}=(0,o.L)(),{colorMode:t}=(0,r.I)(),n=e.theme,a=e.darkTheme||n;return"dark"===t?a:n}},78586:(e,t,n)=>{"use strict";n.d(t,{S:()=>s});var r=n(67294),o=n(96793);function a(e){const t=e.getBoundingClientRect();return t.top===t.bottom?a(e.parentNode):t}function i(e,t){let{anchorTopOffset:n}=t;const r=e.find((e=>a(e).top>=n));if(r){return function(e){return e.top>0&&e.bottom{e.current=t?0:document.querySelector(".navbar").clientHeight}),[t]),e}function s(e){const t=(0,r.useRef)(void 0),n=l();(0,r.useEffect)((()=>{if(!e)return()=>{};const{linkClassName:r,linkActiveClassName:o,minHeadingLevel:a,maxHeadingLevel:l}=e;function s(){const e=function(e){return Array.from(document.getElementsByClassName(e))}(r),s=function(e){let{minHeadingLevel:t,maxHeadingLevel:n}=e;const r=[];for(let o=t;o<=n;o+=1)r.push(`h${o}.anchor`);return Array.from(document.querySelectorAll(r.join()))}({minHeadingLevel:a,maxHeadingLevel:l}),u=i(s,{anchorTopOffset:n.current}),c=e.find((e=>u&&u.id===function(e){return decodeURIComponent(e.href.substring(e.href.indexOf("#")+1))}(e)));e.forEach((e=>{!function(e,n){n?(t.current&&t.current!==e&&t.current.classList.remove(o),e.classList.add(o),t.current=e):e.classList.remove(o)}(e,e===c)}))}return document.addEventListener("scroll",s),document.addEventListener("resize",s),s(),()=>{document.removeEventListener("scroll",s),document.removeEventListener("resize",s)}}),[e,n])}},94980:(e,t,n)=>{"use strict";n.d(t,{i:()=>u});var r=n(67294),o=n(19901);const a="desktop",i="mobile",l="ssr";function s(){return o.Z.canUseDOM?window.innerWidth>996?a:i:l}function u(){const[e,t]=(0,r.useState)((()=>s()));return(0,r.useEffect)((()=>{function e(){t(s())}return window.addEventListener("resize",e),()=>{window.removeEventListener("resize",e),clearTimeout(undefined)}}),[]),e}},93945:(e,t,n)=>{"use strict";n.r(t),n.d(t,{Collapsible:()=>S,ErrorBoundaryError:()=>q.aG,ErrorBoundaryTryAgainButton:()=>q.Cw,ErrorCauseBoundary:()=>q.QW,HtmlClassNameProvider:()=>O.FG,NavbarSecondaryMenuFiller:()=>P.Zo,PageMetadata:()=>O.d,ReactContextError:()=>T.i6,SkipToContentFallbackId:()=>V.u,SkipToContentLink:()=>V.l,ThemeClassNames:()=>C.k,composeProviders:()=>T.Qc,createStorageSlot:()=>o.WA,duplicates:()=>z.l,filterDocCardListItems:()=>i.MN,isMultiColumnFooterLinks:()=>F.a,isRegexpStringMatch:()=>B,listStorageKeys:()=>o._f,listTagsByLetters:()=>L,prefersReducedMotion:()=>g.n,processAdmonitionProps:()=>H,translateTagsPageTitle:()=>I,uniq:()=>z.j,useCollapsible:()=>v,useColorMode:()=>D.I,useContextualSearchFilters:()=>a._q,useCurrentSidebarCategory:()=>i.jA,useDocsPreferredVersion:()=>U.J,useEvent:()=>T.zX,useIsomorphicLayoutEffect:()=>T.LI,usePluralForm:()=>p,usePrevious:()=>T.D9,usePrismTheme:()=>$.p,useSearchLinkCreator:()=>M,useSearchQueryString:()=>j,useStorageSlot:()=>o.Nk,useThemeConfig:()=>r.L,useWindowSize:()=>N.i});var r=n(96793),o=n(99200),a=n(39105),i=n(85919),l=n(67294),s=n(6832);const u=["zero","one","two","few","many","other"];function c(e){return u.filter((t=>e.includes(t)))}const d={locale:"en",pluralForms:c(["one","other"]),select:e=>1===e?"one":"other"};function f(){const{i18n:{currentLocale:e}}=(0,s.default)();return(0,l.useMemo)((()=>{try{return function(e){const t=new Intl.PluralRules(e);return{locale:e,pluralForms:c(t.resolvedOptions().pluralCategories),select:e=>t.select(e)}}(e)}catch(t){return console.error(`Failed to use Intl.PluralRules for locale "${e}".\nDocusaurus will fallback to the default (English) implementation.\nError: ${t.message}\n`),d}}),[e])}function p(){const e=f();return{selectMessage:(t,n)=>function(e,t,n){const r=e.split("|");if(1===r.length)return r[0];r.length>n.pluralForms.length&&console.error(`For locale=${n.locale}, a maximum of ${n.pluralForms.length} plural forms are expected (${n.pluralForms.join(",")}), but the message contains ${r.length}: ${e}`);const o=n.select(t),a=n.pluralForms.indexOf(o);return r[Math.min(a,r.length-1)]}(n,t,e)}}var h=n(87462),m=n(19901),g=n(39657);function v(e){let{initialState:t}=e;const[n,r]=(0,l.useState)(t??!1),o=(0,l.useCallback)((()=>{r((e=>!e))}),[]);return{collapsed:n,setCollapsed:r,toggleCollapsed:o}}const b={display:"none",overflow:"hidden",height:"0px"},y={display:"block",overflow:"visible",height:"auto"};function w(e,t){const n=t?b:y;e.style.display=n.display,e.style.overflow=n.overflow,e.style.height=n.height}function x(e){let{collapsibleRef:t,collapsed:n,animation:r}=e;const o=(0,l.useRef)(!1);(0,l.useEffect)((()=>{const e=t.current;function a(){const t=e.scrollHeight,n=(null==r?void 0:r.duration)??function(e){if((0,g.n)())return 1;const t=e/36;return Math.round(10*(4+15*t**.25+t/5))}(t);return{transition:`height ${n}ms ${(null==r?void 0:r.easing)??"ease-in-out"}`,height:`${t}px`}}function i(){const t=a();e.style.transition=t.transition,e.style.height=t.height}if(!o.current)return w(e,n),void(o.current=!0);return e.style.willChange="height",function(){const t=requestAnimationFrame((()=>{n?(i(),requestAnimationFrame((()=>{e.style.height=b.height,e.style.overflow=b.overflow}))):(e.style.display="block",requestAnimationFrame((()=>{i()})))}));return()=>cancelAnimationFrame(t)}()}),[t,n,r])}function _(e){if(!m.Z.canUseDOM)return e?b:y}function k(e){let{as:t="div",collapsed:n,children:r,animation:o,onCollapseTransitionEnd:a,className:i,disableSSRStyle:s}=e;const u=(0,l.useRef)(null);return x({collapsibleRef:u,collapsed:n,animation:o}),l.createElement(t,{ref:u,style:s?void 0:_(n),onTransitionEnd:e=>{"height"===e.propertyName&&(w(u.current,n),null==a||a(n))},className:i},r)}function E(e){let{collapsed:t,...n}=e;const[r,o]=(0,l.useState)(!t),[a,i]=(0,l.useState)(t);return(0,l.useLayoutEffect)((()=>{t||o(!0)}),[t]),(0,l.useLayoutEffect)((()=>{r&&i(t)}),[r,t]),r?l.createElement(k,(0,h.Z)({},n,{collapsed:a})):null}function S(e){let{lazy:t,...n}=e;const r=t?E:k;return l.createElement(r,n)}var C=n(18015),T=n(93478),O=n(44873),D=n(70524),P=n(82306),N=n(94980),A=n(11614);const I=()=>(0,A.translate)({id:"theme.tags.tagsPageTitle",message:"Tags",description:"The title of the tag list page"});function L(e){const t={};return Object.values(e).forEach((e=>{const n=function(e){return e[0].toUpperCase()}(e.label);t[n]??=[],t[n].push(e)})),Object.entries(t).sort(((e,t)=>{let[n]=e,[r]=t;return n.localeCompare(r)})).map((e=>{let[t,n]=e;return{letter:t,tags:n.sort(((e,t)=>e.label.localeCompare(t.label)))}}))}var R=n(34423);function j(){return(0,R.Nc)("q")}function M(){const{siteConfig:{baseUrl:e,themeConfig:t}}=(0,s.default)(),{algolia:{searchPagePath:n}}=t;return(0,l.useCallback)((t=>`${e}${n}?q=${encodeURIComponent(t)}`),[e,n])}var F=n(68211);function B(e,t){return void 0!==e&&void 0!==t&&new RegExp(e,"gi").test(t)}var z=n(20636),$=n(99401),U=n(4049);function H(e){const{mdxAdmonitionTitle:t,rest:n}=function(e){const t=l.Children.toArray(e),n=t.find((e=>{var t;return l.isValidElement(e)&&"mdxAdmonitionTitle"===(null==(t=e.props)?void 0:t.mdxType)})),r=l.createElement(l.Fragment,null,t.filter((e=>e!==n)));return{mdxAdmonitionTitle:null==n?void 0:n.props.children,rest:r}}(e.children),r=e.title??t;return{...e,...r&&{title:r},children:n}}var V=n(66470),q=n(48348)},13616:(e,t,n)=>{"use strict";n.r(t),n.d(t,{AnnouncementBarProvider:()=>c.pl,BlogPostProvider:()=>s.n,Collapsible:()=>r.Collapsible,ColorModeProvider:()=>O.S,DEFAULT_SEARCH_TAG:()=>N.HX,DocProvider:()=>l.b,DocSidebarItemsExpandedStateProvider:()=>o.D,DocsPreferredVersionContextProvider:()=>u.L5,DocsSidebarProvider:()=>i.b,DocsVersionProvider:()=>a.q,ErrorBoundaryError:()=>r.ErrorBoundaryError,ErrorBoundaryTryAgainButton:()=>r.ErrorBoundaryTryAgainButton,ErrorCauseBoundary:()=>r.ErrorCauseBoundary,HtmlClassNameProvider:()=>r.HtmlClassNameProvider,NavbarProvider:()=>U,NavbarSecondaryMenuFiller:()=>r.NavbarSecondaryMenuFiller,PageMetadata:()=>r.PageMetadata,PluginHtmlClassNameProvider:()=>z.VC,ReactContextError:()=>r.ReactContextError,ScrollControllerProvider:()=>F.OC,SkipToContentFallbackId:()=>r.SkipToContentFallbackId,SkipToContentLink:()=>r.SkipToContentLink,ThemeClassNames:()=>r.ThemeClassNames,composeProviders:()=>r.composeProviders,containsLineNumbers:()=>P.nt,createStorageSlot:()=>r.createStorageSlot,docVersionSearchTag:()=>N.os,duplicates:()=>r.duplicates,filterDocCardListItems:()=>r.filterDocCardListItems,findFirstCategoryLink:()=>A.Wl,findSidebarCategory:()=>A.em,getPrismCssVariables:()=>P.QC,isActiveSidebarItem:()=>A._F,isDocsPluginEnabled:()=>A.cE,isMultiColumnFooterLinks:()=>r.isMultiColumnFooterLinks,isRegexpStringMatch:()=>r.isRegexpStringMatch,isSamePath:()=>B.Mg,keyboardFocusedClassName:()=>q.h,listStorageKeys:()=>r.listStorageKeys,listTagsByLetters:()=>r.listTagsByLetters,parseCodeBlockTitle:()=>P.bc,parseLanguage:()=>P.Vo,parseLines:()=>P.nZ,prefersReducedMotion:()=>r.prefersReducedMotion,processAdmonitionProps:()=>r.processAdmonitionProps,splitNavbarItems:()=>$,translateTagsPageTitle:()=>r.translateTagsPageTitle,uniq:()=>r.uniq,useAlternatePageUtils:()=>D.l,useAnnouncementBar:()=>c.nT,useBackToTopButton:()=>Y.a,useBlogPost:()=>s.C,useCodeWordWrap:()=>Q,useCollapsible:()=>r.useCollapsible,useColorMode:()=>r.useColorMode,useContextualSearchFilters:()=>r.useContextualSearchFilters,useCurrentSidebarCategory:()=>r.useCurrentSidebarCategory,useDoc:()=>l.k,useDocById:()=>A.xz,useDocRouteMetadata:()=>A.hI,useDocSidebarItemsExpandedState:()=>o.f,useDocsPreferredVersion:()=>r.useDocsPreferredVersion,useDocsPreferredVersionByPluginId:()=>u.Oh,useDocsSidebar:()=>i.V,useDocsVersion:()=>a.E,useDocsVersionCandidates:()=>A.lO,useEvent:()=>r.useEvent,useFilteredAndTreeifiedTOC:()=>M.b,useHideableNavbar:()=>V,useHistoryPopHandler:()=>p.Rb,useHistorySelector:()=>p.xL,useHomePageRoute:()=>B.Ns,useIsomorphicLayoutEffect:()=>r.useIsomorphicLayoutEffect,useKeyboardNavigation:()=>q.t,useLayoutDoc:()=>A.vY,useLayoutDocsSidebar:()=>A.oz,useLocalPathname:()=>j,useLocationChange:()=>L.S,useLockBodyScroll:()=>G.N,useNavbarMobileSidebar:()=>x.e,useNavbarSecondaryMenu:()=>T,usePluralForm:()=>r.usePluralForm,usePrevious:()=>r.usePrevious,usePrismTheme:()=>r.usePrismTheme,useQueryStringValue:()=>p._X,useScrollController:()=>F.sG,useScrollPosition:()=>F.RF,useScrollPositionBlocker:()=>F.o5,useSearchLinkCreator:()=>r.useSearchLinkCreator,useSearchQueryString:()=>r.useSearchQueryString,useSidebarBreadcrumbs:()=>A.s1,useSmoothScrollTo:()=>F.Ct,useStorageSlot:()=>r.useStorageSlot,useTOCHighlight:()=>H.S,useTabs:()=>w,useThemeConfig:()=>r.useThemeConfig,useTitleFormatter:()=>I.p,useTreeifiedTOC:()=>M.a,useWindowSize:()=>r.useWindowSize});var r=n(93945),o=n(55132),a=n(6141),i=n(50003),l=n(2791),s=n(17762),u=n(4049),c=n(69061),d=n(67294),f=n(16550),p=n(34423),h=n(20636),m=n(99200);function g(e){return function(e){var t;return(null==(t=d.Children.map(e,(e=>{if(!e||(0,d.isValidElement)(e)&&function(e){const{props:t}=e;return!!t&&"object"==typeof t&&"value"in t}(e))return e;throw new Error(`Docusaurus error: Bad child <${"string"==typeof e.type?e.type:e.type.name}>: all children of the component should be , and every should have a unique "value" prop.`)})))?void 0:t.filter(Boolean))??[]}(e).map((e=>{let{props:{value:t,label:n,attributes:r,default:o}}=e;return{value:t,label:n,attributes:r,default:o}}))}function v(e){const{values:t,children:n}=e;return(0,d.useMemo)((()=>{const e=t??g(n);return function(e){const t=(0,h.l)(e,((e,t)=>e.value===t.value));if(t.length>0)throw new Error(`Docusaurus error: Duplicate values "${t.map((e=>e.value)).join(", ")}" found in . Every value needs to be unique.`)}(e),e}),[t,n])}function b(e){let{value:t,tabValues:n}=e;return n.some((e=>e.value===t))}function y(e){let{queryString:t=!1,groupId:n}=e;const r=(0,f.k6)(),o=function(e){let{queryString:t=!1,groupId:n}=e;if("string"==typeof t)return t;if(!1===t)return null;if(!0===t&&!n)throw new Error('Docusaurus error: The component groupId prop is required if queryString=true, because this value is used as the search param name. You can also provide an explicit value such as queryString="my-search-param".');return n??null}({queryString:t,groupId:n});return[(0,p._X)(o),(0,d.useCallback)((e=>{if(!o)return;const t=new URLSearchParams(r.location.search);t.set(o,e),r.replace({...r.location,search:t.toString()})}),[o,r])]}function w(e){const{defaultValue:t,queryString:n=!1,groupId:r}=e,o=v(e),[a,i]=(0,d.useState)((()=>function(e){let{defaultValue:t,tabValues:n}=e;if(0===n.length)throw new Error("Docusaurus error: the component requires at least one children component");if(t){if(!b({value:t,tabValues:n}))throw new Error(`Docusaurus error: The has a defaultValue "${t}" but none of its children has the corresponding value. Available values are: ${n.map((e=>e.value)).join(", ")}. If you intend to show no default tab, use defaultValue={null} instead.`);return t}const r=n.find((e=>e.default))??n[0];if(!r)throw new Error("Unexpected error: 0 tabValues");return r.value}({defaultValue:t,tabValues:o}))),[l,s]=y({queryString:n,groupId:r}),[u,c]=function(e){let{groupId:t}=e;const n=function(e){return e?`docusaurus.tab.${e}`:null}(t),[r,o]=(0,m.Nk)(n);return[r,(0,d.useCallback)((e=>{n&&o.set(e)}),[n,o])]}({groupId:r}),f=(()=>{const e=l??u;return b({value:e,tabValues:o})?e:null})();(0,d.useLayoutEffect)((()=>{f&&i(f)}),[f]);return{selectedValue:a,selectValue:(0,d.useCallback)((e=>{if(!b({value:e,tabValues:o}))throw new Error(`Can't select invalid tab value=${e}`);i(e),s(e),c(e)}),[s,c,o]),tabValues:o}}var x=n(35022),_=n(93478),k=n(82306);const E=d.createContext(null);function S(e){let{children:t}=e;const n=function(){const e=(0,x.e)(),t=(0,k.HY)(),[n,r]=(0,d.useState)(!1),o=null!==t.component,a=(0,_.D9)(o);return(0,d.useEffect)((()=>{o&&!a&&r(!0)}),[o,a]),(0,d.useEffect)((()=>{o?e.shown||r(!0):r(!1)}),[e.shown,o]),(0,d.useMemo)((()=>[n,r]),[n])}();return d.createElement(E.Provider,{value:n},t)}function C(e){if(e.component){const t=e.component;return d.createElement(t,e.props)}}function T(){const e=(0,d.useContext)(E);if(!e)throw new _.i6("NavbarSecondaryMenuDisplayProvider");const[t,n]=e,r=(0,d.useCallback)((()=>n(!1)),[n]),o=(0,k.HY)();return(0,d.useMemo)((()=>({shown:t,hide:r,content:C(o)})),[r,o,t])}var O=n(70524),D=n(13156),P=n(96066),N=n(39105),A=n(85919),I=n(71427),L=n(68265),R=n(6832);function j(){const{siteConfig:{baseUrl:e}}=(0,R.default)(),{pathname:t}=(0,f.TH)();return t.replace(e,"/")}var M=n(94462),F=n(63735),B=n(18407),z=n(44873);function $(e){function t(e){return"left"===(e.position??"right")}return[e.filter(t),e.filter((e=>!t(e)))]}function U(e){let{children:t}=e;return d.createElement(k.n2,null,d.createElement(x.M,null,d.createElement(S,null,t)))}var H=n(78586);function V(e){const[t,n]=(0,d.useState)(e),r=(0,d.useRef)(!1),o=(0,d.useRef)(0),a=(0,d.useCallback)((e=>{null!==e&&(o.current=e.getBoundingClientRect().height)}),[]);return(0,F.RF)(((t,a)=>{let{scrollY:i}=t;if(!e)return;if(i=l?n(!1):i+u{if(!e)return;const o=t.location.hash;if(o?document.getElementById(o.substring(1)):void 0)return r.current=!0,void n(!1);n(!0)})),{navbarRef:a,isNavbarVisible:t}}var q=n(22768),G=n(69322);const W={attributes:!0,characterData:!0,childList:!0,subtree:!0};function Z(e,t){const[n,r]=(0,d.useState)(),o=(0,d.useCallback)((()=>{var t;r(null==(t=e.current)?void 0:t.closest("[role=tabpanel][hidden]"))}),[e,r]);(0,d.useEffect)((()=>{o()}),[o]),function(e,t,n){void 0===n&&(n=W);const r=(0,_.zX)(t),o=(0,_.Ql)(n);(0,d.useEffect)((()=>{const t=new MutationObserver(r);return e&&t.observe(e,o),()=>t.disconnect()}),[e,r,o])}(n,(e=>{e.forEach((e=>{"attributes"===e.type&&"hidden"===e.attributeName&&(t(),o())}))}),{attributes:!0,characterData:!1,childList:!1,subtree:!1})}function Q(){const[e,t]=(0,d.useState)(!1),[n,r]=(0,d.useState)(!1),o=(0,d.useRef)(null),a=(0,d.useCallback)((()=>{const n=o.current.querySelector("code");e?n.removeAttribute("style"):(n.style.whiteSpace="pre-wrap",n.style.overflowWrap="anywhere"),t((e=>!e))}),[o,e]),i=(0,d.useCallback)((()=>{const{scrollWidth:e,clientWidth:t}=o.current,n=e>t||o.current.querySelector("code").hasAttribute("style");r(n)}),[o]);return Z(o,i),(0,d.useEffect)((()=>{i()}),[e,i]),(0,d.useEffect)((()=>(window.addEventListener("resize",i,{passive:!0}),()=>{window.removeEventListener("resize",i)})),[i]),{codeBlockRef:o,isEnabled:e,isCodeScrollable:n,toggle:a}}var Y=n(20883)},18015:(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:{}}},39657:(e,t,n)=>{"use strict";function r(){return window.matchMedia("(prefers-reduced-motion: reduce)").matches}n.d(t,{n:()=>r})},96066:(e,t,n)=>{"use strict";n.d(t,{QC:()=>p,Vo:()=>d,bc:()=>u,nZ:()=>f,nt:()=>c});var r=n(87594),o=n.n(r);const a=/title=(?["'])(?.*?)\1/,i=/\{(?<range>[\d,-]+)\}/,l={js:{start:"\\/\\/",end:""},jsBlock:{start:"\\/\\*",end:"\\*\\/"},jsx:{start:"\\{\\s*\\/\\*",end:"\\*\\/\\s*\\}"},bash:{start:"#",end:""},html:{start:"\x3c!--",end:"--\x3e"}};function s(e,t){const n=e.map((e=>{const{start:n,end:r}=l[e];return`(?:${n}\\s*(${t.flatMap((e=>{var t,n;return[e.line,null==(t=e.block)?void 0:t.start,null==(n=e.block)?void 0:n.end].filter(Boolean)})).join("|")})\\s*${r})`})).join("|");return new RegExp(`^\\s*(?:${n})\\s*$`)}function u(e){var t;return(null==e||null==(t=e.match(a))?void 0:t.groups.title)??""}function c(e){return Boolean(null==e?void 0:e.includes("showLineNumbers"))}function d(e){const t=e.split(" ").find((e=>e.startsWith("language-")));return null==t?void 0:t.replace(/language-/,"")}function f(e,t){let n=e.replace(/\n$/,"");const{language:r,magicComments:a,metastring:u}=t;if(u&&i.test(u)){const e=u.match(i).groups.range;if(0===a.length)throw new Error(`A highlight range has been given in code block's metastring (\`\`\` ${u}), but no magic comment config is available. Docusaurus applies the first magic comment entry's className for metastring ranges.`);const t=a[0].className,r=o()(e).filter((e=>e>0)).map((e=>[e-1,[t]]));return{lineClassNames:Object.fromEntries(r),code:n}}if(void 0===r)return{lineClassNames:{},code:n};const c=function(e,t){switch(e){case"js":case"javascript":case"ts":case"typescript":return s(["js","jsBlock"],t);case"jsx":case"tsx":return s(["js","jsBlock","jsx"],t);case"html":return s(["js","jsBlock","html"],t);case"python":case"py":case"bash":return s(["bash"],t);case"markdown":case"md":return s(["html","jsx","bash"],t);default:return s(Object.keys(l),t)}}(r,a),d=n.split("\n"),f=Object.fromEntries(a.map((e=>[e.className,{start:0,range:""}]))),p=Object.fromEntries(a.filter((e=>e.line)).map((e=>{let{className:t,line:n}=e;return[n,t]}))),h=Object.fromEntries(a.filter((e=>e.block)).map((e=>{let{className:t,block:n}=e;return[n.start,t]}))),m=Object.fromEntries(a.filter((e=>e.block)).map((e=>{let{className:t,block:n}=e;return[n.end,t]})));for(let o=0;o<d.length;){const e=d[o].match(c);if(!e){o+=1;continue}const t=e.slice(1).find((e=>void 0!==e));p[t]?f[p[t]].range+=`${o},`:h[t]?f[h[t]].start=o:m[t]&&(f[m[t]].range+=`${f[m[t]].start}-${o-1},`),d.splice(o,1)}n=d.join("\n");const g={};return Object.entries(f).forEach((e=>{let[t,{range:n}]=e;o()(n).forEach((e=>{g[e]??=[],g[e].push(t)}))})),{lineClassNames:g,code:n}}function p(e){const t={color:"--prism-color",backgroundColor:"--prism-background-color"},n={};return Object.entries(e.plain).forEach((e=>{let[r,o]=e;const a=t[r];a&&"string"==typeof o&&(n[a]=o)})),n}},85919:(e,t,n)=>{"use strict";n.d(t,{MN:()=>S,Wl:()=>m,_F:()=>b,cE:()=>f,em:()=>h,hI:()=>E,jA:()=>g,lO:()=>x,oz:()=>_,s1:()=>w,vY:()=>k,xz:()=>p});var r=n(67294),o=n(16550),a=n(18790),i=n(4452),l=n(4049),s=n(6141),u=n(50003),c=n(20636),d=n(18407);const f=!!i.useAllDocsData;function p(e){const t=(0,s.E)();if(!e)return;const n=t.docs[e];if(!n)throw new Error(`no version doc found by id=${e}`);return n}function h(e,t){for(const n of e)if("category"===n.type){if(t(n))return n;const e=h(n.items,t);if(e)return e}}function m(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=m(t);if(e)return e}}}function g(){const{pathname:e}=(0,o.TH)(),t=(0,u.V)();if(!t)throw new Error("Unexpected: cant find current sidebar in context");const n=y({sidebarItems:t.items,pathname:e,onlyCategories:!0}).slice(-1)[0];if(!n)throw new Error(`${e} is not associated with a category. useCurrentSidebarCategory() should only be used on category index pages.`);return n}const v=(e,t)=>void 0!==e&&(0,d.Mg)(e,t);function b(e,t){return"link"===e.type?v(e.href,t):"category"===e.type&&(v(e.href,t)||((e,t)=>e.some((e=>b(e,t))))(e.items,t))}function y(e){let{sidebarItems:t,pathname:n,onlyCategories:r=!1}=e;const o=[];return function e(t){for(const a of t)if("category"===a.type&&((0,d.Mg)(a.href,n)||e(a.items))||"link"===a.type&&(0,d.Mg)(a.href,n)){return r&&"category"!==a.type||o.unshift(a),!0}return!1}(t),o}function w(){var e;const t=(0,u.V)(),{pathname:n}=(0,o.TH)();return!1!==(null==(e=(0,i.useActivePlugin)())?void 0:e.pluginData.breadcrumbs)&&t?y({sidebarItems:t.items,pathname:n}):null}function x(e){const{activeVersion:t}=(0,i.useActiveDocContext)(e),{preferredVersion:n}=(0,l.J)(e),o=(0,i.useLatestVersion)(e);return(0,r.useMemo)((()=>(0,c.j)([t,n,o].filter(Boolean))),[t,n,o])}function _(e,t){const n=x(t);return(0,r.useMemo)((()=>{const t=n.flatMap((e=>e.sidebars?Object.entries(e.sidebars):[])),r=t.find((t=>t[0]===e));if(!r)throw new Error(`Can't find any sidebar with id "${e}" in version${n.length>1?"s":""} ${n.map((e=>e.name)).join(", ")}".\nAvailable sidebar ids are:\n- ${t.map((e=>e[0])).join("\n- ")}`);return r[1]}),[e,n])}function k(e,t){const n=x(t);return(0,r.useMemo)((()=>{const t=n.flatMap((e=>e.docs)),r=t.find((t=>t.id===e));if(!r){if(n.flatMap((e=>e.draftIds)).includes(e))return null;throw new Error(`Couldn't find any doc with id "${e}" in version${n.length>1?"s":""} "${n.map((e=>e.name)).join(", ")}".\nAvailable doc ids are:\n- ${(0,c.j)(t.map((e=>e.id))).join("\n- ")}`)}return r}),[e,n])}function E(e){let{route:t,versionMetadata:n}=e;const r=(0,o.TH)(),i=t.routes,l=i.find((e=>(0,o.LX)(r.pathname,e)));if(!l)return null;const s=l.sidebar,u=s?n.docsSidebars[s]:void 0;return{docElement:(0,a.H)(i),sidebarName:s,sidebarItems:u}}function S(e){return e.filter((e=>"category"!==e.type||!!m(e)))}},48348:(e,t,n)=>{"use strict";n.d(t,{aG:()=>u,Cw:()=>s,QW:()=>c});var r=n(87462),o=n(67294),a=n(11614),i=n(79861);const l="errorBoundaryError_a6uf";function s(e){return o.createElement("button",(0,r.Z)({type:"button"},e),o.createElement(a.default,{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 u(e){let{error:t}=e;const n=(0,i.getErrorCausalChain)(t).map((e=>e.message)).join("\n\nCause:\n");return o.createElement("p",{className:l},n)}class c extends o.Component{componentDidCatch(e,t){throw this.props.onError(e,t)}render(){return this.props.children}}},68211:(e,t,n)=>{"use strict";function r(e){return"title"in e[0]}n.d(t,{a:()=>r})},71427:(e,t,n)=>{"use strict";n.d(t,{p:()=>o});var r=n(6832);function o(e){const{siteConfig:t}=(0,r.default)(),{title:n,titleDelimiter:o}=t;return null!=e&&e.trim().length?`${e.trim()} ${o} ${n}`:n}},34423:(e,t,n)=>{"use strict";n.d(t,{Nc:()=>c,Rb:()=>l,_X:()=>u,xL:()=>s});var r=n(67294),o=n(16550),a=n(61688),i=n(93478);function l(e){!function(e){const t=(0,o.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 s(e){const t=(0,o.k6)();return(0,a.useSyncExternalStore)(t.listen,(()=>e(t)),(()=>e(t)))}function u(e){return s((t=>null===e?null:new URLSearchParams(t.location.search).get(e)))}function c(e){const t=u(e)??"",n=function(){const e=(0,o.k6)();return(0,r.useCallback)(((t,n,r)=>{const o=new URLSearchParams(e.location.search);n?o.set(t,n):o.delete(t),(null!=r&&r.push?e.push:e.replace)({search:o.toString()})}),[e])}();return[t,(0,r.useCallback)(((t,r)=>{n(e,t,r)}),[n,e])]}},20636:(e,t,n)=>{"use strict";function r(e,t){return void 0===t&&(t=(e,t)=>e===t),e.filter(((n,r)=>e.findIndex((e=>t(e,n)))!==r))}function o(e){return Array.from(new Set(e))}n.d(t,{j:()=>o,l:()=>r})},44873:(e,t,n)=>{"use strict";n.d(t,{FG:()=>f,d:()=>c,VC:()=>p});var r=n(67294),o=n(86010),a=n(32411),i=n(66041);function l(){const e=r.useContext(i._);if(!e)throw new Error("Unexpected: no Docusaurus route context found");return e}var s=n(51402),u=n(71427);function c(e){let{title:t,description:n,keywords:o,image:i,children:l}=e;const c=(0,u.p)(t),{withBaseUrl:d}=(0,s.useBaseUrlUtils)(),f=i?d(i,{absolute:!0}):void 0;return r.createElement(a.Z,null,t&&r.createElement("title",null,c),t&&r.createElement("meta",{property:"og:title",content:c}),n&&r.createElement("meta",{name:"description",content:n}),n&&r.createElement("meta",{property:"og:description",content:n}),o&&r.createElement("meta",{name:"keywords",content:Array.isArray(o)?o.join(","):o}),f&&r.createElement("meta",{property:"og:image",content:f}),f&&r.createElement("meta",{name:"twitter:image",content:f}),l)}const d=r.createContext(void 0);function f(e){let{className:t,children:n}=e;const i=r.useContext(d),l=(0,o.default)(i,t);return r.createElement(d.Provider,{value:l},r.createElement(a.Z,null,r.createElement("html",{className:l})),n)}function p(e){let{children:t}=e;const n=l(),a=`plugin-${n.plugin.name.replace(/docusaurus-(?:plugin|theme)-(?:content-)?/gi,"")}`;const i=`plugin-id-${n.plugin.id}`;return r.createElement(f,{className:(0,o.default)(a,i)},t)}},93478:(e,t,n)=>{"use strict";n.d(t,{D9:()=>i,LI:()=>o,Qc:()=>u,Ql:()=>s,i6:()=>l,zX:()=>a});var r=n(67294);const o=n(19901).Z.canUseDOM?r.useLayoutEffect:r.useEffect;function a(e){const t=(0,r.useRef)(e);return o((()=>{t.current=e}),[e]),(0,r.useCallback)((function(){return t.current(...arguments)}),[])}function i(e){const t=(0,r.useRef)();return o((()=>{t.current=e})),t.current}class l extends Error{constructor(e,t){var n,r,o;super(),this.name="ReactContextError",this.message=`Hook ${(null==(n=this.stack)||null==(r=n.split("\n")[1])||null==(o=r.match(/at (?:\w+\.)?(?<name>\w+)/))?void 0:o.groups.name)??""} is called outside the <${e}>. ${t??""}`}}function s(e){const t=Object.entries(e);return t.sort(((e,t)=>e[0].localeCompare(t[0]))),(0,r.useMemo)((()=>e),t.flat())}function u(e){return t=>{let{children:n}=t;return r.createElement(r.Fragment,null,e.reduceRight(((e,t)=>r.createElement(t,null,e)),n))}}},18407:(e,t,n)=>{"use strict";n.d(t,{Mg:()=>i,Ns:()=>l});var r=n(67294),o=n(21204),a=n(6832);function i(e,t){const n=e=>{var t;return null==(t=!e||e.endsWith("/")?e:`${e}/`)?void 0:t.toLowerCase()};return n(e)===n(t)}function l(){const{baseUrl:e}=(0,a.default)().siteConfig;return(0,r.useMemo)((()=>function(e){let{baseUrl:t,routes:n}=e;function r(e){return e.path===t&&!0===e.exact}function o(e){return e.path===t&&!e.exact}return function e(t){if(0===t.length)return;return t.find(r)||e(t.filter(o).flatMap((e=>e.routes??[])))}(n)}({routes:o.Z,baseUrl:e})),[e])}},63735:(e,t,n)=>{"use strict";n.d(t,{Ct:()=>p,OC:()=>s,RF:()=>d,o5:()=>f,sG:()=>u});var r=n(67294),o=n(19901),a=n(5730),i=n(93478);const l=r.createContext(void 0);function s(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(l.Provider,{value:n},t)}function u(){const e=(0,r.useContext)(l);if(null==e)throw new i.i6("ScrollControllerProvider");return e}const c=()=>o.Z.canUseDOM?{scrollX:window.pageXOffset,scrollY:window.pageYOffset}:null;function d(e,t){void 0===t&&(t=[]);const{scrollEventsEnabledRef:n}=u(),o=(0,r.useRef)(c()),a=(0,i.zX)(e);(0,r.useEffect)((()=>{const e=()=>{if(!n.current)return;const e=c();a(e,o.current),o.current=e},t={passive:!0};return e(),window.addEventListener("scroll",e,t),()=>window.removeEventListener("scroll",e,t)}),[a,n,...t])}function f(){const e=u(),t=function(){const e=(0,r.useRef)({elem:null,top:0}),t=(0,r.useCallback)((t=>{e.current={elem:t,top:t.getBoundingClientRect().top}}),[]),n=(0,r.useCallback)((()=>{const{current:{elem:t,top:n}}=e;if(!t)return{restored:!1};const r=t.getBoundingClientRect().top-n;return r&&window.scrollBy({left:0,top:r}),e.current={elem:null,top:0},{restored:0!==r}}),[]);return(0,r.useMemo)((()=>({save:t,restore:n})),[n,t])}(),n=(0,r.useRef)(void 0),o=(0,r.useCallback)((r=>{t.save(r),e.disableScrollEvents(),n.current=()=>{const{restored:r}=t.restore();if(n.current=void 0,r){const t=()=>{e.enableScrollEvents(),window.removeEventListener("scroll",t)};window.addEventListener("scroll",t)}else e.enableScrollEvents()}}),[e,t]);return(0,r.useLayoutEffect)((()=>{queueMicrotask((()=>null==n.current?void 0:n.current()))})),{blockElementScrollPositionUntilNextRender:o}}function p(){const e=(0,r.useRef)(null),t=(0,a.default)()&&"smooth"===getComputedStyle(document.documentElement).scrollBehavior;return{startScroll:n=>{e.current=t?function(e){return window.scrollTo({top:e,behavior:"smooth"}),()=>{}}(n):function(e){let t=null;const n=document.documentElement.scrollTop>e;return function r(){const o=document.documentElement.scrollTop;(n&&o>e||!n&&o<e)&&(t=requestAnimationFrame(r),window.scrollTo(0,Math.floor(.85*(o-e))+e))}(),()=>t&&cancelAnimationFrame(t)}(n)},cancelScroll:()=>null==e.current?void 0:e.current()}}},39105:(e,t,n)=>{"use strict";n.d(t,{HX:()=>i,_q:()=>s,os:()=>l});var r=n(4452),o=n(6832),a=n(4049);const i="default";function l(e,t){return`docs-${e}-${t}`}function s(){const{i18n:e}=(0,o.default)(),t=(0,r.useAllDocsData)(),n=(0,r.useActivePluginAndVersion)(),s=(0,a.Oh)();const u=[i,...Object.keys(t).map((function(e){const r=(null==n?void 0:n.activePlugin.pluginId)===e?n.activeVersion:void 0,o=s[e],a=t[e].versions.find((e=>e.isLast));return l(e,(r??o??a).name)}))];return{locale:e.currentLocale,tags:u}}},66470:(e,t,n)=>{"use strict";n.d(t,{l:()=>f,u:()=>s});var r=n(87462),o=n(67294),a=n(16550),i=n(11614),l=n(68265);const s="__docusaurus_skipToContent_fallback";function u(e){e.setAttribute("tabindex","-1"),e.focus(),e.removeAttribute("tabindex")}function c(){const e=(0,o.useRef)(null),{action:t}=(0,a.k6)(),n=(0,o.useCallback)((e=>{e.preventDefault();const t=document.querySelector("main:first-of-type")??document.getElementById(s);t&&u(t)}),[]);return(0,l.S)((n=>{let{location:r}=n;e.current&&!r.hash&&"PUSH"===t&&u(e.current)})),{containerRef:e,onClick:n}}const d=(0,i.translate)({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 f(e){const t=e.children??d,{containerRef:n,onClick:a}=c();return o.createElement("div",{ref:n,role:"region","aria-label":d},o.createElement("a",(0,r.Z)({},e,{href:`#${s}`,onClick:a}),t))}},99200:(e,t,n)=>{"use strict";n.d(t,{Nk:()=>d,WA:()=>c,_f:()=>f});var r=n(67294),o=n(61688);const a="localStorage";function i(e){let{key:t,oldValue:n,newValue:r,storage:o}=e;if(n===r)return;const a=document.createEvent("StorageEvent");a.initStorageEvent("storage",!1,!1,t,n,r,window.location.href,o),window.dispatchEvent(a)}function l(e){if(void 0===e&&(e=a),"undefined"==typeof window)throw new Error("Browser storage is not available on Node.js/Docusaurus SSR process.");if("none"===e)return null;try{return window[e]}catch(n){return t=n,s||(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),s=!0),null}var t}let s=!1;const u={get:()=>null,set:()=>{},del:()=>{},listen:()=>()=>{}};function c(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=l(null==t?void 0:t.persistence);return null===n?u:{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),i({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),i({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),()=>{}}}}}function d(e,t){const n=(0,r.useRef)((()=>null===e?u:c(e,t))).current(),a=(0,r.useCallback)((e=>"undefined"==typeof window?()=>{}:n.listen(e)),[n]);return[(0,o.useSyncExternalStore)(a,(()=>"undefined"==typeof window?null:n.get()),(()=>null)),n]}function f(e){void 0===e&&(e=a);const t=l(e);if(!t)return[];const n=[];for(let r=0;r<t.length;r+=1){const e=t.key(r);null!==e&&n.push(e)}return n}},94462:(e,t,n)=>{"use strict";n.d(t,{a:()=>a,b:()=>l});var r=n(67294);function o(e){const t=e.map((e=>({...e,parentIndex:-1,children:[]}))),n=Array(7).fill(-1);t.forEach(((e,t)=>{const r=n.slice(2,e.level);e.parentIndex=Math.max(...r),n[e.level]=t}));const r=[];return t.forEach((e=>{const{parentIndex:n,...o}=e;n>=0?t[n].children.push(o):r.push(o)})),r}function a(e){return(0,r.useMemo)((()=>o(e)),[e])}function i(e){let{toc:t,minHeadingLevel:n,maxHeadingLevel:r}=e;return t.flatMap((e=>{const t=i({toc:e.children,minHeadingLevel:n,maxHeadingLevel:r});return function(e){return e.level>=n&&e.level<=r}(e)?[{...e,children:t}]:t}))}function l(e){let{toc:t,minHeadingLevel:n,maxHeadingLevel:a}=e;return(0,r.useMemo)((()=>i({toc:o(t),minHeadingLevel:n,maxHeadingLevel:a})),[t,n,a])}},13156:(e,t,n)=>{"use strict";n.d(t,{l:()=>a});var r=n(6832),o=n(16550);function a(){const{siteConfig:{baseUrl:e,url:t},i18n:{defaultLocale:n,currentLocale:a}}=(0,r.default)(),{pathname:i}=(0,o.TH)(),l=a===n?e:e.replace(`/${a}/`,"/"),s=i.replace(e,"");return{createUrl:function(e){let{locale:r,fullyQualified:o}=e;return`${o?t:""}${function(e){return e===n?`${l}`:`${l}${e}/`}(r)}${s}`}}}},68265:(e,t,n)=>{"use strict";n.d(t,{S:()=>i});var r=n(67294),o=n(16550),a=n(93478);function i(e){const t=(0,o.TH)(),n=(0,a.D9)(t),i=(0,a.zX)(e);(0,r.useEffect)((()=>{n&&t!==n&&i({location:t,previousLocation:n})}),[i,t,n])}},96793:(e,t,n)=>{"use strict";n.d(t,{L:()=>o});var r=n(6832);function o(){return(0,r.default)().siteConfig.themeConfig}},54357:(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[o]=e.split(/[#?]/),a="/"===o||o===r?o:(i=o,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(o,a)}},6009:(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]}},79861: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 o=n(54357);Object.defineProperty(t,"applyTrailingSlash",{enumerable:!0,get:function(){return r(o).default}});var a=n(6009);Object.defineProperty(t,"getErrorCausalChain",{enumerable:!0,get:function(){return a.getErrorCausalChain}})},78007:(e,t,n)=>{"use strict";n.r(t),n.d(t,{fetchIndexes:()=>l,legacyFetchIndexes:()=>s});var r=n(31336),o=n.n(r),a=n(96059);const i=new Map;function l(e,t){const n=`${e}${t}`;let r=i.get(n);return r||(r=s(e,t),i.set(n,r)),r}async function s(e,t){{const n=`${e}${a.searchIndexUrl.replace("{dir}",t?`-${t.replace(/\//g,"-")}`:"")}`;if(new URL(n,location.origin).origin!==location.origin)throw new Error("Unexpected version url");const r=await(await fetch(n)).json(),i=r.map(((e,t)=>{let{documents:n,index:r}=e;return{type:t,documents:n,index:o().Index.load(r)}})),l=r.reduce(((e,t)=>{for(const n of t.index.invertedIndex)/\p{Unified_Ideograph}/u.test(n[0][0])&&e.add(n[0]);return e}),new Set);return{wrappedIndexes:i,zhDictionary:Array.from(l)}}}},58263:(e,t,n)=>{"use strict";n.r(t),n.d(t,{SearchSourceFactory:()=>s});var r=n(31336),o=n.n(r);var a=n(96059);function i(e){return l(e).concat(l(e.filter((e=>{const t=e[e.length-1];return!t.trailing&&t.maybeTyping})),!0))}function l(e,t){return e.map((e=>({tokens:e.map((e=>e.value)),term:e.map((e=>({value:e.value,presence:o().Query.presence.REQUIRED,wildcard:(t?e.trailing||e.maybeTyping:e.trailing)?o().Query.wildcard.TRAILING:o().Query.wildcard.NONE})))})))}function s(e,t,n){return function(r,l){const s=function(e,t){if(1===t.length&&["ja","jp","th"].includes(t[0]))return o()[t[0]].tokenizer(e).map((e=>e.toString()));let n=/[^-\s]+/g;return t.includes("zh")&&(n=/\w+|\p{Unified_Ideograph}+/gu),e.toLowerCase().match(n)||[]}(r,a.language);if(0===s.length)return void l([]);const u=function(e,t){const n=function(e,t){const n=[];return function e(r,o){if(0===r.length)return void n.push(o);const a=r[0];if(/\p{Unified_Ideograph}/u.test(a)){const n=function(e,t){const n=[];return function e(r,o){let a=0,i=!1;for(const l of t)if(r.substr(0,l.length)===l){const t={missed:o.missed,term:o.term.concat({value:l})};r.length>l.length?e(r.substr(l.length),t):n.push(t),i=!0}else for(let t=l.length-1;t>a;t-=1){const s=l.substr(0,t);if(r.substr(0,t)===s){a=t;const l={missed:o.missed,term:o.term.concat({value:s,trailing:!0})};r.length>t?e(r.substr(t),l):n.push(l),i=!0;break}}i||(r.length>0?e(r.substr(1),{missed:o.missed+1,term:o.term}):o.term.length>0&&n.push(o))}(e,{missed:0,term:[]}),n.sort(((e,t)=>{const n=e.missed>0?1:0,r=t.missed>0?1:0;return n!==r?n-r:e.term.length-t.term.length})).map((e=>e.term))}(a,t);for(const t of n){const n=o.concat(...t);e(r.slice(1),n)}}else{const t=o.concat({value:a});e(r.slice(1),t)}}(e,[]),n}(e,t);if(0===n.length)return[{tokens:e,term:e.map((e=>({value:e,presence:o().Query.presence.REQUIRED,wildcard:o().Query.wildcard.LEADING|o().Query.wildcard.TRAILING})))}];for(const o of n)o[o.length-1].maybeTyping=!0;const r=[];for(const i of a.language)if("en"===i)a.removeDefaultStopWordFilter||r.unshift(o().stopWordFilter);else{const e=o()[i];e.stopWordFilter&&r.unshift(e.stopWordFilter)}let l;if(r.length>0){const e=e=>r.reduce(((e,t)=>e.filter((e=>t(e.value)))),e);l=[];const t=[];for(const r of n){const n=e(r);l.push(n),n.length<r.length&&n.length>0&&t.push(n)}n.push(...t)}else l=n.slice();const s=[];for(const o of l)if(o.length>2)for(let e=o.length-1;e>=0;e-=1)s.push(o.slice(0,e).concat(o.slice(e+1)));return i(n).concat(i(s))}(s,t),c=[];e:for(const{term:t,tokens:o}of u)for(const{documents:r,index:a,type:i}of e)if(c.push(...a.query((e=>{for(const n of t)e.term(n.value,{wildcard:n.wildcard,presence:n.presence})})).slice(0,n).filter((e=>!c.some((t=>t.document.i.toString()===e.ref)))).slice(0,n-c.length).map((t=>{const n=r.find((e=>e.i.toString()===t.ref));return{document:n,type:i,page:0!==i&&e[0].documents.find((e=>e.i===n.p)),metadata:t.matchData.metadata,tokens:o,score:t.score}}))),c.length>=n)break e;!function(e){e.forEach(((e,t)=>{e.index=t})),e.sort(((t,n)=>{let r=t.type>0&&t.page?e.findIndex((e=>e.document===t.page)):t.index,o=n.type>0&&n.page?e.findIndex((e=>e.document===n.page)):n.index;return-1===r&&(r=t.index),-1===o&&(o=n.index),r===o?0===t.type?-1:0===n.type?1:t.index-n.index:r-o}))}(c),function(e){e.forEach(((t,n)=>{n>0&&t.page&&e.some((e=>e.document===t.page))&&(n<e.length-1&&e[n+1].page===t.page?t.isInterOfTree=!0:t.isLastOfTree=!0)}))}(c),l(c)}}},84647:(e,t,n)=>{"use strict";function r(e,t){const n=[];for(const r of Object.values(e))r[t]&&n.push(...r[t].position);return n.sort(((e,t)=>e[0]-t[0]||t[1]-e[1]))}n.r(t),n.d(t,{getStemmedPositions:()=>r})},32438:(e,t,n)=>{"use strict";function r(e){return e.replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""").replace(/'/g,"'")}function o(e,t,n){const a=[];for(const i of t){const n=e.toLowerCase().indexOf(i);if(n>=0){n>0&&a.push(o(e.substr(0,n),t)),a.push(`<mark>${r(e.substr(n,i.length))}</mark>`);const l=n+i.length;l<e.length&&a.push(o(e.substr(l),t));break}}return 0===a.length?n?`<mark>${r(e)}</mark>`:r(e):a.join("")}n.r(t),n.d(t,{highlightStemmed:()=>s,splitIntoChunks:()=>u});const a=/\w+|\p{Unified_Ideograph}/u;function i(e){const t=[];let n=0,r=e;for(;r.length>0;){const o=r.match(a);if(!o){t.push(r);break}o.index>0&&t.push(r.substring(0,o.index)),t.push(o[0]),n+=o.index+o[0].length,r=e.substring(n)}return t}var l=n(96059);function s(e,t,n,r){void 0===r&&(r=l.searchResultContextMaxLength);const{chunkIndex:o,chunks:a}=u(e,t,n),i=a.slice(0,o),s=a[o],c=[s.html],d=a.slice(o+1);let f=s.textLength,p=0,h=0,m=!1,g=!1;for(;f<r;)if((p<=h||0===d.length)&&i.length>0){const e=i.pop();f+e.textLength<=r?(c.unshift(e.html),p+=e.textLength,f+=e.textLength):(m=!0,i.length=0)}else{if(!(d.length>0))break;{const e=d.shift();f+e.textLength<=r?(c.push(e.html),h+=e.textLength,f+=e.textLength):(g=!0,d.length=0)}}return(m||i.length>0)&&c.unshift("\u2026"),(g||d.length>0)&&c.push("\u2026"),c.join("")}function u(e,t,n){const a=[];let l=0,s=0,u=-1;for(;l<t.length;){const[c,d]=t[l];if(l+=1,!(c<s)){if(c>s){const t=i(e.substring(s,c)).map((e=>({html:r(e),textLength:e.length})));for(const e of t)a.push(e)}-1===u&&(u=a.length),s=c+d,a.push({html:o(e.substring(c,s),n,!0),textLength:d})}}if(s<e.length){const t=i(e.substring(s)).map((e=>({html:r(e),textLength:e.length})));for(const e of t)a.push(e)}return{chunkIndex:u,chunks:a}}},96059:(e,t,n)=>{"use strict";n.r(t),n.d(t,{Mark:()=>i,docsPluginIdForPreferredVersion:()=>h,explicitSearchResultPath:()=>c,hideSearchBarWithNoSearchContext:()=>v,indexDocs:()=>m,language:()=>r,removeDefaultStemmer:()=>a,removeDefaultStopWordFilter:()=>o,searchBarPosition:()=>p,searchBarShortcut:()=>d,searchBarShortcutHint:()=>f,searchContextByPaths:()=>g,searchIndexUrl:()=>l,searchResultContextMaxLength:()=>u,searchResultLimits:()=>s});n(31336);const r=["en"],o=!1,a=!1,i=null,l="search-index{dir}.json?_=722dc11b",s=8,u=50,c=!1,d=!0,f=!0,p="left",h=void 0,m=!0,g=null,v=!1},9463:(e,t,n)=>{"use strict";n.d(t,{Z:()=>g});var r=function(){function e(e){var t=this;this._insertTag=function(e){var n;n=0===t.tags.length?t.insertionPoint?t.insertionPoint.nextSibling:t.prepend?t.container.firstChild:t.before:t.tags[t.tags.length-1].nextSibling,t.container.insertBefore(e,n),t.tags.push(e)},this.isSpeedy=void 0===e.speedy||e.speedy,this.tags=[],this.ctr=0,this.nonce=e.nonce,this.key=e.key,this.container=e.container,this.prepend=e.prepend,this.insertionPoint=e.insertionPoint,this.before=null}var t=e.prototype;return t.hydrate=function(e){e.forEach(this._insertTag)},t.insert=function(e){this.ctr%(this.isSpeedy?65e3:1)==0&&this._insertTag(function(e){var t=document.createElement("style");return t.setAttribute("data-emotion",e.key),void 0!==e.nonce&&t.setAttribute("nonce",e.nonce),t.appendChild(document.createTextNode("")),t.setAttribute("data-s",""),t}(this));var t=this.tags[this.tags.length-1];if(this.isSpeedy){var n=function(e){if(e.sheet)return e.sheet;for(var t=0;t<document.styleSheets.length;t++)if(document.styleSheets[t].ownerNode===e)return document.styleSheets[t]}(t);try{n.insertRule(e,n.cssRules.length)}catch(r){0}}else t.appendChild(document.createTextNode(e));this.ctr++},t.flush=function(){this.tags.forEach((function(e){return e.parentNode&&e.parentNode.removeChild(e)})),this.tags=[],this.ctr=0},e}(),o=n(46411),a=n(26686),i=n(27563),l=n(20211);var s=n(92190),u=function(e,t,n){for(var r=0,a=0;r=a,a=(0,o.fj)(),38===r&&12===a&&(t[n]=1),!(0,o.r)(a);)(0,o.lp)();return(0,o.tP)(e,o.FK)},c=function(e,t){return(0,o.cE)(function(e,t){var n=-1,r=44;do{switch((0,o.r)(r)){case 0:38===r&&12===(0,o.fj)()&&(t[n]=1),e[n]+=u(o.FK-1,t,n);break;case 2:e[n]+=(0,o.iF)(r);break;case 4:if(44===r){e[++n]=58===(0,o.fj)()?"&\f":"",t[n]=e[n].length;break}default:e[n]+=(0,a.Dp)(r)}}while(r=(0,o.lp)());return e}((0,o.un)(e),t))},d=new WeakMap,f=function(e){if("rule"===e.type&&e.parent&&!(e.length<1)){for(var t=e.value,n=e.parent,r=e.column===n.column&&e.line===n.line;"rule"!==n.type;)if(!(n=n.parent))return;if((1!==e.props.length||58===t.charCodeAt(0)||d.get(n))&&!r){d.set(e,!0);for(var o=[],a=c(t,o),i=n.props,l=0,s=0;l<a.length;l++)for(var u=0;u<i.length;u++,s++)e.props[s]=o[l]?a[l].replace(/&\f/g,i[u]):i[u]+" "+a[l]}}},p=function(e){if("decl"===e.type){var t=e.value;108===t.charCodeAt(0)&&98===t.charCodeAt(2)&&(e.return="",e.value="")}};function h(e,t){switch((0,a.vp)(e,t)){case 5103:return i.G$+"print-"+e+e;case 5737:case 4201:case 3177:case 3433:case 1641:case 4457:case 2921:case 5572:case 6356:case 5844:case 3191:case 6645:case 3005:case 6391:case 5879:case 5623:case 6135:case 4599:case 4855:case 4215:case 6389:case 5109:case 5365:case 5621:case 3829:return i.G$+e+e;case 5349:case 4246:case 4810:case 6968:case 2756:return i.G$+e+i.uj+e+i.MS+e+e;case 6828:case 4268:return i.G$+e+i.MS+e+e;case 6165:return i.G$+e+i.MS+"flex-"+e+e;case 5187:return i.G$+e+(0,a.gx)(e,/(\w+).+(:[^]+)/,i.G$+"box-$1$2"+i.MS+"flex-$1$2")+e;case 5443:return i.G$+e+i.MS+"flex-item-"+(0,a.gx)(e,/flex-|-self/,"")+e;case 4675:return i.G$+e+i.MS+"flex-line-pack"+(0,a.gx)(e,/align-content|flex-|-self/,"")+e;case 5548:return i.G$+e+i.MS+(0,a.gx)(e,"shrink","negative")+e;case 5292:return i.G$+e+i.MS+(0,a.gx)(e,"basis","preferred-size")+e;case 6060:return i.G$+"box-"+(0,a.gx)(e,"-grow","")+i.G$+e+i.MS+(0,a.gx)(e,"grow","positive")+e;case 4554:return i.G$+(0,a.gx)(e,/([^-])(transform)/g,"$1"+i.G$+"$2")+e;case 6187:return(0,a.gx)((0,a.gx)((0,a.gx)(e,/(zoom-|grab)/,i.G$+"$1"),/(image-set)/,i.G$+"$1"),e,"")+e;case 5495:case 3959:return(0,a.gx)(e,/(image-set\([^]*)/,i.G$+"$1$`$1");case 4968:return(0,a.gx)((0,a.gx)(e,/(.+:)(flex-)?(.*)/,i.G$+"box-pack:$3"+i.MS+"flex-pack:$3"),/s.+-b[^;]+/,"justify")+i.G$+e+e;case 4095:case 3583:case 4068:case 2532:return(0,a.gx)(e,/(.+)-inline(.+)/,i.G$+"$1$2")+e;case 8116:case 7059:case 5753:case 5535:case 5445:case 5701:case 4933:case 4677:case 5533:case 5789:case 5021:case 4765:if((0,a.to)(e)-1-t>6)switch((0,a.uO)(e,t+1)){case 109:if(45!==(0,a.uO)(e,t+4))break;case 102:return(0,a.gx)(e,/(.+:)(.+)-([^]+)/,"$1"+i.G$+"$2-$3$1"+i.uj+(108==(0,a.uO)(e,t+3)?"$3":"$2-$3"))+e;case 115:return~(0,a.Cw)(e,"stretch")?h((0,a.gx)(e,"stretch","fill-available"),t)+e:e}break;case 4949:if(115!==(0,a.uO)(e,t+1))break;case 6444:switch((0,a.uO)(e,(0,a.to)(e)-3-(~(0,a.Cw)(e,"!important")&&10))){case 107:return(0,a.gx)(e,":",":"+i.G$)+e;case 101:return(0,a.gx)(e,/(.+:)([^;!]+)(;|!.+)?/,"$1"+i.G$+(45===(0,a.uO)(e,14)?"inline-":"")+"box$3$1"+i.G$+"$2$3$1"+i.MS+"$2box$3")+e}break;case 5936:switch((0,a.uO)(e,t+11)){case 114:return i.G$+e+i.MS+(0,a.gx)(e,/[svh]\w+-[tblr]{2}/,"tb")+e;case 108:return i.G$+e+i.MS+(0,a.gx)(e,/[svh]\w+-[tblr]{2}/,"tb-rl")+e;case 45:return i.G$+e+i.MS+(0,a.gx)(e,/[svh]\w+-[tblr]{2}/,"lr")+e}return i.G$+e+i.MS+e+e}return e}var m=[function(e,t,n,r){if(e.length>-1&&!e.return)switch(e.type){case i.h5:e.return=h(e.value,e.length);break;case i.lK:return(0,l.q)([(0,o.JG)(e,{value:(0,a.gx)(e.value,"@","@"+i.G$)})],r);case i.Fr:if(e.length)return(0,a.$e)(e.props,(function(t){switch((0,a.EQ)(t,/(::plac\w+|:read-\w+)/)){case":read-only":case":read-write":return(0,l.q)([(0,o.JG)(e,{props:[(0,a.gx)(t,/:(read-\w+)/,":"+i.uj+"$1")]})],r);case"::placeholder":return(0,l.q)([(0,o.JG)(e,{props:[(0,a.gx)(t,/:(plac\w+)/,":"+i.G$+"input-$1")]}),(0,o.JG)(e,{props:[(0,a.gx)(t,/:(plac\w+)/,":"+i.uj+"$1")]}),(0,o.JG)(e,{props:[(0,a.gx)(t,/:(plac\w+)/,i.MS+"input-$1")]})],r)}return""}))}}],g=function(e){var t=e.key;if("css"===t){var n=document.querySelectorAll("style[data-emotion]:not([data-s])");Array.prototype.forEach.call(n,(function(e){-1!==e.getAttribute("data-emotion").indexOf(" ")&&(document.head.appendChild(e),e.setAttribute("data-s",""))}))}var o=e.stylisPlugins||m;var i,u,c={},d=[];i=e.container||document.head,Array.prototype.forEach.call(document.querySelectorAll('style[data-emotion^="'+t+' "]'),(function(e){for(var t=e.getAttribute("data-emotion").split(" "),n=1;n<t.length;n++)c[t[n]]=!0;d.push(e)}));var h=[f,p];var g,v,b,y,w=[l.P,(y=function(e){g.insert(e)},function(e){e.root||(e=e.return)&&y(e)})],x=(v=h.concat(o,w),b=(0,a.Ei)(v),function(e,t,n,r){for(var o="",a=0;a<b;a++)o+=v[a](e,t,n,r)||"";return o});u=function(e,t,n,r){var o;g=n,o=e?e+"{"+t.styles+"}":t.styles,(0,l.q)((0,s.MY)(o),x),r&&(_.inserted[t.name]=!0)};var _={key:t,sheet:new r({key:t,container:i,nonce:e.nonce,speedy:e.speedy,prepend:e.prepend,insertionPoint:e.insertionPoint}),nonce:e.nonce,inserted:c,registered:{},insert:u};return _.sheet.hydrate(d),_}},45042:(e,t,n)=>{"use strict";function r(e){var t=Object.create(null);return function(n){return void 0===t[n]&&(t[n]=e(n)),t[n]}}n.d(t,{Z:()=>r})},80123:(e,t,n)=>{"use strict";n.d(t,{C:()=>m,E:()=>C,T:()=>b,_:()=>g,a:()=>x,b:()=>_,c:()=>E,h:()=>p,i:()=>f,u:()=>y,w:()=>v});var r=n(67294),o=n(9463);function a(){return a=Object.assign?Object.assign.bind():function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e},a.apply(this,arguments)}var i=function(e){var t=new WeakMap;return function(n){if(t.has(n))return t.get(n);var r=e(n);return t.set(n,r),r}},l=n(8679),s=n.n(l),u=n(70444),c=n(48137),d=n(27278),f=!0,p={}.hasOwnProperty,h=r.createContext("undefined"!=typeof HTMLElement?(0,o.Z)({key:"css"}):null);var m=h.Provider,g=function(){return(0,r.useContext)(h)},v=function(e){return(0,r.forwardRef)((function(t,n){var o=(0,r.useContext)(h);return e(t,o,n)}))};f||(v=function(e){return function(t){var n=(0,r.useContext)(h);return null===n?(n=(0,o.Z)({key:"css"}),r.createElement(h.Provider,{value:n},e(t,n))):e(t,n)}});var b=r.createContext({});var y=function(){return r.useContext(b)},w=i((function(e){return i((function(t){return function(e,t){return"function"==typeof t?t(e):a({},e,t)}(e,t)}))})),x=function(e){var t=r.useContext(b);return e.theme!==t&&(t=w(t)(e.theme)),r.createElement(b.Provider,{value:t},e.children)};function _(e){var t,n,o=e.displayName||e.name||"Component",i=function(t,n){var o=r.useContext(b);return r.createElement(e,a({theme:o,ref:n},t))},l=r.forwardRef(i);return l.displayName="WithTheme("+o+")",t=l,n=e,s()(t,n)}var k="__EMOTION_TYPE_PLEASE_DO_NOT_USE__",E=function(e,t){var n={};for(var r in t)p.call(t,r)&&(n[r]=t[r]);return n[k]=e,n},S=function(e){var t=e.cache,n=e.serialized,r=e.isStringTag;return(0,u.hC)(t,n,r),(0,d.L)((function(){return(0,u.My)(t,n,r)})),null};var C=v((function(e,t,n){var o=e.css;"string"==typeof o&&void 0!==t.registered[o]&&(o=t.registered[o]);var a=e[k],i=[o],l="";"string"==typeof e.className?l=(0,u.fp)(t.registered,i,e.className):null!=e.className&&(l=e.className+" ");var s=(0,c.O)(i,void 0,r.useContext(b));l+=t.key+"-"+s.name;var d={};for(var f in e)p.call(e,f)&&"css"!==f&&f!==k&&(d[f]=e[f]);return d.ref=n,d.className=l,r.createElement(r.Fragment,null,r.createElement(S,{cache:t,serialized:s,isStringTag:"string"==typeof a}),r.createElement(a,d))}))},70917:(e,t,n)=>{"use strict";n.r(t),n.d(t,{CacheProvider:()=>r.C,ClassNames:()=>m,Global:()=>u,ThemeContext:()=>r.T,ThemeProvider:()=>r.a,__unsafe_useEmotionCache:()=>r._,createElement:()=>s,css:()=>c,jsx:()=>s,keyframes:()=>d,useTheme:()=>r.u,withEmotionCache:()=>r.w,withTheme:()=>r.b});var r=n(80123),o=n(67294),a=n(70444),i=n(27278),l=n(48137),s=(n(9463),n(8679),function(e,t){var n=arguments;if(null==t||!r.h.call(t,"css"))return o.createElement.apply(void 0,n);var a=n.length,i=new Array(a);i[0]=r.E,i[1]=(0,r.c)(e,t);for(var l=2;l<a;l++)i[l]=n[l];return o.createElement.apply(null,i)}),u=(0,r.w)((function(e,t){var n=e.styles,s=(0,l.O)([n],void 0,o.useContext(r.T));if(!r.i){for(var u,c=s.name,d=s.styles,f=s.next;void 0!==f;)c+=" "+f.name,d+=f.styles,f=f.next;var p=!0===t.compat,h=t.insert("",{name:c,styles:d},t.sheet,p);return p?null:o.createElement("style",((u={})["data-emotion"]=t.key+"-global "+c,u.dangerouslySetInnerHTML={__html:h},u.nonce=t.sheet.nonce,u))}var m=o.useRef();return(0,i.j)((function(){var e=t.key+"-global",n=new t.sheet.constructor({key:e,nonce:t.sheet.nonce,container:t.sheet.container,speedy:t.sheet.isSpeedy}),r=!1,o=document.querySelector('style[data-emotion="'+e+" "+s.name+'"]');return t.sheet.tags.length&&(n.before=t.sheet.tags[0]),null!==o&&(r=!0,o.setAttribute("data-emotion",e),n.hydrate([o])),m.current=[n,r],function(){n.flush()}}),[t]),(0,i.j)((function(){var e=m.current,n=e[0];if(e[1])e[1]=!1;else{if(void 0!==s.next&&(0,a.My)(t,s.next,!0),n.tags.length){var r=n.tags[n.tags.length-1].nextElementSibling;n.before=r,n.flush()}t.insert("",s,n,!1)}}),[t,s.name]),null}));function c(){for(var e=arguments.length,t=new Array(e),n=0;n<e;n++)t[n]=arguments[n];return(0,l.O)(t)}var d=function(){var e=c.apply(void 0,arguments),t="animation-"+e.name;return{name:t,styles:"@keyframes "+t+"{"+e.styles+"}",anim:1,toString:function(){return"_EMO_"+this.name+"_"+this.styles+"_EMO_"}}},f=function e(t){for(var n=t.length,r=0,o="";r<n;r++){var a=t[r];if(null!=a){var i=void 0;switch(typeof a){case"boolean":break;case"object":if(Array.isArray(a))i=e(a);else for(var l in i="",a)a[l]&&l&&(i&&(i+=" "),i+=l);break;default:i=a}i&&(o&&(o+=" "),o+=i)}}return o};function p(e,t,n){var r=[],o=(0,a.fp)(e,r,n);return r.length<2?n:o+t(r)}var h=function(e){var t=e.cache,n=e.serializedArr;return(0,i.L)((function(){for(var e=0;e<n.length;e++)(0,a.My)(t,n[e],!1)})),null},m=(0,r.w)((function(e,t){var n=[],i=function(){for(var e=arguments.length,r=new Array(e),o=0;o<e;o++)r[o]=arguments[o];var i=(0,l.O)(r,t.registered);return n.push(i),(0,a.hC)(t,i,!1),t.key+"-"+i.name},s={css:i,cx:function(){for(var e=arguments.length,n=new Array(e),r=0;r<e;r++)n[r]=arguments[r];return p(t.registered,i,f(n))},theme:o.useContext(r.T)},u=e.children(s);return!0,o.createElement(o.Fragment,null,o.createElement(h,{cache:t,serializedArr:n}),u)}))},48137:(e,t,n)=>{"use strict";n.d(t,{O:()=>h});var r={animationIterationCount:1,aspectRatio:1,borderImageOutset:1,borderImageSlice:1,borderImageWidth:1,boxFlex:1,boxFlexGroup:1,boxOrdinalGroup:1,columnCount:1,columns:1,flex:1,flexGrow:1,flexPositive:1,flexShrink:1,flexNegative:1,flexOrder:1,gridRow:1,gridRowEnd:1,gridRowSpan:1,gridRowStart:1,gridColumn:1,gridColumnEnd:1,gridColumnSpan:1,gridColumnStart:1,msGridRow:1,msGridRowSpan:1,msGridColumn:1,msGridColumnSpan:1,fontWeight:1,lineHeight:1,opacity:1,order:1,orphans:1,tabSize:1,widows:1,zIndex:1,zoom:1,WebkitLineClamp:1,fillOpacity:1,floodOpacity:1,stopOpacity:1,strokeDasharray:1,strokeDashoffset:1,strokeMiterlimit:1,strokeOpacity:1,strokeWidth:1},o=n(45042),a=/[A-Z]|^ms/g,i=/_EMO_([^_]+?)_([^]*?)_EMO_/g,l=function(e){return 45===e.charCodeAt(1)},s=function(e){return null!=e&&"boolean"!=typeof e},u=(0,o.Z)((function(e){return l(e)?e:e.replace(a,"-$&").toLowerCase()})),c=function(e,t){switch(e){case"animation":case"animationName":if("string"==typeof t)return t.replace(i,(function(e,t,n){return f={name:t,styles:n,next:f},t}))}return 1===r[e]||l(e)||"number"!=typeof t||0===t?t:t+"px"};function d(e,t,n){if(null==n)return"";if(void 0!==n.__emotion_styles)return n;switch(typeof n){case"boolean":return"";case"object":if(1===n.anim)return f={name:n.name,styles:n.styles,next:f},n.name;if(void 0!==n.styles){var r=n.next;if(void 0!==r)for(;void 0!==r;)f={name:r.name,styles:r.styles,next:f},r=r.next;return n.styles+";"}return function(e,t,n){var r="";if(Array.isArray(n))for(var o=0;o<n.length;o++)r+=d(e,t,n[o])+";";else for(var a in n){var i=n[a];if("object"!=typeof i)null!=t&&void 0!==t[i]?r+=a+"{"+t[i]+"}":s(i)&&(r+=u(a)+":"+c(a,i)+";");else if(!Array.isArray(i)||"string"!=typeof i[0]||null!=t&&void 0!==t[i[0]]){var l=d(e,t,i);switch(a){case"animation":case"animationName":r+=u(a)+":"+l+";";break;default:r+=a+"{"+l+"}"}}else for(var f=0;f<i.length;f++)s(i[f])&&(r+=u(a)+":"+c(a,i[f])+";")}return r}(e,t,n);case"function":if(void 0!==e){var o=f,a=n(e);return f=o,d(e,t,a)}}if(null==t)return n;var i=t[n];return void 0!==i?i:n}var f,p=/label:\s*([^\s;\n{]+)\s*(;|$)/g;var h=function(e,t,n){if(1===e.length&&"object"==typeof e[0]&&null!==e[0]&&void 0!==e[0].styles)return e[0];var r=!0,o="";f=void 0;var a=e[0];null==a||void 0===a.raw?(r=!1,o+=d(n,t,a)):o+=a[0];for(var i=1;i<e.length;i++)o+=d(n,t,e[i]),r&&(o+=a[i]);p.lastIndex=0;for(var l,s="";null!==(l=p.exec(o));)s+="-"+l[1];var u=function(e){for(var t,n=0,r=0,o=e.length;o>=4;++r,o-=4)t=1540483477*(65535&(t=255&e.charCodeAt(r)|(255&e.charCodeAt(++r))<<8|(255&e.charCodeAt(++r))<<16|(255&e.charCodeAt(++r))<<24))+(59797*(t>>>16)<<16),n=1540483477*(65535&(t^=t>>>24))+(59797*(t>>>16)<<16)^1540483477*(65535&n)+(59797*(n>>>16)<<16);switch(o){case 3:n^=(255&e.charCodeAt(r+2))<<16;case 2:n^=(255&e.charCodeAt(r+1))<<8;case 1:n=1540483477*(65535&(n^=255&e.charCodeAt(r)))+(59797*(n>>>16)<<16)}return(((n=1540483477*(65535&(n^=n>>>13))+(59797*(n>>>16)<<16))^n>>>15)>>>0).toString(36)}(o)+s;return{name:u,styles:o,next:f}}},27278:(e,t,n)=>{"use strict";var r;n.d(t,{L:()=>i,j:()=>l});var o=n(67294),a=!!(r||(r=n.t(o,2))).useInsertionEffect&&(r||(r=n.t(o,2))).useInsertionEffect,i=a||function(e){return e()},l=a||o.useLayoutEffect},70444:(e,t,n)=>{"use strict";n.d(t,{My:()=>a,fp:()=>r,hC:()=>o});function r(e,t,n){var r="";return n.split(" ").forEach((function(n){void 0!==e[n]?t.push(e[n]+";"):r+=n+" "})),r}var o=function(e,t,n){var r=e.key+"-"+t.name;!1===n&&void 0===e.registered[r]&&(e.registered[r]=t.styles)},a=function(e,t,n){o(e,t,n);var r=e.key+"-"+t.name;if(void 0===e.inserted[t.name]){var a=t;do{e.insert(t===a?"."+r:"",a,e.sheet,!0),a=a.next}while(void 0!==a)}}},19044:(e,t,n)=>{"use strict";n.r(t),n.d(t,{default:()=>i});var r,o=n(67294);function a(){return a=Object.assign?Object.assign.bind():function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e},a.apply(this,arguments)}const i=e=>{let{title:t,titleId:n,...i}=e;return o.createElement("svg",a({width:18,height:18,viewBox:"0 0 18 18",fill:"none",xmlns:"http://www.w3.org/2000/svg",role:"img","aria-labelledby":n},i),t?o.createElement("title",{id:n},t):null,r||(r=o.createElement("path",{stroke:"#fff",d:"M9 17.5V.5M.5 9h17"})))}},80255:(e,t,n)=>{"use strict";n.r(t),n.d(t,{default:()=>i});var r,o=n(67294);function a(){return a=Object.assign?Object.assign.bind():function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e},a.apply(this,arguments)}const i=e=>{let{title:t,titleId:n,...i}=e;return o.createElement("svg",a({width:20,height:20,viewBox:"0 0 20 20",fill:"none",xmlns:"http://www.w3.org/2000/svg",role:"img","aria-labelledby":n},i),t?o.createElement("title",{id:n},t):null,r||(r=o.createElement("path",{d:"M11.764 5.294 7.06 10l4.705 4.706",stroke:"#000",strokeWidth:2,strokeLinecap:"round",strokeLinejoin:"round"})))}},67146:(e,t,n)=>{"use strict";n.r(t),n.d(t,{default:()=>i});var r,o=n(67294);function a(){return a=Object.assign?Object.assign.bind():function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e},a.apply(this,arguments)}const i=e=>{let{title:t,titleId:n,...i}=e;return o.createElement("svg",a({width:14,height:14,viewBox:"0 0 14 14",fill:"none",xmlns:"http://www.w3.org/2000/svg",role:"img","aria-labelledby":n},i),t?o.createElement("title",{id:n},t):null,r||(r=o.createElement("path",{d:"M11.667 6.417h-7.1l3.261-3.261L7 2.333 2.333 7 7 11.667l.823-.823-3.255-3.26h7.099V6.417Z",fill:"#fff"})))}},68425:(e,t,n)=>{"use strict";n.r(t),n.d(t,{default:()=>l});var r,o,a=n(67294);function i(){return i=Object.assign?Object.assign.bind():function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e},i.apply(this,arguments)}const l=e=>{let{title:t,titleId:n,...l}=e;return a.createElement("svg",i({width:20,height:20,viewBox:"0 0 20 20",fill:"none",xmlns:"http://www.w3.org/2000/svg",role:"img","aria-labelledby":n},l),t?a.createElement("title",{id:n},t):null,r||(r=a.createElement("rect",{width:20,height:20,rx:10,fill:"#000"})),o||(o=a.createElement("path",{d:"m9 8 2 2-2 2",stroke:"#fff",strokeWidth:1.2,strokeLinecap:"round",strokeLinejoin:"round"})))}},88121:(e,t,n)=>{"use strict";n.r(t),n.d(t,{default:()=>i});var r,o=n(67294);function a(){return a=Object.assign?Object.assign.bind():function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e},a.apply(this,arguments)}const i=e=>{let{title:t,titleId:n,...i}=e;return o.createElement("svg",a({width:14,height:14,viewBox:"0 0 14 14",fill:"none",xmlns:"http://www.w3.org/2000/svg",role:"img","aria-labelledby":n},i),t?o.createElement("title",{id:n},t):null,r||(r=o.createElement("path",{d:"m7 2.333-.823.823 3.255 3.26H2.333v1.167h7.1l-3.256 3.261.823.823L11.667 7 7 2.333Z",fill:"#fff"})))}},62082:(e,t,n)=>{"use strict";n.r(t),n.d(t,{default:()=>l});var r,o,a=n(67294);function i(){return i=Object.assign?Object.assign.bind():function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e},i.apply(this,arguments)}const l=e=>{let{title:t,titleId:n,...l}=e;return a.createElement("svg",i({width:40,height:40,viewBox:"0 0 40 40",fill:"none",xmlns:"http://www.w3.org/2000/svg",role:"img","aria-labelledby":n},l),t?a.createElement("title",{id:n},t):null,r||(r=a.createElement("path",{d:"M20 20a3.21 3.21 0 0 1-2.354-.98 3.21 3.21 0 0 1-.98-2.353c0-.917.327-1.702.98-2.355A3.21 3.21 0 0 1 20 13.333a3.21 3.21 0 0 1 2.354.98 3.21 3.21 0 0 1 .98 2.354 3.21 3.21 0 0 1-.98 2.354A3.21 3.21 0 0 1 20 20Zm-6.666 6.667v-2.334c0-.472.121-.906.364-1.302.244-.396.567-.698.969-.906.86-.43 1.736-.754 2.625-.97A11.418 11.418 0 0 1 20 20.834c.917 0 1.82.108 2.709.324.888.215 1.763.538 2.625.968.402.208.725.51.969.907.243.396.364.83.364 1.301v2.334H13.333ZM15 25h10v-.667a.817.817 0 0 0-.417-.708 10.844 10.844 0 0 0-2.27-.843 9.652 9.652 0 0 0-4.625 0c-.764.187-1.521.468-2.271.843a.815.815 0 0 0-.303.292.776.776 0 0 0-.114.416V25Zm5-6.667c.459 0 .851-.163 1.178-.49.326-.326.49-.719.489-1.176 0-.459-.164-.851-.49-1.178A1.602 1.602 0 0 0 20 15c-.458 0-.85.164-1.177.49-.327.328-.49.72-.49 1.178 0 .458.164.85.49 1.177.327.327.72.49 1.177.49Z",fill:"#fff"})),o||(o=a.createElement("rect",{x:.5,y:.5,width:39,height:39,rx:19.5,stroke:"#fff"})))}},80469:(e,t,n)=>{"use strict";n.r(t),n.d(t,{default:()=>i});var r,o=n(67294);function a(){return a=Object.assign?Object.assign.bind():function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e},a.apply(this,arguments)}const i=e=>{let{title:t,titleId:n,...i}=e;return o.createElement("svg",a({width:16,height:16,viewBox:"0 0 16 16",fill:"none",xmlns:"http://www.w3.org/2000/svg",role:"img","aria-labelledby":n},i),t?o.createElement("title",{id:n},t):null,r||(r=o.createElement("path",{d:"m12.667 4.273-.94-.94L8.001 7.06 4.274 3.333l-.94.94L7.061 8l-3.727 3.727.94.94L8.001 8.94l3.726 3.727.94-.94L8.941 8l3.726-3.727Z",fill:"#fff",opacity:.6})))}},94793:(e,t,n)=>{"use strict";n.r(t),n.d(t,{default:()=>i});var r,o=n(67294);function a(){return a=Object.assign?Object.assign.bind():function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e},a.apply(this,arguments)}const i=e=>{let{title:t,titleId:n,...i}=e;return o.createElement("svg",a({width:14,height:14,viewBox:"0 0 14 14",fill:"none",xmlns:"http://www.w3.org/2000/svg",role:"img","aria-labelledby":n},i),t?o.createElement("title",{id:n},t):null,r||(r=o.createElement("path",{d:"M2.917 12.833c-.321 0-.596-.114-.825-.343a1.121 1.121 0 0 1-.342-.823V3.5h1.167v8.167h6.416v1.166H2.917ZM5.25 10.5c-.32 0-.596-.114-.824-.343a1.121 1.121 0 0 1-.343-.824v-7c0-.32.115-.595.343-.824.229-.229.504-.343.824-.342h5.25c.32 0 .596.114.824.343.229.228.343.503.343.823v7c0 .321-.115.596-.343.825a1.121 1.121 0 0 1-.824.342H5.25Zm0-1.167h5.25v-7H5.25v7Z",fill:"#fff"})))}},14607:(e,t,n)=>{"use strict";n.r(t),n.d(t,{default:()=>i});var r,o=n(67294);function a(){return a=Object.assign?Object.assign.bind():function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e},a.apply(this,arguments)}const i=e=>{let{title:t,titleId:n,...i}=e;return o.createElement("svg",a({width:40,height:40,viewBox:"0 0 40 40",fill:"none",xmlns:"http://www.w3.org/2000/svg",role:"img","aria-labelledby":n},i),t?o.createElement("title",{id:n},t):null,r||(r=o.createElement("path",{d:"M14.2 23.077c-1.733 0-3.147-1.575-3.147-3.504 0-1.926 1.379-3.5 3.149-3.5 1.75 0 3.183 1.574 3.148 3.5 0 1.929-1.398 3.504-3.15 3.504Zm11.623 0c-1.733 0-3.15-1.575-3.15-3.504 0-1.926 1.382-3.5 3.15-3.5 1.75 0 3.184 1.574 3.15 3.5 0 1.929-1.381 3.504-3.15 3.504ZM16.875 7.205l-.513-.938-1.057.175a27.255 27.255 0 0 0-6.93 2.133l-.38.177-.237.348C3.403 15.523 2.208 21.847 2.8 28.06l.065.677.55.4a28.181 28.181 0 0 0 8.463 4.238l1.317.403 1.855-4.528c3.183.787 6.717.788 9.898 0l1.845 4.53 1.317-.405a28.033 28.033 0 0 0 8.467-4.24l.545-.397.066-.67c.727-7.2-1.161-13.473-4.93-18.975l-.236-.345-.38-.173a27.625 27.625 0 0 0-6.924-2.133l-1.03-.172-.523.902c-.155.27-.301.544-.438.823a26.463 26.463 0 0 0-5.439 0c-.133-.266-.27-.53-.413-.79Zm-5.683 20.478c.328.19.675.377 1.016.547l-.748 1.827a25.041 25.041 0 0 1-5.713-2.964c-.375-5.231.688-10.508 4.273-15.95a24.256 24.256 0 0 1 4.707-1.521c.1.208.193.411.27.593l.455 1.072 1.153-.169a23.508 23.508 0 0 1 6.817 0l1.15.167.453-1.07c.078-.187.17-.39.267-.593a24.71 24.71 0 0 1 4.713 1.525c3.125 4.7 4.702 9.943 4.243 15.945a24.841 24.841 0 0 1-5.716 2.963l-.742-1.823c.343-.172.69-.359 1.022-.549.816-.47 1.695-1.056 2.255-1.616l-2.134-2.134c-.271.274-.871.7-1.628 1.137-.74.427-1.475.772-1.945.927-3.338 1.105-7.38 1.105-10.72 0-.468-.155-1.203-.5-1.943-.927-.757-.435-1.357-.863-1.63-1.137l-2.134 2.134c.562.56 1.442 1.146 2.259 1.616Z",fill:"#fff"})))}},50437:(e,t,n)=>{"use strict";n.r(t),n.d(t,{default:()=>l});var r,o,a=n(67294);function i(){return i=Object.assign?Object.assign.bind():function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e},i.apply(this,arguments)}const l=e=>{let{title:t,titleId:n,...l}=e;return a.createElement("svg",i({width:71,height:55,viewBox:"0 0 71 55",fill:"none",xmlns:"http://www.w3.org/2000/svg",role:"img","aria-labelledby":n},l),t?a.createElement("title",{id:n},t):null,r||(r=a.createElement("g",{clipPath:"url(#a)"},a.createElement("path",{d:"M60.105 4.898A58.55 58.55 0 0 0 45.653.415a.22.22 0 0 0-.233.11 40.784 40.784 0 0 0-1.8 3.697c-5.456-.817-10.886-.817-16.23 0-.485-1.164-1.201-2.587-1.828-3.697a.228.228 0 0 0-.233-.11 58.386 58.386 0 0 0-14.451 4.483.207.207 0 0 0-.095.082C1.578 18.73-.944 32.144.293 45.39a.244.244 0 0 0 .093.167c6.073 4.46 11.955 7.167 17.729 8.962a.23.23 0 0 0 .249-.082 42.08 42.08 0 0 0 3.627-5.9.225.225 0 0 0-.123-.312 38.772 38.772 0 0 1-5.539-2.64.228.228 0 0 1-.022-.378c.372-.279.744-.569 1.1-.862a.22.22 0 0 1 .23-.03c11.619 5.304 24.198 5.304 35.68 0a.219.219 0 0 1 .233.027c.356.293.728.586 1.103.865a.228.228 0 0 1-.02.378 36.384 36.384 0 0 1-5.54 2.637.227.227 0 0 0-.121.315 47.249 47.249 0 0 0 3.624 5.897.225.225 0 0 0 .249.084c5.801-1.794 11.684-4.502 17.757-8.961a.228.228 0 0 0 .092-.164c1.48-15.315-2.48-28.618-10.497-40.412a.18.18 0 0 0-.093-.084Zm-36.38 32.427c-3.497 0-6.38-3.211-6.38-7.156 0-3.944 2.827-7.156 6.38-7.156 3.583 0 6.438 3.24 6.382 7.156 0 3.945-2.827 7.156-6.381 7.156Zm23.593 0c-3.498 0-6.38-3.211-6.38-7.156 0-3.944 2.826-7.156 6.38-7.156 3.582 0 6.437 3.24 6.38 7.156 0 3.945-2.798 7.156-6.38 7.156Z",fill:"#23272A"}))),o||(o=a.createElement("defs",null,a.createElement("clipPath",{id:"a"},a.createElement("path",{fill:"#fff",d:"M0 0h71v55H0z"})))))}},23179:(e,t,n)=>{"use strict";n.r(t),n.d(t,{default:()=>i});var r,o=n(67294);function a(){return a=Object.assign?Object.assign.bind():function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e},a.apply(this,arguments)}const i=e=>{let{title:t,titleId:n,...i}=e;return o.createElement("svg",a({viewBox:"0 0 24 24",xmlns:"http://www.w3.org/2000/svg",role:"img","aria-labelledby":n},i),void 0===t?o.createElement("title",{id:n},"Discourse"):t?o.createElement("title",{id:n},t):null,r||(r=o.createElement("path",{d:"M12.103 0C18.666 0 24 5.485 24 11.997c0 6.51-5.33 11.99-11.9 11.99L0 24V11.79C0 5.28 5.532 0 12.103 0zm.116 4.563a7.395 7.395 0 0 0-6.337 3.57 7.247 7.247 0 0 0-.148 7.22L4.4 19.61l4.794-1.074a7.424 7.424 0 0 0 8.136-1.39 7.256 7.256 0 0 0 1.737-7.997 7.375 7.375 0 0 0-6.84-4.585h-.008z"})))}},7744:(e,t,n)=>{"use strict";n.r(t),n.d(t,{default:()=>i});var r,o=n(67294);function a(){return a=Object.assign?Object.assign.bind():function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e},a.apply(this,arguments)}const i=e=>{let{title:t,titleId:n,...i}=e;return o.createElement("svg",a({width:16,height:16,viewBox:"0 0 16 16",fill:"none",xmlns:"http://www.w3.org/2000/svg",role:"img","aria-labelledby":n},i),t?o.createElement("title",{id:n},t):null,r||(r=o.createElement("path",{d:"M9.334 1.333H4c-.733 0-1.326.6-1.326 1.334l-.007 10.666c0 .734.593 1.334 1.327 1.334H12c.734 0 1.334-.6 1.334-1.334v-8l-4-4ZM4 13.333V2.667h4.667V6H12v7.333H4Z",fill:"#fff"})))}},19818:(e,t,n)=>{"use strict";n.r(t),n.d(t,{default:()=>i});var r,o=n(67294);function a(){return a=Object.assign?Object.assign.bind():function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e},a.apply(this,arguments)}const i=e=>{let{title:t,titleId:n,...i}=e;return o.createElement("svg",a({width:20,height:20,viewBox:"0 0 20 20",fill:"none",xmlns:"http://www.w3.org/2000/svg",role:"img","aria-labelledby":n},i),t?o.createElement("title",{id:n},t):null,r||(r=o.createElement("circle",{cx:10,cy:10,r:8.333,fill:"#fff"})))}},38981:(e,t,n)=>{"use strict";n.r(t),n.d(t,{default:()=>i});var r,o=n(67294);function a(){return a=Object.assign?Object.assign.bind():function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e},a.apply(this,arguments)}const i=e=>{let{title:t,titleId:n,...i}=e;return o.createElement("svg",a({width:14,height:14,viewBox:"0 0 14 14",fill:"none",xmlns:"http://www.w3.org/2000/svg",role:"img","aria-labelledby":n},i),t?o.createElement("title",{id:n},t):null,r||(r=o.createElement("path",{d:"M7 9.333 4.083 6.417 4.9 5.57l1.517 1.517V2.333h1.166v4.755L9.1 5.57l.817.846L7 9.333Zm-3.5 2.334c-.32 0-.596-.115-.824-.343a1.121 1.121 0 0 1-.343-.824V8.75H3.5v1.75h7V8.75h1.167v1.75c0 .32-.115.596-.343.824a1.121 1.121 0 0 1-.824.343h-7Z",fill:"#fff"})))}},28487:(e,t,n)=>{"use strict";n.r(t),n.d(t,{default:()=>i});var r,o=n(67294);function a(){return a=Object.assign?Object.assign.bind():function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e},a.apply(this,arguments)}const i=e=>{let{title:t,titleId:n,...i}=e;return o.createElement("svg",a({width:12,height:12,viewBox:"0 0 12 12",fill:"none",xmlns:"http://www.w3.org/2000/svg",role:"img","aria-labelledby":n},i),t?o.createElement("title",{id:n},t):null,r||(r=o.createElement("path",{d:"m2 4 4 4 4-4",stroke:"#909091",strokeWidth:1.4,strokeLinecap:"round",strokeLinejoin:"round"})))}},94177:(e,t,n)=>{"use strict";n.r(t),n.d(t,{default:()=>i});var r,o=n(67294);function a(){return a=Object.assign?Object.assign.bind():function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e},a.apply(this,arguments)}const i=e=>{let{title:t,titleId:n,...i}=e;return o.createElement("svg",a({width:16,height:16,viewBox:"0 0 16 16",fill:"none",xmlns:"http://www.w3.org/2000/svg",role:"img","aria-labelledby":n},i),t?o.createElement("title",{id:n},t):null,r||(r=o.createElement("path",{fillRule:"evenodd",clipRule:"evenodd",d:"m12.707 2.393.9.9c.526.52.526 1.367 0 1.887L4.787 14H2v-2.787l6.933-6.94 1.887-1.88c.52-.52 1.367-.52 1.887 0ZM3.333 12.667l.94.04 6.547-6.554-.94-.94-6.547 6.547v.907Z",fill:"#fff"})))}},58611:(e,t,n)=>{"use strict";n.r(t),n.d(t,{default:()=>i});var r,o=n(67294);function a(){return a=Object.assign?Object.assign.bind():function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e},a.apply(this,arguments)}const i=e=>{let{title:t,titleId:n,...i}=e;return o.createElement("svg",a({width:16,height:16,viewBox:"0 0 16 16",fill:"none",xmlns:"http://www.w3.org/2000/svg",role:"img","aria-labelledby":n},i),t?o.createElement("title",{id:n},t):null,r||(r=o.createElement("path",{fillRule:"evenodd",clipRule:"evenodd",d:"M11.192 4H3.428V2.857h9.715v9.715H12V4.808l-8.167 8.168-.809-.808L11.192 4Z",fill:"#fff"})))}},13042:(e,t,n)=>{"use strict";n.r(t),n.d(t,{default:()=>i});var r,o=n(67294);function a(){return a=Object.assign?Object.assign.bind():function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e},a.apply(this,arguments)}const i=e=>{let{title:t,titleId:n,...i}=e;return o.createElement("svg",a({width:20,height:20,viewBox:"0 0 20 20",fill:"none",xmlns:"http://www.w3.org/2000/svg",role:"img","aria-labelledby":n},i),t?o.createElement("title",{id:n},t):null,r||(r=o.createElement("path",{d:"M1.804 16.292a.836.836 0 0 0 .696.374H15a.832.832 0 0 0 .766-.505l2.5-5.833a.833.833 0 0 0-.766-1.162h-.833v-2.5C16.667 5.747 15.919 5 15 5H9.454l-2.13-1.667h-3.99c-.92 0-1.667.748-1.667 1.667v10.833h.006a.834.834 0 0 0 .131.46ZM15 6.666v2.5H5a.832.832 0 0 0-.766.505l-.9 2.103V6.666H15Z",fill:"#000"})))}},96367:(e,t,n)=>{"use strict";n.r(t),n.d(t,{default:()=>i});var r,o=n(67294);function a(){return a=Object.assign?Object.assign.bind():function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e},a.apply(this,arguments)}const i=e=>{let{title:t,titleId:n,...i}=e;return o.createElement("svg",a({width:14,height:14,viewBox:"0 0 14 14",fill:"none",xmlns:"http://www.w3.org/2000/svg",role:"img","aria-labelledby":n},i),t?o.createElement("title",{id:n},t):null,r||(r=o.createElement("path",{d:"M4.667 11.083v-1.75h-1.75V8.166h2.916v2.917H4.667Zm3.5 0V8.166h2.916v1.167h-1.75v1.75H8.167Zm-5.25-5.25V4.666h1.75v-1.75h1.166v2.917H2.917Zm5.25 0V2.916h1.166v1.75h1.75v1.167H8.167Z",fill:"#fff"})))}},6907:(e,t,n)=>{"use strict";n.r(t),n.d(t,{default:()=>i});var r,o=n(67294);function a(){return a=Object.assign?Object.assign.bind():function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e},a.apply(this,arguments)}const i=e=>{let{title:t,titleId:n,...i}=e;return o.createElement("svg",a({width:14,height:14,viewBox:"0 0 14 14",fill:"none",xmlns:"http://www.w3.org/2000/svg",role:"img","aria-labelledby":n},i),t?o.createElement("title",{id:n},t):null,r||(r=o.createElement("path",{d:"M1.75 2.917V5.25h1.167V2.917H5.25V1.75H2.917A1.17 1.17 0 0 0 1.75 2.917ZM2.917 8.75H1.75v2.333a1.17 1.17 0 0 0 1.167 1.167H5.25v-1.167H2.917V8.75Zm8.166 2.333H8.75v1.167h2.333a1.17 1.17 0 0 0 1.167-1.167V8.75h-1.167v2.333Zm0-9.333H8.75v1.167h2.333V5.25h1.167V2.917a1.17 1.17 0 0 0-1.167-1.167Z",fill:"#fff"})))}},59570:(e,t,n)=>{"use strict";n.r(t),n.d(t,{default:()=>i});var r,o=n(67294);function a(){return a=Object.assign?Object.assign.bind():function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e},a.apply(this,arguments)}const i=e=>{let{title:t,titleId:n,...i}=e;return o.createElement("svg",a({width:40,height:40,viewBox:"0 0 40 40",fill:"none",xmlns:"http://www.w3.org/2000/svg",role:"img","aria-labelledby":n},i),t?o.createElement("title",{id:n},t):null,r||(r=o.createElement("path",{d:"M20 4.4a16 16 0 0 0-16 16c0 7.072 4.592 13.072 10.944 15.2.8.128 1.056-.368 1.056-.8v-2.704c-4.432.96-5.376-2.144-5.376-2.144-.736-1.856-1.776-2.352-1.776-2.352-1.456-.992.112-.96.112-.96 1.6.112 2.448 1.648 2.448 1.648C12.8 30.72 15.152 30 16.064 29.616c.144-1.04.56-1.744 1.008-2.144-3.552-.4-7.28-1.776-7.28-7.872 0-1.776.608-3.2 1.648-4.336-.16-.4-.72-2.064.16-4.224 0 0 1.344-.432 4.4 1.632a15.075 15.075 0 0 1 4-.528c1.36 0 2.736.176 4 .528 3.056-2.064 4.4-1.632 4.4-1.632.88 2.16.32 3.824.16 4.224 1.04 1.136 1.648 2.56 1.648 4.336 0 6.112-3.744 7.456-7.312 7.856.576.496 1.104 1.472 1.104 2.96V34.8c0 .432.256.944 1.072.8C31.424 33.456 36 27.472 36 20.4a16.001 16.001 0 0 0-16-16Z",fill:"#fff"})))}},26890:(e,t,n)=>{"use strict";n.r(t),n.d(t,{default:()=>l});var r,o,a=n(67294);function i(){return i=Object.assign?Object.assign.bind():function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e},i.apply(this,arguments)}const l=e=>{let{title:t,titleId:n,...l}=e;return a.createElement("svg",i({xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 512 512",role:"img","aria-labelledby":n},l),t?a.createElement("title",{id:n},t):null,r||(r=a.createElement("path",{d:"M256 411.12 0 202.667 256 0zM256 411.12l256-208.453L256 0z"})),o||(o=a.createElement("circle",{cx:256,cy:362.667,r:149.333})))}},42924:(e,t,n)=>{"use strict";n.r(t),n.d(t,{default:()=>i});var r,o=n(67294);function a(){return a=Object.assign?Object.assign.bind():function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e},a.apply(this,arguments)}const i=e=>{let{title:t,titleId:n,...i}=e;return o.createElement("svg",a({width:16,height:16,viewBox:"0 0 16 16",fill:"none",xmlns:"http://www.w3.org/2000/svg",role:"img","aria-labelledby":n},i),t?o.createElement("title",{id:n},t):null,r||(r=o.createElement("path",{d:"m4 13.333.667-2.666H2.333l.334-1.334H5l.667-2.666H3l.333-1.334H6l.667-2.666H8l-.667 2.666H10l.667-2.666H12l-.667 2.666h2.334l-.334 1.334H11l-.667 2.666H13l-.333 1.334H10l-.667 2.666H8l.667-2.666H6l-.667 2.666H4Zm2.333-4H9l.667-2.666H7l-.667 2.666Z",fill:"#fff"})))}},74297:(e,t,n)=>{"use strict";n.r(t),n.d(t,{default:()=>i});var r,o=n(67294);function a(){return a=Object.assign?Object.assign.bind():function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e},a.apply(this,arguments)}const i=e=>{let{title:t,titleId:n,...i}=e;return o.createElement("svg",a({width:16,height:16,viewBox:"0 0 16 16",fill:"none",xmlns:"http://www.w3.org/2000/svg",role:"img","aria-labelledby":n},i),t?o.createElement("title",{id:n},t):null,r||(r=o.createElement("path",{d:"M8 14c-1.533 0-2.87-.508-4.009-1.525-1.139-1.017-1.791-2.287-1.958-3.808H3.4c.156 1.155.67 2.11 1.542 2.866.872.756 1.892 1.134 3.058 1.134 1.3 0 2.403-.453 3.309-1.359.905-.906 1.358-2.008 1.358-3.308 0-1.3-.453-2.403-1.359-3.309C10.402 3.786 9.3 3.333 8 3.333a4.5 4.5 0 0 0-2.15.534 4.954 4.954 0 0 0-1.683 1.466H6v1.334H2v-4h1.333v1.566A5.954 5.954 0 0 1 8 2c.833 0 1.614.158 2.342.475a6.107 6.107 0 0 1 1.9 1.283c.539.54.966 1.172 1.283 1.9C13.842 6.386 14 7.166 14 8c0 .833-.158 1.614-.475 2.342a6.108 6.108 0 0 1-1.283 1.9 6.11 6.11 0 0 1-1.9 1.283A5.793 5.793 0 0 1 8 14Zm1.867-3.2L7.333 8.267v-3.6h1.334v3.066L10.8 9.867l-.933.933Z",fill:"#fff"})))}},33336:(e,t,n)=>{"use strict";n.r(t),n.d(t,{default:()=>i});var r,o=n(67294);function a(){return a=Object.assign?Object.assign.bind():function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e},a.apply(this,arguments)}const i=e=>{let{title:t,titleId:n,...i}=e;return o.createElement("svg",a({width:16,height:16,viewBox:"0 0 16 16",fill:"none",xmlns:"http://www.w3.org/2000/svg",role:"img","aria-labelledby":n},i),t?o.createElement("title",{id:n},t):null,r||(r=o.createElement("path",{fillRule:"evenodd",clipRule:"evenodd",d:"M0 1.337A1.337 1.337 0 0 1 1.337 0h13.325A1.336 1.336 0 0 1 16 1.337v13.325A1.338 1.338 0 0 1 14.662 16H1.338A1.337 1.337 0 0 1 0 14.662V1.338ZM6.333 6.1H8.5v1.088C8.812 6.563 9.612 6 10.815 6c2.304 0 2.85 1.246 2.85 3.532v4.234h-2.332v-3.714c0-1.301-.313-2.036-1.107-2.036-1.102 0-1.56.792-1.56 2.036v3.714H6.333V6.1Zm-4 7.566h2.333V6H2.333v7.666ZM5 3.5a1.5 1.5 0 1 1-3 .066A1.5 1.5 0 0 1 5 3.5Z",fill:"#000"})))}},78951:(e,t,n)=>{"use strict";n.r(t),n.d(t,{default:()=>i});var r,o=n(67294);function a(){return a=Object.assign?Object.assign.bind():function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e},a.apply(this,arguments)}const i=e=>{let{title:t,titleId:n,...i}=e;return o.createElement("svg",a({width:18,height:18,viewBox:"0 0 18 18",fill:"none",xmlns:"http://www.w3.org/2000/svg",role:"img","aria-labelledby":n},i),t?o.createElement("title",{id:n},t):null,r||(r=o.createElement("path",{stroke:"#fff",d:"M.5 9h17"})))}},84629:(e,t,n)=>{"use strict";n.r(t),n.d(t,{default:()=>l});var r,o,a=n(67294);function i(){return i=Object.assign?Object.assign.bind():function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e},i.apply(this,arguments)}const l=e=>{let{title:t,titleId:n,...l}=e;return a.createElement("svg",i({width:18,height:18,viewBox:"0 0 18 18",fill:"none",xmlns:"http://www.w3.org/2000/svg",role:"img","aria-labelledby":n},l),t?a.createElement("title",{id:n},t):null,r||(r=a.createElement("g",{clipPath:"url(#a)"},a.createElement("path",{fillRule:"evenodd",clipRule:"evenodd",d:"M1.79 6.75a4.979 4.979 0 1 1 9.957 0 4.979 4.979 0 0 1-9.957 0ZM6.768.572a6.179 6.179 0 1 0 3.817 11.037l5.146 5.146a1 1 0 0 0 1.414-1.414l-5.207-5.207A6.179 6.179 0 0 0 6.768.571Z",fill:"#000"}))),o||(o=a.createElement("defs",null,a.createElement("clipPath",{id:"a"},a.createElement("path",{fill:"#fff",d:"M0 0h18v18H0z"})))))}},23816:(e,t,n)=>{"use strict";n.r(t),n.d(t,{default:()=>i});var r,o=n(67294);function a(){return a=Object.assign?Object.assign.bind():function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e},a.apply(this,arguments)}const i=e=>{let{title:t,titleId:n,...i}=e;return o.createElement("svg",a({width:179,height:178,viewBox:"0 0 179 178",fill:"none",xmlns:"http://www.w3.org/2000/svg",role:"img","aria-labelledby":n},i),t?o.createElement("title",{id:n},t):null,r||(r=o.createElement("path",{fillRule:"evenodd",clipRule:"evenodd",d:"M104.512 88.178c-10.667.615-17.352-1.87-28.02-1.254a44.732 44.732 0 0 0-7.853 1.146c1.575-19.73 15.538-36.988 34.525-38.085 11.652-.672 23.298 6.522 23.93 18.2.621 11.479-8.131 19.158-22.58 19.992l-.002.001Zm-28.645 40.355c-11.162.631-22.317-6.104-22.923-17.033-.596-10.742 7.79-17.93 21.633-18.71 10.218-.575 16.623 1.751 26.84 1.174a43.776 43.776 0 0 0 7.522-1.073c-1.506 18.464-14.881 34.617-33.072 35.642ZM89.5.001C40.346 0 .5 39.846.5 89c0 49.154 39.846 89 89 89s89-39.847 89-89-39.846-89-89-89",fill:"#000"})))}},35245:(e,t,n)=>{"use strict";n.r(t),n.d(t,{default:()=>i});var r,o=n(67294);function a(){return a=Object.assign?Object.assign.bind():function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e},a.apply(this,arguments)}const i=e=>{let{title:t,titleId:n,...i}=e;return o.createElement("svg",a({width:40,height:40,viewBox:"0 0 40 40",fill:"none",xmlns:"http://www.w3.org/2000/svg",role:"img","aria-labelledby":n},i),t?o.createElement("title",{id:n},t):null,r||(r=o.createElement("path",{fillRule:"evenodd",clipRule:"evenodd",d:"M4.906 17.987c9.395-4.094 15.66-6.792 18.795-8.096 8.95-3.723 10.81-4.37 12.022-4.39.267-.005.863.06 1.249.374.326.264.416.622.459.873.043.25.096.822.053 1.268-.485 5.097-2.583 17.463-3.65 23.171-.453 2.415-1.342 3.225-2.203 3.304-1.872.172-3.293-1.237-5.106-2.425-2.836-1.86-4.439-3.017-7.192-4.831-3.182-2.097-1.12-3.25.694-5.133.475-.493 8.72-7.993 8.88-8.674.02-.085.039-.402-.15-.57-.188-.167-.466-.11-.667-.064-.284.064-4.816 3.06-13.594 8.985-1.286.883-2.451 1.314-3.495 1.29-1.15-.024-3.364-.65-5.01-1.185-2.018-.656-3.622-1.003-3.483-2.117.073-.58.872-1.174 2.398-1.78Z",fill:"#fff"})))}},68902:(e,t,n)=>{"use strict";n.r(t),n.d(t,{default:()=>i});var r,o=n(67294);function a(){return a=Object.assign?Object.assign.bind():function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e},a.apply(this,arguments)}const i=e=>{let{title:t,titleId:n,...i}=e;return o.createElement("svg",a({width:24,height:24,xmlns:"http://www.w3.org/2000/svg",xmlSpace:"preserve",style:{fillRule:"evenodd",clipRule:"evenodd",strokeLinejoin:"round",strokeMiterlimit:1.41421},role:"img","aria-labelledby":n},i),t?o.createElement("title",{id:n},t):null,r||(r=o.createElement("path",{d:"M12 0C5.374 0 0 5.372 0 12c0 6.627 5.374 12 12 12 6.627 0 12-5.373 12-12 0-6.628-5.373-12-12-12Zm3.224 17.871c.188.133.43.166.646.085a.678.678 0 0 0 .422-.491c.507-2.382 1.737-8.412 2.198-10.578a.457.457 0 0 0-.151-.443.47.47 0 0 0-.465-.082c-2.446.906-9.979 3.732-13.058 4.871a.484.484 0 0 0-.316.467.483.483 0 0 0 .346.445c1.381.413 3.193.988 3.193.988s.847 2.558 1.288 3.858a.512.512 0 0 0 .352.336.505.505 0 0 0 .474-.121l1.805-1.704s2.084 1.527 3.266 2.369Zm-6.423-5.062.98 3.231.218-2.046 5.941-5.358a.162.162 0 0 0 .019-.22.165.165 0 0 0-.219-.037l-6.939 4.43Z"})))}},86089:(e,t,n)=>{"use strict";n.r(t),n.d(t,{default:()=>i});var r,o=n(67294);function a(){return a=Object.assign?Object.assign.bind():function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e},a.apply(this,arguments)}const i=e=>{let{title:t,titleId:n,...i}=e;return o.createElement("svg",a({width:17,height:14,viewBox:"0 0 17 14",fill:"none",xmlns:"http://www.w3.org/2000/svg",role:"img","aria-labelledby":n},i),t?o.createElement("title",{id:n},t):null,r||(r=o.createElement("path",{d:"M16.557 1.597a6.802 6.802 0 0 1-1.95.534A3.406 3.406 0 0 0 16.1.251a6.782 6.782 0 0 1-2.157.824 3.398 3.398 0 0 0-5.788 3.1A9.647 9.647 0 0 1 1.153.624a3.395 3.395 0 0 0-.059 3.31c.264.494.645.915 1.11 1.225a3.389 3.389 0 0 1-1.538-.425v.044a3.398 3.398 0 0 0 2.725 3.33c-.5.136-1.025.156-1.534.06a3.399 3.399 0 0 0 3.173 2.357A6.817 6.817 0 0 1 0 11.934a9.607 9.607 0 0 0 5.207 1.526c6.249 0 9.665-5.176 9.665-9.665 0-.146-.004-.293-.01-.439A6.905 6.905 0 0 0 16.556 1.6l.001-.002Z",fill:"#000"})))}},92358:(e,t,n)=>{"use strict";n.r(t),n.d(t,{default:()=>i});var r,o=n(67294);function a(){return a=Object.assign?Object.assign.bind():function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e},a.apply(this,arguments)}const i=e=>{let{title:t,titleId:n,...i}=e;return o.createElement("svg",a({width:40,height:40,viewBox:"0 0 40 40",fill:"none",xmlns:"http://www.w3.org/2000/svg",role:"img","aria-labelledby":n},i),t?o.createElement("title",{id:n},t):null,r||(r=o.createElement("path",{d:"M22.62 19.134 32.63 7.5h-2.373l-8.69 10.102L14.627 7.5H6.62l10.496 15.275-10.496 12.2h2.372l9.177-10.668 7.33 10.668h8.005L22.62 19.134Zm-3.248 3.776-1.063-1.521L9.847 9.285h3.643l6.829 9.768 1.063 1.521 8.877 12.697h-3.643l-7.244-10.36v-.001Z",fill:"#fff"})))}},86010:(e,t,n)=>{"use strict";function r(e){var t,n,o="";if("string"==typeof e||"number"==typeof e)o+=e;else if("object"==typeof e)if(Array.isArray(e))for(t=0;t<e.length;t++)e[t]&&(n=r(e[t]))&&(o&&(o+=" "),o+=n);else for(t in e)e[t]&&(o&&(o+=" "),o+=t);return o}function o(){for(var e,t,n=0,o="";n<arguments.length;)(e=arguments[n++])&&(t=r(e))&&(o&&(o+=" "),o+=t);return o}n.r(t),n.d(t,{clsx:()=>o,default:()=>a});const a=o},20640:(e,t,n)=>{"use strict";var r=n(11742),o={"text/plain":"Text","text/html":"Url",default:"Text"};e.exports=function(e,t){var n,a,i,l,s,u,c=!1;t||(t={}),n=t.debug||!1;try{if(i=r(),l=document.createRange(),s=document.getSelection(),(u=document.createElement("span")).textContent=e,u.ariaHidden="true",u.style.all="unset",u.style.position="fixed",u.style.top=0,u.style.clip="rect(0, 0, 0, 0)",u.style.whiteSpace="pre",u.style.webkitUserSelect="text",u.style.MozUserSelect="text",u.style.msUserSelect="text",u.style.userSelect="text",u.addEventListener("copy",(function(r){if(r.stopPropagation(),t.format)if(r.preventDefault(),void 0===r.clipboardData){n&&console.warn("unable to use e.clipboardData"),n&&console.warn("trying IE specific stuff"),window.clipboardData.clearData();var a=o[t.format]||o.default;window.clipboardData.setData(a,e)}else r.clipboardData.clearData(),r.clipboardData.setData(t.format,e);t.onCopy&&(r.preventDefault(),t.onCopy(r.clipboardData))})),document.body.appendChild(u),l.selectNodeContents(u),s.addRange(l),!document.execCommand("copy"))throw new Error("copy command was unsuccessful");c=!0}catch(d){n&&console.error("unable to copy using execCommand: ",d),n&&console.warn("trying IE specific stuff");try{window.clipboardData.setData(t.format||"text",e),t.onCopy&&t.onCopy(window.clipboardData),c=!0}catch(d){n&&console.error("unable to copy using clipboardData: ",d),n&&console.error("falling back to prompt"),a=function(e){var t=(/mac os x/i.test(navigator.userAgent)?"\u2318":"Ctrl")+"+C";return e.replace(/#{\s*key\s*}/g,t)}("message"in t?t.message:"Copy to clipboard: #{key}, Enter"),window.prompt(a,e)}}finally{s&&("function"==typeof s.removeRange?s.removeRange(l):s.removeAllRanges()),u&&document.body.removeChild(u),i()}return c}},38252:e=>{"use strict";e.exports=function e(t,n){if(t===n)return!0;if(t&&n&&"object"==typeof t&&"object"==typeof n){if(t.constructor!==n.constructor)return!1;var r,o,a;if(Array.isArray(t)){if((r=t.length)!=n.length)return!1;for(o=r;0!=o--;)if(!e(t[o],n[o]))return!1;return!0}if(t.constructor===RegExp)return t.source===n.source&&t.flags===n.flags;if(t.valueOf!==Object.prototype.valueOf)return t.valueOf()===n.valueOf();if(t.toString!==Object.prototype.toString)return t.toString()===n.toString();if((r=(a=Object.keys(t)).length)!==Object.keys(n).length)return!1;for(o=r;0!=o--;)if(!Object.prototype.hasOwnProperty.call(n,a[o]))return!1;for(o=r;0!=o--;){var i=a[o];if(("_owner"!==i||!t.$$typeof)&&!e(t[i],n[i]))return!1}return!0}return t!=t&&n!=n}},99376:(e,t)=>{var n=Object.keys;t.D=function(e,t){if(e===t)return!0;if(!(e instanceof Object&&t instanceof Object))return!1;for(var r=n(e),o=r.length,a=0;a<o;a++)if(!(r[a]in t))return!1;for(a=0;a<o;a++)if(e[r[a]]!==t[r[a]])return!1;return o===n(t).length}},42358:(e,t,n)=>{"use strict";n.d(t,{lX:()=>k,q_:()=>D,ob:()=>m,PP:()=>N,Ep:()=>h,Hp:()=>g});var r=n(87462);function o(e){return"/"===e.charAt(0)}function a(e,t){for(var n=t,r=n+1,o=e.length;r<o;n+=1,r+=1)e[n]=e[r];e.pop()}const i=function(e,t){void 0===t&&(t="");var n,r=e&&e.split("/")||[],i=t&&t.split("/")||[],l=e&&o(e),s=t&&o(t),u=l||s;if(e&&o(e)?i=r:r.length&&(i.pop(),i=i.concat(r)),!i.length)return"/";if(i.length){var c=i[i.length-1];n="."===c||".."===c||""===c}else n=!1;for(var d=0,f=i.length;f>=0;f--){var p=i[f];"."===p?a(i,f):".."===p?(a(i,f),d++):d&&(a(i,f),d--)}if(!u)for(;d--;d)i.unshift("..");!u||""===i[0]||i[0]&&o(i[0])||i.unshift("");var h=i.join("/");return n&&"/"!==h.substr(-1)&&(h+="/"),h};function l(e){return e.valueOf?e.valueOf():Object.prototype.valueOf.call(e)}const s=function e(t,n){if(t===n)return!0;if(null==t||null==n)return!1;if(Array.isArray(t))return Array.isArray(n)&&t.length===n.length&&t.every((function(t,r){return e(t,n[r])}));if("object"==typeof t||"object"==typeof n){var r=l(t),o=l(n);return r!==t||o!==n?e(r,o):Object.keys(Object.assign({},t,n)).every((function(r){return e(t[r],n[r])}))}return!1};var u=n(38776);function c(e){return"/"===e.charAt(0)?e:"/"+e}function d(e){return"/"===e.charAt(0)?e.substr(1):e}function f(e,t){return function(e,t){return 0===e.toLowerCase().indexOf(t.toLowerCase())&&-1!=="/?#".indexOf(e.charAt(t.length))}(e,t)?e.substr(t.length):e}function p(e){return"/"===e.charAt(e.length-1)?e.slice(0,-1):e}function h(e){var t=e.pathname,n=e.search,r=e.hash,o=t||"/";return n&&"?"!==n&&(o+="?"===n.charAt(0)?n:"?"+n),r&&"#"!==r&&(o+="#"===r.charAt(0)?r:"#"+r),o}function m(e,t,n,o){var a;"string"==typeof e?(a=function(e){var t=e||"/",n="",r="",o=t.indexOf("#");-1!==o&&(r=t.substr(o),t=t.substr(0,o));var a=t.indexOf("?");return-1!==a&&(n=t.substr(a),t=t.substr(0,a)),{pathname:t,search:"?"===n?"":n,hash:"#"===r?"":r}}(e),a.state=t):(void 0===(a=(0,r.Z)({},e)).pathname&&(a.pathname=""),a.search?"?"!==a.search.charAt(0)&&(a.search="?"+a.search):a.search="",a.hash?"#"!==a.hash.charAt(0)&&(a.hash="#"+a.hash):a.hash="",void 0!==t&&void 0===a.state&&(a.state=t));try{a.pathname=decodeURI(a.pathname)}catch(l){throw l instanceof URIError?new URIError('Pathname "'+a.pathname+'" could not be decoded. This is likely caused by an invalid percent-encoding.'):l}return n&&(a.key=n),o?a.pathname?"/"!==a.pathname.charAt(0)&&(a.pathname=i(a.pathname,o.pathname)):a.pathname=o.pathname:a.pathname||(a.pathname="/"),a}function g(e,t){return e.pathname===t.pathname&&e.search===t.search&&e.hash===t.hash&&e.key===t.key&&s(e.state,t.state)}function v(){var e=null;var t=[];return{setPrompt:function(t){return e=t,function(){e===t&&(e=null)}},confirmTransitionTo:function(t,n,r,o){if(null!=e){var a="function"==typeof e?e(t,n):e;"string"==typeof a?"function"==typeof r?r(a,o):o(!0):o(!1!==a)}else o(!0)},appendListener:function(e){var n=!0;function r(){n&&e.apply(void 0,arguments)}return t.push(r),function(){n=!1,t=t.filter((function(e){return e!==r}))}},notifyListeners:function(){for(var e=arguments.length,n=new Array(e),r=0;r<e;r++)n[r]=arguments[r];t.forEach((function(e){return e.apply(void 0,n)}))}}}var b=!("undefined"==typeof window||!window.document||!window.document.createElement);function y(e,t){t(window.confirm(e))}var w="popstate",x="hashchange";function _(){try{return window.history.state||{}}catch(e){return{}}}function k(e){void 0===e&&(e={}),b||(0,u.Z)(!1);var t,n=window.history,o=(-1===(t=window.navigator.userAgent).indexOf("Android 2.")&&-1===t.indexOf("Android 4.0")||-1===t.indexOf("Mobile Safari")||-1!==t.indexOf("Chrome")||-1!==t.indexOf("Windows Phone"))&&window.history&&"pushState"in window.history,a=!(-1===window.navigator.userAgent.indexOf("Trident")),i=e,l=i.forceRefresh,s=void 0!==l&&l,d=i.getUserConfirmation,g=void 0===d?y:d,k=i.keyLength,E=void 0===k?6:k,S=e.basename?p(c(e.basename)):"";function C(e){var t=e||{},n=t.key,r=t.state,o=window.location,a=o.pathname+o.search+o.hash;return S&&(a=f(a,S)),m(a,r,n)}function T(){return Math.random().toString(36).substr(2,E)}var O=v();function D(e){(0,r.Z)($,e),$.length=n.length,O.notifyListeners($.location,$.action)}function P(e){(function(e){return void 0===e.state&&-1===navigator.userAgent.indexOf("CriOS")})(e)||I(C(e.state))}function N(){I(C(_()))}var A=!1;function I(e){if(A)A=!1,D();else{O.confirmTransitionTo(e,"POP",g,(function(t){t?D({action:"POP",location:e}):function(e){var t=$.location,n=R.indexOf(t.key);-1===n&&(n=0);var r=R.indexOf(e.key);-1===r&&(r=0);var o=n-r;o&&(A=!0,M(o))}(e)}))}}var L=C(_()),R=[L.key];function j(e){return S+h(e)}function M(e){n.go(e)}var F=0;function B(e){1===(F+=e)&&1===e?(window.addEventListener(w,P),a&&window.addEventListener(x,N)):0===F&&(window.removeEventListener(w,P),a&&window.removeEventListener(x,N))}var z=!1;var $={length:n.length,action:"POP",location:L,createHref:j,push:function(e,t){var r="PUSH",a=m(e,t,T(),$.location);O.confirmTransitionTo(a,r,g,(function(e){if(e){var t=j(a),i=a.key,l=a.state;if(o)if(n.pushState({key:i,state:l},null,t),s)window.location.href=t;else{var u=R.indexOf($.location.key),c=R.slice(0,u+1);c.push(a.key),R=c,D({action:r,location:a})}else window.location.href=t}}))},replace:function(e,t){var r="REPLACE",a=m(e,t,T(),$.location);O.confirmTransitionTo(a,r,g,(function(e){if(e){var t=j(a),i=a.key,l=a.state;if(o)if(n.replaceState({key:i,state:l},null,t),s)window.location.replace(t);else{var u=R.indexOf($.location.key);-1!==u&&(R[u]=a.key),D({action:r,location:a})}else window.location.replace(t)}}))},go:M,goBack:function(){M(-1)},goForward:function(){M(1)},block:function(e){void 0===e&&(e=!1);var t=O.setPrompt(e);return z||(B(1),z=!0),function(){return z&&(z=!1,B(-1)),t()}},listen:function(e){var t=O.appendListener(e);return B(1),function(){B(-1),t()}}};return $}var E="hashchange",S={hashbang:{encodePath:function(e){return"!"===e.charAt(0)?e:"!/"+d(e)},decodePath:function(e){return"!"===e.charAt(0)?e.substr(1):e}},noslash:{encodePath:d,decodePath:c},slash:{encodePath:c,decodePath:c}};function C(e){var t=e.indexOf("#");return-1===t?e:e.slice(0,t)}function T(){var e=window.location.href,t=e.indexOf("#");return-1===t?"":e.substring(t+1)}function O(e){window.location.replace(C(window.location.href)+"#"+e)}function D(e){void 0===e&&(e={}),b||(0,u.Z)(!1);var t=window.history,n=(window.navigator.userAgent.indexOf("Firefox"),e),o=n.getUserConfirmation,a=void 0===o?y:o,i=n.hashType,l=void 0===i?"slash":i,s=e.basename?p(c(e.basename)):"",d=S[l],g=d.encodePath,w=d.decodePath;function x(){var e=w(T());return s&&(e=f(e,s)),m(e)}var _=v();function k(e){(0,r.Z)(z,e),z.length=t.length,_.notifyListeners(z.location,z.action)}var D=!1,P=null;function N(){var e,t,n=T(),r=g(n);if(n!==r)O(r);else{var o=x(),i=z.location;if(!D&&(t=o,(e=i).pathname===t.pathname&&e.search===t.search&&e.hash===t.hash))return;if(P===h(o))return;P=null,function(e){if(D)D=!1,k();else{var t="POP";_.confirmTransitionTo(e,t,a,(function(n){n?k({action:t,location:e}):function(e){var t=z.location,n=R.lastIndexOf(h(t));-1===n&&(n=0);var r=R.lastIndexOf(h(e));-1===r&&(r=0);var o=n-r;o&&(D=!0,j(o))}(e)}))}}(o)}}var A=T(),I=g(A);A!==I&&O(I);var L=x(),R=[h(L)];function j(e){t.go(e)}var M=0;function F(e){1===(M+=e)&&1===e?window.addEventListener(E,N):0===M&&window.removeEventListener(E,N)}var B=!1;var z={length:t.length,action:"POP",location:L,createHref:function(e){var t=document.querySelector("base"),n="";return t&&t.getAttribute("href")&&(n=C(window.location.href)),n+"#"+g(s+h(e))},push:function(e,t){var n="PUSH",r=m(e,void 0,void 0,z.location);_.confirmTransitionTo(r,n,a,(function(e){if(e){var t=h(r),o=g(s+t);if(T()!==o){P=t,function(e){window.location.hash=e}(o);var a=R.lastIndexOf(h(z.location)),i=R.slice(0,a+1);i.push(t),R=i,k({action:n,location:r})}else k()}}))},replace:function(e,t){var n="REPLACE",r=m(e,void 0,void 0,z.location);_.confirmTransitionTo(r,n,a,(function(e){if(e){var t=h(r),o=g(s+t);T()!==o&&(P=t,O(o));var a=R.indexOf(h(z.location));-1!==a&&(R[a]=t),k({action:n,location:r})}}))},go:j,goBack:function(){j(-1)},goForward:function(){j(1)},block:function(e){void 0===e&&(e=!1);var t=_.setPrompt(e);return B||(F(1),B=!0),function(){return B&&(B=!1,F(-1)),t()}},listen:function(e){var t=_.appendListener(e);return F(1),function(){F(-1),t()}}};return z}function P(e,t,n){return Math.min(Math.max(e,t),n)}function N(e){void 0===e&&(e={});var t=e,n=t.getUserConfirmation,o=t.initialEntries,a=void 0===o?["/"]:o,i=t.initialIndex,l=void 0===i?0:i,s=t.keyLength,u=void 0===s?6:s,c=v();function d(e){(0,r.Z)(w,e),w.length=w.entries.length,c.notifyListeners(w.location,w.action)}function f(){return Math.random().toString(36).substr(2,u)}var p=P(l,0,a.length-1),g=a.map((function(e){return m(e,void 0,"string"==typeof e?f():e.key||f())})),b=h;function y(e){var t=P(w.index+e,0,w.entries.length-1),r=w.entries[t];c.confirmTransitionTo(r,"POP",n,(function(e){e?d({action:"POP",location:r,index:t}):d()}))}var w={length:g.length,action:"POP",location:g[p],index:p,entries:g,createHref:b,push:function(e,t){var r="PUSH",o=m(e,t,f(),w.location);c.confirmTransitionTo(o,r,n,(function(e){if(e){var t=w.index+1,n=w.entries.slice(0);n.length>t?n.splice(t,n.length-t,o):n.push(o),d({action:r,location:o,index:t,entries:n})}}))},replace:function(e,t){var r="REPLACE",o=m(e,t,f(),w.location);c.confirmTransitionTo(o,r,n,(function(e){e&&(w.entries[w.index]=o,d({action:r,location:o}))}))},go:y,goBack:function(){y(-1)},goForward:function(){y(1)},canGo:function(e){var t=w.index+e;return t>=0&&t<w.entries.length},block:function(e){return void 0===e&&(e=!1),c.setPrompt(e)},listen:function(e){return c.appendListener(e)}};return w}},8679:(e,t,n)=>{"use strict";var r=n(59864),o={childContextTypes:!0,contextType:!0,contextTypes:!0,defaultProps:!0,displayName:!0,getDefaultProps:!0,getDerivedStateFromError:!0,getDerivedStateFromProps:!0,mixins:!0,propTypes:!0,type:!0},a={name:!0,length:!0,prototype:!0,caller:!0,callee:!0,arguments:!0,arity:!0},i={$$typeof:!0,compare:!0,defaultProps:!0,displayName:!0,propTypes:!0,type:!0},l={};function s(e){return r.isMemo(e)?i:l[e.$$typeof]||o}l[r.ForwardRef]={$$typeof:!0,render:!0,defaultProps:!0,displayName:!0,propTypes:!0},l[r.Memo]=i;var u=Object.defineProperty,c=Object.getOwnPropertyNames,d=Object.getOwnPropertySymbols,f=Object.getOwnPropertyDescriptor,p=Object.getPrototypeOf,h=Object.prototype;e.exports=function e(t,n,r){if("string"!=typeof n){if(h){var o=p(n);o&&o!==h&&e(t,o,r)}var i=c(n);d&&(i=i.concat(d(n)));for(var l=s(t),m=s(n),g=0;g<i.length;++g){var v=i[g];if(!(a[v]||r&&r[v]||m&&m[v]||l&&l[v])){var b=f(n,v);try{u(t,v,b)}catch(y){}}}}return t}},41143:e=>{"use strict";e.exports=function(e,t,n,r,o,a,i,l){if(!e){var s;if(void 0===t)s=new Error("Minified exception occurred; use the non-minified dev environment for the full error message and additional helpful warnings.");else{var u=[n,r,o,a,i,l],c=0;(s=new Error(t.replace(/%s/g,(function(){return u[c++]})))).name="Invariant Violation"}throw s.framesToPop=1,s}}},36808:(e,t,n)=>{var r,o;!function(a){if(void 0===(o="function"==typeof(r=a)?r.call(t,n,t,e):r)||(e.exports=o),!0,e.exports=a(),!!0){var i=window.Cookies,l=window.Cookies=a();l.noConflict=function(){return window.Cookies=i,l}}}((function(){function e(){for(var e=0,t={};e<arguments.length;e++){var n=arguments[e];for(var r in n)t[r]=n[r]}return t}function t(e){return e.replace(/(%[0-9A-Z]{2})+/g,decodeURIComponent)}return function n(r){function o(){}function a(t,n,a){if("undefined"!=typeof document){"number"==typeof(a=e({path:"/"},o.defaults,a)).expires&&(a.expires=new Date(1*new Date+864e5*a.expires)),a.expires=a.expires?a.expires.toUTCString():"";try{var i=JSON.stringify(n);/^[\{\[]/.test(i)&&(n=i)}catch(u){}n=r.write?r.write(n,t):encodeURIComponent(String(n)).replace(/%(23|24|26|2B|3A|3C|3E|3D|2F|3F|40|5B|5D|5E|60|7B|7D|7C)/g,decodeURIComponent),t=encodeURIComponent(String(t)).replace(/%(23|24|26|2B|5E|60|7C)/g,decodeURIComponent).replace(/[\(\)]/g,escape);var l="";for(var s in a)a[s]&&(l+="; "+s,!0!==a[s]&&(l+="="+a[s].split(";")[0]));return document.cookie=t+"="+n+l}}function i(e,n){if("undefined"!=typeof document){for(var o={},a=document.cookie?document.cookie.split("; "):[],i=0;i<a.length;i++){var l=a[i].split("="),s=l.slice(1).join("=");n||'"'!==s.charAt(0)||(s=s.slice(1,-1));try{var u=t(l[0]);if(s=(r.read||r)(s,u)||t(s),n)try{s=JSON.parse(s)}catch(c){}if(o[u]=s,e===u)break}catch(c){}}return e?o[e]:o}}return o.set=a,o.get=function(e){return i(e,!1)},o.getJSON=function(e){return i(e,!0)},o.remove=function(t,n){a(t,"",e(n,{expires:-1}))},o.defaults={},o.withConverter=n,o}((function(){}))}))},18552:(e,t,n)=>{var r=n(10852)(n(55639),"DataView");e.exports=r},1989:(e,t,n)=>{var r=n(51789),o=n(80401),a=n(57667),i=n(21327),l=n(81866);function s(e){var t=-1,n=null==e?0:e.length;for(this.clear();++t<n;){var r=e[t];this.set(r[0],r[1])}}s.prototype.clear=r,s.prototype.delete=o,s.prototype.get=a,s.prototype.has=i,s.prototype.set=l,e.exports=s},38407:(e,t,n)=>{var r=n(27040),o=n(14125),a=n(82117),i=n(67518),l=n(54705);function s(e){var t=-1,n=null==e?0:e.length;for(this.clear();++t<n;){var r=e[t];this.set(r[0],r[1])}}s.prototype.clear=r,s.prototype.delete=o,s.prototype.get=a,s.prototype.has=i,s.prototype.set=l,e.exports=s},57071:(e,t,n)=>{var r=n(10852)(n(55639),"Map");e.exports=r},83369:(e,t,n)=>{var r=n(24785),o=n(11285),a=n(96e3),i=n(49916),l=n(95265);function s(e){var t=-1,n=null==e?0:e.length;for(this.clear();++t<n;){var r=e[t];this.set(r[0],r[1])}}s.prototype.clear=r,s.prototype.delete=o,s.prototype.get=a,s.prototype.has=i,s.prototype.set=l,e.exports=s},53818:(e,t,n)=>{var r=n(10852)(n(55639),"Promise");e.exports=r},58525:(e,t,n)=>{var r=n(10852)(n(55639),"Set");e.exports=r},88668:(e,t,n)=>{var r=n(83369),o=n(90619),a=n(72385);function i(e){var t=-1,n=null==e?0:e.length;for(this.__data__=new r;++t<n;)this.add(e[t])}i.prototype.add=i.prototype.push=o,i.prototype.has=a,e.exports=i},46384:(e,t,n)=>{var r=n(38407),o=n(37465),a=n(63779),i=n(67599),l=n(44758),s=n(34309);function u(e){var t=this.__data__=new r(e);this.size=t.size}u.prototype.clear=o,u.prototype.delete=a,u.prototype.get=i,u.prototype.has=l,u.prototype.set=s,e.exports=u},62705:(e,t,n)=>{var r=n(55639).Symbol;e.exports=r},11149:(e,t,n)=>{var r=n(55639).Uint8Array;e.exports=r},70577:(e,t,n)=>{var r=n(10852)(n(55639),"WeakMap");e.exports=r},96874:e=>{e.exports=function(e,t,n){switch(n.length){case 0:return e.call(t);case 1:return e.call(t,n[0]);case 2:return e.call(t,n[0],n[1]);case 3:return e.call(t,n[0],n[1],n[2])}return e.apply(t,n)}},44174:e=>{e.exports=function(e,t,n,r){for(var o=-1,a=null==e?0:e.length;++o<a;){var i=e[o];t(r,i,n(i),e)}return r}},77412:e=>{e.exports=function(e,t){for(var n=-1,r=null==e?0:e.length;++n<r&&!1!==t(e[n],n,e););return e}},34963:e=>{e.exports=function(e,t){for(var n=-1,r=null==e?0:e.length,o=0,a=[];++n<r;){var i=e[n];t(i,n,e)&&(a[o++]=i)}return a}},14636:(e,t,n)=>{var r=n(22545),o=n(35694),a=n(1469),i=n(44144),l=n(65776),s=n(36719),u=Object.prototype.hasOwnProperty;e.exports=function(e,t){var n=a(e),c=!n&&o(e),d=!n&&!c&&i(e),f=!n&&!c&&!d&&s(e),p=n||c||d||f,h=p?r(e.length,String):[],m=h.length;for(var g in e)!t&&!u.call(e,g)||p&&("length"==g||d&&("offset"==g||"parent"==g)||f&&("buffer"==g||"byteLength"==g||"byteOffset"==g)||l(g,m))||h.push(g);return h}},29932:e=>{e.exports=function(e,t){for(var n=-1,r=null==e?0:e.length,o=Array(r);++n<r;)o[n]=t(e[n],n,e);return o}},62488:e=>{e.exports=function(e,t){for(var n=-1,r=t.length,o=e.length;++n<r;)e[o+n]=t[n];return e}},82908:e=>{e.exports=function(e,t){for(var n=-1,r=null==e?0:e.length;++n<r;)if(t(e[n],n,e))return!0;return!1}},34865:(e,t,n)=>{var r=n(89465),o=n(77813),a=Object.prototype.hasOwnProperty;e.exports=function(e,t,n){var i=e[t];a.call(e,t)&&o(i,n)&&(void 0!==n||t in e)||r(e,t,n)}},18470:(e,t,n)=>{var r=n(77813);e.exports=function(e,t){for(var n=e.length;n--;)if(r(e[n][0],t))return n;return-1}},81119:(e,t,n)=>{var r=n(89881);e.exports=function(e,t,n,o){return r(e,(function(e,r,a){t(o,e,n(e),a)})),o}},44037:(e,t,n)=>{var r=n(98363),o=n(3674);e.exports=function(e,t){return e&&r(t,o(t),e)}},63886:(e,t,n)=>{var r=n(98363),o=n(81704);e.exports=function(e,t){return e&&r(t,o(t),e)}},89465:(e,t,n)=>{var r=n(38777);e.exports=function(e,t,n){"__proto__"==t&&r?r(e,t,{configurable:!0,enumerable:!0,value:n,writable:!0}):e[t]=n}},85990:(e,t,n)=>{var r=n(46384),o=n(77412),a=n(34865),i=n(44037),l=n(63886),s=n(64626),u=n(278),c=n(18805),d=n(1911),f=n(58234),p=n(46904),h=n(64160),m=n(43824),g=n(29148),v=n(38517),b=n(1469),y=n(44144),w=n(56688),x=n(13218),_=n(72928),k=n(3674),E=n(81704),S="[object Arguments]",C="[object Function]",T="[object Object]",O={};O[S]=O["[object Array]"]=O["[object ArrayBuffer]"]=O["[object DataView]"]=O["[object Boolean]"]=O["[object Date]"]=O["[object Float32Array]"]=O["[object Float64Array]"]=O["[object Int8Array]"]=O["[object Int16Array]"]=O["[object Int32Array]"]=O["[object Map]"]=O["[object Number]"]=O[T]=O["[object RegExp]"]=O["[object Set]"]=O["[object String]"]=O["[object Symbol]"]=O["[object Uint8Array]"]=O["[object Uint8ClampedArray]"]=O["[object Uint16Array]"]=O["[object Uint32Array]"]=!0,O["[object Error]"]=O[C]=O["[object WeakMap]"]=!1,e.exports=function e(t,n,D,P,N,A){var I,L=1&n,R=2&n,j=4&n;if(D&&(I=N?D(t,P,N,A):D(t)),void 0!==I)return I;if(!x(t))return t;var M=b(t);if(M){if(I=m(t),!L)return u(t,I)}else{var F=h(t),B=F==C||"[object GeneratorFunction]"==F;if(y(t))return s(t,L);if(F==T||F==S||B&&!N){if(I=R||B?{}:v(t),!L)return R?d(t,l(I,t)):c(t,i(I,t))}else{if(!O[F])return N?t:{};I=g(t,F,L)}}A||(A=new r);var z=A.get(t);if(z)return z;A.set(t,I),_(t)?t.forEach((function(r){I.add(e(r,n,D,r,t,A))})):w(t)&&t.forEach((function(r,o){I.set(o,e(r,n,D,o,t,A))}));var $=M?void 0:(j?R?p:f:R?E:k)(t);return o($||t,(function(r,o){$&&(r=t[o=r]),a(I,o,e(r,n,D,o,t,A))})),I}},3118:(e,t,n)=>{var r=n(13218),o=Object.create,a=function(){function e(){}return function(t){if(!r(t))return{};if(o)return o(t);e.prototype=t;var n=new e;return e.prototype=void 0,n}}();e.exports=a},89881:(e,t,n)=>{var r=n(47816),o=n(99291)(r);e.exports=o},21078:(e,t,n)=>{var r=n(62488),o=n(37285);e.exports=function e(t,n,a,i,l){var s=-1,u=t.length;for(a||(a=o),l||(l=[]);++s<u;){var c=t[s];n>0&&a(c)?n>1?e(c,n-1,a,i,l):r(l,c):i||(l[l.length]=c)}return l}},28483:(e,t,n)=>{var r=n(25063)();e.exports=r},47816:(e,t,n)=>{var r=n(28483),o=n(3674);e.exports=function(e,t){return e&&r(e,t,o)}},97786:(e,t,n)=>{var r=n(71811),o=n(40327);e.exports=function(e,t){for(var n=0,a=(t=r(t,e)).length;null!=e&&n<a;)e=e[o(t[n++])];return n&&n==a?e:void 0}},68866:(e,t,n)=>{var r=n(62488),o=n(1469);e.exports=function(e,t,n){var a=t(e);return o(e)?a:r(a,n(e))}},44239:(e,t,n)=>{var r=n(62705),o=n(89607),a=n(2333),i=r?r.toStringTag:void 0;e.exports=function(e){return null==e?void 0===e?"[object Undefined]":"[object Null]":i&&i in Object(e)?o(e):a(e)}},13:e=>{e.exports=function(e,t){return null!=e&&t in Object(e)}},9454:(e,t,n)=>{var r=n(44239),o=n(37005);e.exports=function(e){return o(e)&&"[object Arguments]"==r(e)}},90939:(e,t,n)=>{var r=n(2492),o=n(37005);e.exports=function e(t,n,a,i,l){return t===n||(null==t||null==n||!o(t)&&!o(n)?t!=t&&n!=n:r(t,n,a,i,e,l))}},2492:(e,t,n)=>{var r=n(46384),o=n(67114),a=n(18351),i=n(16096),l=n(64160),s=n(1469),u=n(44144),c=n(36719),d="[object Arguments]",f="[object Array]",p="[object Object]",h=Object.prototype.hasOwnProperty;e.exports=function(e,t,n,m,g,v){var b=s(e),y=s(t),w=b?f:l(e),x=y?f:l(t),_=(w=w==d?p:w)==p,k=(x=x==d?p:x)==p,E=w==x;if(E&&u(e)){if(!u(t))return!1;b=!0,_=!1}if(E&&!_)return v||(v=new r),b||c(e)?o(e,t,n,m,g,v):a(e,t,w,n,m,g,v);if(!(1&n)){var S=_&&h.call(e,"__wrapped__"),C=k&&h.call(t,"__wrapped__");if(S||C){var T=S?e.value():e,O=C?t.value():t;return v||(v=new r),g(T,O,n,m,v)}}return!!E&&(v||(v=new r),i(e,t,n,m,g,v))}},25588:(e,t,n)=>{var r=n(64160),o=n(37005);e.exports=function(e){return o(e)&&"[object Map]"==r(e)}},2958:(e,t,n)=>{var r=n(46384),o=n(90939);e.exports=function(e,t,n,a){var i=n.length,l=i,s=!a;if(null==e)return!l;for(e=Object(e);i--;){var u=n[i];if(s&&u[2]?u[1]!==e[u[0]]:!(u[0]in e))return!1}for(;++i<l;){var c=(u=n[i])[0],d=e[c],f=u[1];if(s&&u[2]){if(void 0===d&&!(c in e))return!1}else{var p=new r;if(a)var h=a(d,f,c,e,t,p);if(!(void 0===h?o(f,d,3,a,p):h))return!1}}return!0}},28458:(e,t,n)=>{var r=n(23560),o=n(15346),a=n(13218),i=n(80346),l=/^\[object .+?Constructor\]$/,s=Function.prototype,u=Object.prototype,c=s.toString,d=u.hasOwnProperty,f=RegExp("^"+c.call(d).replace(/[\\^$.*+?()[\]{}|]/g,"\\$&").replace(/hasOwnProperty|(function).*?(?=\\\()| for .+?(?=\\\])/g,"$1.*?")+"$");e.exports=function(e){return!(!a(e)||o(e))&&(r(e)?f:l).test(i(e))}},29221:(e,t,n)=>{var r=n(64160),o=n(37005);e.exports=function(e){return o(e)&&"[object Set]"==r(e)}},38749:(e,t,n)=>{var r=n(44239),o=n(41780),a=n(37005),i={};i["[object Float32Array]"]=i["[object Float64Array]"]=i["[object Int8Array]"]=i["[object Int16Array]"]=i["[object Int32Array]"]=i["[object Uint8Array]"]=i["[object Uint8ClampedArray]"]=i["[object Uint16Array]"]=i["[object Uint32Array]"]=!0,i["[object Arguments]"]=i["[object Array]"]=i["[object ArrayBuffer]"]=i["[object Boolean]"]=i["[object DataView]"]=i["[object Date]"]=i["[object Error]"]=i["[object Function]"]=i["[object Map]"]=i["[object Number]"]=i["[object Object]"]=i["[object RegExp]"]=i["[object Set]"]=i["[object String]"]=i["[object WeakMap]"]=!1,e.exports=function(e){return a(e)&&o(e.length)&&!!i[r(e)]}},67206:(e,t,n)=>{var r=n(91573),o=n(16432),a=n(6557),i=n(1469),l=n(39601);e.exports=function(e){return"function"==typeof e?e:null==e?a:"object"==typeof e?i(e)?o(e[0],e[1]):r(e):l(e)}},280:(e,t,n)=>{var r=n(25726),o=n(86916),a=Object.prototype.hasOwnProperty;e.exports=function(e){if(!r(e))return o(e);var t=[];for(var n in Object(e))a.call(e,n)&&"constructor"!=n&&t.push(n);return t}},10313:(e,t,n)=>{var r=n(13218),o=n(25726),a=n(33498),i=Object.prototype.hasOwnProperty;e.exports=function(e){if(!r(e))return a(e);var t=o(e),n=[];for(var l in e)("constructor"!=l||!t&&i.call(e,l))&&n.push(l);return n}},91573:(e,t,n)=>{var r=n(2958),o=n(1499),a=n(42634);e.exports=function(e){var t=o(e);return 1==t.length&&t[0][2]?a(t[0][0],t[0][1]):function(n){return n===e||r(n,e,t)}}},16432:(e,t,n)=>{var r=n(90939),o=n(27361),a=n(79095),i=n(15403),l=n(89162),s=n(42634),u=n(40327);e.exports=function(e,t){return i(e)&&l(t)?s(u(e),t):function(n){var i=o(n,e);return void 0===i&&i===t?a(n,e):r(t,i,3)}}},40371:e=>{e.exports=function(e){return function(t){return null==t?void 0:t[e]}}},79152:(e,t,n)=>{var r=n(97786);e.exports=function(e){return function(t){return r(t,e)}}},56560:(e,t,n)=>{var r=n(75703),o=n(38777),a=n(6557),i=o?function(e,t){return o(e,"toString",{configurable:!0,enumerable:!1,value:r(t),writable:!0})}:a;e.exports=i},14259:e=>{e.exports=function(e,t,n){var r=-1,o=e.length;t<0&&(t=-t>o?0:o+t),(n=n>o?o:n)<0&&(n+=o),o=t>n?0:n-t>>>0,t>>>=0;for(var a=Array(o);++r<o;)a[r]=e[r+t];return a}},22545:e=>{e.exports=function(e,t){for(var n=-1,r=Array(e);++n<e;)r[n]=t(n);return r}},80531:(e,t,n)=>{var r=n(62705),o=n(29932),a=n(1469),i=n(33448),l=r?r.prototype:void 0,s=l?l.toString:void 0;e.exports=function e(t){if("string"==typeof t)return t;if(a(t))return o(t,e)+"";if(i(t))return s?s.call(t):"";var n=t+"";return"0"==n&&1/t==-Infinity?"-0":n}},7518:e=>{e.exports=function(e){return function(t){return e(t)}}},57406:(e,t,n)=>{var r=n(71811),o=n(10928),a=n(40292),i=n(40327);e.exports=function(e,t){return t=r(t,e),null==(e=a(e,t))||delete e[i(o(t))]}},74757:e=>{e.exports=function(e,t){return e.has(t)}},71811:(e,t,n)=>{var r=n(1469),o=n(15403),a=n(55514),i=n(79833);e.exports=function(e,t){return r(e)?e:o(e,t)?[e]:a(i(e))}},74318:(e,t,n)=>{var r=n(11149);e.exports=function(e){var t=new e.constructor(e.byteLength);return new r(t).set(new r(e)),t}},64626:(e,t,n)=>{e=n.nmd(e);var r=n(55639),o=t&&!t.nodeType&&t,a=o&&e&&!e.nodeType&&e,i=a&&a.exports===o?r.Buffer:void 0,l=i?i.allocUnsafe:void 0;e.exports=function(e,t){if(t)return e.slice();var n=e.length,r=l?l(n):new e.constructor(n);return e.copy(r),r}},57157:(e,t,n)=>{var r=n(74318);e.exports=function(e,t){var n=t?r(e.buffer):e.buffer;return new e.constructor(n,e.byteOffset,e.byteLength)}},93147:e=>{var t=/\w*$/;e.exports=function(e){var n=new e.constructor(e.source,t.exec(e));return n.lastIndex=e.lastIndex,n}},40419:(e,t,n)=>{var r=n(62705),o=r?r.prototype:void 0,a=o?o.valueOf:void 0;e.exports=function(e){return a?Object(a.call(e)):{}}},77133:(e,t,n)=>{var r=n(74318);e.exports=function(e,t){var n=t?r(e.buffer):e.buffer;return new e.constructor(n,e.byteOffset,e.length)}},278:e=>{e.exports=function(e,t){var n=-1,r=e.length;for(t||(t=Array(r));++n<r;)t[n]=e[n];return t}},98363:(e,t,n)=>{var r=n(34865),o=n(89465);e.exports=function(e,t,n,a){var i=!n;n||(n={});for(var l=-1,s=t.length;++l<s;){var u=t[l],c=a?a(n[u],e[u],u,n,e):void 0;void 0===c&&(c=e[u]),i?o(n,u,c):r(n,u,c)}return n}},18805:(e,t,n)=>{var r=n(98363),o=n(99551);e.exports=function(e,t){return r(e,o(e),t)}},1911:(e,t,n)=>{var r=n(98363),o=n(51442);e.exports=function(e,t){return r(e,o(e),t)}},14429:(e,t,n)=>{var r=n(55639)["__core-js_shared__"];e.exports=r},55189:(e,t,n)=>{var r=n(44174),o=n(81119),a=n(67206),i=n(1469);e.exports=function(e,t){return function(n,l){var s=i(n)?r:o,u=t?t():{};return s(n,e,a(l,2),u)}}},99291:(e,t,n)=>{var r=n(98612);e.exports=function(e,t){return function(n,o){if(null==n)return n;if(!r(n))return e(n,o);for(var a=n.length,i=t?a:-1,l=Object(n);(t?i--:++i<a)&&!1!==o(l[i],i,l););return n}}},25063:e=>{e.exports=function(e){return function(t,n,r){for(var o=-1,a=Object(t),i=r(t),l=i.length;l--;){var s=i[e?l:++o];if(!1===n(a[s],s,a))break}return t}}},60696:(e,t,n)=>{var r=n(68630);e.exports=function(e){return r(e)?void 0:e}},38777:(e,t,n)=>{var r=n(10852),o=function(){try{var e=r(Object,"defineProperty");return e({},"",{}),e}catch(t){}}();e.exports=o},67114:(e,t,n)=>{var r=n(88668),o=n(82908),a=n(74757);e.exports=function(e,t,n,i,l,s){var u=1&n,c=e.length,d=t.length;if(c!=d&&!(u&&d>c))return!1;var f=s.get(e),p=s.get(t);if(f&&p)return f==t&&p==e;var h=-1,m=!0,g=2&n?new r:void 0;for(s.set(e,t),s.set(t,e);++h<c;){var v=e[h],b=t[h];if(i)var y=u?i(b,v,h,t,e,s):i(v,b,h,e,t,s);if(void 0!==y){if(y)continue;m=!1;break}if(g){if(!o(t,(function(e,t){if(!a(g,t)&&(v===e||l(v,e,n,i,s)))return g.push(t)}))){m=!1;break}}else if(v!==b&&!l(v,b,n,i,s)){m=!1;break}}return s.delete(e),s.delete(t),m}},18351:(e,t,n)=>{var r=n(62705),o=n(11149),a=n(77813),i=n(67114),l=n(68776),s=n(21814),u=r?r.prototype:void 0,c=u?u.valueOf:void 0;e.exports=function(e,t,n,r,u,d,f){switch(n){case"[object DataView]":if(e.byteLength!=t.byteLength||e.byteOffset!=t.byteOffset)return!1;e=e.buffer,t=t.buffer;case"[object ArrayBuffer]":return!(e.byteLength!=t.byteLength||!d(new o(e),new o(t)));case"[object Boolean]":case"[object Date]":case"[object Number]":return a(+e,+t);case"[object Error]":return e.name==t.name&&e.message==t.message;case"[object RegExp]":case"[object String]":return e==t+"";case"[object Map]":var p=l;case"[object Set]":var h=1&r;if(p||(p=s),e.size!=t.size&&!h)return!1;var m=f.get(e);if(m)return m==t;r|=2,f.set(e,t);var g=i(p(e),p(t),r,u,d,f);return f.delete(e),g;case"[object Symbol]":if(c)return c.call(e)==c.call(t)}return!1}},16096:(e,t,n)=>{var r=n(58234),o=Object.prototype.hasOwnProperty;e.exports=function(e,t,n,a,i,l){var s=1&n,u=r(e),c=u.length;if(c!=r(t).length&&!s)return!1;for(var d=c;d--;){var f=u[d];if(!(s?f in t:o.call(t,f)))return!1}var p=l.get(e),h=l.get(t);if(p&&h)return p==t&&h==e;var m=!0;l.set(e,t),l.set(t,e);for(var g=s;++d<c;){var v=e[f=u[d]],b=t[f];if(a)var y=s?a(b,v,f,t,e,l):a(v,b,f,e,t,l);if(!(void 0===y?v===b||i(v,b,n,a,l):y)){m=!1;break}g||(g="constructor"==f)}if(m&&!g){var w=e.constructor,x=t.constructor;w==x||!("constructor"in e)||!("constructor"in t)||"function"==typeof w&&w instanceof w&&"function"==typeof x&&x instanceof x||(m=!1)}return l.delete(e),l.delete(t),m}},99021:(e,t,n)=>{var r=n(85564),o=n(45357),a=n(30061);e.exports=function(e){return a(o(e,void 0,r),e+"")}},31957:(e,t,n)=>{var r="object"==typeof n.g&&n.g&&n.g.Object===Object&&n.g;e.exports=r},58234:(e,t,n)=>{var r=n(68866),o=n(99551),a=n(3674);e.exports=function(e){return r(e,a,o)}},46904:(e,t,n)=>{var r=n(68866),o=n(51442),a=n(81704);e.exports=function(e){return r(e,a,o)}},45050:(e,t,n)=>{var r=n(37019);e.exports=function(e,t){var n=e.__data__;return r(t)?n["string"==typeof t?"string":"hash"]:n.map}},1499:(e,t,n)=>{var r=n(89162),o=n(3674);e.exports=function(e){for(var t=o(e),n=t.length;n--;){var a=t[n],i=e[a];t[n]=[a,i,r(i)]}return t}},10852:(e,t,n)=>{var r=n(28458),o=n(47801);e.exports=function(e,t){var n=o(e,t);return r(n)?n:void 0}},85924:(e,t,n)=>{var r=n(5569)(Object.getPrototypeOf,Object);e.exports=r},89607:(e,t,n)=>{var r=n(62705),o=Object.prototype,a=o.hasOwnProperty,i=o.toString,l=r?r.toStringTag:void 0;e.exports=function(e){var t=a.call(e,l),n=e[l];try{e[l]=void 0;var r=!0}catch(s){}var o=i.call(e);return r&&(t?e[l]=n:delete e[l]),o}},99551:(e,t,n)=>{var r=n(34963),o=n(70479),a=Object.prototype.propertyIsEnumerable,i=Object.getOwnPropertySymbols,l=i?function(e){return null==e?[]:(e=Object(e),r(i(e),(function(t){return a.call(e,t)})))}:o;e.exports=l},51442:(e,t,n)=>{var r=n(62488),o=n(85924),a=n(99551),i=n(70479),l=Object.getOwnPropertySymbols?function(e){for(var t=[];e;)r(t,a(e)),e=o(e);return t}:i;e.exports=l},64160:(e,t,n)=>{var r=n(18552),o=n(57071),a=n(53818),i=n(58525),l=n(70577),s=n(44239),u=n(80346),c="[object Map]",d="[object Promise]",f="[object Set]",p="[object WeakMap]",h="[object DataView]",m=u(r),g=u(o),v=u(a),b=u(i),y=u(l),w=s;(r&&w(new r(new ArrayBuffer(1)))!=h||o&&w(new o)!=c||a&&w(a.resolve())!=d||i&&w(new i)!=f||l&&w(new l)!=p)&&(w=function(e){var t=s(e),n="[object Object]"==t?e.constructor:void 0,r=n?u(n):"";if(r)switch(r){case m:return h;case g:return c;case v:return d;case b:return f;case y:return p}return t}),e.exports=w},47801:e=>{e.exports=function(e,t){return null==e?void 0:e[t]}},222:(e,t,n)=>{var r=n(71811),o=n(35694),a=n(1469),i=n(65776),l=n(41780),s=n(40327);e.exports=function(e,t,n){for(var u=-1,c=(t=r(t,e)).length,d=!1;++u<c;){var f=s(t[u]);if(!(d=null!=e&&n(e,f)))break;e=e[f]}return d||++u!=c?d:!!(c=null==e?0:e.length)&&l(c)&&i(f,c)&&(a(e)||o(e))}},51789:(e,t,n)=>{var r=n(94536);e.exports=function(){this.__data__=r?r(null):{},this.size=0}},80401:e=>{e.exports=function(e){var t=this.has(e)&&delete this.__data__[e];return this.size-=t?1:0,t}},57667:(e,t,n)=>{var r=n(94536),o=Object.prototype.hasOwnProperty;e.exports=function(e){var t=this.__data__;if(r){var n=t[e];return"__lodash_hash_undefined__"===n?void 0:n}return o.call(t,e)?t[e]:void 0}},21327:(e,t,n)=>{var r=n(94536),o=Object.prototype.hasOwnProperty;e.exports=function(e){var t=this.__data__;return r?void 0!==t[e]:o.call(t,e)}},81866:(e,t,n)=>{var r=n(94536);e.exports=function(e,t){var n=this.__data__;return this.size+=this.has(e)?0:1,n[e]=r&&void 0===t?"__lodash_hash_undefined__":t,this}},43824:e=>{var t=Object.prototype.hasOwnProperty;e.exports=function(e){var n=e.length,r=new e.constructor(n);return n&&"string"==typeof e[0]&&t.call(e,"index")&&(r.index=e.index,r.input=e.input),r}},29148:(e,t,n)=>{var r=n(74318),o=n(57157),a=n(93147),i=n(40419),l=n(77133);e.exports=function(e,t,n){var s=e.constructor;switch(t){case"[object ArrayBuffer]":return r(e);case"[object Boolean]":case"[object Date]":return new s(+e);case"[object DataView]":return o(e,n);case"[object Float32Array]":case"[object Float64Array]":case"[object Int8Array]":case"[object Int16Array]":case"[object Int32Array]":case"[object Uint8Array]":case"[object Uint8ClampedArray]":case"[object Uint16Array]":case"[object Uint32Array]":return l(e,n);case"[object Map]":case"[object Set]":return new s;case"[object Number]":case"[object String]":return new s(e);case"[object RegExp]":return a(e);case"[object Symbol]":return i(e)}}},38517:(e,t,n)=>{var r=n(3118),o=n(85924),a=n(25726);e.exports=function(e){return"function"!=typeof e.constructor||a(e)?{}:r(o(e))}},37285:(e,t,n)=>{var r=n(62705),o=n(35694),a=n(1469),i=r?r.isConcatSpreadable:void 0;e.exports=function(e){return a(e)||o(e)||!!(i&&e&&e[i])}},65776:e=>{var t=/^(?:0|[1-9]\d*)$/;e.exports=function(e,n){var r=typeof e;return!!(n=null==n?9007199254740991:n)&&("number"==r||"symbol"!=r&&t.test(e))&&e>-1&&e%1==0&&e<n}},15403:(e,t,n)=>{var r=n(1469),o=n(33448),a=/\.|\[(?:[^[\]]*|(["'])(?:(?!\1)[^\\]|\\.)*?\1)\]/,i=/^\w*$/;e.exports=function(e,t){if(r(e))return!1;var n=typeof e;return!("number"!=n&&"symbol"!=n&&"boolean"!=n&&null!=e&&!o(e))||(i.test(e)||!a.test(e)||null!=t&&e in Object(t))}},37019:e=>{e.exports=function(e){var t=typeof e;return"string"==t||"number"==t||"symbol"==t||"boolean"==t?"__proto__"!==e:null===e}},15346:(e,t,n)=>{var r,o=n(14429),a=(r=/[^.]+$/.exec(o&&o.keys&&o.keys.IE_PROTO||""))?"Symbol(src)_1."+r:"";e.exports=function(e){return!!a&&a in e}},25726:e=>{var t=Object.prototype;e.exports=function(e){var n=e&&e.constructor;return e===("function"==typeof n&&n.prototype||t)}},89162:(e,t,n)=>{var r=n(13218);e.exports=function(e){return e==e&&!r(e)}},27040:e=>{e.exports=function(){this.__data__=[],this.size=0}},14125:(e,t,n)=>{var r=n(18470),o=Array.prototype.splice;e.exports=function(e){var t=this.__data__,n=r(t,e);return!(n<0)&&(n==t.length-1?t.pop():o.call(t,n,1),--this.size,!0)}},82117:(e,t,n)=>{var r=n(18470);e.exports=function(e){var t=this.__data__,n=r(t,e);return n<0?void 0:t[n][1]}},67518:(e,t,n)=>{var r=n(18470);e.exports=function(e){return r(this.__data__,e)>-1}},54705:(e,t,n)=>{var r=n(18470);e.exports=function(e,t){var n=this.__data__,o=r(n,e);return o<0?(++this.size,n.push([e,t])):n[o][1]=t,this}},24785:(e,t,n)=>{var r=n(1989),o=n(38407),a=n(57071);e.exports=function(){this.size=0,this.__data__={hash:new r,map:new(a||o),string:new r}}},11285:(e,t,n)=>{var r=n(45050);e.exports=function(e){var t=r(this,e).delete(e);return this.size-=t?1:0,t}},96e3:(e,t,n)=>{var r=n(45050);e.exports=function(e){return r(this,e).get(e)}},49916:(e,t,n)=>{var r=n(45050);e.exports=function(e){return r(this,e).has(e)}},95265:(e,t,n)=>{var r=n(45050);e.exports=function(e,t){var n=r(this,e),o=n.size;return n.set(e,t),this.size+=n.size==o?0:1,this}},68776:e=>{e.exports=function(e){var t=-1,n=Array(e.size);return e.forEach((function(e,r){n[++t]=[r,e]})),n}},42634:e=>{e.exports=function(e,t){return function(n){return null!=n&&(n[e]===t&&(void 0!==t||e in Object(n)))}}},24523:(e,t,n)=>{var r=n(88306);e.exports=function(e){var t=r(e,(function(e){return 500===n.size&&n.clear(),e})),n=t.cache;return t}},94536:(e,t,n)=>{var r=n(10852)(Object,"create");e.exports=r},86916:(e,t,n)=>{var r=n(5569)(Object.keys,Object);e.exports=r},33498:e=>{e.exports=function(e){var t=[];if(null!=e)for(var n in Object(e))t.push(n);return t}},31167:(e,t,n)=>{e=n.nmd(e);var r=n(31957),o=t&&!t.nodeType&&t,a=o&&e&&!e.nodeType&&e,i=a&&a.exports===o&&r.process,l=function(){try{var e=a&&a.require&&a.require("util").types;return e||i&&i.binding&&i.binding("util")}catch(t){}}();e.exports=l},2333:e=>{var t=Object.prototype.toString;e.exports=function(e){return t.call(e)}},5569:e=>{e.exports=function(e,t){return function(n){return e(t(n))}}},45357:(e,t,n)=>{var r=n(96874),o=Math.max;e.exports=function(e,t,n){return t=o(void 0===t?e.length-1:t,0),function(){for(var a=arguments,i=-1,l=o(a.length-t,0),s=Array(l);++i<l;)s[i]=a[t+i];i=-1;for(var u=Array(t+1);++i<t;)u[i]=a[i];return u[t]=n(s),r(e,this,u)}}},40292:(e,t,n)=>{var r=n(97786),o=n(14259);e.exports=function(e,t){return t.length<2?e:r(e,o(t,0,-1))}},55639:(e,t,n)=>{var r=n(31957),o="object"==typeof self&&self&&self.Object===Object&&self,a=r||o||Function("return this")();e.exports=a},90619:e=>{e.exports=function(e){return this.__data__.set(e,"__lodash_hash_undefined__"),this}},72385:e=>{e.exports=function(e){return this.__data__.has(e)}},21814:e=>{e.exports=function(e){var t=-1,n=Array(e.size);return e.forEach((function(e){n[++t]=e})),n}},30061:(e,t,n)=>{var r=n(56560),o=n(21275)(r);e.exports=o},21275:e=>{var t=Date.now;e.exports=function(e){var n=0,r=0;return function(){var o=t(),a=16-(o-r);if(r=o,a>0){if(++n>=800)return arguments[0]}else n=0;return e.apply(void 0,arguments)}}},37465:(e,t,n)=>{var r=n(38407);e.exports=function(){this.__data__=new r,this.size=0}},63779:e=>{e.exports=function(e){var t=this.__data__,n=t.delete(e);return this.size=t.size,n}},67599:e=>{e.exports=function(e){return this.__data__.get(e)}},44758:e=>{e.exports=function(e){return this.__data__.has(e)}},34309:(e,t,n)=>{var r=n(38407),o=n(57071),a=n(83369);e.exports=function(e,t){var n=this.__data__;if(n instanceof r){var i=n.__data__;if(!o||i.length<199)return i.push([e,t]),this.size=++n.size,this;n=this.__data__=new a(i)}return n.set(e,t),this.size=n.size,this}},55514:(e,t,n)=>{var r=n(24523),o=/[^.[\]]+|\[(?:(-?\d+(?:\.\d+)?)|(["'])((?:(?!\2)[^\\]|\\.)*?)\2)\]|(?=(?:\.|\[\])(?:\.|\[\]|$))/g,a=/\\(\\)?/g,i=r((function(e){var t=[];return 46===e.charCodeAt(0)&&t.push(""),e.replace(o,(function(e,n,r,o){t.push(r?o.replace(a,"$1"):n||e)})),t}));e.exports=i},40327:(e,t,n)=>{var r=n(33448);e.exports=function(e){if("string"==typeof e||r(e))return e;var t=e+"";return"0"==t&&1/e==-Infinity?"-0":t}},80346:e=>{var t=Function.prototype.toString;e.exports=function(e){if(null!=e){try{return t.call(e)}catch(n){}try{return e+""}catch(n){}}return""}},75703:e=>{e.exports=function(e){return function(){return e}}},77813:e=>{e.exports=function(e,t){return e===t||e!=e&&t!=t}},85564:(e,t,n)=>{var r=n(21078);e.exports=function(e){return(null==e?0:e.length)?r(e,1):[]}},27361:(e,t,n)=>{var r=n(97786);e.exports=function(e,t,n){var o=null==e?void 0:r(e,t);return void 0===o?n:o}},7739:(e,t,n)=>{var r=n(89465),o=n(55189),a=Object.prototype.hasOwnProperty,i=o((function(e,t,n){a.call(e,n)?e[n].push(t):r(e,n,[t])}));e.exports=i},79095:(e,t,n)=>{var r=n(13),o=n(222);e.exports=function(e,t){return null!=e&&o(e,t,r)}},6557:e=>{e.exports=function(e){return e}},35694:(e,t,n)=>{var r=n(9454),o=n(37005),a=Object.prototype,i=a.hasOwnProperty,l=a.propertyIsEnumerable,s=r(function(){return arguments}())?r:function(e){return o(e)&&i.call(e,"callee")&&!l.call(e,"callee")};e.exports=s},1469:e=>{var t=Array.isArray;e.exports=t},98612:(e,t,n)=>{var r=n(23560),o=n(41780);e.exports=function(e){return null!=e&&o(e.length)&&!r(e)}},44144:(e,t,n)=>{e=n.nmd(e);var r=n(55639),o=n(95062),a=t&&!t.nodeType&&t,i=a&&e&&!e.nodeType&&e,l=i&&i.exports===a?r.Buffer:void 0,s=(l?l.isBuffer:void 0)||o;e.exports=s},23560:(e,t,n)=>{var r=n(44239),o=n(13218);e.exports=function(e){if(!o(e))return!1;var t=r(e);return"[object Function]"==t||"[object GeneratorFunction]"==t||"[object AsyncFunction]"==t||"[object Proxy]"==t}},41780:e=>{e.exports=function(e){return"number"==typeof e&&e>-1&&e%1==0&&e<=9007199254740991}},56688:(e,t,n)=>{var r=n(25588),o=n(7518),a=n(31167),i=a&&a.isMap,l=i?o(i):r;e.exports=l},13218:e=>{e.exports=function(e){var t=typeof e;return null!=e&&("object"==t||"function"==t)}},37005:e=>{e.exports=function(e){return null!=e&&"object"==typeof e}},68630:(e,t,n)=>{var r=n(44239),o=n(85924),a=n(37005),i=Function.prototype,l=Object.prototype,s=i.toString,u=l.hasOwnProperty,c=s.call(Object);e.exports=function(e){if(!a(e)||"[object Object]"!=r(e))return!1;var t=o(e);if(null===t)return!0;var n=u.call(t,"constructor")&&t.constructor;return"function"==typeof n&&n instanceof n&&s.call(n)==c}},72928:(e,t,n)=>{var r=n(29221),o=n(7518),a=n(31167),i=a&&a.isSet,l=i?o(i):r;e.exports=l},33448:(e,t,n)=>{var r=n(44239),o=n(37005);e.exports=function(e){return"symbol"==typeof e||o(e)&&"[object Symbol]"==r(e)}},36719:(e,t,n)=>{var r=n(38749),o=n(7518),a=n(31167),i=a&&a.isTypedArray,l=i?o(i):r;e.exports=l},3674:(e,t,n)=>{var r=n(14636),o=n(280),a=n(98612);e.exports=function(e){return a(e)?r(e):o(e)}},81704:(e,t,n)=>{var r=n(14636),o=n(10313),a=n(98612);e.exports=function(e){return a(e)?r(e,!0):o(e)}},10928:e=>{e.exports=function(e){var t=null==e?0:e.length;return t?e[t-1]:void 0}},88306:(e,t,n)=>{var r=n(83369);function o(e,t){if("function"!=typeof e||null!=t&&"function"!=typeof t)throw new TypeError("Expected a function");var n=function(){var r=arguments,o=t?t.apply(this,r):r[0],a=n.cache;if(a.has(o))return a.get(o);var i=e.apply(this,r);return n.cache=a.set(o,i)||a,i};return n.cache=new(o.Cache||r),n}o.Cache=r,e.exports=o},57557:(e,t,n)=>{var r=n(29932),o=n(85990),a=n(57406),i=n(71811),l=n(98363),s=n(60696),u=n(99021),c=n(46904),d=u((function(e,t){var n={};if(null==e)return n;var u=!1;t=r(t,(function(t){return t=i(t,e),u||(u=t.length>1),t})),l(e,c(e),n),u&&(n=o(n,7,s));for(var d=t.length;d--;)a(n,t[d]);return n}));e.exports=d},39601:(e,t,n)=>{var r=n(40371),o=n(79152),a=n(15403),i=n(40327);e.exports=function(e){return a(e)?r(i(e)):o(e)}},70479:e=>{e.exports=function(){return[]}},95062:e=>{e.exports=function(){return!1}},79833:(e,t,n)=>{var r=n(80531);e.exports=function(e){return null==e?"":r(e)}},31336:(e,t,n)=>{var r,o;!function(){var a,i,l,s,u,c,d,f,p,h,m,g,v,b,y,w,x,_,k,E,S,C,T,O,D,P,N=function(e){var t=new N.Builder;return t.pipeline.add(N.trimmer,N.stopWordFilter,N.stemmer),t.searchPipeline.add(N.stemmer),e.call(t,t),t.build()};N.version="2.3.9",N.utils={},N.utils.warn=(a=this,function(e){a.console&&console.warn&&console.warn(e)}),N.utils.asString=function(e){return null==e?"":e.toString()},N.utils.clone=function(e){if(null==e)return e;for(var t=Object.create(null),n=Object.keys(e),r=0;r<n.length;r++){var o=n[r],a=e[o];if(Array.isArray(a))t[o]=a.slice();else{if("string"!=typeof a&&"number"!=typeof a&&"boolean"!=typeof a)throw new TypeError("clone is not deep and does not support nested objects");t[o]=a}}return t},N.FieldRef=function(e,t,n){this.docRef=e,this.fieldName=t,this._stringValue=n},N.FieldRef.joiner="/",N.FieldRef.fromString=function(e){var t=e.indexOf(N.FieldRef.joiner);if(-1===t)throw"malformed field ref string";var n=e.slice(0,t),r=e.slice(t+1);return new N.FieldRef(r,n,e)},N.FieldRef.prototype.toString=function(){return null==this._stringValue&&(this._stringValue=this.fieldName+N.FieldRef.joiner+this.docRef),this._stringValue},N.Set=function(e){if(this.elements=Object.create(null),e){this.length=e.length;for(var t=0;t<this.length;t++)this.elements[e[t]]=!0}else this.length=0},N.Set.complete={intersect:function(e){return e},union:function(){return this},contains:function(){return!0}},N.Set.empty={intersect:function(){return this},union:function(e){return e},contains:function(){return!1}},N.Set.prototype.contains=function(e){return!!this.elements[e]},N.Set.prototype.intersect=function(e){var t,n,r,o=[];if(e===N.Set.complete)return this;if(e===N.Set.empty)return e;this.length<e.length?(t=this,n=e):(t=e,n=this),r=Object.keys(t.elements);for(var a=0;a<r.length;a++){var i=r[a];i in n.elements&&o.push(i)}return new N.Set(o)},N.Set.prototype.union=function(e){return e===N.Set.complete?N.Set.complete:e===N.Set.empty?this:new N.Set(Object.keys(this.elements).concat(Object.keys(e.elements)))},N.idf=function(e,t){var n=0;for(var r in e)"_index"!=r&&(n+=Object.keys(e[r]).length);var o=(t-n+.5)/(n+.5);return Math.log(1+Math.abs(o))},N.Token=function(e,t){this.str=e||"",this.metadata=t||{}},N.Token.prototype.toString=function(){return this.str},N.Token.prototype.update=function(e){return this.str=e(this.str,this.metadata),this},N.Token.prototype.clone=function(e){return e=e||function(e){return e},new N.Token(e(this.str,this.metadata),this.metadata)},N.tokenizer=function(e,t){if(null==e||null==e)return[];if(Array.isArray(e))return e.map((function(e){return new N.Token(N.utils.asString(e).toLowerCase(),N.utils.clone(t))}));for(var n=e.toString().toLowerCase(),r=n.length,o=[],a=0,i=0;a<=r;a++){var l=a-i;if(n.charAt(a).match(N.tokenizer.separator)||a==r){if(l>0){var s=N.utils.clone(t)||{};s.position=[i,l],s.index=o.length,o.push(new N.Token(n.slice(i,a),s))}i=a+1}}return o},N.tokenizer.separator=/[\s\-]+/,N.Pipeline=function(){this._stack=[]},N.Pipeline.registeredFunctions=Object.create(null),N.Pipeline.registerFunction=function(e,t){t in this.registeredFunctions&&N.utils.warn("Overwriting existing registered function: "+t),e.label=t,N.Pipeline.registeredFunctions[e.label]=e},N.Pipeline.warnIfFunctionNotRegistered=function(e){e.label&&e.label in this.registeredFunctions||N.utils.warn("Function is not registered with pipeline. This may cause problems when serialising the index.\n",e)},N.Pipeline.load=function(e){var t=new N.Pipeline;return e.forEach((function(e){var n=N.Pipeline.registeredFunctions[e];if(!n)throw new Error("Cannot load unregistered function: "+e);t.add(n)})),t},N.Pipeline.prototype.add=function(){var e=Array.prototype.slice.call(arguments);e.forEach((function(e){N.Pipeline.warnIfFunctionNotRegistered(e),this._stack.push(e)}),this)},N.Pipeline.prototype.after=function(e,t){N.Pipeline.warnIfFunctionNotRegistered(t);var n=this._stack.indexOf(e);if(-1==n)throw new Error("Cannot find existingFn");n+=1,this._stack.splice(n,0,t)},N.Pipeline.prototype.before=function(e,t){N.Pipeline.warnIfFunctionNotRegistered(t);var n=this._stack.indexOf(e);if(-1==n)throw new Error("Cannot find existingFn");this._stack.splice(n,0,t)},N.Pipeline.prototype.remove=function(e){var t=this._stack.indexOf(e);-1!=t&&this._stack.splice(t,1)},N.Pipeline.prototype.run=function(e){for(var t=this._stack.length,n=0;n<t;n++){for(var r=this._stack[n],o=[],a=0;a<e.length;a++){var i=r(e[a],a,e);if(null!=i&&""!==i)if(Array.isArray(i))for(var l=0;l<i.length;l++)o.push(i[l]);else o.push(i)}e=o}return e},N.Pipeline.prototype.runString=function(e,t){var n=new N.Token(e,t);return this.run([n]).map((function(e){return e.toString()}))},N.Pipeline.prototype.reset=function(){this._stack=[]},N.Pipeline.prototype.toJSON=function(){return this._stack.map((function(e){return N.Pipeline.warnIfFunctionNotRegistered(e),e.label}))},N.Vector=function(e){this._magnitude=0,this.elements=e||[]},N.Vector.prototype.positionForIndex=function(e){if(0==this.elements.length)return 0;for(var t=0,n=this.elements.length/2,r=n-t,o=Math.floor(r/2),a=this.elements[2*o];r>1&&(a<e&&(t=o),a>e&&(n=o),a!=e);)r=n-t,o=t+Math.floor(r/2),a=this.elements[2*o];return a==e||a>e?2*o:a<e?2*(o+1):void 0},N.Vector.prototype.insert=function(e,t){this.upsert(e,t,(function(){throw"duplicate index"}))},N.Vector.prototype.upsert=function(e,t,n){this._magnitude=0;var r=this.positionForIndex(e);this.elements[r]==e?this.elements[r+1]=n(this.elements[r+1],t):this.elements.splice(r,0,e,t)},N.Vector.prototype.magnitude=function(){if(this._magnitude)return this._magnitude;for(var e=0,t=this.elements.length,n=1;n<t;n+=2){var r=this.elements[n];e+=r*r}return this._magnitude=Math.sqrt(e)},N.Vector.prototype.dot=function(e){for(var t=0,n=this.elements,r=e.elements,o=n.length,a=r.length,i=0,l=0,s=0,u=0;s<o&&u<a;)(i=n[s])<(l=r[u])?s+=2:i>l?u+=2:i==l&&(t+=n[s+1]*r[u+1],s+=2,u+=2);return t},N.Vector.prototype.similarity=function(e){return this.dot(e)/this.magnitude()||0},N.Vector.prototype.toArray=function(){for(var e=new Array(this.elements.length/2),t=1,n=0;t<this.elements.length;t+=2,n++)e[n]=this.elements[t];return e},N.Vector.prototype.toJSON=function(){return this.elements},N.stemmer=(i={ational:"ate",tional:"tion",enci:"ence",anci:"ance",izer:"ize",bli:"ble",alli:"al",entli:"ent",eli:"e",ousli:"ous",ization:"ize",ation:"ate",ator:"ate",alism:"al",iveness:"ive",fulness:"ful",ousness:"ous",aliti:"al",iviti:"ive",biliti:"ble",logi:"log"},l={icate:"ic",ative:"",alize:"al",iciti:"ic",ical:"ic",ful:"",ness:""},s="[aeiouy]",u="[^aeiou][^aeiouy]*",c=new RegExp("^([^aeiou][^aeiouy]*)?[aeiouy][aeiou]*[^aeiou][^aeiouy]*"),d=new RegExp("^([^aeiou][^aeiouy]*)?[aeiouy][aeiou]*[^aeiou][^aeiouy]*[aeiouy][aeiou]*[^aeiou][^aeiouy]*"),f=new RegExp("^([^aeiou][^aeiouy]*)?[aeiouy][aeiou]*[^aeiou][^aeiouy]*([aeiouy][aeiou]*)?$"),p=new RegExp("^([^aeiou][^aeiouy]*)?[aeiouy]"),h=/^(.+?)(ss|i)es$/,m=/^(.+?)([^s])s$/,g=/^(.+?)eed$/,v=/^(.+?)(ed|ing)$/,b=/.$/,y=/(at|bl|iz)$/,w=new RegExp("([^aeiouylsz])\\1$"),x=new RegExp("^"+u+s+"[^aeiouwxy]$"),_=/^(.+?[^aeiou])y$/,k=/^(.+?)(ational|tional|enci|anci|izer|bli|alli|entli|eli|ousli|ization|ation|ator|alism|iveness|fulness|ousness|aliti|iviti|biliti|logi)$/,E=/^(.+?)(icate|ative|alize|iciti|ical|ful|ness)$/,S=/^(.+?)(al|ance|ence|er|ic|able|ible|ant|ement|ment|ent|ou|ism|ate|iti|ous|ive|ize)$/,C=/^(.+?)(s|t)(ion)$/,T=/^(.+?)e$/,O=/ll$/,D=new RegExp("^"+u+s+"[^aeiouwxy]$"),P=function(e){var t,n,r,o,a,s,u;if(e.length<3)return e;if("y"==(r=e.substr(0,1))&&(e=r.toUpperCase()+e.substr(1)),a=m,(o=h).test(e)?e=e.replace(o,"$1$2"):a.test(e)&&(e=e.replace(a,"$1$2")),a=v,(o=g).test(e)){var P=o.exec(e);(o=c).test(P[1])&&(o=b,e=e.replace(o,""))}else a.test(e)&&(t=(P=a.exec(e))[1],(a=p).test(t)&&(s=w,u=x,(a=y).test(e=t)?e+="e":s.test(e)?(o=b,e=e.replace(o,"")):u.test(e)&&(e+="e")));return(o=_).test(e)&&(e=(t=(P=o.exec(e))[1])+"i"),(o=k).test(e)&&(t=(P=o.exec(e))[1],n=P[2],(o=c).test(t)&&(e=t+i[n])),(o=E).test(e)&&(t=(P=o.exec(e))[1],n=P[2],(o=c).test(t)&&(e=t+l[n])),a=C,(o=S).test(e)?(t=(P=o.exec(e))[1],(o=d).test(t)&&(e=t)):a.test(e)&&(t=(P=a.exec(e))[1]+P[2],(a=d).test(t)&&(e=t)),(o=T).test(e)&&(t=(P=o.exec(e))[1],a=f,s=D,((o=d).test(t)||a.test(t)&&!s.test(t))&&(e=t)),a=d,(o=O).test(e)&&a.test(e)&&(o=b,e=e.replace(o,"")),"y"==r&&(e=r.toLowerCase()+e.substr(1)),e},function(e){return e.update(P)}),N.Pipeline.registerFunction(N.stemmer,"stemmer"),N.generateStopWordFilter=function(e){var t=e.reduce((function(e,t){return e[t]=t,e}),{});return function(e){if(e&&t[e.toString()]!==e.toString())return e}},N.stopWordFilter=N.generateStopWordFilter(["a","able","about","across","after","all","almost","also","am","among","an","and","any","are","as","at","be","because","been","but","by","can","cannot","could","dear","did","do","does","either","else","ever","every","for","from","get","got","had","has","have","he","her","hers","him","his","how","however","i","if","in","into","is","it","its","just","least","let","like","likely","may","me","might","most","must","my","neither","no","nor","not","of","off","often","on","only","or","other","our","own","rather","said","say","says","she","should","since","so","some","than","that","the","their","them","then","there","these","they","this","tis","to","too","twas","us","wants","was","we","were","what","when","where","which","while","who","whom","why","will","with","would","yet","you","your"]),N.Pipeline.registerFunction(N.stopWordFilter,"stopWordFilter"),N.trimmer=function(e){return e.update((function(e){return e.replace(/^\W+/,"").replace(/\W+$/,"")}))},N.Pipeline.registerFunction(N.trimmer,"trimmer"),N.TokenSet=function(){this.final=!1,this.edges={},this.id=N.TokenSet._nextId,N.TokenSet._nextId+=1},N.TokenSet._nextId=1,N.TokenSet.fromArray=function(e){for(var t=new N.TokenSet.Builder,n=0,r=e.length;n<r;n++)t.insert(e[n]);return t.finish(),t.root},N.TokenSet.fromClause=function(e){return"editDistance"in e?N.TokenSet.fromFuzzyString(e.term,e.editDistance):N.TokenSet.fromString(e.term)},N.TokenSet.fromFuzzyString=function(e,t){for(var n=new N.TokenSet,r=[{node:n,editsRemaining:t,str:e}];r.length;){var o=r.pop();if(o.str.length>0){var a,i=o.str.charAt(0);i in o.node.edges?a=o.node.edges[i]:(a=new N.TokenSet,o.node.edges[i]=a),1==o.str.length&&(a.final=!0),r.push({node:a,editsRemaining:o.editsRemaining,str:o.str.slice(1)})}if(0!=o.editsRemaining){if("*"in o.node.edges)var l=o.node.edges["*"];else{l=new N.TokenSet;o.node.edges["*"]=l}if(0==o.str.length&&(l.final=!0),r.push({node:l,editsRemaining:o.editsRemaining-1,str:o.str}),o.str.length>1&&r.push({node:o.node,editsRemaining:o.editsRemaining-1,str:o.str.slice(1)}),1==o.str.length&&(o.node.final=!0),o.str.length>=1){if("*"in o.node.edges)var s=o.node.edges["*"];else{s=new N.TokenSet;o.node.edges["*"]=s}1==o.str.length&&(s.final=!0),r.push({node:s,editsRemaining:o.editsRemaining-1,str:o.str.slice(1)})}if(o.str.length>1){var u,c=o.str.charAt(0),d=o.str.charAt(1);d in o.node.edges?u=o.node.edges[d]:(u=new N.TokenSet,o.node.edges[d]=u),1==o.str.length&&(u.final=!0),r.push({node:u,editsRemaining:o.editsRemaining-1,str:c+o.str.slice(2)})}}}return n},N.TokenSet.fromString=function(e){for(var t=new N.TokenSet,n=t,r=0,o=e.length;r<o;r++){var a=e[r],i=r==o-1;if("*"==a)t.edges[a]=t,t.final=i;else{var l=new N.TokenSet;l.final=i,t.edges[a]=l,t=l}}return n},N.TokenSet.prototype.toArray=function(){for(var e=[],t=[{prefix:"",node:this}];t.length;){var n=t.pop(),r=Object.keys(n.node.edges),o=r.length;n.node.final&&(n.prefix.charAt(0),e.push(n.prefix));for(var a=0;a<o;a++){var i=r[a];t.push({prefix:n.prefix.concat(i),node:n.node.edges[i]})}}return e},N.TokenSet.prototype.toString=function(){if(this._str)return this._str;for(var e=this.final?"1":"0",t=Object.keys(this.edges).sort(),n=t.length,r=0;r<n;r++){var o=t[r];e=e+o+this.edges[o].id}return e},N.TokenSet.prototype.intersect=function(e){for(var t=new N.TokenSet,n=void 0,r=[{qNode:e,output:t,node:this}];r.length;){n=r.pop();for(var o=Object.keys(n.qNode.edges),a=o.length,i=Object.keys(n.node.edges),l=i.length,s=0;s<a;s++)for(var u=o[s],c=0;c<l;c++){var d=i[c];if(d==u||"*"==u){var f=n.node.edges[d],p=n.qNode.edges[u],h=f.final&&p.final,m=void 0;d in n.output.edges?(m=n.output.edges[d]).final=m.final||h:((m=new N.TokenSet).final=h,n.output.edges[d]=m),r.push({qNode:p,output:m,node:f})}}}return t},N.TokenSet.Builder=function(){this.previousWord="",this.root=new N.TokenSet,this.uncheckedNodes=[],this.minimizedNodes={}},N.TokenSet.Builder.prototype.insert=function(e){var t,n=0;if(e<this.previousWord)throw new Error("Out of order word insertion");for(var r=0;r<e.length&&r<this.previousWord.length&&e[r]==this.previousWord[r];r++)n++;this.minimize(n),t=0==this.uncheckedNodes.length?this.root:this.uncheckedNodes[this.uncheckedNodes.length-1].child;for(r=n;r<e.length;r++){var o=new N.TokenSet,a=e[r];t.edges[a]=o,this.uncheckedNodes.push({parent:t,char:a,child:o}),t=o}t.final=!0,this.previousWord=e},N.TokenSet.Builder.prototype.finish=function(){this.minimize(0)},N.TokenSet.Builder.prototype.minimize=function(e){for(var t=this.uncheckedNodes.length-1;t>=e;t--){var n=this.uncheckedNodes[t],r=n.child.toString();r in this.minimizedNodes?n.parent.edges[n.char]=this.minimizedNodes[r]:(n.child._str=r,this.minimizedNodes[r]=n.child),this.uncheckedNodes.pop()}},N.Index=function(e){this.invertedIndex=e.invertedIndex,this.fieldVectors=e.fieldVectors,this.tokenSet=e.tokenSet,this.fields=e.fields,this.pipeline=e.pipeline},N.Index.prototype.search=function(e){return this.query((function(t){new N.QueryParser(e,t).parse()}))},N.Index.prototype.query=function(e){for(var t=new N.Query(this.fields),n=Object.create(null),r=Object.create(null),o=Object.create(null),a=Object.create(null),i=Object.create(null),l=0;l<this.fields.length;l++)r[this.fields[l]]=new N.Vector;e.call(t,t);for(l=0;l<t.clauses.length;l++){var s=t.clauses[l],u=null,c=N.Set.empty;u=s.usePipeline?this.pipeline.runString(s.term,{fields:s.fields}):[s.term];for(var d=0;d<u.length;d++){var f=u[d];s.term=f;var p=N.TokenSet.fromClause(s),h=this.tokenSet.intersect(p).toArray();if(0===h.length&&s.presence===N.Query.presence.REQUIRED){for(var m=0;m<s.fields.length;m++){a[A=s.fields[m]]=N.Set.empty}break}for(var g=0;g<h.length;g++){var v=h[g],b=this.invertedIndex[v],y=b._index;for(m=0;m<s.fields.length;m++){var w=b[A=s.fields[m]],x=Object.keys(w),_=v+"/"+A,k=new N.Set(x);if(s.presence==N.Query.presence.REQUIRED&&(c=c.union(k),void 0===a[A]&&(a[A]=N.Set.complete)),s.presence!=N.Query.presence.PROHIBITED){if(r[A].upsert(y,s.boost,(function(e,t){return e+t})),!o[_]){for(var E=0;E<x.length;E++){var S,C=x[E],T=new N.FieldRef(C,A),O=w[C];void 0===(S=n[T])?n[T]=new N.MatchData(v,A,O):S.add(v,A,O)}o[_]=!0}}else void 0===i[A]&&(i[A]=N.Set.empty),i[A]=i[A].union(k)}}}if(s.presence===N.Query.presence.REQUIRED)for(m=0;m<s.fields.length;m++){a[A=s.fields[m]]=a[A].intersect(c)}}var D=N.Set.complete,P=N.Set.empty;for(l=0;l<this.fields.length;l++){var A;a[A=this.fields[l]]&&(D=D.intersect(a[A])),i[A]&&(P=P.union(i[A]))}var I=Object.keys(n),L=[],R=Object.create(null);if(t.isNegated()){I=Object.keys(this.fieldVectors);for(l=0;l<I.length;l++){T=I[l];var j=N.FieldRef.fromString(T);n[T]=new N.MatchData}}for(l=0;l<I.length;l++){var M=(j=N.FieldRef.fromString(I[l])).docRef;if(D.contains(M)&&!P.contains(M)){var F,B=this.fieldVectors[j],z=r[j.fieldName].similarity(B);if(void 0!==(F=R[M]))F.score+=z,F.matchData.combine(n[j]);else{var $={ref:M,score:z,matchData:n[j]};R[M]=$,L.push($)}}}return L.sort((function(e,t){return t.score-e.score}))},N.Index.prototype.toJSON=function(){var e=Object.keys(this.invertedIndex).sort().map((function(e){return[e,this.invertedIndex[e]]}),this),t=Object.keys(this.fieldVectors).map((function(e){return[e,this.fieldVectors[e].toJSON()]}),this);return{version:N.version,fields:this.fields,fieldVectors:t,invertedIndex:e,pipeline:this.pipeline.toJSON()}},N.Index.load=function(e){var t={},n={},r=e.fieldVectors,o=Object.create(null),a=e.invertedIndex,i=new N.TokenSet.Builder,l=N.Pipeline.load(e.pipeline);e.version!=N.version&&N.utils.warn("Version mismatch when loading serialised index. Current version of lunr '"+N.version+"' does not match serialized index '"+e.version+"'");for(var s=0;s<r.length;s++){var u=(d=r[s])[0],c=d[1];n[u]=new N.Vector(c)}for(s=0;s<a.length;s++){var d,f=(d=a[s])[0],p=d[1];i.insert(f),o[f]=p}return i.finish(),t.fields=e.fields,t.fieldVectors=n,t.invertedIndex=o,t.tokenSet=i.root,t.pipeline=l,new N.Index(t)},N.Builder=function(){this._ref="id",this._fields=Object.create(null),this._documents=Object.create(null),this.invertedIndex=Object.create(null),this.fieldTermFrequencies={},this.fieldLengths={},this.tokenizer=N.tokenizer,this.pipeline=new N.Pipeline,this.searchPipeline=new N.Pipeline,this.documentCount=0,this._b=.75,this._k1=1.2,this.termIndex=0,this.metadataWhitelist=[]},N.Builder.prototype.ref=function(e){this._ref=e},N.Builder.prototype.field=function(e,t){if(/\//.test(e))throw new RangeError("Field '"+e+"' contains illegal character '/'");this._fields[e]=t||{}},N.Builder.prototype.b=function(e){this._b=e<0?0:e>1?1:e},N.Builder.prototype.k1=function(e){this._k1=e},N.Builder.prototype.add=function(e,t){var n=e[this._ref],r=Object.keys(this._fields);this._documents[n]=t||{},this.documentCount+=1;for(var o=0;o<r.length;o++){var a=r[o],i=this._fields[a].extractor,l=i?i(e):e[a],s=this.tokenizer(l,{fields:[a]}),u=this.pipeline.run(s),c=new N.FieldRef(n,a),d=Object.create(null);this.fieldTermFrequencies[c]=d,this.fieldLengths[c]=0,this.fieldLengths[c]+=u.length;for(var f=0;f<u.length;f++){var p=u[f];if(null==d[p]&&(d[p]=0),d[p]+=1,null==this.invertedIndex[p]){var h=Object.create(null);h._index=this.termIndex,this.termIndex+=1;for(var m=0;m<r.length;m++)h[r[m]]=Object.create(null);this.invertedIndex[p]=h}null==this.invertedIndex[p][a][n]&&(this.invertedIndex[p][a][n]=Object.create(null));for(var g=0;g<this.metadataWhitelist.length;g++){var v=this.metadataWhitelist[g],b=p.metadata[v];null==this.invertedIndex[p][a][n][v]&&(this.invertedIndex[p][a][n][v]=[]),this.invertedIndex[p][a][n][v].push(b)}}}},N.Builder.prototype.calculateAverageFieldLengths=function(){for(var e=Object.keys(this.fieldLengths),t=e.length,n={},r={},o=0;o<t;o++){var a=N.FieldRef.fromString(e[o]),i=a.fieldName;r[i]||(r[i]=0),r[i]+=1,n[i]||(n[i]=0),n[i]+=this.fieldLengths[a]}var l=Object.keys(this._fields);for(o=0;o<l.length;o++){var s=l[o];n[s]=n[s]/r[s]}this.averageFieldLength=n},N.Builder.prototype.createFieldVectors=function(){for(var e={},t=Object.keys(this.fieldTermFrequencies),n=t.length,r=Object.create(null),o=0;o<n;o++){for(var a=N.FieldRef.fromString(t[o]),i=a.fieldName,l=this.fieldLengths[a],s=new N.Vector,u=this.fieldTermFrequencies[a],c=Object.keys(u),d=c.length,f=this._fields[i].boost||1,p=this._documents[a.docRef].boost||1,h=0;h<d;h++){var m,g,v,b=c[h],y=u[b],w=this.invertedIndex[b]._index;void 0===r[b]?(m=N.idf(this.invertedIndex[b],this.documentCount),r[b]=m):m=r[b],g=m*((this._k1+1)*y)/(this._k1*(1-this._b+this._b*(l/this.averageFieldLength[i]))+y),g*=f,g*=p,v=Math.round(1e3*g)/1e3,s.insert(w,v)}e[a]=s}this.fieldVectors=e},N.Builder.prototype.createTokenSet=function(){this.tokenSet=N.TokenSet.fromArray(Object.keys(this.invertedIndex).sort())},N.Builder.prototype.build=function(){return this.calculateAverageFieldLengths(),this.createFieldVectors(),this.createTokenSet(),new N.Index({invertedIndex:this.invertedIndex,fieldVectors:this.fieldVectors,tokenSet:this.tokenSet,fields:Object.keys(this._fields),pipeline:this.searchPipeline})},N.Builder.prototype.use=function(e){var t=Array.prototype.slice.call(arguments,1);t.unshift(this),e.apply(this,t)},N.MatchData=function(e,t,n){for(var r=Object.create(null),o=Object.keys(n||{}),a=0;a<o.length;a++){var i=o[a];r[i]=n[i].slice()}this.metadata=Object.create(null),void 0!==e&&(this.metadata[e]=Object.create(null),this.metadata[e][t]=r)},N.MatchData.prototype.combine=function(e){for(var t=Object.keys(e.metadata),n=0;n<t.length;n++){var r=t[n],o=Object.keys(e.metadata[r]);null==this.metadata[r]&&(this.metadata[r]=Object.create(null));for(var a=0;a<o.length;a++){var i=o[a],l=Object.keys(e.metadata[r][i]);null==this.metadata[r][i]&&(this.metadata[r][i]=Object.create(null));for(var s=0;s<l.length;s++){var u=l[s];null==this.metadata[r][i][u]?this.metadata[r][i][u]=e.metadata[r][i][u]:this.metadata[r][i][u]=this.metadata[r][i][u].concat(e.metadata[r][i][u])}}}},N.MatchData.prototype.add=function(e,t,n){if(!(e in this.metadata))return this.metadata[e]=Object.create(null),void(this.metadata[e][t]=n);if(t in this.metadata[e])for(var r=Object.keys(n),o=0;o<r.length;o++){var a=r[o];a in this.metadata[e][t]?this.metadata[e][t][a]=this.metadata[e][t][a].concat(n[a]):this.metadata[e][t][a]=n[a]}else this.metadata[e][t]=n},N.Query=function(e){this.clauses=[],this.allFields=e},N.Query.wildcard=new String("*"),N.Query.wildcard.NONE=0,N.Query.wildcard.LEADING=1,N.Query.wildcard.TRAILING=2,N.Query.presence={OPTIONAL:1,REQUIRED:2,PROHIBITED:3},N.Query.prototype.clause=function(e){return"fields"in e||(e.fields=this.allFields),"boost"in e||(e.boost=1),"usePipeline"in e||(e.usePipeline=!0),"wildcard"in e||(e.wildcard=N.Query.wildcard.NONE),e.wildcard&N.Query.wildcard.LEADING&&e.term.charAt(0)!=N.Query.wildcard&&(e.term="*"+e.term),e.wildcard&N.Query.wildcard.TRAILING&&e.term.slice(-1)!=N.Query.wildcard&&(e.term=e.term+"*"),"presence"in e||(e.presence=N.Query.presence.OPTIONAL),this.clauses.push(e),this},N.Query.prototype.isNegated=function(){for(var e=0;e<this.clauses.length;e++)if(this.clauses[e].presence!=N.Query.presence.PROHIBITED)return!1;return!0},N.Query.prototype.term=function(e,t){if(Array.isArray(e))return e.forEach((function(e){this.term(e,N.utils.clone(t))}),this),this;var n=t||{};return n.term=e.toString(),this.clause(n),this},N.QueryParseError=function(e,t,n){this.name="QueryParseError",this.message=e,this.start=t,this.end=n},N.QueryParseError.prototype=new Error,N.QueryLexer=function(e){this.lexemes=[],this.str=e,this.length=e.length,this.pos=0,this.start=0,this.escapeCharPositions=[]},N.QueryLexer.prototype.run=function(){for(var e=N.QueryLexer.lexText;e;)e=e(this)},N.QueryLexer.prototype.sliceString=function(){for(var e=[],t=this.start,n=this.pos,r=0;r<this.escapeCharPositions.length;r++)n=this.escapeCharPositions[r],e.push(this.str.slice(t,n)),t=n+1;return e.push(this.str.slice(t,this.pos)),this.escapeCharPositions.length=0,e.join("")},N.QueryLexer.prototype.emit=function(e){this.lexemes.push({type:e,str:this.sliceString(),start:this.start,end:this.pos}),this.start=this.pos},N.QueryLexer.prototype.escapeCharacter=function(){this.escapeCharPositions.push(this.pos-1),this.pos+=1},N.QueryLexer.prototype.next=function(){if(this.pos>=this.length)return N.QueryLexer.EOS;var e=this.str.charAt(this.pos);return this.pos+=1,e},N.QueryLexer.prototype.width=function(){return this.pos-this.start},N.QueryLexer.prototype.ignore=function(){this.start==this.pos&&(this.pos+=1),this.start=this.pos},N.QueryLexer.prototype.backup=function(){this.pos-=1},N.QueryLexer.prototype.acceptDigitRun=function(){var e,t;do{t=(e=this.next()).charCodeAt(0)}while(t>47&&t<58);e!=N.QueryLexer.EOS&&this.backup()},N.QueryLexer.prototype.more=function(){return this.pos<this.length},N.QueryLexer.EOS="EOS",N.QueryLexer.FIELD="FIELD",N.QueryLexer.TERM="TERM",N.QueryLexer.EDIT_DISTANCE="EDIT_DISTANCE",N.QueryLexer.BOOST="BOOST",N.QueryLexer.PRESENCE="PRESENCE",N.QueryLexer.lexField=function(e){return e.backup(),e.emit(N.QueryLexer.FIELD),e.ignore(),N.QueryLexer.lexText},N.QueryLexer.lexTerm=function(e){if(e.width()>1&&(e.backup(),e.emit(N.QueryLexer.TERM)),e.ignore(),e.more())return N.QueryLexer.lexText},N.QueryLexer.lexEditDistance=function(e){return e.ignore(),e.acceptDigitRun(),e.emit(N.QueryLexer.EDIT_DISTANCE),N.QueryLexer.lexText},N.QueryLexer.lexBoost=function(e){return e.ignore(),e.acceptDigitRun(),e.emit(N.QueryLexer.BOOST),N.QueryLexer.lexText},N.QueryLexer.lexEOS=function(e){e.width()>0&&e.emit(N.QueryLexer.TERM)},N.QueryLexer.termSeparator=N.tokenizer.separator,N.QueryLexer.lexText=function(e){for(;;){var t=e.next();if(t==N.QueryLexer.EOS)return N.QueryLexer.lexEOS;if(92!=t.charCodeAt(0)){if(":"==t)return N.QueryLexer.lexField;if("~"==t)return e.backup(),e.width()>0&&e.emit(N.QueryLexer.TERM),N.QueryLexer.lexEditDistance;if("^"==t)return e.backup(),e.width()>0&&e.emit(N.QueryLexer.TERM),N.QueryLexer.lexBoost;if("+"==t&&1===e.width())return e.emit(N.QueryLexer.PRESENCE),N.QueryLexer.lexText;if("-"==t&&1===e.width())return e.emit(N.QueryLexer.PRESENCE),N.QueryLexer.lexText;if(t.match(N.QueryLexer.termSeparator))return N.QueryLexer.lexTerm}else e.escapeCharacter()}},N.QueryParser=function(e,t){this.lexer=new N.QueryLexer(e),this.query=t,this.currentClause={},this.lexemeIdx=0},N.QueryParser.prototype.parse=function(){this.lexer.run(),this.lexemes=this.lexer.lexemes;for(var e=N.QueryParser.parseClause;e;)e=e(this);return this.query},N.QueryParser.prototype.peekLexeme=function(){return this.lexemes[this.lexemeIdx]},N.QueryParser.prototype.consumeLexeme=function(){var e=this.peekLexeme();return this.lexemeIdx+=1,e},N.QueryParser.prototype.nextClause=function(){var e=this.currentClause;this.query.clause(e),this.currentClause={}},N.QueryParser.parseClause=function(e){var t=e.peekLexeme();if(null!=t)switch(t.type){case N.QueryLexer.PRESENCE:return N.QueryParser.parsePresence;case N.QueryLexer.FIELD:return N.QueryParser.parseField;case N.QueryLexer.TERM:return N.QueryParser.parseTerm;default:var n="expected either a field or a term, found "+t.type;throw t.str.length>=1&&(n+=" with value '"+t.str+"'"),new N.QueryParseError(n,t.start,t.end)}},N.QueryParser.parsePresence=function(e){var t=e.consumeLexeme();if(null!=t){switch(t.str){case"-":e.currentClause.presence=N.Query.presence.PROHIBITED;break;case"+":e.currentClause.presence=N.Query.presence.REQUIRED;break;default:var n="unrecognised presence operator'"+t.str+"'";throw new N.QueryParseError(n,t.start,t.end)}var r=e.peekLexeme();if(null==r){n="expecting term or field, found nothing";throw new N.QueryParseError(n,t.start,t.end)}switch(r.type){case N.QueryLexer.FIELD:return N.QueryParser.parseField;case N.QueryLexer.TERM:return N.QueryParser.parseTerm;default:n="expecting term or field, found '"+r.type+"'";throw new N.QueryParseError(n,r.start,r.end)}}},N.QueryParser.parseField=function(e){var t=e.consumeLexeme();if(null!=t){if(-1==e.query.allFields.indexOf(t.str)){var n=e.query.allFields.map((function(e){return"'"+e+"'"})).join(", "),r="unrecognised field '"+t.str+"', possible fields: "+n;throw new N.QueryParseError(r,t.start,t.end)}e.currentClause.fields=[t.str];var o=e.peekLexeme();if(null==o){r="expecting term, found nothing";throw new N.QueryParseError(r,t.start,t.end)}if(o.type===N.QueryLexer.TERM)return N.QueryParser.parseTerm;r="expecting term, found '"+o.type+"'";throw new N.QueryParseError(r,o.start,o.end)}},N.QueryParser.parseTerm=function(e){var t=e.consumeLexeme();if(null!=t){e.currentClause.term=t.str.toLowerCase(),-1!=t.str.indexOf("*")&&(e.currentClause.usePipeline=!1);var n=e.peekLexeme();if(null!=n)switch(n.type){case N.QueryLexer.TERM:return e.nextClause(),N.QueryParser.parseTerm;case N.QueryLexer.FIELD:return e.nextClause(),N.QueryParser.parseField;case N.QueryLexer.EDIT_DISTANCE:return N.QueryParser.parseEditDistance;case N.QueryLexer.BOOST:return N.QueryParser.parseBoost;case N.QueryLexer.PRESENCE:return e.nextClause(),N.QueryParser.parsePresence;default:var r="Unexpected lexeme type '"+n.type+"'";throw new N.QueryParseError(r,n.start,n.end)}else e.nextClause()}},N.QueryParser.parseEditDistance=function(e){var t=e.consumeLexeme();if(null!=t){var n=parseInt(t.str,10);if(isNaN(n)){var r="edit distance must be numeric";throw new N.QueryParseError(r,t.start,t.end)}e.currentClause.editDistance=n;var o=e.peekLexeme();if(null!=o)switch(o.type){case N.QueryLexer.TERM:return e.nextClause(),N.QueryParser.parseTerm;case N.QueryLexer.FIELD:return e.nextClause(),N.QueryParser.parseField;case N.QueryLexer.EDIT_DISTANCE:return N.QueryParser.parseEditDistance;case N.QueryLexer.BOOST:return N.QueryParser.parseBoost;case N.QueryLexer.PRESENCE:return e.nextClause(),N.QueryParser.parsePresence;default:r="Unexpected lexeme type '"+o.type+"'";throw new N.QueryParseError(r,o.start,o.end)}else e.nextClause()}},N.QueryParser.parseBoost=function(e){var t=e.consumeLexeme();if(null!=t){var n=parseInt(t.str,10);if(isNaN(n)){var r="boost must be numeric";throw new N.QueryParseError(r,t.start,t.end)}e.currentClause.boost=n;var o=e.peekLexeme();if(null!=o)switch(o.type){case N.QueryLexer.TERM:return e.nextClause(),N.QueryParser.parseTerm;case N.QueryLexer.FIELD:return e.nextClause(),N.QueryParser.parseField;case N.QueryLexer.EDIT_DISTANCE:return N.QueryParser.parseEditDistance;case N.QueryLexer.BOOST:return N.QueryParser.parseBoost;case N.QueryLexer.PRESENCE:return e.nextClause(),N.QueryParser.parsePresence;default:r="Unexpected lexeme type '"+o.type+"'";throw new N.QueryParseError(r,o.start,o.end)}else e.nextClause()}},void 0===(o="function"==typeof(r=function(){return N})?r.call(t,n,t,e):r)||(e.exports=o)}()},27861:(e,t,n)=>{"use strict";n.r(t),n.d(t,{default:()=>r});const r={icon:"icon_S7Kx",s:"s_AZDZ",m:"m_thRi",l:"l_WHPt",fill:"fill_hNhN",stroke:"stroke_N8dm"}},10153:(e,t,n)=>{"use strict";n.r(t),n.d(t,{default:()=>r});const r={backdrop:"backdrop_Ifvc",navWrapper:"navWrapper_ybYI",nav:"nav_cMpg",visible:"visible_ynAX",wrapper:"wrapper_SWrM",fullscreenButton:"fullscreenButton_Bocn",active:"active_qZD5"}},8633:(e,t,n)=>{"use strict";n.r(t),n.d(t,{default:()=>r});const r={toggle:"toggle_K23S",toggleButton:"toggleButton_dl49",darkToggleIcon:"darkToggleIcon_lKkA",lightToggleIcon:"lightToggleIcon_K4TL",toggleButtonDisabled:"toggleButtonDisabled_AAS_"}},79762:(e,t,n)=>{"use strict";n.r(t),n.d(t,{default:()=>r});const r={firstRow:"firstRow_ar1q",secondRow:"secondRow__ww3",backToTop:"backToTop_wDfN"}},90826:(e,t,n)=>{"use strict";n.r(t),n.d(t,{default:()=>r});const r={colorModeToggle:"colorModeToggle_GSaI",rightSection:"rightSection_CLeF",iconButtonGroup:"iconButtonGroup_ktNv"}},83244:(e,t,n)=>{"use strict";n.r(t),n.d(t,{default:()=>r});const r={dropdownNavbarItem:"dropdownNavbarItem_o23I"}},31259:(e,t,n)=>{"use strict";n.r(t),n.d(t,{default:()=>r});const r={modal:"modal_kLVz",closeButton:"closeButton_Rr0e",header:"header_QwCa"}},61699:(e,t,n)=>{"use strict";n.r(t),n.d(t,{default:()=>r});const r={root:"root_ONDG",empty:"empty_a7qb",title:"title_uwS_",item:"item_RHYF",itemTitle:"itemTitle_jtAv"}},9592:(e,t,n)=>{"use strict";n.r(t),n.d(t,{default:()=>r});const r={root:"root_xZfc",textField:"textField_af43"}},1443:(e,t,n)=>{"use strict";n.r(t),n.d(t,{default:()=>r});const r={root:"root_N57j"}},18589:(e,t,n)=>{"use strict";n.r(t),n.d(t,{default:()=>r});const r={root:"root_Ooa0",level1:"level1_fpUf",icon:"icon_sZn2",fill:"fill_fkan",stroke:"stroke_j3wH"}},86620:(e,t,n)=>{"use strict";n.r(t),n.d(t,{default:()=>r});const r={root:"root_JWD1"}},38076:(e,t,n)=>{"use strict";n.r(t),n.d(t,{default:()=>r});const r={root:"root_EFVO"}},20550:(e,t,n)=>{"use strict";n.r(t),n.d(t,{default:()=>r});const r={root:"root_ltHz",noResults:"noResults_mD2O",groups:"groups_p1lF",divider:"divider_eGUz",topBar:"topBar_Dtew"}},22473:(e,t,n)=>{"use strict";n.r(t)},11057:(e,t,n)=>{"use strict";n.r(t)},93878:(e,t,n)=>{"use strict";n.r(t)},32497:(e,t,n)=>{"use strict";n.r(t)},97087:(e,t,n)=>{"use strict";n.r(t),n.d(t,{default:()=>r});const r={navbarHideable:"navbarHideable_OoEf",navbarHidden:"navbarHidden_zoxl"}},88822:(e,t,n)=>{"use strict";n.r(t),n.d(t,{default:()=>r});const r={linkContent:"linkContent__x3v",externalLinkIcon:"externalLinkIcon_Qfue"}},36459:(e,t,n)=>{"use strict";n.r(t),n.d(t,{default:()=>r});const r={root:"root_QACb"}},97142:(e,t)=>{"use strict";t.I=function(e){e.client&&(document.head.appendChild(e.msh=document.createElement("style")),e.createRule=function(t,n){var r=t+"{}";n&&(r=n+"{"+r+"}");var o=n?e.msh.sheet:e.sh.sheet,a=o.insertRule(r,o.cssRules.length),i=(o.cssRules||o.rules)[a];if(i.index=a,n){var l=(i.cssRules||i.rules)[0];i.style=l.style,i.styleMap=l.styleMap}return i})}},52099:(e,t,n)=>{"use strict";var r=n(39662).D;t.I=function(e){if(e.client){0;var t=e.kebab;n.prototype.diff=function(e){var n,r=this.decl,o=this.rule.style;for(n in r)void 0===e[n]&&o.removeProperty(n);for(n in e)e[n]!==r[n]&&o.setProperty(t(n),e[n]);this.decl=e},n.prototype.del=function(){r(this.rule)},o.prototype.diff=function(e){var t=this.tree;for(var r in t)if(void 0===e[r]){var o=t[r];for(var a in o)o[a].del()}for(var r in e)if(void 0===t[r])for(var a in e[r]){(s=new n(a,r)).diff(e[r][a]),e[r][a]=s}else{var i=t[r],l=e[r];for(var a in i)l[a]||i[a].del();for(var a in l){var s;(s=i[a])?(s.diff(l[a]),l[a]=s):((s=new n(a,r)).diff(l[a]),l[a]=s)}}this.tree=e},e.VRule=n,e.VSheet=o}function n(t,n){this.rule=e.createRule(t,n),this.decl={}}function o(){this.tree={}}}},87749:(e,t)=>{t.z=function e(t,n,r,o){var a,i,l={},s=!1;for(a in n)"object"!=typeof(i=n[a])&&(s=!0,l[a]=i);for(a in s&&(t[o]||(t[o]={}),t[o][r]=l),n)if("object"==typeof(i=n[a]))if("@"===a[0])e(t,i,r,a);else{var u=a.indexOf("&")>-1,c=r.split(",");if(u)for(var d=0;d<c.length;d++)c[d]=a.replace(/&/g,c[d]);else for(d=0;d<c.length;d++)c[d]=c[d]+" "+a;e(t,i,c.join(","),o)}}},39662:(e,t)=>{t.D=function(e){var t=e.index,n=e.parentStyleSheet,r=n.cssRules||n.rules;for(t=Math.max(t,r.length-1);t>=0;){if(r[t]===e){n.deleteRule(t);break}t--}}},40818:(e,t)=>{"use strict";var n=/[A-Z]/g;t.U=function(e){var t=(e=e||{}).assign||Object.assign;var r=t({raw:"",pfx:"_",client:"object"==typeof window,assign:t,stringify:JSON.stringify,kebab:function(e){return e.replace(n,"-$&").toLowerCase()},decl:function(e,t){return(e=r.kebab(e))+":"+t+";"},hash:function(e){return function(e){for(var t=5381,n=e.length;n;)t=33*t^e.charCodeAt(--n);return"_"+(t>>>0).toString(36)}(r.stringify(e))},selector:function(e,t){return e+(":"===t[0]?"":" ")+t},putRaw:function(e){r.raw+=e}},e);return r.client&&(r.sh||document.head.appendChild(r.sh=document.createElement("style")),r.putRaw=function(e){var t=r.sh.sheet;try{t.insertRule(e,t.cssRules.length)}catch(n){}}),r.put=function(e,t,n){var o,a,i="",l=[];for(o in t)(a=t[o])instanceof Object&&!(a instanceof Array)?l.push(o):i+=r.decl(o,a,e,n);i&&(i=e+"{"+i+"}",r.putRaw(n?n+"{"+i+"}":i));for(var s=0;s<l.length;s++)"@"===(o=l[s])[0]&&"@font-face"!==o?r.putAt(e,t[o],o):r.put(r.selector(e,o),t[o],n)},r.putAt=r.put,r}},74865:function(e,t,n){var r,o;r=function(){var e,t,n={version:"0.2.0"},r=n.settings={minimum:.08,easing:"ease",positionUsing:"",speed:200,trickle:!0,trickleRate:.02,trickleSpeed:800,showSpinner:!0,barSelector:'[role="bar"]',spinnerSelector:'[role="spinner"]',parent:"body",template:'<div class="bar" role="bar"><div class="peg"></div></div><div class="spinner" role="spinner"><div class="spinner-icon"></div></div>'};function o(e,t,n){return e<t?t:e>n?n:e}function a(e){return 100*(-1+e)}function i(e,t,n){var o;return(o="translate3d"===r.positionUsing?{transform:"translate3d("+a(e)+"%,0,0)"}:"translate"===r.positionUsing?{transform:"translate("+a(e)+"%,0)"}:{"margin-left":a(e)+"%"}).transition="all "+t+"ms "+n,o}n.configure=function(e){var t,n;for(t in e)void 0!==(n=e[t])&&e.hasOwnProperty(t)&&(r[t]=n);return this},n.status=null,n.set=function(e){var t=n.isStarted();e=o(e,r.minimum,1),n.status=1===e?null:e;var a=n.render(!t),u=a.querySelector(r.barSelector),c=r.speed,d=r.easing;return a.offsetWidth,l((function(t){""===r.positionUsing&&(r.positionUsing=n.getPositioningCSS()),s(u,i(e,c,d)),1===e?(s(a,{transition:"none",opacity:1}),a.offsetWidth,setTimeout((function(){s(a,{transition:"all "+c+"ms linear",opacity:0}),setTimeout((function(){n.remove(),t()}),c)}),c)):setTimeout(t,c)})),this},n.isStarted=function(){return"number"==typeof n.status},n.start=function(){n.status||n.set(0);var e=function(){setTimeout((function(){n.status&&(n.trickle(),e())}),r.trickleSpeed)};return r.trickle&&e(),this},n.done=function(e){return e||n.status?n.inc(.3+.5*Math.random()).set(1):this},n.inc=function(e){var t=n.status;return t?("number"!=typeof e&&(e=(1-t)*o(Math.random()*t,.1,.95)),t=o(t+e,0,.994),n.set(t)):n.start()},n.trickle=function(){return n.inc(Math.random()*r.trickleRate)},e=0,t=0,n.promise=function(r){return r&&"resolved"!==r.state()?(0===t&&n.start(),e++,t++,r.always((function(){0==--t?(e=0,n.done()):n.set((e-t)/e)})),this):this},n.render=function(e){if(n.isRendered())return document.getElementById("nprogress");c(document.documentElement,"nprogress-busy");var t=document.createElement("div");t.id="nprogress",t.innerHTML=r.template;var o,i=t.querySelector(r.barSelector),l=e?"-100":a(n.status||0),u=document.querySelector(r.parent);return s(i,{transition:"all 0 linear",transform:"translate3d("+l+"%,0,0)"}),r.showSpinner||(o=t.querySelector(r.spinnerSelector))&&p(o),u!=document.body&&c(u,"nprogress-custom-parent"),u.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 l=function(){var e=[];function t(){var n=e.shift();n&&n(t)}return function(n){e.push(n),1==e.length&&t()}}(),s=function(){var e=["Webkit","O","Moz","ms"],t={};function n(e){return e.replace(/^-ms-/,"ms-").replace(/-([\da-z])/gi,(function(e,t){return t.toUpperCase()}))}function r(t){var n=document.body.style;if(t in n)return t;for(var r,o=e.length,a=t.charAt(0).toUpperCase()+t.slice(1);o--;)if((r=e[o]+a)in n)return r;return t}function o(e){return e=n(e),t[e]||(t[e]=r(e))}function a(e,t,n){t=o(t),e.style[t]=n}return function(e,t){var n,r,o=arguments;if(2==o.length)for(n in t)void 0!==(r=t[n])&&t.hasOwnProperty(n)&&a(e,n,r);else a(e,o[1],o[2])}}();function u(e,t){return("string"==typeof e?e:f(e)).indexOf(" "+t+" ")>=0}function c(e,t){var n=f(e),r=n+t;u(n,t)||(e.className=r.substring(1))}function d(e,t){var n,r=f(e);u(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===(o="function"==typeof r?r.call(t,n,t,e):r)||(e.exports=o)},27418:e=>{"use strict";var t=Object.getOwnPropertySymbols,n=Object.prototype.hasOwnProperty,r=Object.prototype.propertyIsEnumerable;function o(e){if(null==e)throw new TypeError("Object.assign cannot be called with null or undefined");return Object(e)}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(o){return!1}}()?Object.assign:function(e,a){for(var i,l,s=o(e),u=1;u<arguments.length;u++){for(var c in i=Object(arguments[u]))n.call(i,c)&&(s[c]=i[c]);if(t){l=t(i);for(var d=0;d<l.length;d++)r.call(i,l[d])&&(s[l[d]]=i[l[d]])}}return s}},87594:(e,t)=>{function n(e){let t,n=[];for(let r of e.split(",").map((e=>e.trim())))if(/^-?\d+$/.test(r))n.push(parseInt(r,10));else if(t=r.match(/^(-?\d+)(-|\.\.\.?|\u2025|\u2026|\u22EF)(-?\d+)$/)){let[e,r,o,a]=t;if(r&&a){r=parseInt(r),a=parseInt(a);const e=r<a?1:-1;"-"!==o&&".."!==o&&"\u2025"!==o||(a+=e);for(let t=r;t!==a;t+=e)n.push(t)}}return n}t.default=n,e.exports=n},87410:(e,t,n)=>{"use strict";n.d(t,{Z:()=>a});var r=function(){var e=/(?:^|\s)lang(?:uage)?-([\w-]+)(?=\s|$)/i,t=0,n={},r={util:{encode:function e(t){return t instanceof o?new o(t.type,e(t.content),t.alias):Array.isArray(t)?t.map(e):t.replace(/&/g,"&").replace(/</g,"<").replace(/\u00a0/g," ")},type:function(e){return Object.prototype.toString.call(e).slice(8,-1)},objId:function(e){return e.__id||Object.defineProperty(e,"__id",{value:++t}),e.__id},clone:function e(t,n){var o,a;switch(n=n||{},r.util.type(t)){case"Object":if(a=r.util.objId(t),n[a])return n[a];for(var i in o={},n[a]=o,t)t.hasOwnProperty(i)&&(o[i]=e(t[i],n));return o;case"Array":return a=r.util.objId(t),n[a]?n[a]:(o=[],n[a]=o,t.forEach((function(t,r){o[r]=e(t,n)})),o);default:return t}},getLanguage:function(t){for(;t;){var n=e.exec(t.className);if(n)return n[1].toLowerCase();t=t.parentElement}return"none"},setLanguage:function(t,n){t.className=t.className.replace(RegExp(e,"gi"),""),t.classList.add("language-"+n)},isActive:function(e,t,n){for(var r="no-"+t;e;){var o=e.classList;if(o.contains(t))return!0;if(o.contains(r))return!1;e=e.parentElement}return!!n}},languages:{plain:n,plaintext:n,text:n,txt:n,extend:function(e,t){var n=r.util.clone(r.languages[e]);for(var o in t)n[o]=t[o];return n},insertBefore:function(e,t,n,o){var a=(o=o||r.languages)[e],i={};for(var l in a)if(a.hasOwnProperty(l)){if(l==t)for(var s in n)n.hasOwnProperty(s)&&(i[s]=n[s]);n.hasOwnProperty(l)||(i[l]=a[l])}var u=o[e];return o[e]=i,r.languages.DFS(r.languages,(function(t,n){n===u&&t!=e&&(this[t]=i)})),i},DFS:function e(t,n,o,a){a=a||{};var i=r.util.objId;for(var l in t)if(t.hasOwnProperty(l)){n.call(t,l,t[l],o||l);var s=t[l],u=r.util.type(s);"Object"!==u||a[i(s)]?"Array"!==u||a[i(s)]||(a[i(s)]=!0,e(s,n,l,a)):(a[i(s)]=!0,e(s,n,null,a))}}},plugins:{},highlight:function(e,t,n){var a={code:e,grammar:t,language:n};return r.hooks.run("before-tokenize",a),a.tokens=r.tokenize(a.code,a.grammar),r.hooks.run("after-tokenize",a),o.stringify(r.util.encode(a.tokens),a.language)},tokenize:function(e,t){var n=t.rest;if(n){for(var r in n)t[r]=n[r];delete t.rest}var o=new l;return s(o,o.head,e),i(e,o,t,o.head,0),function(e){var t=[],n=e.head.next;for(;n!==e.tail;)t.push(n.value),n=n.next;return t}(o)},hooks:{all:{},add:function(e,t){var n=r.hooks.all;n[e]=n[e]||[],n[e].push(t)},run:function(e,t){var n=r.hooks.all[e];if(n&&n.length)for(var o,a=0;o=n[a++];)o(t)}},Token:o};function o(e,t,n,r){this.type=e,this.content=t,this.alias=n,this.length=0|(r||"").length}function a(e,t,n,r){e.lastIndex=t;var o=e.exec(n);if(o&&r&&o[1]){var a=o[1].length;o.index+=a,o[0]=o[0].slice(a)}return o}function i(e,t,n,l,c,d){for(var f in n)if(n.hasOwnProperty(f)&&n[f]){var p=n[f];p=Array.isArray(p)?p:[p];for(var h=0;h<p.length;++h){if(d&&d.cause==f+","+h)return;var m=p[h],g=m.inside,v=!!m.lookbehind,b=!!m.greedy,y=m.alias;if(b&&!m.pattern.global){var w=m.pattern.toString().match(/[imsuy]*$/)[0];m.pattern=RegExp(m.pattern.source,w+"g")}for(var x=m.pattern||m,_=l.next,k=c;_!==t.tail&&!(d&&k>=d.reach);k+=_.value.length,_=_.next){var E=_.value;if(t.length>e.length)return;if(!(E instanceof o)){var S,C=1;if(b){if(!(S=a(x,k,e,v))||S.index>=e.length)break;var T=S.index,O=S.index+S[0].length,D=k;for(D+=_.value.length;T>=D;)D+=(_=_.next).value.length;if(k=D-=_.value.length,_.value instanceof o)continue;for(var P=_;P!==t.tail&&(D<O||"string"==typeof P.value);P=P.next)C++,D+=P.value.length;C--,E=e.slice(k,D),S.index-=k}else if(!(S=a(x,0,E,v)))continue;T=S.index;var N=S[0],A=E.slice(0,T),I=E.slice(T+N.length),L=k+E.length;d&&L>d.reach&&(d.reach=L);var R=_.prev;if(A&&(R=s(t,R,A),k+=A.length),u(t,R,C),_=s(t,R,new o(f,g?r.tokenize(N,g):N,y,N)),I&&s(t,_,I),C>1){var j={cause:f+","+h,reach:L};i(e,t,n,_.prev,k,j),d&&j.reach>d.reach&&(d.reach=j.reach)}}}}}}function l(){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 s(e,t,n){var r=t.next,o={value:n,prev:t,next:r};return t.next=o,r.prev=o,e.length++,o}function u(e,t,n){for(var r=t.next,o=0;o<n&&r!==e.tail;o++)r=r.next;t.next=r,r.prev=t,e.length-=o}return o.stringify=function e(t,n){if("string"==typeof t)return t;if(Array.isArray(t)){var o="";return t.forEach((function(t){o+=e(t,n)})),o}var a={type:t.type,content:e(t.content,n),tag:"span",classes:["token",t.type],attributes:{},language:n},i=t.alias;i&&(Array.isArray(i)?Array.prototype.push.apply(a.classes,i):a.classes.push(i)),r.hooks.run("wrap",a);var l="";for(var s in a.attributes)l+=" "+s+'="'+(a.attributes[s]||"").replace(/"/g,""")+'"';return"<"+a.tag+' class="'+a.classes.join(" ")+'"'+l+">"+a.content+"</"+a.tag+">"},r}(),o=r;r.default=r,o.languages.markup={comment:{pattern:/<!--(?:(?!<!--)[\s\S])*?-->/,greedy:!0},prolog:{pattern:/<\?[\s\S]+?\?>/,greedy:!0},doctype:{pattern:/<!DOCTYPE(?:[^>"'[\]]|"[^"]*"|'[^']*')+(?:\[(?:[^<"'\]]|"[^"]*"|'[^']*'|<(?!!--)|<!--(?:[^-]|-(?!->))*-->)*\]\s*)?>/i,greedy:!0,inside:{"internal-subset":{pattern:/(^[^\[]*\[)[\s\S]+(?=\]>$)/,lookbehind:!0,greedy:!0,inside:null},string:{pattern:/"[^"]*"|'[^']*'/,greedy:!0},punctuation:/^<!|>$|[[\]]/,"doctype-tag":/^DOCTYPE/i,name:/[^\s<>'"]+/}},cdata:{pattern:/<!\[CDATA\[[\s\S]*?\]\]>/i,greedy:!0},tag:{pattern:/<\/?(?!\d)[^\s>\/=$<%]+(?:\s(?:\s*[^\s>\/=]+(?:\s*=\s*(?:"[^"]*"|'[^']*'|[^\s'">=]+(?=[\s>]))|(?=[\s/>])))+)?\s*\/?>/,greedy:!0,inside:{tag:{pattern:/^<\/?[^\s>\/]+/,inside:{punctuation:/^<\/?/,namespace:/^[^\s>\/:]+:/}},"special-attr":[],"attr-value":{pattern:/=\s*(?:"[^"]*"|'[^']*'|[^\s'">=]+)/,inside:{punctuation:[{pattern:/^=/,alias:"attr-equals"},/"|'/]}},punctuation:/\/?>/,"attr-name":{pattern:/[^\s>\/]+/,inside:{namespace:/^[^\s>\/:]+:/}}}},entity:[{pattern:/&[\da-z]{1,8};/i,alias:"named-entity"},/&#x?[\da-f]{1,8};/i]},o.languages.markup.tag.inside["attr-value"].inside.entity=o.languages.markup.entity,o.languages.markup.doctype.inside["internal-subset"].inside=o.languages.markup,o.hooks.add("wrap",(function(e){"entity"===e.type&&(e.attributes.title=e.content.replace(/&/,"&"))})),Object.defineProperty(o.languages.markup.tag,"addInlined",{value:function(e,t){var n={};n["language-"+t]={pattern:/(^<!\[CDATA\[)[\s\S]+?(?=\]\]>$)/i,lookbehind:!0,inside:o.languages[t]},n.cdata=/^<!\[CDATA\[|\]\]>$/i;var r={"included-cdata":{pattern:/<!\[CDATA\[[\s\S]*?\]\]>/i,inside:n}};r["language-"+t]={pattern:/[\s\S]+/,inside:o.languages[t]};var a={};a[e]={pattern:RegExp(/(<__[^>]*>)(?:<!\[CDATA\[(?:[^\]]|\](?!\]>))*\]\]>|(?!<!\[CDATA\[)[\s\S])*?(?=<\/__>)/.source.replace(/__/g,(function(){return e})),"i"),lookbehind:!0,greedy:!0,inside:r},o.languages.insertBefore("markup","cdata",a)}}),Object.defineProperty(o.languages.markup.tag,"addAttribute",{value:function(e,t){o.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:o.languages[t]},punctuation:[{pattern:/^=/,alias:"attr-equals"},/"|'/]}}}})}}),o.languages.html=o.languages.markup,o.languages.mathml=o.languages.markup,o.languages.svg=o.languages.markup,o.languages.xml=o.languages.extend("markup",{}),o.languages.ssml=o.languages.xml,o.languages.atom=o.languages.xml,o.languages.rss=o.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 o=["comment","function-name","for-or-select","assign-left","string","environment","function","keyword","builtin","boolean","file-descriptor","operator","punctuation","number"],a=r.variable[1].inside,i=0;i<o.length;i++)a[o[i]]=e.languages.bash[o[i]];e.languages.shell=e.languages.bash}(o),o.languages.clike={comment:[{pattern:/(^|[^\\])\/\*[\s\S]*?(?:\*\/|$)/,lookbehind:!0,greedy:!0},{pattern:/(^|[^\\:])\/\/.*/,lookbehind:!0,greedy:!0}],string:{pattern:/(["'])(?:\\(?:\r\n|[\s\S])|(?!\1)[^\\\r\n])*\1/,greedy:!0},"class-name":{pattern:/(\b(?:class|extends|implements|instanceof|interface|new|trait)\s+|\bcatch\s+\()[\w.\\]+/i,lookbehind:!0,inside:{punctuation:/[.\\]/}},keyword:/\b(?:break|catch|continue|do|else|finally|for|function|if|in|instanceof|new|null|return|throw|try|while)\b/,boolean:/\b(?:false|true)\b/,function:/\b\w+(?=\()/,number:/\b0x[\da-f]+\b|(?:\b\d+(?:\.\d*)?|\B\.\d+)(?:e[+-]?\d+)?/i,operator:/[<>]=?|[!=]=?=?|--?|\+\+?|&&?|\|\|?|[?*/~^%]/,punctuation:/[{}[\];(),.:]/},o.languages.c=o.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|[?:~]|[-+*/%&|^!=<>]=?/}),o.languages.insertBefore("c","string",{char:{pattern:/'(?:\\(?:\r\n|[\s\S])|[^'\\\r\n]){0,32}'/,greedy:!0}}),o.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},o.languages.c.string],char:o.languages.c.char,comment:o.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:o.languages.c}}}}),o.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 o.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(?!<keyword>)\w+(?:\s*\.\s*\w+)*\b/.source.replace(/<keyword>/g,(function(){return t.source}));e.languages.cpp=e.languages.extend("c",{"class-name":[{pattern:RegExp(/(\b(?:class|concept|enum|struct|typename)\s+)(?!<keyword>)\w+/.source.replace(/<keyword>/g,(function(){return t.source}))),lookbehind:!0},/\b[A-Z]\w*(?=\s*::\s*\w+\s*\()/,/\b[A-Z_]\w*(?=\s*::\s*~\w+\s*\()/i,/\b\w+(?=\s*<(?:[^<>]|<(?:[^<>]|<[^<>]*>)*>)*>\s*::\s*\w+\s*\()/],keyword:t,number:{pattern:/(?:\b0b[01']+|\b0x(?:[\da-f']+(?:\.[\da-f']*)?|\.[\da-f']+)(?:p[+-]?[\d']+)?|(?:\b[\d']+(?:\.[\d']*)?|\B\.[\d']+)(?:e[+-]?[\d']+)?)[ful]{0,4}/i,greedy:!0},operator:/>>=?|<<=?|->|--|\+\+|&&|\|\||[?:~]|<=>|[-+*/%&|^!=<>]=?|\b(?:and|and_eq|bitand|bitor|not|not_eq|or|or_eq|xor|xor_eq)\b/,boolean:/\b(?:false|true)\b/}),e.languages.insertBefore("cpp","string",{module:{pattern:RegExp(/(\b(?:import|module)\s+)/.source+"(?:"+/"(?:\\(?:\r\n|[\s\S])|[^"\\\r\n])*"|<[^<>\r\n]*>/.source+"|"+/<mod-name>(?:\s*:\s*<mod-name>)?|:\s*<mod-name>/.source.replace(/<mod-name>/g,(function(){return n}))+")"),lookbehind:!0,greedy:!0,inside:{string:/^[<"][\s\S]+/,operator:/:/,punctuation:/\./}},"raw-string":{pattern:/R"([^()\\ ]{0,16})\([\s\S]*?\)\1"/,alias:"string",greedy:!0}}),e.languages.insertBefore("cpp","keyword",{"generic-function":{pattern:/\b(?!operator\b)[a-z_]\w*\s*<(?:[^<>]|<[^<>]*>)*>(?=\s*\()/i,inside:{function:/^\w+/,generic:{pattern:/<[\s\S]+/,alias:"class-name",inside:e.languages.cpp}}}}),e.languages.insertBefore("cpp","operator",{"double-colon":{pattern:/::/,alias:"punctuation"}}),e.languages.insertBefore("cpp","class-name",{"base-clause":{pattern:/(\b(?:class|struct)\s+\w+\s*:\s*)[^;{}"'\s]+(?:\s+[^;{}"'\s]+)*(?=\s*[;{])/,lookbehind:!0,greedy:!0,inside:e.languages.extend("cpp",{})}}),e.languages.insertBefore("inside","double-colon",{"class-name":/\b[a-z_]\w*\b(?!\s*::)/i},e.languages.cpp["base-clause"])}(o),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"))}(o),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},o={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:o,function:/[\w-]+(?=\()/,punctuation:/[(),]/}}],entity:/\\[\da-f]{1,8}/i,unit:r,number:o})}(o),o.languages.javascript=o.languages.extend("clike",{"class-name":[o.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}|\?\?=?|\?\.?|[~:]/}),o.languages.javascript["class-name"][0].pattern=/(\b(?:class|extends|implements|instanceof|interface|new)\s+)[\w.\\]+/,o.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:o.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:o.languages.javascript},{pattern:/(^|[^$\w\xA0-\uFFFF])(?!\s)[_$a-z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\s*=>)/i,lookbehind:!0,inside:o.languages.javascript},{pattern:/(\(\s*)(?!\s)(?:[^()\s]|\s+(?![\s)])|\([^()]*\))+(?=\s*\)\s*=>)/,lookbehind:!0,inside:o.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:o.languages.javascript}],constant:/\b[A-Z](?:[A-Z_]|\dx?)*\b/}),o.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:o.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"}}),o.languages.insertBefore("javascript","operator",{"literal-property":{pattern:/((?:^|[,{])[ \t]*)(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\s*:)/m,lookbehind:!0,alias:"property"}}),o.languages.markup&&(o.languages.markup.tag.addInlined("script","javascript"),o.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")),o.languages.js=o.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}(o),function(e){var t=/[*&][^\s[\]{},]+/,n=/!(?:<[\w\-%#;/?:@&=+$,.!~*'()[\]]+>|(?:[a-zA-Z\d-]*!)?[\w\-%#;/?:@&=+$.~*'()]+)?/,r="(?:"+n.source+"(?:[ \t]+"+t.source+")?|"+t.source+"(?:[ \t]+"+n.source+")?)",o=/(?:[^\s\x00-\x08\x0e-\x1f!"#%&'*,\-:>?@[\]`{|}\x7f-\x84\x86-\x9f\ud800-\udfff\ufffe\uffff]|[?:-]<PLAIN>)(?:[ \t]*(?:(?![#:])<PLAIN>|:<PLAIN>))*/.source.replace(/<PLAIN>/g,(function(){return/[^\s\x00-\x08\x0e-\x1f,[\]{}\x7f-\x84\x86-\x9f\ud800-\udfff\ufffe\uffff]/.source})),a=/"(?:[^"\\\r\n]|\\.)*"|'(?:[^'\\\r\n]|\\.)*'/.source;function i(e,t){t=(t||"").replace(/m/g,"")+"m";var n=/([:\-,[{]\s*(?:\s<<prop>>[ \t]+)?)(?:<<value>>)(?=[ \t]*(?:$|,|\]|\}|(?:[\r\n]\s*)?#))/.source.replace(/<<prop>>/g,(function(){return r})).replace(/<<value>>/g,(function(){return e}));return RegExp(n,t)}e.languages.yaml={scalar:{pattern:RegExp(/([\-:]\s*(?:\s<<prop>>[ \t]+)?[|>])[ \t]*(?:((?:\r?\n|\r)[ \t]+)\S[^\r\n]*(?:\2[^\r\n]+)*)/.source.replace(/<<prop>>/g,(function(){return r}))),lookbehind:!0,alias:"string"},comment:/#.*/,key:{pattern:RegExp(/((?:^|[:\-,[{\r\n?])[ \t]*(?:<<prop>>[ \t]+)?)<<key>>(?=\s*:\s)/.source.replace(/<<prop>>/g,(function(){return r})).replace(/<<key>>/g,(function(){return"(?:"+o+"|"+a+")"}))),lookbehind:!0,greedy:!0,alias:"atrule"},directive:{pattern:/(^[ \t]*)%.+/m,lookbehind:!0,alias:"important"},datetime:{pattern:i(/\d{4}-\d\d?-\d\d?(?:[tT]|[ \t]+)\d\d?:\d{2}:\d{2}(?:\.\d*)?(?:[ \t]*(?:Z|[-+]\d\d?(?::\d{2})?))?|\d{4}-\d{2}-\d{2}|\d\d?:\d{2}(?::\d{2}(?:\.\d*)?)?/.source),lookbehind:!0,alias:"number"},boolean:{pattern:i(/false|true/.source,"i"),lookbehind:!0,alias:"important"},null:{pattern:i(/null|~/.source,"i"),lookbehind:!0,alias:"important"},string:{pattern:i(a),lookbehind:!0,greedy:!0},number:{pattern:i(/[+-]?(?:0x[\da-f]+|0o[0-7]+|(?:\d+(?:\.\d*)?|\.\d+)(?:e[+-]?\d+)?|\.inf|\.nan)/.source,"i"),lookbehind:!0},tag:n,important:t,punctuation:/---|[:[\]{}\-,|>?]|\.\.\./},e.languages.yml=e.languages.yaml}(o),function(e){var t=/(?:\\.|[^\\\n\r]|(?:\n|\r\n?)(?![\r\n]))/.source;function n(e){return e=e.replace(/<inner>/g,(function(){return t})),RegExp(/((?:^|[^\\])(?:\\{2})*)/.source+"(?:"+e+")")}var r=/(?:\\.|``(?:[^`\r\n]|`(?!`))+``|`[^`\r\n]+`|[^\\|\r\n`])+/.source,o=/\|?__(?:\|__)+\|?(?:(?:\n|\r\n?)|(?![\s\S]))/.source.replace(/__/g,(function(){return r})),a=/\|?[ \t]*:?-{3,}:?[ \t]*(?:\|[ \t]*:?-{3,}:?[ \t]*)+\|?(?:\n|\r\n?)/.source;e.languages.markdown=e.languages.extend("markup",{}),e.languages.insertBefore("markdown","prolog",{"front-matter-block":{pattern:/(^(?:\s*[\r\n])?)---(?!.)[\s\S]*?[\r\n]---(?!.)/,lookbehind:!0,greedy:!0,inside:{punctuation:/^---|---$/,"front-matter":{pattern:/\S+(?:\s+\S+)*/,alias:["yaml","language-yaml"],inside:e.languages.yaml}}},blockquote:{pattern:/^>(?:[\t ]*>)*/m,alias:"punctuation"},table:{pattern:RegExp("^"+o+a+"(?:"+o+")*","m"),inside:{"table-data-rows":{pattern:RegExp("^("+o+a+")(?:"+o+")*$"),lookbehind:!0,inside:{"table-data":{pattern:RegExp(r),inside:e.languages.markdown},punctuation:/\|/}},"table-line":{pattern:RegExp("^("+o+")"+a+"$"),lookbehind:!0,inside:{punctuation:/\||:?-{3,}:?/}},"table-header-row":{pattern:RegExp("^"+o+"$"),inside:{"table-header":{pattern:RegExp(r),alias:"important",inside:e.languages.markdown},punctuation:/\|/}}}},code:[{pattern:/((?:^|\n)[ \t]*\n|(?:^|\r\n?)[ \t]*\r\n?)(?: {4}|\t).+(?:(?:\n|\r\n?)(?: {4}|\t).+)*/,lookbehind:!0,alias:"keyword"},{pattern:/^```[\s\S]*?^```$/m,greedy:!0,inside:{"code-block":{pattern:/^(```.*(?:\n|\r\n?))[\s\S]+?(?=(?:\n|\r\n?)^```$)/m,lookbehind:!0},"code-language":{pattern:/^(```).+/,lookbehind:!0},punctuation:/```/}}],title:[{pattern:/\S.*(?:\n|\r\n?)(?:==+|--+)(?=[ \t]*$)/m,alias:"important",inside:{punctuation:/==+$|--+$/}},{pattern:/(^\s*)#.+/m,lookbehind:!0,alias:"important",inside:{punctuation:/^#+|#+$/}}],hr:{pattern:/(^\s*)([*-])(?:[\t ]*\2){2,}(?=\s*$)/m,lookbehind:!0,alias:"punctuation"},list:{pattern:/(^\s*)(?:[*+-]|\d+\.)(?=[\t ].)/m,lookbehind:!0,alias:"punctuation"},"url-reference":{pattern:/!?\[[^\]]+\]:[\t ]+(?:\S+|<(?:\\.|[^>\\])+>)(?:[\t ]+(?:"(?:\\.|[^"\\])*"|'(?:\\.|[^'\\])*'|\((?:\\.|[^)\\])*\)))?/,inside:{variable:{pattern:/^(!?\[)[^\]]+/,lookbehind:!0},string:/(?:"(?:\\.|[^"\\])*"|'(?:\\.|[^'\\])*'|\((?:\\.|[^)\\])*\))$/,punctuation:/^[\[\]!:]|[<>]/},alias:"url"},bold:{pattern:n(/\b__(?:(?!_)<inner>|_(?:(?!_)<inner>)+_)+__\b|\*\*(?:(?!\*)<inner>|\*(?:(?!\*)<inner>)+\*)+\*\*/.source),lookbehind:!0,greedy:!0,inside:{content:{pattern:/(^..)[\s\S]+(?=..$)/,lookbehind:!0,inside:{}},punctuation:/\*\*|__/}},italic:{pattern:n(/\b_(?:(?!_)<inner>|__(?:(?!_)<inner>)+__)+_\b|\*(?:(?!\*)<inner>|\*\*(?:(?!\*)<inner>)+\*\*)+\*/.source),lookbehind:!0,greedy:!0,inside:{content:{pattern:/(^.)[\s\S]+(?=.$)/,lookbehind:!0,inside:{}},punctuation:/[*_]/}},strike:{pattern:n(/(~~?)(?:(?!~)<inner>)+\2/.source),lookbehind:!0,greedy:!0,inside:{content:{pattern:/(^~~?)[\s\S]+(?=\1$)/,lookbehind:!0,inside:{}},punctuation:/~~?/}},"code-snippet":{pattern:/(^|[^\\`])(?:``[^`\r\n]+(?:`[^`\r\n]+)*``(?!`)|`[^`\r\n]+`(?!`))/,lookbehind:!0,greedy:!0,alias:["code","keyword"]},url:{pattern:n(/!?\[(?:(?!\])<inner>)+\](?:\([^\s)]+(?:[\t ]+"(?:\\.|[^"\\])*")?\)|[ \t]?\[(?:(?!\])<inner>)+\])/.source),lookbehind:!0,greedy:!0,inside:{operator:/^!/,content:{pattern:/(^\[)[^\]]+(?=\])/,lookbehind:!0,inside:{}},variable:{pattern:/(^\][ \t]?\[)[^\]]+(?=\]$)/,lookbehind:!0},url:{pattern:/(^\]\()[^\s)]+/,lookbehind:!0},string:{pattern:/(^[ \t]+)"(?:\\.|[^"\\])*"(?=\)$)/,lookbehind:!0}}}}),["url","bold","italic","strike"].forEach((function(t){["url","bold","italic","strike","code-snippet"].forEach((function(n){t!==n&&(e.languages.markdown[t].inside.content.inside[n]=e.languages.markdown[n])}))})),e.hooks.add("after-tokenize",(function(e){"markdown"!==e.language&&"md"!==e.language||function e(t){if(t&&"string"!=typeof t)for(var n=0,r=t.length;n<r;n++){var o=t[n];if("code"===o.type){var a=o.content[1],i=o.content[3];if(a&&i&&"code-language"===a.type&&"code-block"===i.type&&"string"==typeof a.content){var l=a.content.replace(/\b#/g,"sharp").replace(/\b\+\+/g,"pp"),s="language-"+(l=(/[a-z][\w-]*/i.exec(l)||[""])[0].toLowerCase());i.alias?"string"==typeof i.alias?i.alias=[i.alias,s]:i.alias.push(s):i.alias=[s]}}else e(o.content)}}(e.tokens)})),e.hooks.add("wrap",(function(t){if("code-block"===t.type){for(var n="",r=0,o=t.classes.length;r<o;r++){var a=t.classes[r],u=/language-(.+)/.exec(a);if(u){n=u[1];break}}var c,d=e.languages[n];if(d)t.content=e.highlight((c=t.content,c.replace(i,"").replace(/&(\w{1,8}|#x?[\da-f]{1,8});/gi,(function(e,t){var n;if("#"===(t=t.toLowerCase())[0])return n="x"===t[1]?parseInt(t.slice(2),16):Number(t.slice(1)),s(n);var r=l[t];return r||e}))),d,n);else if(n&&"none"!==n&&e.plugins.autoloader){var f="md-"+(new Date).valueOf()+"-"+Math.floor(1e16*Math.random());t.attributes.id=f,e.plugins.autoloader.loadLanguages(n,(function(){var t=document.getElementById(f);t&&(t.innerHTML=e.highlight(t.textContent,e.languages[n],n))}))}}}));var i=RegExp(e.languages.markup.tag.pattern.source,"gi"),l={amp:"&",lt:"<",gt:">",quot:'"'},s=String.fromCodePoint||String.fromCharCode;e.languages.md=e.languages.markdown}(o),o.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:o.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+/},o.hooks.add("after-tokenize",(function(e){if("graphql"===e.language)for(var t=e.tokens.filter((function(e){return"string"!=typeof e&&"comment"!==e.type&&"scalar"!==e.type})),n=0;n<t.length;){var r=t[n++];if("keyword"===r.type&&"mutation"===r.content){var o=[];if(d(["definition-mutation","punctuation"])&&"("===c(1).content){n+=2;var a=f(/^\($/,/^\)$/);if(-1===a)continue;for(;n<a;n++){var i=c(0);"variable"===i.type&&(p(i,"variable-input"),o.push(i.content))}n=a+1}if(d(["punctuation","property-query"])&&"{"===c(0).content&&(n++,p(c(0),"property-mutation"),o.length>0)){var l=f(/^\{$/,/^\}$/);if(-1===l)continue;for(var s=n;s<l;s++){var u=t[s];"variable"===u.type&&o.indexOf(u.content)>=0&&p(u,"variable-input")}}}}function c(e){return t[n+e]}function d(e,t){t=t||0;for(var n=0;n<e.length;n++){var r=c(n+t);if(!r||r.type!==e[n])return!1}return!0}function f(e,r){for(var o=1,a=n;a<t.length;a++){var i=t[a],l=i.content;if("punctuation"===i.type&&"string"==typeof l)if(e.test(l))o++;else if(r.test(l)&&0===--o)return a}return-1}function p(e,t){var n=e.alias;n?Array.isArray(n)||(e.alias=n=[n]):e.alias=n=[],n.push(t)}})),o.languages.sql={comment:{pattern:/(^|[^\\])(?:\/\*[\s\S]*?\*\/|(?:--|\/\/|#).*)/,lookbehind:!0},variable:[{pattern:/@(["'`])(?:\\[\s\S]|(?!\1)[^\\])+\1/,greedy:!0},/@[\w.$]+/],string:{pattern:/(^|[^@\\])("|')(?:\\[\s\S]|(?!\2)[^\\]|\2\2)*\2/,greedy:!0,lookbehind:!0},identifier:{pattern:/(^|[^@\\])`(?:\\[\s\S]|[^`\\]|``)*`/,greedy:!0,lookbehind:!0,inside:{punctuation:/^`|`$/}},function:/\b(?:AVG|COUNT|FIRST|FORMAT|LAST|LCASE|LEN|MAX|MID|MIN|MOD|NOW|ROUND|SUM|UCASE)(?=\s*\()/i,keyword:/\b(?:ACTION|ADD|AFTER|ALGORITHM|ALL|ALTER|ANALYZE|ANY|APPLY|AS|ASC|AUTHORIZATION|AUTO_INCREMENT|BACKUP|BDB|BEGIN|BERKELEYDB|BIGINT|BINARY|BIT|BLOB|BOOL|BOOLEAN|BREAK|BROWSE|BTREE|BULK|BY|CALL|CASCADED?|CASE|CHAIN|CHAR(?:ACTER|SET)?|CHECK(?:POINT)?|CLOSE|CLUSTERED|COALESCE|COLLATE|COLUMNS?|COMMENT|COMMIT(?:TED)?|COMPUTE|CONNECT|CONSISTENT|CONSTRAINT|CONTAINS(?:TABLE)?|CONTINUE|CONVERT|CREATE|CROSS|CURRENT(?:_DATE|_TIME|_TIMESTAMP|_USER)?|CURSOR|CYCLE|DATA(?:BASES?)?|DATE(?:TIME)?|DAY|DBCC|DEALLOCATE|DEC|DECIMAL|DECLARE|DEFAULT|DEFINER|DELAYED|DELETE|DELIMITERS?|DENY|DESC|DESCRIBE|DETERMINISTIC|DISABLE|DISCARD|DISK|DISTINCT|DISTINCTROW|DISTRIBUTED|DO|DOUBLE|DROP|DUMMY|DUMP(?:FILE)?|DUPLICATE|ELSE(?:IF)?|ENABLE|ENCLOSED|END|ENGINE|ENUM|ERRLVL|ERRORS|ESCAPED?|EXCEPT|EXEC(?:UTE)?|EXISTS|EXIT|EXPLAIN|EXTENDED|FETCH|FIELDS|FILE|FILLFACTOR|FIRST|FIXED|FLOAT|FOLLOWING|FOR(?: EACH ROW)?|FORCE|FOREIGN|FREETEXT(?:TABLE)?|FROM|FULL|FUNCTION|GEOMETRY(?:COLLECTION)?|GLOBAL|GOTO|GRANT|GROUP|HANDLER|HASH|HAVING|HOLDLOCK|HOUR|IDENTITY(?:COL|_INSERT)?|IF|IGNORE|IMPORT|INDEX|INFILE|INNER|INNODB|INOUT|INSERT|INT|INTEGER|INTERSECT|INTERVAL|INTO|INVOKER|ISOLATION|ITERATE|JOIN|KEYS?|KILL|LANGUAGE|LAST|LEAVE|LEFT|LEVEL|LIMIT|LINENO|LINES|LINESTRING|LOAD|LOCAL|LOCK|LONG(?:BLOB|TEXT)|LOOP|MATCH(?:ED)?|MEDIUM(?:BLOB|INT|TEXT)|MERGE|MIDDLEINT|MINUTE|MODE|MODIFIES|MODIFY|MONTH|MULTI(?:LINESTRING|POINT|POLYGON)|NATIONAL|NATURAL|NCHAR|NEXT|NO|NONCLUSTERED|NULLIF|NUMERIC|OFF?|OFFSETS?|ON|OPEN(?:DATASOURCE|QUERY|ROWSET)?|OPTIMIZE|OPTION(?:ALLY)?|ORDER|OUT(?:ER|FILE)?|OVER|PARTIAL|PARTITION|PERCENT|PIVOT|PLAN|POINT|POLYGON|PRECEDING|PRECISION|PREPARE|PREV|PRIMARY|PRINT|PRIVILEGES|PROC(?:EDURE)?|PUBLIC|PURGE|QUICK|RAISERROR|READS?|REAL|RECONFIGURE|REFERENCES|RELEASE|RENAME|REPEAT(?:ABLE)?|REPLACE|REPLICATION|REQUIRE|RESIGNAL|RESTORE|RESTRICT|RETURN(?:ING|S)?|REVOKE|RIGHT|ROLLBACK|ROUTINE|ROW(?:COUNT|GUIDCOL|S)?|RTREE|RULE|SAVE(?:POINT)?|SCHEMA|SECOND|SELECT|SERIAL(?:IZABLE)?|SESSION(?:_USER)?|SET(?:USER)?|SHARE|SHOW|SHUTDOWN|SIMPLE|SMALLINT|SNAPSHOT|SOME|SONAME|SQL|START(?:ING)?|STATISTICS|STATUS|STRIPED|SYSTEM_USER|TABLES?|TABLESPACE|TEMP(?:ORARY|TABLE)?|TERMINATED|TEXT(?:SIZE)?|THEN|TIME(?:STAMP)?|TINY(?:BLOB|INT|TEXT)|TOP?|TRAN(?:SACTIONS?)?|TRIGGER|TRUNCATE|TSEQUAL|TYPES?|UNBOUNDED|UNCOMMITTED|UNDEFINED|UNION|UNIQUE|UNLOCK|UNPIVOT|UNSIGNED|UPDATE(?:TEXT)?|USAGE|USE|USER|USING|VALUES?|VAR(?:BINARY|CHAR|CHARACTER|YING)|VIEW|WAITFOR|WARNINGS|WHEN|WHERE|WHILE|WITH(?: ROLLUP|IN)?|WORK|WRITE(?:TEXT)?|YEAR)\b/i,boolean:/\b(?:FALSE|NULL|TRUE)\b/i,number:/\b0x[\da-f]+\b|\b\d+(?:\.\d*)?|\B\.\d+\b/i,operator:/[-+*\/=%^~]|&&?|\|\|?|!=?|<(?:=>?|<|>)?|>[>=]?|\b(?:AND|BETWEEN|DIV|ILIKE|IN|IS|LIKE|NOT|OR|REGEXP|RLIKE|SOUNDS LIKE|XOR)\b/i,punctuation:/[;[\]()`,.]/},function(e){var t=e.languages.javascript["template-string"],n=t.pattern.source,r=t.inside.interpolation,o=r.inside["interpolation-punctuation"],a=r.pattern.source;function i(t,r){if(e.languages[t])return{pattern:RegExp("((?:"+r+")\\s*)"+n),lookbehind:!0,greedy:!0,inside:{"template-punctuation":{pattern:/^`|`$/,alias:"string"},"embedded-code":{pattern:/[\s\S]+/,alias:t}}}}function l(e,t){return"___"+t.toUpperCase()+"_"+e+"___"}function s(t,n,r){var o={code:t,grammar:n,language:r};return e.hooks.run("before-tokenize",o),o.tokens=e.tokenize(o.code,o.grammar),e.hooks.run("after-tokenize",o),o.tokens}function u(t){var n={};n["interpolation-punctuation"]=o;var a=e.tokenize(t,n);if(3===a.length){var i=[1,1];i.push.apply(i,s(a[1],e.languages.javascript,"javascript")),a.splice.apply(a,i)}return new e.Token("interpolation",a,r.alias,t)}function c(t,n,r){var o=e.tokenize(t,{interpolation:{pattern:RegExp(a),lookbehind:!0}}),i=0,c={},d=s(o.map((function(e){if("string"==typeof e)return e;for(var n,o=e.content;-1!==t.indexOf(n=l(i++,r)););return c[n]=o,n})).join(""),n,r),f=Object.keys(c);return i=0,function e(t){for(var n=0;n<t.length;n++){if(i>=f.length)return;var r=t[n];if("string"==typeof r||"string"==typeof r.content){var o=f[i],a="string"==typeof r?r:r.content,l=a.indexOf(o);if(-1!==l){++i;var s=a.substring(0,l),d=u(c[o]),p=a.substring(l+o.length),h=[];if(s&&h.push(s),h.push(d),p){var m=[p];e(m),h.push.apply(h,m)}"string"==typeof r?(t.splice.apply(t,[n,1].concat(h)),n+=h.length-1):r.content=h}}else{var g=r.content;Array.isArray(g)?e(g):e([g])}}}(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,o=n.length;r<o;r++){var a=n[r];if("string"!=typeof a){var i=a.content;if(Array.isArray(i))if("template-string"===a.type){var l=i[1];if(3===i.length&&"string"!=typeof l&&"embedded-code"===l.type){var s=f(l),u=l.alias,d=Array.isArray(u)?u[0]:u,p=e.languages[d];if(!p)continue;i[1]=c(s,p,d)}}else t(i);else"string"!=typeof i&&t([i])}}}(t.tokens)}))}(o),function(e){e.languages.typescript=e.languages.extend("javascript",{"class-name":{pattern:/(\b(?:class|extends|implements|instanceof|interface|new|type)\s+)(?!keyof\b)(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?:\s*<(?:[^<>]|<(?:[^<>]|<[^<>]*>)*>)*>)?/,lookbehind:!0,greedy:!0,inside:null},builtin:/\b(?:Array|Function|Promise|any|boolean|console|never|number|string|symbol|unknown)\b/}),e.languages.typescript.keyword.push(/\b(?:abstract|declare|is|keyof|readonly|require)\b/,/\b(?:asserts|infer|interface|module|namespace|type)\b(?=\s*(?:[{_$a-zA-Z\xA0-\uFFFF]|$))/,/\btype\b(?=\s*(?:[\{*]|$))/),delete e.languages.typescript.parameter,delete e.languages.typescript["literal-property"];var t=e.languages.extend("typescript",{});delete t["class-name"],e.languages.typescript["class-name"].inside=t,e.languages.insertBefore("typescript","function",{decorator:{pattern:/@[$\w\xA0-\uFFFF]+/,inside:{at:{pattern:/^@/,alias:"operator"},function:/^[\s\S]+/}},"generic-function":{pattern:/#?(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*\s*<(?:[^<>]|<(?:[^<>]|<[^<>]*>)*>)*>(?=\s*\()/,greedy:!0,inside:{function:/^#?(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*/,generic:{pattern:/<[\s\S]+/,alias:"class-name",inside:t}}}}),e.languages.ts=e.languages.typescript}(o),function(e){function t(e,t){return RegExp(e.replace(/<ID>/g,(function(){return/(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*/.source})),t)}e.languages.insertBefore("javascript","function-variable",{"method-variable":{pattern:RegExp("(\\.\\s*)"+e.languages.javascript["function-variable"].pattern.source),lookbehind:!0,alias:["function-variable","method","function","property-access"]}}),e.languages.insertBefore("javascript","function",{method:{pattern:RegExp("(\\.\\s*)"+e.languages.javascript.function.source),lookbehind:!0,alias:["function","property-access"]}}),e.languages.insertBefore("javascript","constant",{"known-class-name":[{pattern:/\b(?:(?:Float(?:32|64)|(?:Int|Uint)(?:8|16|32)|Uint8Clamped)?Array|ArrayBuffer|BigInt|Boolean|DataView|Date|Error|Function|Intl|JSON|(?:Weak)?(?:Map|Set)|Math|Number|Object|Promise|Proxy|Reflect|RegExp|String|Symbol|WebAssembly)\b/,alias:"class-name"},{pattern:/\b(?:[A-Z]\w*)Error\b/,alias:"class-name"}]}),e.languages.insertBefore("javascript","keyword",{imports:{pattern:t(/(\bimport\b\s*)(?:<ID>(?:\s*,\s*(?:\*\s*as\s+<ID>|\{[^{}]*\}))?|\*\s*as\s+<ID>|\{[^{}]*\})(?=\s*\bfrom\b)/.source),lookbehind:!0,inside:e.languages.javascript},exports:{pattern:t(/(\bexport\b\s*)(?:\*(?:\s*as\s+<ID>)?(?=\s*\bfrom\b)|\{[^{}]*\})/.source),lookbehind:!0,inside:e.languages.javascript}}),e.languages.javascript.keyword.unshift({pattern:/\b(?:as|default|export|from|import)\b/,alias:"module"},{pattern:/\b(?:await|break|catch|continue|do|else|finally|for|if|return|switch|throw|try|while|yield)\b/,alias:"control-flow"},{pattern:/\bnull\b/,alias:["null","nil"]},{pattern:/\bundefined\b/,alias:"nil"}),e.languages.insertBefore("javascript","operator",{spread:{pattern:/\.{3}/,alias:"operator"},arrow:{pattern:/=>/,alias:"operator"}}),e.languages.insertBefore("javascript","punctuation",{"property-access":{pattern:t(/(\.\s*)#?<ID>/.source),lookbehind:!0},"maybe-class-name":{pattern:/(^|[^$\w\xA0-\uFFFF])[A-Z][$\w\xA0-\uFFFF]+/,lookbehind:!0},dom:{pattern:/\b(?:document|(?:local|session)Storage|location|navigator|performance|window)\b/,alias:"variable"},console:{pattern:/\bconsole(?=\s*\.)/,alias:"class-name"}});for(var n=["function","function-variable","method","method-variable","property-access"],r=0;r<n.length;r++){var o=n[r],a=e.languages.javascript[o];"RegExp"===e.util.type(a)&&(a=e.languages.javascript[o]={pattern:a});var i=a.inside||{};a.inside=i,i["maybe-class-name"]=/^[A-Z][\s\S]*/}}(o),function(e){var t=e.util.clone(e.languages.javascript),n=/(?:\s|\/\/.*(?!.)|\/\*(?:[^*]|\*(?!\/))\*\/)/.source,r=/(?:\{(?:\{(?:\{[^{}]*\}|[^{}])*\}|[^{}])*\})/.source,o=/(?:\{<S>*\.{3}(?:[^{}]|<BRACES>)*\})/.source;function a(e,t){return e=e.replace(/<S>/g,(function(){return n})).replace(/<BRACES>/g,(function(){return r})).replace(/<SPREAD>/g,(function(){return o})),RegExp(e,t)}o=a(o).source,e.languages.jsx=e.languages.extend("markup",t),e.languages.jsx.tag.pattern=a(/<\/?(?:[\w.:-]+(?:<S>+(?:[\w.:$-]+(?:=(?:"(?:\\[\s\S]|[^\\"])*"|'(?:\\[\s\S]|[^\\'])*'|[^\s{'"/>=]+|<BRACES>))?|<SPREAD>))*<S>*\/?)?>/.source),e.languages.jsx.tag.inside.tag.pattern=/^<\/?[^\s>\/]*/,e.languages.jsx.tag.inside["attr-value"].pattern=/=(?!\{)(?:"(?:\\[\s\S]|[^\\"])*"|'(?:\\[\s\S]|[^\\'])*'|[^\s'">]+)/,e.languages.jsx.tag.inside.tag.inside["class-name"]=/^[A-Z]\w*(?:\.[A-Z]\w*)*$/,e.languages.jsx.tag.inside.comment=t.comment,e.languages.insertBefore("inside","attr-name",{spread:{pattern:a(/<SPREAD>/.source),inside:e.languages.jsx}},e.languages.jsx.tag),e.languages.insertBefore("inside","special-attr",{script:{pattern:a(/=<BRACES>/.source),alias:"language-javascript",inside:{"script-punctuation":{pattern:/^=(?=\{)/,alias:"punctuation"},rest:e.languages.jsx}}},e.languages.jsx.tag);var i=function(e){return e?"string"==typeof e?e:"string"==typeof e.content?e.content:e.content.map(i).join(""):""},l=function(t){for(var n=[],r=0;r<t.length;r++){var o=t[r],a=!1;if("string"!=typeof o&&("tag"===o.type&&o.content[0]&&"tag"===o.content[0].type?"</"===o.content[0].content[0].content?n.length>0&&n[n.length-1].tagName===i(o.content[0].content[1])&&n.pop():"/>"===o.content[o.content.length-1].content||n.push({tagName:i(o.content[0].content[1]),openedBraces:0}):n.length>0&&"punctuation"===o.type&&"{"===o.content?n[n.length-1].openedBraces++:n.length>0&&n[n.length-1].openedBraces>0&&"punctuation"===o.type&&"}"===o.content?n[n.length-1].openedBraces--:a=!0),(a||"string"==typeof o)&&n.length>0&&0===n[n.length-1].openedBraces){var s=i(o);r<t.length-1&&("string"==typeof t[r+1]||"plain-text"===t[r+1].type)&&(s+=i(t[r+1]),t.splice(r+1,1)),r>0&&("string"==typeof t[r-1]||"plain-text"===t[r-1].type)&&(s=i(t[r-1])+s,t.splice(r-1,1),r--),t[r]=new e.Token("plain-text",s,null,s)}o.content&&"string"!=typeof o.content&&l(o.content)}};e.hooks.add("after-tokenize",(function(e){"jsx"!==e.language&&"tsx"!==e.language||l(e.tokens)}))}(o),function(e){e.languages.diff={coord:[/^(?:\*{3}|-{3}|\+{3}).*$/m,/^@@.*@@$/m,/^\d.*$/m]};var t={"deleted-sign":"-","deleted-arrow":"<","inserted-sign":"+","inserted-arrow":">",unchanged:" ",diff:"!"};Object.keys(t).forEach((function(n){var r=t[n],o=[];/^\w+$/.test(n)||o.push(/\w+/.exec(n)[0]),"diff"===n&&o.push("bold"),e.languages.diff[n]={pattern:RegExp("^(?:["+r+"].*(?:\r\n?|\n|(?![\\s\\S])))+","m"),alias:o,inside:{line:{pattern:/(.)(?=[\s\S]).*(?:\r\n?|\n)?/,lookbehind:!0},prefix:{pattern:/[\s\S]/,alias:/\w+/.exec(n)[0]}}}})),Object.defineProperty(e.languages.diff,"PREFIXES",{value:t})}(o),o.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},o.languages.go=o.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/}),o.languages.insertBefore("go","string",{char:{pattern:/'(?:\\.|[^'\\\r\n]){0,10}'/,greedy:!0}}),delete o.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,o,a){if(n.language===r){var i=n.tokenStack=[];n.code=n.code.replace(o,(function(e){if("function"==typeof a&&!a(e))return e;for(var o,l=i.length;-1!==n.code.indexOf(o=t(r,l));)++l;return i[l]=e,o})),n.grammar=e.languages.markup}}},tokenizePlaceholders:{value:function(n,r){if(n.language===r&&n.tokenStack){n.grammar=e.languages[r];var o=0,a=Object.keys(n.tokenStack);!function i(l){for(var s=0;s<l.length&&!(o>=a.length);s++){var u=l[s];if("string"==typeof u||u.content&&"string"==typeof u.content){var c=a[o],d=n.tokenStack[c],f="string"==typeof u?u:u.content,p=t(r,c),h=f.indexOf(p);if(h>-1){++o;var m=f.substring(0,h),g=new e.Token(r,e.tokenize(d,n.grammar),"language-"+r,d),v=f.substring(h+p.length),b=[];m&&b.push.apply(b,i([m])),b.push(g),v&&b.push.apply(b,i([v])),"string"==typeof u?l.splice.apply(l,[s,1].concat(b)):u.content=b}}else u.content&&i(u.content)}return l}(n.tokens)}}}})}(o),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}(o),o.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"}},o.languages.webmanifest=o.languages.json,o.languages.less=o.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:/[+\-*\/]/}),o.languages.insertBefore("less","property",{variable:[{pattern:/@[\w-]+\s*:/,inside:{punctuation:/:/}},/@@?[\w-]+/],"mixin-usage":{pattern:/([{;]\s*)[.#](?!\d)[\w-].*?(?=[(;])/,lookbehind:!0,alias:"function"}}),o.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:/[:;(){}]/},o.languages.objectivec=o.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 o.languages.objectivec["class-name"],o.languages.objc=o.languages.objectivec,o.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/},o.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:/[{}[\];(),.:]/},o.languages.python["string-interpolation"].inside.interpolation.inside.rest=o.languages.python,o.languages.py=o.languages.python,o.languages.reason=o.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/}),o.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 o.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}})}(o),o.languages.scss=o.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]+\}/}}}),o.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}]}),o.languages.insertBefore("scss","important",{variable:/\$[-\w]+|#\{\$[-\w]+\}/}),o.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}}),o.languages.scss.atrule.inside.rest=o.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:/[{}()\[\];:.]/}}(o),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}(o),o.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 a=o},29901: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 <a href="https://webplatform.github.io/docs/">WebPlatform.org documentation</a>. The links open in a new tab.'},"custom-class":{title:"Custom Class",description:"This plugin allows you to prefix Prism's default classes (<code>.comment</code> can become <code>.namespace--comment</code>) or replace them with your defined ones (like <code>.editor__comment</code>). 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 <code>highlightAll</code> and <code>highlightAllUnder</code> 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(29901),o=n(39642),a=new Set;function i(e){void 0===e?e=Object.keys(r.languages).filter((e=>"meta"!=e)):Array.isArray(e)||(e=[e]);const t=[...a,...Object.keys(Prism.languages)];o(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(16500).resolve(t)],delete Prism.languages[e],n(16500)(t),a.add(e)}))}i.silent=!1,e.exports=i},6726:(e,t,n)=>{var r={"./":2885};function o(e){var t=a(e);return n(t)}function a(e){if(!n.o(r,e)){var t=new Error("Cannot find module '"+e+"'");throw t.code="MODULE_NOT_FOUND",t}return r[e]}o.keys=function(){return Object.keys(r)},o.resolve=a,e.exports=o,o.id=6726},16500:(e,t,n)=>{var r={"./":2885};function o(e){var t=a(e);return n(t)}function a(e){if(!n.o(r,e)){var t=new Error("Cannot find module '"+e+"'");throw t.code="MODULE_NOT_FOUND",t}return r[e]}o.keys=function(){return Object.keys(r)},o.resolve=a,e.exports=o,o.id=16500},39642: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<r;n++)t[e[n]]=!0;return t}function r(e){var n={},r=[];function o(r,a){if(!(r in n)){a.push(r);var i=a.indexOf(r);if(i<a.length-1)throw new Error("Circular dependency: "+a.slice(i).join(" -> "));var l={},s=e[r];if(s){function u(t){if(!(t in e))throw new Error(r+" depends on an unknown component "+t);if(!(t in l))for(var i in o(t,a),l[t]=!0,n[t])l[i]=!0}t(s.require,u),t(s.optional,u),t(s.modify,u)}n[r]=l,a.pop()}}return function(e){var t=n[e];return t||(o(e,r),t=n[e]),t}}function o(e){for(var t in e)return!0;return!1}return function(a,i,l){var s=function(e){var t={};for(var n in e){var r=e[n];for(var o in r)if("meta"!=o){var a=r[o];t[o]="string"==typeof a?{title:a}:a}}return t}(a),u=function(e){var n;return function(r){if(r in e)return r;if(!n)for(var o in n={},e){var a=e[o];t(a&&a.alias,(function(t){if(t in n)throw new Error(t+" cannot be alias for both "+o+" and "+n[t]);if(t in e)throw new Error(t+" cannot be alias of "+o+" because it is a component.");n[t]=o}))}return n[r]||r}}(s);i=i.map(u),l=(l||[]).map(u);var c=n(i),d=n(l);i.forEach((function e(n){var r=s[n];t(r&&r.require,(function(t){t in d||(c[t]=!0,e(t))}))}));for(var f,p=r(s),h=c;o(h);){for(var m in f={},h){var g=s[m];t(g&&g.modify,(function(e){e in d&&(f[e]=!0)}))}for(var v in d)if(!(v in c))for(var b in p(v))if(b in c){f[v]=!0;break}for(var y in h=f)c[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,o){var a=o?o.series:void 0,i=o?o.parallel:e,l={},s={};function u(e){if(e in l)return l[e];s[e]=!0;var o,c=[];for(var d in t(e))d in n&&c.push(d);if(0===c.length)o=r(e);else{var f=i(c.map((function(e){var t=u(e);return delete s[e],t})));a?o=a(f,(function(){return r(e)})):r(e)}return l[e]=o}for(var c in n)u(c);var d=[];for(var f in s)d.push(l[f]);return i(d)}(p,c,t,n)}};return w}}();e.exports=t},92703:(e,t,n)=>{"use strict";var r=n(50414);function o(){}function a(){}a.resetWarningCache=o,e.exports=function(){function e(e,t,n,o,a,i){if(i!==r){var l=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 l.name="Invariant Violation",l}}function t(){return e}e.isRequired=e;var n={array:e,bigint:e,bool:e,func:e,number:e,object:e,string:e,symbol:e,any:e,arrayOf:t,element:e,elementType:e,instanceOf:t,node:e,objectOf:t,oneOf:t,oneOfType:t,shape:t,exact:t,checkPropTypes:a,resetWarningCache:o};return n.PropTypes=n,n}},45697:(e,t,n)=>{e.exports=n(92703)()},50414:e=>{"use strict";e.exports="SECRET_DO_NOT_PASS_THIS_OR_YOU_WILL_BE_FIRED"},64448:(e,t,n)=>{"use strict";var r=n(67294),o=n(27418),a=n(63840);function i(e){for(var t="https://reactjs.org/docs/error-decoder.html?invariant="+e,n=1;n<arguments.length;n++)t+="&args[]="+encodeURIComponent(arguments[n]);return"Minified React error #"+e+"; visit "+t+" for the full message or use the non-minified dev environment for full errors and additional helpful warnings."}if(!r)throw Error(i(227));var l=new Set,s={};function u(e,t){c(e,t),c(e+"Capture",t)}function c(e,t){for(s[e]=t,e=0;e<t.length;e++)l.add(t[e])}var d=!("undefined"==typeof window||void 0===window.document||void 0===window.document.createElement),f=/^[:A-Z_a-z\u00C0-\u00D6\u00D8-\u00F6\u00F8-\u02FF\u0370-\u037D\u037F-\u1FFF\u200C-\u200D\u2070-\u218F\u2C00-\u2FEF\u3001-\uD7FF\uF900-\uFDCF\uFDF0-\uFFFD][:A-Z_a-z\u00C0-\u00D6\u00D8-\u00F6\u00F8-\u02FF\u0370-\u037D\u037F-\u1FFF\u200C-\u200D\u2070-\u218F\u2C00-\u2FEF\u3001-\uD7FF\uF900-\uFDCF\uFDF0-\uFFFD\-.0-9\u00B7\u0300-\u036F\u203F-\u2040]*$/,p=Object.prototype.hasOwnProperty,h={},m={};function g(e,t,n,r,o,a,i){this.acceptsBooleans=2===t||3===t||4===t,this.attributeName=r,this.attributeNamespace=o,this.mustUseProperty=n,this.propertyName=e,this.type=t,this.sanitizeURL=a,this.removeEmptyString=i}var v={};"children dangerouslySetInnerHTML defaultValue defaultChecked innerHTML suppressContentEditableWarning suppressHydrationWarning style".split(" ").forEach((function(e){v[e]=new g(e,0,!1,e,null,!1,!1)})),[["acceptCharset","accept-charset"],["className","class"],["htmlFor","for"],["httpEquiv","http-equiv"]].forEach((function(e){var t=e[0];v[t]=new g(t,1,!1,e[1],null,!1,!1)})),["contentEditable","draggable","spellCheck","value"].forEach((function(e){v[e]=new g(e,2,!1,e.toLowerCase(),null,!1,!1)})),["autoReverse","externalResourcesRequired","focusable","preserveAlpha"].forEach((function(e){v[e]=new g(e,2,!1,e,null,!1,!1)})),"allowFullScreen async autoFocus autoPlay controls default defer disabled disablePictureInPicture disableRemotePlayback formNoValidate hidden loop noModule noValidate open playsInline readOnly required reversed scoped seamless itemScope".split(" ").forEach((function(e){v[e]=new g(e,3,!1,e.toLowerCase(),null,!1,!1)})),["checked","multiple","muted","selected"].forEach((function(e){v[e]=new g(e,3,!0,e,null,!1,!1)})),["capture","download"].forEach((function(e){v[e]=new g(e,4,!1,e,null,!1,!1)})),["cols","rows","size","span"].forEach((function(e){v[e]=new g(e,6,!1,e,null,!1,!1)})),["rowSpan","start"].forEach((function(e){v[e]=new g(e,5,!1,e.toLowerCase(),null,!1,!1)}));var b=/[\-:]([a-z])/g;function y(e){return e[1].toUpperCase()}function w(e,t,n,r){var o=v.hasOwnProperty(t)?v[t]:null;(null!==o?0===o.type:!r&&(2<t.length&&("o"===t[0]||"O"===t[0])&&("n"===t[1]||"N"===t[1])))||(function(e,t,n,r){if(null==t||function(e,t,n,r){if(null!==n&&0===n.type)return!1;switch(typeof t){case"function":case"symbol":return!0;case"boolean":return!r&&(null!==n?!n.acceptsBooleans:"data-"!==(e=e.toLowerCase().slice(0,5))&&"aria-"!==e);default:return!1}}(e,t,n,r))return!0;if(r)return!1;if(null!==n)switch(n.type){case 3:return!t;case 4:return!1===t;case 5:return isNaN(t);case 6:return isNaN(t)||1>t}return!1}(t,n,o,r)&&(n=null),r||null===o?function(e){return!!p.call(m,e)||!p.call(h,e)&&(f.test(e)?m[e]=!0:(h[e]=!0,!1))}(t)&&(null===n?e.removeAttribute(t):e.setAttribute(t,""+n)):o.mustUseProperty?e[o.propertyName]=null===n?3!==o.type&&"":n:(t=o.attributeName,r=o.attributeNamespace,null===n?e.removeAttribute(t):(n=3===(o=o.type)||4===o&&!0===n?"":""+n,r?e.setAttributeNS(r,t,n):e.setAttribute(t,n))))}"accent-height alignment-baseline arabic-form baseline-shift cap-height clip-path clip-rule color-interpolation color-interpolation-filters color-profile color-rendering dominant-baseline enable-background fill-opacity fill-rule flood-color flood-opacity font-family font-size font-size-adjust font-stretch font-style font-variant font-weight glyph-name glyph-orientation-horizontal glyph-orientation-vertical horiz-adv-x horiz-origin-x image-rendering letter-spacing lighting-color marker-end marker-mid marker-start overline-position overline-thickness paint-order panose-1 pointer-events rendering-intent shape-rendering stop-color stop-opacity strikethrough-position strikethrough-thickness stroke-dasharray stroke-dashoffset stroke-linecap stroke-linejoin stroke-miterlimit stroke-opacity stroke-width text-anchor text-decoration text-rendering underline-position underline-thickness unicode-bidi unicode-range units-per-em v-alphabetic v-hanging v-ideographic v-mathematical vector-effect vert-adv-y vert-origin-x vert-origin-y word-spacing writing-mode xmlns:xlink x-height".split(" ").forEach((function(e){var t=e.replace(b,y);v[t]=new g(t,1,!1,e,null,!1,!1)})),"xlink:actuate xlink:arcrole xlink:role xlink:show xlink:title xlink:type".split(" ").forEach((function(e){var t=e.replace(b,y);v[t]=new g(t,1,!1,e,"http://www.w3.org/1999/xlink",!1,!1)})),["xml:base","xml:lang","xml:space"].forEach((function(e){var t=e.replace(b,y);v[t]=new g(t,1,!1,e,"http://www.w3.org/XML/1998/namespace",!1,!1)})),["tabIndex","crossOrigin"].forEach((function(e){v[e]=new g(e,1,!1,e.toLowerCase(),null,!1,!1)})),v.xlinkHref=new g("xlinkHref",1,!1,"xlink:href","http://www.w3.org/1999/xlink",!0,!1),["src","href","action","formAction"].forEach((function(e){v[e]=new g(e,1,!1,e.toLowerCase(),null,!0,!0)}));var x=r.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED,_=60103,k=60106,E=60107,S=60108,C=60114,T=60109,O=60110,D=60112,P=60113,N=60120,A=60115,I=60116,L=60121,R=60128,j=60129,M=60130,F=60131;if("function"==typeof Symbol&&Symbol.for){var B=Symbol.for;_=B("react.element"),k=B("react.portal"),E=B("react.fragment"),S=B("react.strict_mode"),C=B("react.profiler"),T=B("react.provider"),O=B("react.context"),D=B("react.forward_ref"),P=B("react.suspense"),N=B("react.suspense_list"),A=B("react.memo"),I=B("react.lazy"),L=B("react.block"),B("react.scope"),R=B("react.opaque.id"),j=B("react.debug_trace_mode"),M=B("react.offscreen"),F=B("react.legacy_hidden")}var z,$="function"==typeof Symbol&&Symbol.iterator;function U(e){return null===e||"object"!=typeof e?null:"function"==typeof(e=$&&e[$]||e["@@iterator"])?e:null}function H(e){if(void 0===z)try{throw Error()}catch(n){var t=n.stack.trim().match(/\n( *(at )?)/);z=t&&t[1]||""}return"\n"+z+e}var V=!1;function q(e,t){if(!e||V)return"";V=!0;var n=Error.prepareStackTrace;Error.prepareStackTrace=void 0;try{if(t)if(t=function(){throw Error()},Object.defineProperty(t.prototype,"props",{set:function(){throw Error()}}),"object"==typeof Reflect&&Reflect.construct){try{Reflect.construct(t,[])}catch(s){var r=s}Reflect.construct(e,[],t)}else{try{t.call()}catch(s){r=s}e.call(t.prototype)}else{try{throw Error()}catch(s){r=s}e()}}catch(s){if(s&&r&&"string"==typeof s.stack){for(var o=s.stack.split("\n"),a=r.stack.split("\n"),i=o.length-1,l=a.length-1;1<=i&&0<=l&&o[i]!==a[l];)l--;for(;1<=i&&0<=l;i--,l--)if(o[i]!==a[l]){if(1!==i||1!==l)do{if(i--,0>--l||o[i]!==a[l])return"\n"+o[i].replace(" at new "," at ")}while(1<=i&&0<=l);break}}}finally{V=!1,Error.prepareStackTrace=n}return(e=e?e.displayName||e.name:"")?H(e):""}function G(e){switch(e.tag){case 5:return H(e.type);case 16:return H("Lazy");case 13:return H("Suspense");case 19:return H("SuspenseList");case 0:case 2:case 15:return e=q(e.type,!1);case 11:return e=q(e.type.render,!1);case 22:return e=q(e.type._render,!1);case 1:return e=q(e.type,!0);default:return""}}function W(e){if(null==e)return null;if("function"==typeof e)return e.displayName||e.name||null;if("string"==typeof e)return e;switch(e){case E:return"Fragment";case k:return"Portal";case C:return"Profiler";case S:return"StrictMode";case P:return"Suspense";case N:return"SuspenseList"}if("object"==typeof e)switch(e.$$typeof){case O:return(e.displayName||"Context")+".Consumer";case T:return(e._context.displayName||"Context")+".Provider";case D:var t=e.render;return t=t.displayName||t.name||"",e.displayName||(""!==t?"ForwardRef("+t+")":"ForwardRef");case A:return W(e.type);case L:return W(e._render);case I:t=e._payload,e=e._init;try{return W(e(t))}catch(n){}}return null}function Z(e){switch(typeof e){case"boolean":case"number":case"object":case"string":case"undefined":return e;default:return""}}function Q(e){var t=e.type;return(e=e.nodeName)&&"input"===e.toLowerCase()&&("checkbox"===t||"radio"===t)}function Y(e){e._valueTracker||(e._valueTracker=function(e){var t=Q(e)?"checked":"value",n=Object.getOwnPropertyDescriptor(e.constructor.prototype,t),r=""+e[t];if(!e.hasOwnProperty(t)&&void 0!==n&&"function"==typeof n.get&&"function"==typeof n.set){var o=n.get,a=n.set;return Object.defineProperty(e,t,{configurable:!0,get:function(){return o.call(this)},set:function(e){r=""+e,a.call(this,e)}}),Object.defineProperty(e,t,{enumerable:n.enumerable}),{getValue:function(){return r},setValue:function(e){r=""+e},stopTracking:function(){e._valueTracker=null,delete e[t]}}}}(e))}function X(e){if(!e)return!1;var t=e._valueTracker;if(!t)return!0;var n=t.getValue(),r="";return e&&(r=Q(e)?e.checked?"true":"false":e.value),(e=r)!==n&&(t.setValue(e),!0)}function K(e){if(void 0===(e=e||("undefined"!=typeof document?document:void 0)))return null;try{return e.activeElement||e.body}catch(t){return e.body}}function J(e,t){var n=t.checked;return o({},t,{defaultChecked:void 0,defaultValue:void 0,value:void 0,checked:null!=n?n:e._wrapperState.initialChecked})}function ee(e,t){var n=null==t.defaultValue?"":t.defaultValue,r=null!=t.checked?t.checked:t.defaultChecked;n=Z(null!=t.value?t.value:n),e._wrapperState={initialChecked:r,initialValue:n,controlled:"checkbox"===t.type||"radio"===t.type?null!=t.checked:null!=t.value}}function te(e,t){null!=(t=t.checked)&&w(e,"checked",t,!1)}function ne(e,t){te(e,t);var n=Z(t.value),r=t.type;if(null!=n)"number"===r?(0===n&&""===e.value||e.value!=n)&&(e.value=""+n):e.value!==""+n&&(e.value=""+n);else if("submit"===r||"reset"===r)return void e.removeAttribute("value");t.hasOwnProperty("value")?oe(e,t.type,n):t.hasOwnProperty("defaultValue")&&oe(e,t.type,Z(t.defaultValue)),null==t.checked&&null!=t.defaultChecked&&(e.defaultChecked=!!t.defaultChecked)}function re(e,t,n){if(t.hasOwnProperty("value")||t.hasOwnProperty("defaultValue")){var r=t.type;if(!("submit"!==r&&"reset"!==r||void 0!==t.value&&null!==t.value))return;t=""+e._wrapperState.initialValue,n||t===e.value||(e.value=t),e.defaultValue=t}""!==(n=e.name)&&(e.name=""),e.defaultChecked=!!e._wrapperState.initialChecked,""!==n&&(e.name=n)}function oe(e,t,n){"number"===t&&K(e.ownerDocument)===e||(null==n?e.defaultValue=""+e._wrapperState.initialValue:e.defaultValue!==""+n&&(e.defaultValue=""+n))}function ae(e,t){return e=o({children:void 0},t),(t=function(e){var t="";return r.Children.forEach(e,(function(e){null!=e&&(t+=e)})),t}(t.children))&&(e.children=t),e}function ie(e,t,n,r){if(e=e.options,t){t={};for(var o=0;o<n.length;o++)t["$"+n[o]]=!0;for(n=0;n<e.length;n++)o=t.hasOwnProperty("$"+e[n].value),e[n].selected!==o&&(e[n].selected=o),o&&r&&(e[n].defaultSelected=!0)}else{for(n=""+Z(n),t=null,o=0;o<e.length;o++){if(e[o].value===n)return e[o].selected=!0,void(r&&(e[o].defaultSelected=!0));null!==t||e[o].disabled||(t=e[o])}null!==t&&(t.selected=!0)}}function le(e,t){if(null!=t.dangerouslySetInnerHTML)throw Error(i(91));return o({},t,{value:void 0,defaultValue:void 0,children:""+e._wrapperState.initialValue})}function se(e,t){var n=t.value;if(null==n){if(n=t.children,t=t.defaultValue,null!=n){if(null!=t)throw Error(i(92));if(Array.isArray(n)){if(!(1>=n.length))throw Error(i(93));n=n[0]}t=n}null==t&&(t=""),n=t}e._wrapperState={initialValue:Z(n)}}function ue(e,t){var n=Z(t.value),r=Z(t.defaultValue);null!=n&&((n=""+n)!==e.value&&(e.value=n),null==t.defaultValue&&e.defaultValue!==n&&(e.defaultValue=n)),null!=r&&(e.defaultValue=""+r)}function ce(e){var t=e.textContent;t===e._wrapperState.initialValue&&""!==t&&null!==t&&(e.value=t)}var de="http://www.w3.org/1999/xhtml",fe="http://www.w3.org/2000/svg";function pe(e){switch(e){case"svg":return"http://www.w3.org/2000/svg";case"math":return"http://www.w3.org/1998/Math/MathML";default:return"http://www.w3.org/1999/xhtml"}}function he(e,t){return null==e||"http://www.w3.org/1999/xhtml"===e?pe(t):"http://www.w3.org/2000/svg"===e&&"foreignObject"===t?"http://www.w3.org/1999/xhtml":e}var me,ge,ve=(ge=function(e,t){if(e.namespaceURI!==fe||"innerHTML"in e)e.innerHTML=t;else{for((me=me||document.createElement("div")).innerHTML="<svg>"+t.valueOf().toString()+"</svg>",t=me.firstChild;e.firstChild;)e.removeChild(e.firstChild);for(;t.firstChild;)e.appendChild(t.firstChild)}},"undefined"!=typeof MSApp&&MSApp.execUnsafeLocalFunction?function(e,t,n,r){MSApp.execUnsafeLocalFunction((function(){return ge(e,t)}))}:ge);function be(e,t){if(t){var n=e.firstChild;if(n&&n===e.lastChild&&3===n.nodeType)return void(n.nodeValue=t)}e.textContent=t}var ye={animationIterationCount:!0,borderImageOutset:!0,borderImageSlice:!0,borderImageWidth:!0,boxFlex:!0,boxFlexGroup:!0,boxOrdinalGroup:!0,columnCount:!0,columns:!0,flex:!0,flexGrow:!0,flexPositive:!0,flexShrink:!0,flexNegative:!0,flexOrder:!0,gridArea:!0,gridRow:!0,gridRowEnd:!0,gridRowSpan:!0,gridRowStart:!0,gridColumn:!0,gridColumnEnd:!0,gridColumnSpan:!0,gridColumnStart:!0,fontWeight:!0,lineClamp:!0,lineHeight:!0,opacity:!0,order:!0,orphans:!0,tabSize:!0,widows:!0,zIndex:!0,zoom:!0,fillOpacity:!0,floodOpacity:!0,stopOpacity:!0,strokeDasharray:!0,strokeDashoffset:!0,strokeMiterlimit:!0,strokeOpacity:!0,strokeWidth:!0},we=["Webkit","ms","Moz","O"];function xe(e,t,n){return null==t||"boolean"==typeof t||""===t?"":n||"number"!=typeof t||0===t||ye.hasOwnProperty(e)&&ye[e]?(""+t).trim():t+"px"}function _e(e,t){for(var n in e=e.style,t)if(t.hasOwnProperty(n)){var r=0===n.indexOf("--"),o=xe(n,t[n],r);"float"===n&&(n="cssFloat"),r?e.setProperty(n,o):e[n]=o}}Object.keys(ye).forEach((function(e){we.forEach((function(t){t=t+e.charAt(0).toUpperCase()+e.substring(1),ye[t]=ye[e]}))}));var ke=o({menuitem:!0},{area:!0,base:!0,br:!0,col:!0,embed:!0,hr:!0,img:!0,input:!0,keygen:!0,link:!0,meta:!0,param:!0,source:!0,track:!0,wbr:!0});function Ee(e,t){if(t){if(ke[e]&&(null!=t.children||null!=t.dangerouslySetInnerHTML))throw Error(i(137,e));if(null!=t.dangerouslySetInnerHTML){if(null!=t.children)throw Error(i(60));if("object"!=typeof t.dangerouslySetInnerHTML||!("__html"in t.dangerouslySetInnerHTML))throw Error(i(61))}if(null!=t.style&&"object"!=typeof t.style)throw Error(i(62))}}function Se(e,t){if(-1===e.indexOf("-"))return"string"==typeof t.is;switch(e){case"annotation-xml":case"color-profile":case"font-face":case"font-face-src":case"font-face-uri":case"font-face-format":case"font-face-name":case"missing-glyph":return!1;default:return!0}}function Ce(e){return(e=e.target||e.srcElement||window).correspondingUseElement&&(e=e.correspondingUseElement),3===e.nodeType?e.parentNode:e}var Te=null,Oe=null,De=null;function Pe(e){if(e=ro(e)){if("function"!=typeof Te)throw Error(i(280));var t=e.stateNode;t&&(t=ao(t),Te(e.stateNode,e.type,t))}}function Ne(e){Oe?De?De.push(e):De=[e]:Oe=e}function Ae(){if(Oe){var e=Oe,t=De;if(De=Oe=null,Pe(e),t)for(e=0;e<t.length;e++)Pe(t[e])}}function Ie(e,t){return e(t)}function Le(e,t,n,r,o){return e(t,n,r,o)}function Re(){}var je=Ie,Me=!1,Fe=!1;function Be(){null===Oe&&null===De||(Re(),Ae())}function ze(e,t){var n=e.stateNode;if(null===n)return null;var r=ao(n);if(null===r)return null;n=r[t];e:switch(t){case"onClick":case"onClickCapture":case"onDoubleClick":case"onDoubleClickCapture":case"onMouseDown":case"onMouseDownCapture":case"onMouseMove":case"onMouseMoveCapture":case"onMouseUp":case"onMouseUpCapture":case"onMouseEnter":(r=!r.disabled)||(r=!("button"===(e=e.type)||"input"===e||"select"===e||"textarea"===e)),e=!r;break e;default:e=!1}if(e)return null;if(n&&"function"!=typeof n)throw Error(i(231,t,typeof n));return n}var $e=!1;if(d)try{var Ue={};Object.defineProperty(Ue,"passive",{get:function(){$e=!0}}),window.addEventListener("test",Ue,Ue),window.removeEventListener("test",Ue,Ue)}catch(ge){$e=!1}function He(e,t,n,r,o,a,i,l,s){var u=Array.prototype.slice.call(arguments,3);try{t.apply(n,u)}catch(c){this.onError(c)}}var Ve=!1,qe=null,Ge=!1,We=null,Ze={onError:function(e){Ve=!0,qe=e}};function Qe(e,t,n,r,o,a,i,l,s){Ve=!1,qe=null,He.apply(Ze,arguments)}function Ye(e){var t=e,n=e;if(e.alternate)for(;t.return;)t=t.return;else{e=t;do{0!=(1026&(t=e).flags)&&(n=t.return),e=t.return}while(e)}return 3===t.tag?n:null}function Xe(e){if(13===e.tag){var t=e.memoizedState;if(null===t&&(null!==(e=e.alternate)&&(t=e.memoizedState)),null!==t)return t.dehydrated}return null}function Ke(e){if(Ye(e)!==e)throw Error(i(188))}function Je(e){if(e=function(e){var t=e.alternate;if(!t){if(null===(t=Ye(e)))throw Error(i(188));return t!==e?null:e}for(var n=e,r=t;;){var o=n.return;if(null===o)break;var a=o.alternate;if(null===a){if(null!==(r=o.return)){n=r;continue}break}if(o.child===a.child){for(a=o.child;a;){if(a===n)return Ke(o),e;if(a===r)return Ke(o),t;a=a.sibling}throw Error(i(188))}if(n.return!==r.return)n=o,r=a;else{for(var l=!1,s=o.child;s;){if(s===n){l=!0,n=o,r=a;break}if(s===r){l=!0,r=o,n=a;break}s=s.sibling}if(!l){for(s=a.child;s;){if(s===n){l=!0,n=a,r=o;break}if(s===r){l=!0,r=a,n=o;break}s=s.sibling}if(!l)throw Error(i(189))}}if(n.alternate!==r)throw Error(i(190))}if(3!==n.tag)throw Error(i(188));return n.stateNode.current===n?e:t}(e),!e)return null;for(var t=e;;){if(5===t.tag||6===t.tag)return t;if(t.child)t.child.return=t,t=t.child;else{if(t===e)break;for(;!t.sibling;){if(!t.return||t.return===e)return null;t=t.return}t.sibling.return=t.return,t=t.sibling}}return null}function et(e,t){for(var n=e.alternate;null!==t;){if(t===e||t===n)return!0;t=t.return}return!1}var tt,nt,rt,ot,at=!1,it=[],lt=null,st=null,ut=null,ct=new Map,dt=new Map,ft=[],pt="mousedown mouseup touchcancel touchend touchstart auxclick dblclick pointercancel pointerdown pointerup dragend dragstart drop compositionend compositionstart keydown keypress keyup input textInput copy cut paste click change contextmenu reset submit".split(" ");function ht(e,t,n,r,o){return{blockedOn:e,domEventName:t,eventSystemFlags:16|n,nativeEvent:o,targetContainers:[r]}}function mt(e,t){switch(e){case"focusin":case"focusout":lt=null;break;case"dragenter":case"dragleave":st=null;break;case"mouseover":case"mouseout":ut=null;break;case"pointerover":case"pointerout":ct.delete(t.pointerId);break;case"gotpointercapture":case"lostpointercapture":dt.delete(t.pointerId)}}function gt(e,t,n,r,o,a){return null===e||e.nativeEvent!==a?(e=ht(t,n,r,o,a),null!==t&&(null!==(t=ro(t))&&nt(t)),e):(e.eventSystemFlags|=r,t=e.targetContainers,null!==o&&-1===t.indexOf(o)&&t.push(o),e)}function vt(e){var t=no(e.target);if(null!==t){var n=Ye(t);if(null!==n)if(13===(t=n.tag)){if(null!==(t=Xe(n)))return e.blockedOn=t,void ot(e.lanePriority,(function(){a.unstable_runWithPriority(e.priority,(function(){rt(n)}))}))}else if(3===t&&n.stateNode.hydrate)return void(e.blockedOn=3===n.tag?n.stateNode.containerInfo:null)}e.blockedOn=null}function bt(e){if(null!==e.blockedOn)return!1;for(var t=e.targetContainers;0<t.length;){var n=Jt(e.domEventName,e.eventSystemFlags,t[0],e.nativeEvent);if(null!==n)return null!==(t=ro(n))&&nt(t),e.blockedOn=n,!1;t.shift()}return!0}function yt(e,t,n){bt(e)&&n.delete(t)}function wt(){for(at=!1;0<it.length;){var e=it[0];if(null!==e.blockedOn){null!==(e=ro(e.blockedOn))&&tt(e);break}for(var t=e.targetContainers;0<t.length;){var n=Jt(e.domEventName,e.eventSystemFlags,t[0],e.nativeEvent);if(null!==n){e.blockedOn=n;break}t.shift()}null===e.blockedOn&&it.shift()}null!==lt&&bt(lt)&&(lt=null),null!==st&&bt(st)&&(st=null),null!==ut&&bt(ut)&&(ut=null),ct.forEach(yt),dt.forEach(yt)}function xt(e,t){e.blockedOn===t&&(e.blockedOn=null,at||(at=!0,a.unstable_scheduleCallback(a.unstable_NormalPriority,wt)))}function _t(e){function t(t){return xt(t,e)}if(0<it.length){xt(it[0],e);for(var n=1;n<it.length;n++){var r=it[n];r.blockedOn===e&&(r.blockedOn=null)}}for(null!==lt&&xt(lt,e),null!==st&&xt(st,e),null!==ut&&xt(ut,e),ct.forEach(t),dt.forEach(t),n=0;n<ft.length;n++)(r=ft[n]).blockedOn===e&&(r.blockedOn=null);for(;0<ft.length&&null===(n=ft[0]).blockedOn;)vt(n),null===n.blockedOn&&ft.shift()}function kt(e,t){var n={};return n[e.toLowerCase()]=t.toLowerCase(),n["Webkit"+e]="webkit"+t,n["Moz"+e]="moz"+t,n}var Et={animationend:kt("Animation","AnimationEnd"),animationiteration:kt("Animation","AnimationIteration"),animationstart:kt("Animation","AnimationStart"),transitionend:kt("Transition","TransitionEnd")},St={},Ct={};function Tt(e){if(St[e])return St[e];if(!Et[e])return e;var t,n=Et[e];for(t in n)if(n.hasOwnProperty(t)&&t in Ct)return St[e]=n[t];return e}d&&(Ct=document.createElement("div").style,"AnimationEvent"in window||(delete Et.animationend.animation,delete Et.animationiteration.animation,delete Et.animationstart.animation),"TransitionEvent"in window||delete Et.transitionend.transition);var Ot=Tt("animationend"),Dt=Tt("animationiteration"),Pt=Tt("animationstart"),Nt=Tt("transitionend"),At=new Map,It=new Map,Lt=["abort","abort",Ot,"animationEnd",Dt,"animationIteration",Pt,"animationStart","canplay","canPlay","canplaythrough","canPlayThrough","durationchange","durationChange","emptied","emptied","encrypted","encrypted","ended","ended","error","error","gotpointercapture","gotPointerCapture","load","load","loadeddata","loadedData","loadedmetadata","loadedMetadata","loadstart","loadStart","lostpointercapture","lostPointerCapture","playing","playing","progress","progress","seeking","seeking","stalled","stalled","suspend","suspend","timeupdate","timeUpdate",Nt,"transitionEnd","waiting","waiting"];function Rt(e,t){for(var n=0;n<e.length;n+=2){var r=e[n],o=e[n+1];o="on"+(o[0].toUpperCase()+o.slice(1)),It.set(r,t),At.set(r,o),u(o,[r])}}(0,a.unstable_now)();var jt=8;function Mt(e){if(0!=(1&e))return jt=15,1;if(0!=(2&e))return jt=14,2;if(0!=(4&e))return jt=13,4;var t=24&e;return 0!==t?(jt=12,t):0!=(32&e)?(jt=11,32):0!==(t=192&e)?(jt=10,t):0!=(256&e)?(jt=9,256):0!==(t=3584&e)?(jt=8,t):0!=(4096&e)?(jt=7,4096):0!==(t=4186112&e)?(jt=6,t):0!==(t=62914560&e)?(jt=5,t):67108864&e?(jt=4,67108864):0!=(134217728&e)?(jt=3,134217728):0!==(t=805306368&e)?(jt=2,t):0!=(1073741824&e)?(jt=1,1073741824):(jt=8,e)}function Ft(e,t){var n=e.pendingLanes;if(0===n)return jt=0;var r=0,o=0,a=e.expiredLanes,i=e.suspendedLanes,l=e.pingedLanes;if(0!==a)r=a,o=jt=15;else if(0!==(a=134217727&n)){var s=a&~i;0!==s?(r=Mt(s),o=jt):0!==(l&=a)&&(r=Mt(l),o=jt)}else 0!==(a=n&~i)?(r=Mt(a),o=jt):0!==l&&(r=Mt(l),o=jt);if(0===r)return 0;if(r=n&((0>(r=31-Vt(r))?0:1<<r)<<1)-1,0!==t&&t!==r&&0==(t&i)){if(Mt(t),o<=jt)return t;jt=o}if(0!==(t=e.entangledLanes))for(e=e.entanglements,t&=r;0<t;)o=1<<(n=31-Vt(t)),r|=e[n],t&=~o;return r}function Bt(e){return 0!==(e=-1073741825&e.pendingLanes)?e:1073741824&e?1073741824:0}function zt(e,t){switch(e){case 15:return 1;case 14:return 2;case 12:return 0===(e=$t(24&~t))?zt(10,t):e;case 10:return 0===(e=$t(192&~t))?zt(8,t):e;case 8:return 0===(e=$t(3584&~t))&&(0===(e=$t(4186112&~t))&&(e=512)),e;case 2:return 0===(t=$t(805306368&~t))&&(t=268435456),t}throw Error(i(358,e))}function $t(e){return e&-e}function Ut(e){for(var t=[],n=0;31>n;n++)t.push(e);return t}function Ht(e,t,n){e.pendingLanes|=t;var r=t-1;e.suspendedLanes&=r,e.pingedLanes&=r,(e=e.eventTimes)[t=31-Vt(t)]=n}var Vt=Math.clz32?Math.clz32:function(e){return 0===e?32:31-(qt(e)/Gt|0)|0},qt=Math.log,Gt=Math.LN2;var Wt=a.unstable_UserBlockingPriority,Zt=a.unstable_runWithPriority,Qt=!0;function Yt(e,t,n,r){Me||Re();var o=Kt,a=Me;Me=!0;try{Le(o,e,t,n,r)}finally{(Me=a)||Be()}}function Xt(e,t,n,r){Zt(Wt,Kt.bind(null,e,t,n,r))}function Kt(e,t,n,r){var o;if(Qt)if((o=0==(4&t))&&0<it.length&&-1<pt.indexOf(e))e=ht(null,e,t,n,r),it.push(e);else{var a=Jt(e,t,n,r);if(null===a)o&&mt(e,r);else{if(o){if(-1<pt.indexOf(e))return e=ht(a,e,t,n,r),void it.push(e);if(function(e,t,n,r,o){switch(t){case"focusin":return lt=gt(lt,e,t,n,r,o),!0;case"dragenter":return st=gt(st,e,t,n,r,o),!0;case"mouseover":return ut=gt(ut,e,t,n,r,o),!0;case"pointerover":var a=o.pointerId;return ct.set(a,gt(ct.get(a)||null,e,t,n,r,o)),!0;case"gotpointercapture":return a=o.pointerId,dt.set(a,gt(dt.get(a)||null,e,t,n,r,o)),!0}return!1}(a,e,t,n,r))return;mt(e,r)}Rr(e,t,r,null,n)}}}function Jt(e,t,n,r){var o=Ce(r);if(null!==(o=no(o))){var a=Ye(o);if(null===a)o=null;else{var i=a.tag;if(13===i){if(null!==(o=Xe(a)))return o;o=null}else if(3===i){if(a.stateNode.hydrate)return 3===a.tag?a.stateNode.containerInfo:null;o=null}else a!==o&&(o=null)}}return Rr(e,t,r,o,n),null}var en=null,tn=null,nn=null;function rn(){if(nn)return nn;var e,t,n=tn,r=n.length,o="value"in en?en.value:en.textContent,a=o.length;for(e=0;e<r&&n[e]===o[e];e++);var i=r-e;for(t=1;t<=i&&n[r-t]===o[a-t];t++);return nn=o.slice(e,1<t?1-t:void 0)}function on(e){var t=e.keyCode;return"charCode"in e?0===(e=e.charCode)&&13===t&&(e=13):e=t,10===e&&(e=13),32<=e||13===e?e:0}function an(){return!0}function ln(){return!1}function sn(e){function t(t,n,r,o,a){for(var i in this._reactName=t,this._targetInst=r,this.type=n,this.nativeEvent=o,this.target=a,this.currentTarget=null,e)e.hasOwnProperty(i)&&(t=e[i],this[i]=t?t(o):o[i]);return this.isDefaultPrevented=(null!=o.defaultPrevented?o.defaultPrevented:!1===o.returnValue)?an:ln,this.isPropagationStopped=ln,this}return o(t.prototype,{preventDefault:function(){this.defaultPrevented=!0;var e=this.nativeEvent;e&&(e.preventDefault?e.preventDefault():"unknown"!=typeof e.returnValue&&(e.returnValue=!1),this.isDefaultPrevented=an)},stopPropagation:function(){var e=this.nativeEvent;e&&(e.stopPropagation?e.stopPropagation():"unknown"!=typeof e.cancelBubble&&(e.cancelBubble=!0),this.isPropagationStopped=an)},persist:function(){},isPersistent:an}),t}var un,cn,dn,fn={eventPhase:0,bubbles:0,cancelable:0,timeStamp:function(e){return e.timeStamp||Date.now()},defaultPrevented:0,isTrusted:0},pn=sn(fn),hn=o({},fn,{view:0,detail:0}),mn=sn(hn),gn=o({},hn,{screenX:0,screenY:0,clientX:0,clientY:0,pageX:0,pageY:0,ctrlKey:0,shiftKey:0,altKey:0,metaKey:0,getModifierState:On,button:0,buttons:0,relatedTarget:function(e){return void 0===e.relatedTarget?e.fromElement===e.srcElement?e.toElement:e.fromElement:e.relatedTarget},movementX:function(e){return"movementX"in e?e.movementX:(e!==dn&&(dn&&"mousemove"===e.type?(un=e.screenX-dn.screenX,cn=e.screenY-dn.screenY):cn=un=0,dn=e),un)},movementY:function(e){return"movementY"in e?e.movementY:cn}}),vn=sn(gn),bn=sn(o({},gn,{dataTransfer:0})),yn=sn(o({},hn,{relatedTarget:0})),wn=sn(o({},fn,{animationName:0,elapsedTime:0,pseudoElement:0})),xn=o({},fn,{clipboardData:function(e){return"clipboardData"in e?e.clipboardData:window.clipboardData}}),_n=sn(xn),kn=sn(o({},fn,{data:0})),En={Esc:"Escape",Spacebar:" ",Left:"ArrowLeft",Up:"ArrowUp",Right:"ArrowRight",Down:"ArrowDown",Del:"Delete",Win:"OS",Menu:"ContextMenu",Apps:"ContextMenu",Scroll:"ScrollLock",MozPrintableKey:"Unidentified"},Sn={8:"Backspace",9:"Tab",12:"Clear",13:"Enter",16:"Shift",17:"Control",18:"Alt",19:"Pause",20:"CapsLock",27:"Escape",32:" ",33:"PageUp",34:"PageDown",35:"End",36:"Home",37:"ArrowLeft",38:"ArrowUp",39:"ArrowRight",40:"ArrowDown",45:"Insert",46:"Delete",112:"F1",113:"F2",114:"F3",115:"F4",116:"F5",117:"F6",118:"F7",119:"F8",120:"F9",121:"F10",122:"F11",123:"F12",144:"NumLock",145:"ScrollLock",224:"Meta"},Cn={Alt:"altKey",Control:"ctrlKey",Meta:"metaKey",Shift:"shiftKey"};function Tn(e){var t=this.nativeEvent;return t.getModifierState?t.getModifierState(e):!!(e=Cn[e])&&!!t[e]}function On(){return Tn}var Dn=o({},hn,{key:function(e){if(e.key){var t=En[e.key]||e.key;if("Unidentified"!==t)return t}return"keypress"===e.type?13===(e=on(e))?"Enter":String.fromCharCode(e):"keydown"===e.type||"keyup"===e.type?Sn[e.keyCode]||"Unidentified":""},code:0,location:0,ctrlKey:0,shiftKey:0,altKey:0,metaKey:0,repeat:0,locale:0,getModifierState:On,charCode:function(e){return"keypress"===e.type?on(e):0},keyCode:function(e){return"keydown"===e.type||"keyup"===e.type?e.keyCode:0},which:function(e){return"keypress"===e.type?on(e):"keydown"===e.type||"keyup"===e.type?e.keyCode:0}}),Pn=sn(Dn),Nn=sn(o({},gn,{pointerId:0,width:0,height:0,pressure:0,tangentialPressure:0,tiltX:0,tiltY:0,twist:0,pointerType:0,isPrimary:0})),An=sn(o({},hn,{touches:0,targetTouches:0,changedTouches:0,altKey:0,metaKey:0,ctrlKey:0,shiftKey:0,getModifierState:On})),In=sn(o({},fn,{propertyName:0,elapsedTime:0,pseudoElement:0})),Ln=o({},gn,{deltaX:function(e){return"deltaX"in e?e.deltaX:"wheelDeltaX"in e?-e.wheelDeltaX:0},deltaY:function(e){return"deltaY"in e?e.deltaY:"wheelDeltaY"in e?-e.wheelDeltaY:"wheelDelta"in e?-e.wheelDelta:0},deltaZ:0,deltaMode:0}),Rn=sn(Ln),jn=[9,13,27,32],Mn=d&&"CompositionEvent"in window,Fn=null;d&&"documentMode"in document&&(Fn=document.documentMode);var Bn=d&&"TextEvent"in window&&!Fn,zn=d&&(!Mn||Fn&&8<Fn&&11>=Fn),$n=String.fromCharCode(32),Un=!1;function Hn(e,t){switch(e){case"keyup":return-1!==jn.indexOf(t.keyCode);case"keydown":return 229!==t.keyCode;case"keypress":case"mousedown":case"focusout":return!0;default:return!1}}function Vn(e){return"object"==typeof(e=e.detail)&&"data"in e?e.data:null}var qn=!1;var Gn={color:!0,date:!0,datetime:!0,"datetime-local":!0,email:!0,month:!0,number:!0,password:!0,range:!0,search:!0,tel:!0,text:!0,time:!0,url:!0,week:!0};function Wn(e){var t=e&&e.nodeName&&e.nodeName.toLowerCase();return"input"===t?!!Gn[e.type]:"textarea"===t}function Zn(e,t,n,r){Ne(r),0<(t=Mr(t,"onChange")).length&&(n=new pn("onChange","change",null,n,r),e.push({event:n,listeners:t}))}var Qn=null,Yn=null;function Xn(e){Dr(e,0)}function Kn(e){if(X(oo(e)))return e}function Jn(e,t){if("change"===e)return t}var er=!1;if(d){var tr;if(d){var nr="oninput"in document;if(!nr){var rr=document.createElement("div");rr.setAttribute("oninput","return;"),nr="function"==typeof rr.oninput}tr=nr}else tr=!1;er=tr&&(!document.documentMode||9<document.documentMode)}function or(){Qn&&(Qn.detachEvent("onpropertychange",ar),Yn=Qn=null)}function ar(e){if("value"===e.propertyName&&Kn(Yn)){var t=[];if(Zn(t,Yn,e,Ce(e)),e=Xn,Me)e(t);else{Me=!0;try{Ie(e,t)}finally{Me=!1,Be()}}}}function ir(e,t,n){"focusin"===e?(or(),Yn=n,(Qn=t).attachEvent("onpropertychange",ar)):"focusout"===e&&or()}function lr(e){if("selectionchange"===e||"keyup"===e||"keydown"===e)return Kn(Yn)}function sr(e,t){if("click"===e)return Kn(t)}function ur(e,t){if("input"===e||"change"===e)return Kn(t)}var cr="function"==typeof Object.is?Object.is:function(e,t){return e===t&&(0!==e||1/e==1/t)||e!=e&&t!=t},dr=Object.prototype.hasOwnProperty;function fr(e,t){if(cr(e,t))return!0;if("object"!=typeof e||null===e||"object"!=typeof t||null===t)return!1;var n=Object.keys(e),r=Object.keys(t);if(n.length!==r.length)return!1;for(r=0;r<n.length;r++)if(!dr.call(t,n[r])||!cr(e[n[r]],t[n[r]]))return!1;return!0}function pr(e){for(;e&&e.firstChild;)e=e.firstChild;return e}function hr(e,t){var n,r=pr(e);for(e=0;r;){if(3===r.nodeType){if(n=e+r.textContent.length,e<=t&&n>=t)return{node:r,offset:t-e};e=n}e:{for(;r;){if(r.nextSibling){r=r.nextSibling;break e}r=r.parentNode}r=void 0}r=pr(r)}}function mr(e,t){return!(!e||!t)&&(e===t||(!e||3!==e.nodeType)&&(t&&3===t.nodeType?mr(e,t.parentNode):"contains"in e?e.contains(t):!!e.compareDocumentPosition&&!!(16&e.compareDocumentPosition(t))))}function gr(){for(var e=window,t=K();t instanceof e.HTMLIFrameElement;){try{var n="string"==typeof t.contentWindow.location.href}catch(r){n=!1}if(!n)break;t=K((e=t.contentWindow).document)}return t}function vr(e){var t=e&&e.nodeName&&e.nodeName.toLowerCase();return t&&("input"===t&&("text"===e.type||"search"===e.type||"tel"===e.type||"url"===e.type||"password"===e.type)||"textarea"===t||"true"===e.contentEditable)}var br=d&&"documentMode"in document&&11>=document.documentMode,yr=null,wr=null,xr=null,_r=!1;function kr(e,t,n){var r=n.window===n?n.document:9===n.nodeType?n:n.ownerDocument;_r||null==yr||yr!==K(r)||("selectionStart"in(r=yr)&&vr(r)?r={start:r.selectionStart,end:r.selectionEnd}:r={anchorNode:(r=(r.ownerDocument&&r.ownerDocument.defaultView||window).getSelection()).anchorNode,anchorOffset:r.anchorOffset,focusNode:r.focusNode,focusOffset:r.focusOffset},xr&&fr(xr,r)||(xr=r,0<(r=Mr(wr,"onSelect")).length&&(t=new pn("onSelect","select",null,t,n),e.push({event:t,listeners:r}),t.target=yr)))}Rt("cancel cancel click click close close contextmenu contextMenu copy copy cut cut auxclick auxClick dblclick doubleClick dragend dragEnd dragstart dragStart drop drop focusin focus focusout blur input input invalid invalid keydown keyDown keypress keyPress keyup keyUp mousedown mouseDown mouseup mouseUp paste paste pause pause play play pointercancel pointerCancel pointerdown pointerDown pointerup pointerUp ratechange rateChange reset reset seeked seeked submit submit touchcancel touchCancel touchend touchEnd touchstart touchStart volumechange volumeChange".split(" "),0),Rt("drag drag dragenter dragEnter dragexit dragExit dragleave dragLeave dragover dragOver mousemove mouseMove mouseout mouseOut mouseover mouseOver pointermove pointerMove pointerout pointerOut pointerover pointerOver scroll scroll toggle toggle touchmove touchMove wheel wheel".split(" "),1),Rt(Lt,2);for(var Er="change selectionchange textInput compositionstart compositionend compositionupdate".split(" "),Sr=0;Sr<Er.length;Sr++)It.set(Er[Sr],0);c("onMouseEnter",["mouseout","mouseover"]),c("onMouseLeave",["mouseout","mouseover"]),c("onPointerEnter",["pointerout","pointerover"]),c("onPointerLeave",["pointerout","pointerover"]),u("onChange","change click focusin focusout input keydown keyup selectionchange".split(" ")),u("onSelect","focusout contextmenu dragend focusin keydown keyup mousedown mouseup selectionchange".split(" ")),u("onBeforeInput",["compositionend","keypress","textInput","paste"]),u("onCompositionEnd","compositionend focusout keydown keypress keyup mousedown".split(" ")),u("onCompositionStart","compositionstart focusout keydown keypress keyup mousedown".split(" ")),u("onCompositionUpdate","compositionupdate focusout keydown keypress keyup mousedown".split(" "));var Cr="abort canplay canplaythrough durationchange emptied encrypted ended error loadeddata loadedmetadata loadstart pause play playing progress ratechange seeked seeking stalled suspend timeupdate volumechange waiting".split(" "),Tr=new Set("cancel close invalid load scroll toggle".split(" ").concat(Cr));function Or(e,t,n){var r=e.type||"unknown-event";e.currentTarget=n,function(e,t,n,r,o,a,l,s,u){if(Qe.apply(this,arguments),Ve){if(!Ve)throw Error(i(198));var c=qe;Ve=!1,qe=null,Ge||(Ge=!0,We=c)}}(r,t,void 0,e),e.currentTarget=null}function Dr(e,t){t=0!=(4&t);for(var n=0;n<e.length;n++){var r=e[n],o=r.event;r=r.listeners;e:{var a=void 0;if(t)for(var i=r.length-1;0<=i;i--){var l=r[i],s=l.instance,u=l.currentTarget;if(l=l.listener,s!==a&&o.isPropagationStopped())break e;Or(o,l,u),a=s}else for(i=0;i<r.length;i++){if(s=(l=r[i]).instance,u=l.currentTarget,l=l.listener,s!==a&&o.isPropagationStopped())break e;Or(o,l,u),a=s}}}if(Ge)throw e=We,Ge=!1,We=null,e}function Pr(e,t){var n=io(t),r=e+"__bubble";n.has(r)||(Lr(t,e,2,!1),n.add(r))}var Nr="_reactListening"+Math.random().toString(36).slice(2);function Ar(e){e[Nr]||(e[Nr]=!0,l.forEach((function(t){Tr.has(t)||Ir(t,!1,e,null),Ir(t,!0,e,null)})))}function Ir(e,t,n,r){var o=4<arguments.length&&void 0!==arguments[4]?arguments[4]:0,a=n;if("selectionchange"===e&&9!==n.nodeType&&(a=n.ownerDocument),null!==r&&!t&&Tr.has(e)){if("scroll"!==e)return;o|=2,a=r}var i=io(a),l=e+"__"+(t?"capture":"bubble");i.has(l)||(t&&(o|=4),Lr(a,e,o,t),i.add(l))}function Lr(e,t,n,r){var o=It.get(t);switch(void 0===o?2:o){case 0:o=Yt;break;case 1:o=Xt;break;default:o=Kt}n=o.bind(null,t,n,e),o=void 0,!$e||"touchstart"!==t&&"touchmove"!==t&&"wheel"!==t||(o=!0),r?void 0!==o?e.addEventListener(t,n,{capture:!0,passive:o}):e.addEventListener(t,n,!0):void 0!==o?e.addEventListener(t,n,{passive:o}):e.addEventListener(t,n,!1)}function Rr(e,t,n,r,o){var a=r;if(0==(1&t)&&0==(2&t)&&null!==r)e:for(;;){if(null===r)return;var i=r.tag;if(3===i||4===i){var l=r.stateNode.containerInfo;if(l===o||8===l.nodeType&&l.parentNode===o)break;if(4===i)for(i=r.return;null!==i;){var s=i.tag;if((3===s||4===s)&&((s=i.stateNode.containerInfo)===o||8===s.nodeType&&s.parentNode===o))return;i=i.return}for(;null!==l;){if(null===(i=no(l)))return;if(5===(s=i.tag)||6===s){r=a=i;continue e}l=l.parentNode}}r=r.return}!function(e,t,n){if(Fe)return e(t,n);Fe=!0;try{je(e,t,n)}finally{Fe=!1,Be()}}((function(){var r=a,o=Ce(n),i=[];e:{var l=At.get(e);if(void 0!==l){var s=pn,u=e;switch(e){case"keypress":if(0===on(n))break e;case"keydown":case"keyup":s=Pn;break;case"focusin":u="focus",s=yn;break;case"focusout":u="blur",s=yn;break;case"beforeblur":case"afterblur":s=yn;break;case"click":if(2===n.button)break e;case"auxclick":case"dblclick":case"mousedown":case"mousemove":case"mouseup":case"mouseout":case"mouseover":case"contextmenu":s=vn;break;case"drag":case"dragend":case"dragenter":case"dragexit":case"dragleave":case"dragover":case"dragstart":case"drop":s=bn;break;case"touchcancel":case"touchend":case"touchmove":case"touchstart":s=An;break;case Ot:case Dt:case Pt:s=wn;break;case Nt:s=In;break;case"scroll":s=mn;break;case"wheel":s=Rn;break;case"copy":case"cut":case"paste":s=_n;break;case"gotpointercapture":case"lostpointercapture":case"pointercancel":case"pointerdown":case"pointermove":case"pointerout":case"pointerover":case"pointerup":s=Nn}var c=0!=(4&t),d=!c&&"scroll"===e,f=c?null!==l?l+"Capture":null:l;c=[];for(var p,h=r;null!==h;){var m=(p=h).stateNode;if(5===p.tag&&null!==m&&(p=m,null!==f&&(null!=(m=ze(h,f))&&c.push(jr(h,m,p)))),d)break;h=h.return}0<c.length&&(l=new s(l,u,null,n,o),i.push({event:l,listeners:c}))}}if(0==(7&t)){if(s="mouseout"===e||"pointerout"===e,(!(l="mouseover"===e||"pointerover"===e)||0!=(16&t)||!(u=n.relatedTarget||n.fromElement)||!no(u)&&!u[eo])&&(s||l)&&(l=o.window===o?o:(l=o.ownerDocument)?l.defaultView||l.parentWindow:window,s?(s=r,null!==(u=(u=n.relatedTarget||n.toElement)?no(u):null)&&(u!==(d=Ye(u))||5!==u.tag&&6!==u.tag)&&(u=null)):(s=null,u=r),s!==u)){if(c=vn,m="onMouseLeave",f="onMouseEnter",h="mouse","pointerout"!==e&&"pointerover"!==e||(c=Nn,m="onPointerLeave",f="onPointerEnter",h="pointer"),d=null==s?l:oo(s),p=null==u?l:oo(u),(l=new c(m,h+"leave",s,n,o)).target=d,l.relatedTarget=p,m=null,no(o)===r&&((c=new c(f,h+"enter",u,n,o)).target=p,c.relatedTarget=d,m=c),d=m,s&&u)e:{for(f=u,h=0,p=c=s;p;p=Fr(p))h++;for(p=0,m=f;m;m=Fr(m))p++;for(;0<h-p;)c=Fr(c),h--;for(;0<p-h;)f=Fr(f),p--;for(;h--;){if(c===f||null!==f&&c===f.alternate)break e;c=Fr(c),f=Fr(f)}c=null}else c=null;null!==s&&Br(i,l,s,c,!1),null!==u&&null!==d&&Br(i,d,u,c,!0)}if("select"===(s=(l=r?oo(r):window).nodeName&&l.nodeName.toLowerCase())||"input"===s&&"file"===l.type)var g=Jn;else if(Wn(l))if(er)g=ur;else{g=lr;var v=ir}else(s=l.nodeName)&&"input"===s.toLowerCase()&&("checkbox"===l.type||"radio"===l.type)&&(g=sr);switch(g&&(g=g(e,r))?Zn(i,g,n,o):(v&&v(e,l,r),"focusout"===e&&(v=l._wrapperState)&&v.controlled&&"number"===l.type&&oe(l,"number",l.value)),v=r?oo(r):window,e){case"focusin":(Wn(v)||"true"===v.contentEditable)&&(yr=v,wr=r,xr=null);break;case"focusout":xr=wr=yr=null;break;case"mousedown":_r=!0;break;case"contextmenu":case"mouseup":case"dragend":_r=!1,kr(i,n,o);break;case"selectionchange":if(br)break;case"keydown":case"keyup":kr(i,n,o)}var b;if(Mn)e:{switch(e){case"compositionstart":var y="onCompositionStart";break e;case"compositionend":y="onCompositionEnd";break e;case"compositionupdate":y="onCompositionUpdate";break e}y=void 0}else qn?Hn(e,n)&&(y="onCompositionEnd"):"keydown"===e&&229===n.keyCode&&(y="onCompositionStart");y&&(zn&&"ko"!==n.locale&&(qn||"onCompositionStart"!==y?"onCompositionEnd"===y&&qn&&(b=rn()):(tn="value"in(en=o)?en.value:en.textContent,qn=!0)),0<(v=Mr(r,y)).length&&(y=new kn(y,e,null,n,o),i.push({event:y,listeners:v}),b?y.data=b:null!==(b=Vn(n))&&(y.data=b))),(b=Bn?function(e,t){switch(e){case"compositionend":return Vn(t);case"keypress":return 32!==t.which?null:(Un=!0,$n);case"textInput":return(e=t.data)===$n&&Un?null:e;default:return null}}(e,n):function(e,t){if(qn)return"compositionend"===e||!Mn&&Hn(e,t)?(e=rn(),nn=tn=en=null,qn=!1,e):null;switch(e){case"paste":default:return null;case"keypress":if(!(t.ctrlKey||t.altKey||t.metaKey)||t.ctrlKey&&t.altKey){if(t.char&&1<t.char.length)return t.char;if(t.which)return String.fromCharCode(t.which)}return null;case"compositionend":return zn&&"ko"!==t.locale?null:t.data}}(e,n))&&(0<(r=Mr(r,"onBeforeInput")).length&&(o=new kn("onBeforeInput","beforeinput",null,n,o),i.push({event:o,listeners:r}),o.data=b))}Dr(i,t)}))}function jr(e,t,n){return{instance:e,listener:t,currentTarget:n}}function Mr(e,t){for(var n=t+"Capture",r=[];null!==e;){var o=e,a=o.stateNode;5===o.tag&&null!==a&&(o=a,null!=(a=ze(e,n))&&r.unshift(jr(e,a,o)),null!=(a=ze(e,t))&&r.push(jr(e,a,o))),e=e.return}return r}function Fr(e){if(null===e)return null;do{e=e.return}while(e&&5!==e.tag);return e||null}function Br(e,t,n,r,o){for(var a=t._reactName,i=[];null!==n&&n!==r;){var l=n,s=l.alternate,u=l.stateNode;if(null!==s&&s===r)break;5===l.tag&&null!==u&&(l=u,o?null!=(s=ze(n,a))&&i.unshift(jr(n,s,l)):o||null!=(s=ze(n,a))&&i.push(jr(n,s,l))),n=n.return}0!==i.length&&e.push({event:t,listeners:i})}function zr(){}var $r=null,Ur=null;function Hr(e,t){switch(e){case"button":case"input":case"select":case"textarea":return!!t.autoFocus}return!1}function Vr(e,t){return"textarea"===e||"option"===e||"noscript"===e||"string"==typeof t.children||"number"==typeof t.children||"object"==typeof t.dangerouslySetInnerHTML&&null!==t.dangerouslySetInnerHTML&&null!=t.dangerouslySetInnerHTML.__html}var qr="function"==typeof setTimeout?setTimeout:void 0,Gr="function"==typeof clearTimeout?clearTimeout:void 0;function Wr(e){1===e.nodeType?e.textContent="":9===e.nodeType&&(null!=(e=e.body)&&(e.textContent=""))}function Zr(e){for(;null!=e;e=e.nextSibling){var t=e.nodeType;if(1===t||3===t)break}return e}function Qr(e){e=e.previousSibling;for(var t=0;e;){if(8===e.nodeType){var n=e.data;if("$"===n||"$!"===n||"$?"===n){if(0===t)return e;t--}else"/$"===n&&t++}e=e.previousSibling}return null}var Yr=0;var Xr=Math.random().toString(36).slice(2),Kr="__reactFiber$"+Xr,Jr="__reactProps$"+Xr,eo="__reactContainer$"+Xr,to="__reactEvents$"+Xr;function no(e){var t=e[Kr];if(t)return t;for(var n=e.parentNode;n;){if(t=n[eo]||n[Kr]){if(n=t.alternate,null!==t.child||null!==n&&null!==n.child)for(e=Qr(e);null!==e;){if(n=e[Kr])return n;e=Qr(e)}return t}n=(e=n).parentNode}return null}function ro(e){return!(e=e[Kr]||e[eo])||5!==e.tag&&6!==e.tag&&13!==e.tag&&3!==e.tag?null:e}function oo(e){if(5===e.tag||6===e.tag)return e.stateNode;throw Error(i(33))}function ao(e){return e[Jr]||null}function io(e){var t=e[to];return void 0===t&&(t=e[to]=new Set),t}var lo=[],so=-1;function uo(e){return{current:e}}function co(e){0>so||(e.current=lo[so],lo[so]=null,so--)}function fo(e,t){so++,lo[so]=e.current,e.current=t}var po={},ho=uo(po),mo=uo(!1),go=po;function vo(e,t){var n=e.type.contextTypes;if(!n)return po;var r=e.stateNode;if(r&&r.__reactInternalMemoizedUnmaskedChildContext===t)return r.__reactInternalMemoizedMaskedChildContext;var o,a={};for(o in n)a[o]=t[o];return r&&((e=e.stateNode).__reactInternalMemoizedUnmaskedChildContext=t,e.__reactInternalMemoizedMaskedChildContext=a),a}function bo(e){return null!=(e=e.childContextTypes)}function yo(){co(mo),co(ho)}function wo(e,t,n){if(ho.current!==po)throw Error(i(168));fo(ho,t),fo(mo,n)}function xo(e,t,n){var r=e.stateNode;if(e=t.childContextTypes,"function"!=typeof r.getChildContext)return n;for(var a in r=r.getChildContext())if(!(a in e))throw Error(i(108,W(t)||"Unknown",a));return o({},n,r)}function _o(e){return e=(e=e.stateNode)&&e.__reactInternalMemoizedMergedChildContext||po,go=ho.current,fo(ho,e),fo(mo,mo.current),!0}function ko(e,t,n){var r=e.stateNode;if(!r)throw Error(i(169));n?(e=xo(e,t,go),r.__reactInternalMemoizedMergedChildContext=e,co(mo),co(ho),fo(ho,e)):co(mo),fo(mo,n)}var Eo=null,So=null,Co=a.unstable_runWithPriority,To=a.unstable_scheduleCallback,Oo=a.unstable_cancelCallback,Do=a.unstable_shouldYield,Po=a.unstable_requestPaint,No=a.unstable_now,Ao=a.unstable_getCurrentPriorityLevel,Io=a.unstable_ImmediatePriority,Lo=a.unstable_UserBlockingPriority,Ro=a.unstable_NormalPriority,jo=a.unstable_LowPriority,Mo=a.unstable_IdlePriority,Fo={},Bo=void 0!==Po?Po:function(){},zo=null,$o=null,Uo=!1,Ho=No(),Vo=1e4>Ho?No:function(){return No()-Ho};function qo(){switch(Ao()){case Io:return 99;case Lo:return 98;case Ro:return 97;case jo:return 96;case Mo:return 95;default:throw Error(i(332))}}function Go(e){switch(e){case 99:return Io;case 98:return Lo;case 97:return Ro;case 96:return jo;case 95:return Mo;default:throw Error(i(332))}}function Wo(e,t){return e=Go(e),Co(e,t)}function Zo(e,t,n){return e=Go(e),To(e,t,n)}function Qo(){if(null!==$o){var e=$o;$o=null,Oo(e)}Yo()}function Yo(){if(!Uo&&null!==zo){Uo=!0;var e=0;try{var t=zo;Wo(99,(function(){for(;e<t.length;e++){var n=t[e];do{n=n(!0)}while(null!==n)}})),zo=null}catch(n){throw null!==zo&&(zo=zo.slice(e+1)),To(Io,Qo),n}finally{Uo=!1}}}var Xo=x.ReactCurrentBatchConfig;function Ko(e,t){if(e&&e.defaultProps){for(var n in t=o({},t),e=e.defaultProps)void 0===t[n]&&(t[n]=e[n]);return t}return t}var Jo=uo(null),ea=null,ta=null,na=null;function ra(){na=ta=ea=null}function oa(e){var t=Jo.current;co(Jo),e.type._context._currentValue=t}function aa(e,t){for(;null!==e;){var n=e.alternate;if((e.childLanes&t)===t){if(null===n||(n.childLanes&t)===t)break;n.childLanes|=t}else e.childLanes|=t,null!==n&&(n.childLanes|=t);e=e.return}}function ia(e,t){ea=e,na=ta=null,null!==(e=e.dependencies)&&null!==e.firstContext&&(0!=(e.lanes&t)&&(Mi=!0),e.firstContext=null)}function la(e,t){if(na!==e&&!1!==t&&0!==t)if("number"==typeof t&&1073741823!==t||(na=e,t=1073741823),t={context:e,observedBits:t,next:null},null===ta){if(null===ea)throw Error(i(308));ta=t,ea.dependencies={lanes:0,firstContext:t,responders:null}}else ta=ta.next=t;return e._currentValue}var sa=!1;function ua(e){e.updateQueue={baseState:e.memoizedState,firstBaseUpdate:null,lastBaseUpdate:null,shared:{pending:null},effects:null}}function ca(e,t){e=e.updateQueue,t.updateQueue===e&&(t.updateQueue={baseState:e.baseState,firstBaseUpdate:e.firstBaseUpdate,lastBaseUpdate:e.lastBaseUpdate,shared:e.shared,effects:e.effects})}function da(e,t){return{eventTime:e,lane:t,tag:0,payload:null,callback:null,next:null}}function fa(e,t){if(null!==(e=e.updateQueue)){var n=(e=e.shared).pending;null===n?t.next=t:(t.next=n.next,n.next=t),e.pending=t}}function pa(e,t){var n=e.updateQueue,r=e.alternate;if(null!==r&&n===(r=r.updateQueue)){var o=null,a=null;if(null!==(n=n.firstBaseUpdate)){do{var i={eventTime:n.eventTime,lane:n.lane,tag:n.tag,payload:n.payload,callback:n.callback,next:null};null===a?o=a=i:a=a.next=i,n=n.next}while(null!==n);null===a?o=a=t:a=a.next=t}else o=a=t;return n={baseState:r.baseState,firstBaseUpdate:o,lastBaseUpdate:a,shared:r.shared,effects:r.effects},void(e.updateQueue=n)}null===(e=n.lastBaseUpdate)?n.firstBaseUpdate=t:e.next=t,n.lastBaseUpdate=t}function ha(e,t,n,r){var a=e.updateQueue;sa=!1;var i=a.firstBaseUpdate,l=a.lastBaseUpdate,s=a.shared.pending;if(null!==s){a.shared.pending=null;var u=s,c=u.next;u.next=null,null===l?i=c:l.next=c,l=u;var d=e.alternate;if(null!==d){var f=(d=d.updateQueue).lastBaseUpdate;f!==l&&(null===f?d.firstBaseUpdate=c:f.next=c,d.lastBaseUpdate=u)}}if(null!==i){for(f=a.baseState,l=0,d=c=u=null;;){s=i.lane;var p=i.eventTime;if((r&s)===s){null!==d&&(d=d.next={eventTime:p,lane:0,tag:i.tag,payload:i.payload,callback:i.callback,next:null});e:{var h=e,m=i;switch(s=t,p=n,m.tag){case 1:if("function"==typeof(h=m.payload)){f=h.call(p,f,s);break e}f=h;break e;case 3:h.flags=-4097&h.flags|64;case 0:if(null==(s="function"==typeof(h=m.payload)?h.call(p,f,s):h))break e;f=o({},f,s);break e;case 2:sa=!0}}null!==i.callback&&(e.flags|=32,null===(s=a.effects)?a.effects=[i]:s.push(i))}else p={eventTime:p,lane:s,tag:i.tag,payload:i.payload,callback:i.callback,next:null},null===d?(c=d=p,u=f):d=d.next=p,l|=s;if(null===(i=i.next)){if(null===(s=a.shared.pending))break;i=s.next,s.next=null,a.lastBaseUpdate=s,a.shared.pending=null}}null===d&&(u=f),a.baseState=u,a.firstBaseUpdate=c,a.lastBaseUpdate=d,$l|=l,e.lanes=l,e.memoizedState=f}}function ma(e,t,n){if(e=t.effects,t.effects=null,null!==e)for(t=0;t<e.length;t++){var r=e[t],o=r.callback;if(null!==o){if(r.callback=null,r=n,"function"!=typeof o)throw Error(i(191,o));o.call(r)}}}var ga=(new r.Component).refs;function va(e,t,n,r){n=null==(n=n(r,t=e.memoizedState))?t:o({},t,n),e.memoizedState=n,0===e.lanes&&(e.updateQueue.baseState=n)}var ba={isMounted:function(e){return!!(e=e._reactInternals)&&Ye(e)===e},enqueueSetState:function(e,t,n){e=e._reactInternals;var r=fs(),o=ps(e),a=da(r,o);a.payload=t,null!=n&&(a.callback=n),fa(e,a),hs(e,o,r)},enqueueReplaceState:function(e,t,n){e=e._reactInternals;var r=fs(),o=ps(e),a=da(r,o);a.tag=1,a.payload=t,null!=n&&(a.callback=n),fa(e,a),hs(e,o,r)},enqueueForceUpdate:function(e,t){e=e._reactInternals;var n=fs(),r=ps(e),o=da(n,r);o.tag=2,null!=t&&(o.callback=t),fa(e,o),hs(e,r,n)}};function ya(e,t,n,r,o,a,i){return"function"==typeof(e=e.stateNode).shouldComponentUpdate?e.shouldComponentUpdate(r,a,i):!t.prototype||!t.prototype.isPureReactComponent||(!fr(n,r)||!fr(o,a))}function wa(e,t,n){var r=!1,o=po,a=t.contextType;return"object"==typeof a&&null!==a?a=la(a):(o=bo(t)?go:ho.current,a=(r=null!=(r=t.contextTypes))?vo(e,o):po),t=new t(n,a),e.memoizedState=null!==t.state&&void 0!==t.state?t.state:null,t.updater=ba,e.stateNode=t,t._reactInternals=e,r&&((e=e.stateNode).__reactInternalMemoizedUnmaskedChildContext=o,e.__reactInternalMemoizedMaskedChildContext=a),t}function xa(e,t,n,r){e=t.state,"function"==typeof t.componentWillReceiveProps&&t.componentWillReceiveProps(n,r),"function"==typeof t.UNSAFE_componentWillReceiveProps&&t.UNSAFE_componentWillReceiveProps(n,r),t.state!==e&&ba.enqueueReplaceState(t,t.state,null)}function _a(e,t,n,r){var o=e.stateNode;o.props=n,o.state=e.memoizedState,o.refs=ga,ua(e);var a=t.contextType;"object"==typeof a&&null!==a?o.context=la(a):(a=bo(t)?go:ho.current,o.context=vo(e,a)),ha(e,n,o,r),o.state=e.memoizedState,"function"==typeof(a=t.getDerivedStateFromProps)&&(va(e,t,a,n),o.state=e.memoizedState),"function"==typeof t.getDerivedStateFromProps||"function"==typeof o.getSnapshotBeforeUpdate||"function"!=typeof o.UNSAFE_componentWillMount&&"function"!=typeof o.componentWillMount||(t=o.state,"function"==typeof o.componentWillMount&&o.componentWillMount(),"function"==typeof o.UNSAFE_componentWillMount&&o.UNSAFE_componentWillMount(),t!==o.state&&ba.enqueueReplaceState(o,o.state,null),ha(e,n,o,r),o.state=e.memoizedState),"function"==typeof o.componentDidMount&&(e.flags|=4)}var ka=Array.isArray;function Ea(e,t,n){if(null!==(e=n.ref)&&"function"!=typeof e&&"object"!=typeof e){if(n._owner){if(n=n._owner){if(1!==n.tag)throw Error(i(309));var r=n.stateNode}if(!r)throw Error(i(147,e));var o=""+e;return null!==t&&null!==t.ref&&"function"==typeof t.ref&&t.ref._stringRef===o?t.ref:(t=function(e){var t=r.refs;t===ga&&(t=r.refs={}),null===e?delete t[o]:t[o]=e},t._stringRef=o,t)}if("string"!=typeof e)throw Error(i(284));if(!n._owner)throw Error(i(290,e))}return e}function Sa(e,t){if("textarea"!==e.type)throw Error(i(31,"[object Object]"===Object.prototype.toString.call(t)?"object with keys {"+Object.keys(t).join(", ")+"}":t))}function Ca(e){function t(t,n){if(e){var r=t.lastEffect;null!==r?(r.nextEffect=n,t.lastEffect=n):t.firstEffect=t.lastEffect=n,n.nextEffect=null,n.flags=8}}function n(n,r){if(!e)return null;for(;null!==r;)t(n,r),r=r.sibling;return null}function r(e,t){for(e=new Map;null!==t;)null!==t.key?e.set(t.key,t):e.set(t.index,t),t=t.sibling;return e}function o(e,t){return(e=Gs(e,t)).index=0,e.sibling=null,e}function a(t,n,r){return t.index=r,e?null!==(r=t.alternate)?(r=r.index)<n?(t.flags=2,n):r:(t.flags=2,n):n}function l(t){return e&&null===t.alternate&&(t.flags=2),t}function s(e,t,n,r){return null===t||6!==t.tag?((t=Ys(n,e.mode,r)).return=e,t):((t=o(t,n)).return=e,t)}function u(e,t,n,r){return null!==t&&t.elementType===n.type?((r=o(t,n.props)).ref=Ea(e,t,n),r.return=e,r):((r=Ws(n.type,n.key,n.props,null,e.mode,r)).ref=Ea(e,t,n),r.return=e,r)}function c(e,t,n,r){return null===t||4!==t.tag||t.stateNode.containerInfo!==n.containerInfo||t.stateNode.implementation!==n.implementation?((t=Xs(n,e.mode,r)).return=e,t):((t=o(t,n.children||[])).return=e,t)}function d(e,t,n,r,a){return null===t||7!==t.tag?((t=Zs(n,e.mode,r,a)).return=e,t):((t=o(t,n)).return=e,t)}function f(e,t,n){if("string"==typeof t||"number"==typeof t)return(t=Ys(""+t,e.mode,n)).return=e,t;if("object"==typeof t&&null!==t){switch(t.$$typeof){case _:return(n=Ws(t.type,t.key,t.props,null,e.mode,n)).ref=Ea(e,null,t),n.return=e,n;case k:return(t=Xs(t,e.mode,n)).return=e,t}if(ka(t)||U(t))return(t=Zs(t,e.mode,n,null)).return=e,t;Sa(e,t)}return null}function p(e,t,n,r){var o=null!==t?t.key:null;if("string"==typeof n||"number"==typeof n)return null!==o?null:s(e,t,""+n,r);if("object"==typeof n&&null!==n){switch(n.$$typeof){case _:return n.key===o?n.type===E?d(e,t,n.props.children,r,o):u(e,t,n,r):null;case k:return n.key===o?c(e,t,n,r):null}if(ka(n)||U(n))return null!==o?null:d(e,t,n,r,null);Sa(e,n)}return null}function h(e,t,n,r,o){if("string"==typeof r||"number"==typeof r)return s(t,e=e.get(n)||null,""+r,o);if("object"==typeof r&&null!==r){switch(r.$$typeof){case _:return e=e.get(null===r.key?n:r.key)||null,r.type===E?d(t,e,r.props.children,o,r.key):u(t,e,r,o);case k:return c(t,e=e.get(null===r.key?n:r.key)||null,r,o)}if(ka(r)||U(r))return d(t,e=e.get(n)||null,r,o,null);Sa(t,r)}return null}function m(o,i,l,s){for(var u=null,c=null,d=i,m=i=0,g=null;null!==d&&m<l.length;m++){d.index>m?(g=d,d=null):g=d.sibling;var v=p(o,d,l[m],s);if(null===v){null===d&&(d=g);break}e&&d&&null===v.alternate&&t(o,d),i=a(v,i,m),null===c?u=v:c.sibling=v,c=v,d=g}if(m===l.length)return n(o,d),u;if(null===d){for(;m<l.length;m++)null!==(d=f(o,l[m],s))&&(i=a(d,i,m),null===c?u=d:c.sibling=d,c=d);return u}for(d=r(o,d);m<l.length;m++)null!==(g=h(d,o,m,l[m],s))&&(e&&null!==g.alternate&&d.delete(null===g.key?m:g.key),i=a(g,i,m),null===c?u=g:c.sibling=g,c=g);return e&&d.forEach((function(e){return t(o,e)})),u}function g(o,l,s,u){var c=U(s);if("function"!=typeof c)throw Error(i(150));if(null==(s=c.call(s)))throw Error(i(151));for(var d=c=null,m=l,g=l=0,v=null,b=s.next();null!==m&&!b.done;g++,b=s.next()){m.index>g?(v=m,m=null):v=m.sibling;var y=p(o,m,b.value,u);if(null===y){null===m&&(m=v);break}e&&m&&null===y.alternate&&t(o,m),l=a(y,l,g),null===d?c=y:d.sibling=y,d=y,m=v}if(b.done)return n(o,m),c;if(null===m){for(;!b.done;g++,b=s.next())null!==(b=f(o,b.value,u))&&(l=a(b,l,g),null===d?c=b:d.sibling=b,d=b);return c}for(m=r(o,m);!b.done;g++,b=s.next())null!==(b=h(m,o,g,b.value,u))&&(e&&null!==b.alternate&&m.delete(null===b.key?g:b.key),l=a(b,l,g),null===d?c=b:d.sibling=b,d=b);return e&&m.forEach((function(e){return t(o,e)})),c}return function(e,r,a,s){var u="object"==typeof a&&null!==a&&a.type===E&&null===a.key;u&&(a=a.props.children);var c="object"==typeof a&&null!==a;if(c)switch(a.$$typeof){case _:e:{for(c=a.key,u=r;null!==u;){if(u.key===c){if(7===u.tag){if(a.type===E){n(e,u.sibling),(r=o(u,a.props.children)).return=e,e=r;break e}}else if(u.elementType===a.type){n(e,u.sibling),(r=o(u,a.props)).ref=Ea(e,u,a),r.return=e,e=r;break e}n(e,u);break}t(e,u),u=u.sibling}a.type===E?((r=Zs(a.props.children,e.mode,s,a.key)).return=e,e=r):((s=Ws(a.type,a.key,a.props,null,e.mode,s)).ref=Ea(e,r,a),s.return=e,e=s)}return l(e);case k:e:{for(u=a.key;null!==r;){if(r.key===u){if(4===r.tag&&r.stateNode.containerInfo===a.containerInfo&&r.stateNode.implementation===a.implementation){n(e,r.sibling),(r=o(r,a.children||[])).return=e,e=r;break e}n(e,r);break}t(e,r),r=r.sibling}(r=Xs(a,e.mode,s)).return=e,e=r}return l(e)}if("string"==typeof a||"number"==typeof a)return a=""+a,null!==r&&6===r.tag?(n(e,r.sibling),(r=o(r,a)).return=e,e=r):(n(e,r),(r=Ys(a,e.mode,s)).return=e,e=r),l(e);if(ka(a))return m(e,r,a,s);if(U(a))return g(e,r,a,s);if(c&&Sa(e,a),void 0===a&&!u)switch(e.tag){case 1:case 22:case 0:case 11:case 15:throw Error(i(152,W(e.type)||"Component"))}return n(e,r)}}var Ta=Ca(!0),Oa=Ca(!1),Da={},Pa=uo(Da),Na=uo(Da),Aa=uo(Da);function Ia(e){if(e===Da)throw Error(i(174));return e}function La(e,t){switch(fo(Aa,t),fo(Na,e),fo(Pa,Da),e=t.nodeType){case 9:case 11:t=(t=t.documentElement)?t.namespaceURI:he(null,"");break;default:t=he(t=(e=8===e?t.parentNode:t).namespaceURI||null,e=e.tagName)}co(Pa),fo(Pa,t)}function Ra(){co(Pa),co(Na),co(Aa)}function ja(e){Ia(Aa.current);var t=Ia(Pa.current),n=he(t,e.type);t!==n&&(fo(Na,e),fo(Pa,n))}function Ma(e){Na.current===e&&(co(Pa),co(Na))}var Fa=uo(0);function Ba(e){for(var t=e;null!==t;){if(13===t.tag){var n=t.memoizedState;if(null!==n&&(null===(n=n.dehydrated)||"$?"===n.data||"$!"===n.data))return t}else if(19===t.tag&&void 0!==t.memoizedProps.revealOrder){if(0!=(64&t.flags))return t}else if(null!==t.child){t.child.return=t,t=t.child;continue}if(t===e)break;for(;null===t.sibling;){if(null===t.return||t.return===e)return null;t=t.return}t.sibling.return=t.return,t=t.sibling}return null}var za=null,$a=null,Ua=!1;function Ha(e,t){var n=Vs(5,null,null,0);n.elementType="DELETED",n.type="DELETED",n.stateNode=t,n.return=e,n.flags=8,null!==e.lastEffect?(e.lastEffect.nextEffect=n,e.lastEffect=n):e.firstEffect=e.lastEffect=n}function Va(e,t){switch(e.tag){case 5:var n=e.type;return null!==(t=1!==t.nodeType||n.toLowerCase()!==t.nodeName.toLowerCase()?null:t)&&(e.stateNode=t,!0);case 6:return null!==(t=""===e.pendingProps||3!==t.nodeType?null:t)&&(e.stateNode=t,!0);default:return!1}}function qa(e){if(Ua){var t=$a;if(t){var n=t;if(!Va(e,t)){if(!(t=Zr(n.nextSibling))||!Va(e,t))return e.flags=-1025&e.flags|2,Ua=!1,void(za=e);Ha(za,n)}za=e,$a=Zr(t.firstChild)}else e.flags=-1025&e.flags|2,Ua=!1,za=e}}function Ga(e){for(e=e.return;null!==e&&5!==e.tag&&3!==e.tag&&13!==e.tag;)e=e.return;za=e}function Wa(e){if(e!==za)return!1;if(!Ua)return Ga(e),Ua=!0,!1;var t=e.type;if(5!==e.tag||"head"!==t&&"body"!==t&&!Vr(t,e.memoizedProps))for(t=$a;t;)Ha(e,t),t=Zr(t.nextSibling);if(Ga(e),13===e.tag){if(!(e=null!==(e=e.memoizedState)?e.dehydrated:null))throw Error(i(317));e:{for(e=e.nextSibling,t=0;e;){if(8===e.nodeType){var n=e.data;if("/$"===n){if(0===t){$a=Zr(e.nextSibling);break e}t--}else"$"!==n&&"$!"!==n&&"$?"!==n||t++}e=e.nextSibling}$a=null}}else $a=za?Zr(e.stateNode.nextSibling):null;return!0}function Za(){$a=za=null,Ua=!1}var Qa=[];function Ya(){for(var e=0;e<Qa.length;e++)Qa[e]._workInProgressVersionPrimary=null;Qa.length=0}var Xa=x.ReactCurrentDispatcher,Ka=x.ReactCurrentBatchConfig,Ja=0,ei=null,ti=null,ni=null,ri=!1,oi=!1;function ai(){throw Error(i(321))}function ii(e,t){if(null===t)return!1;for(var n=0;n<t.length&&n<e.length;n++)if(!cr(e[n],t[n]))return!1;return!0}function li(e,t,n,r,o,a){if(Ja=a,ei=t,t.memoizedState=null,t.updateQueue=null,t.lanes=0,Xa.current=null===e||null===e.memoizedState?Ii:Li,e=n(r,o),oi){a=0;do{if(oi=!1,!(25>a))throw Error(i(301));a+=1,ni=ti=null,t.updateQueue=null,Xa.current=Ri,e=n(r,o)}while(oi)}if(Xa.current=Ai,t=null!==ti&&null!==ti.next,Ja=0,ni=ti=ei=null,ri=!1,t)throw Error(i(300));return e}function si(){var e={memoizedState:null,baseState:null,baseQueue:null,queue:null,next:null};return null===ni?ei.memoizedState=ni=e:ni=ni.next=e,ni}function ui(){if(null===ti){var e=ei.alternate;e=null!==e?e.memoizedState:null}else e=ti.next;var t=null===ni?ei.memoizedState:ni.next;if(null!==t)ni=t,ti=e;else{if(null===e)throw Error(i(310));e={memoizedState:(ti=e).memoizedState,baseState:ti.baseState,baseQueue:ti.baseQueue,queue:ti.queue,next:null},null===ni?ei.memoizedState=ni=e:ni=ni.next=e}return ni}function ci(e,t){return"function"==typeof t?t(e):t}function di(e){var t=ui(),n=t.queue;if(null===n)throw Error(i(311));n.lastRenderedReducer=e;var r=ti,o=r.baseQueue,a=n.pending;if(null!==a){if(null!==o){var l=o.next;o.next=a.next,a.next=l}r.baseQueue=o=a,n.pending=null}if(null!==o){o=o.next,r=r.baseState;var s=l=a=null,u=o;do{var c=u.lane;if((Ja&c)===c)null!==s&&(s=s.next={lane:0,action:u.action,eagerReducer:u.eagerReducer,eagerState:u.eagerState,next:null}),r=u.eagerReducer===e?u.eagerState:e(r,u.action);else{var d={lane:c,action:u.action,eagerReducer:u.eagerReducer,eagerState:u.eagerState,next:null};null===s?(l=s=d,a=r):s=s.next=d,ei.lanes|=c,$l|=c}u=u.next}while(null!==u&&u!==o);null===s?a=r:s.next=l,cr(r,t.memoizedState)||(Mi=!0),t.memoizedState=r,t.baseState=a,t.baseQueue=s,n.lastRenderedState=r}return[t.memoizedState,n.dispatch]}function fi(e){var t=ui(),n=t.queue;if(null===n)throw Error(i(311));n.lastRenderedReducer=e;var r=n.dispatch,o=n.pending,a=t.memoizedState;if(null!==o){n.pending=null;var l=o=o.next;do{a=e(a,l.action),l=l.next}while(l!==o);cr(a,t.memoizedState)||(Mi=!0),t.memoizedState=a,null===t.baseQueue&&(t.baseState=a),n.lastRenderedState=a}return[a,r]}function pi(e,t,n){var r=t._getVersion;r=r(t._source);var o=t._workInProgressVersionPrimary;if(null!==o?e=o===r:(e=e.mutableReadLanes,(e=(Ja&e)===e)&&(t._workInProgressVersionPrimary=r,Qa.push(t))),e)return n(t._source);throw Qa.push(t),Error(i(350))}function hi(e,t,n,r){var o=Il;if(null===o)throw Error(i(349));var a=t._getVersion,l=a(t._source),s=Xa.current,u=s.useState((function(){return pi(o,t,n)})),c=u[1],d=u[0];u=ni;var f=e.memoizedState,p=f.refs,h=p.getSnapshot,m=f.source;f=f.subscribe;var g=ei;return e.memoizedState={refs:p,source:t,subscribe:r},s.useEffect((function(){p.getSnapshot=n,p.setSnapshot=c;var e=a(t._source);if(!cr(l,e)){e=n(t._source),cr(d,e)||(c(e),e=ps(g),o.mutableReadLanes|=e&o.pendingLanes),e=o.mutableReadLanes,o.entangledLanes|=e;for(var r=o.entanglements,i=e;0<i;){var s=31-Vt(i),u=1<<s;r[s]|=e,i&=~u}}}),[n,t,r]),s.useEffect((function(){return r(t._source,(function(){var e=p.getSnapshot,n=p.setSnapshot;try{n(e(t._source));var r=ps(g);o.mutableReadLanes|=r&o.pendingLanes}catch(a){n((function(){throw a}))}}))}),[t,r]),cr(h,n)&&cr(m,t)&&cr(f,r)||((e={pending:null,dispatch:null,lastRenderedReducer:ci,lastRenderedState:d}).dispatch=c=Ni.bind(null,ei,e),u.queue=e,u.baseQueue=null,d=pi(o,t,n),u.memoizedState=u.baseState=d),d}function mi(e,t,n){return hi(ui(),e,t,n)}function gi(e){var t=si();return"function"==typeof e&&(e=e()),t.memoizedState=t.baseState=e,e=(e=t.queue={pending:null,dispatch:null,lastRenderedReducer:ci,lastRenderedState:e}).dispatch=Ni.bind(null,ei,e),[t.memoizedState,e]}function vi(e,t,n,r){return e={tag:e,create:t,destroy:n,deps:r,next:null},null===(t=ei.updateQueue)?(t={lastEffect:null},ei.updateQueue=t,t.lastEffect=e.next=e):null===(n=t.lastEffect)?t.lastEffect=e.next=e:(r=n.next,n.next=e,e.next=r,t.lastEffect=e),e}function bi(e){return e={current:e},si().memoizedState=e}function yi(){return ui().memoizedState}function wi(e,t,n,r){var o=si();ei.flags|=e,o.memoizedState=vi(1|t,n,void 0,void 0===r?null:r)}function xi(e,t,n,r){var o=ui();r=void 0===r?null:r;var a=void 0;if(null!==ti){var i=ti.memoizedState;if(a=i.destroy,null!==r&&ii(r,i.deps))return void vi(t,n,a,r)}ei.flags|=e,o.memoizedState=vi(1|t,n,a,r)}function _i(e,t){return wi(516,4,e,t)}function ki(e,t){return xi(516,4,e,t)}function Ei(e,t){return xi(4,2,e,t)}function Si(e,t){return"function"==typeof t?(e=e(),t(e),function(){t(null)}):null!=t?(e=e(),t.current=e,function(){t.current=null}):void 0}function Ci(e,t,n){return n=null!=n?n.concat([e]):null,xi(4,2,Si.bind(null,t,e),n)}function Ti(){}function Oi(e,t){var n=ui();t=void 0===t?null:t;var r=n.memoizedState;return null!==r&&null!==t&&ii(t,r[1])?r[0]:(n.memoizedState=[e,t],e)}function Di(e,t){var n=ui();t=void 0===t?null:t;var r=n.memoizedState;return null!==r&&null!==t&&ii(t,r[1])?r[0]:(e=e(),n.memoizedState=[e,t],e)}function Pi(e,t){var n=qo();Wo(98>n?98:n,(function(){e(!0)})),Wo(97<n?97:n,(function(){var n=Ka.transition;Ka.transition=1;try{e(!1),t()}finally{Ka.transition=n}}))}function Ni(e,t,n){var r=fs(),o=ps(e),a={lane:o,action:n,eagerReducer:null,eagerState:null,next:null},i=t.pending;if(null===i?a.next=a:(a.next=i.next,i.next=a),t.pending=a,i=e.alternate,e===ei||null!==i&&i===ei)oi=ri=!0;else{if(0===e.lanes&&(null===i||0===i.lanes)&&null!==(i=t.lastRenderedReducer))try{var l=t.lastRenderedState,s=i(l,n);if(a.eagerReducer=i,a.eagerState=s,cr(s,l))return}catch(u){}hs(e,o,r)}}var Ai={readContext:la,useCallback:ai,useContext:ai,useEffect:ai,useImperativeHandle:ai,useLayoutEffect:ai,useMemo:ai,useReducer:ai,useRef:ai,useState:ai,useDebugValue:ai,useDeferredValue:ai,useTransition:ai,useMutableSource:ai,useOpaqueIdentifier:ai,unstable_isNewReconciler:!1},Ii={readContext:la,useCallback:function(e,t){return si().memoizedState=[e,void 0===t?null:t],e},useContext:la,useEffect:_i,useImperativeHandle:function(e,t,n){return n=null!=n?n.concat([e]):null,wi(4,2,Si.bind(null,t,e),n)},useLayoutEffect:function(e,t){return wi(4,2,e,t)},useMemo:function(e,t){var n=si();return t=void 0===t?null:t,e=e(),n.memoizedState=[e,t],e},useReducer:function(e,t,n){var r=si();return t=void 0!==n?n(t):t,r.memoizedState=r.baseState=t,e=(e=r.queue={pending:null,dispatch:null,lastRenderedReducer:e,lastRenderedState:t}).dispatch=Ni.bind(null,ei,e),[r.memoizedState,e]},useRef:bi,useState:gi,useDebugValue:Ti,useDeferredValue:function(e){var t=gi(e),n=t[0],r=t[1];return _i((function(){var t=Ka.transition;Ka.transition=1;try{r(e)}finally{Ka.transition=t}}),[e]),n},useTransition:function(){var e=gi(!1),t=e[0];return bi(e=Pi.bind(null,e[1])),[e,t]},useMutableSource:function(e,t,n){var r=si();return r.memoizedState={refs:{getSnapshot:t,setSnapshot:null},source:e,subscribe:n},hi(r,e,t,n)},useOpaqueIdentifier:function(){if(Ua){var e=!1,t=function(e){return{$$typeof:R,toString:e,valueOf:e}}((function(){throw e||(e=!0,n("r:"+(Yr++).toString(36))),Error(i(355))})),n=gi(t)[1];return 0==(2&ei.mode)&&(ei.flags|=516,vi(5,(function(){n("r:"+(Yr++).toString(36))}),void 0,null)),t}return gi(t="r:"+(Yr++).toString(36)),t},unstable_isNewReconciler:!1},Li={readContext:la,useCallback:Oi,useContext:la,useEffect:ki,useImperativeHandle:Ci,useLayoutEffect:Ei,useMemo:Di,useReducer:di,useRef:yi,useState:function(){return di(ci)},useDebugValue:Ti,useDeferredValue:function(e){var t=di(ci),n=t[0],r=t[1];return ki((function(){var t=Ka.transition;Ka.transition=1;try{r(e)}finally{Ka.transition=t}}),[e]),n},useTransition:function(){var e=di(ci)[0];return[yi().current,e]},useMutableSource:mi,useOpaqueIdentifier:function(){return di(ci)[0]},unstable_isNewReconciler:!1},Ri={readContext:la,useCallback:Oi,useContext:la,useEffect:ki,useImperativeHandle:Ci,useLayoutEffect:Ei,useMemo:Di,useReducer:fi,useRef:yi,useState:function(){return fi(ci)},useDebugValue:Ti,useDeferredValue:function(e){var t=fi(ci),n=t[0],r=t[1];return ki((function(){var t=Ka.transition;Ka.transition=1;try{r(e)}finally{Ka.transition=t}}),[e]),n},useTransition:function(){var e=fi(ci)[0];return[yi().current,e]},useMutableSource:mi,useOpaqueIdentifier:function(){return fi(ci)[0]},unstable_isNewReconciler:!1},ji=x.ReactCurrentOwner,Mi=!1;function Fi(e,t,n,r){t.child=null===e?Oa(t,null,n,r):Ta(t,e.child,n,r)}function Bi(e,t,n,r,o){n=n.render;var a=t.ref;return ia(t,o),r=li(e,t,n,r,a,o),null===e||Mi?(t.flags|=1,Fi(e,t,r,o),t.child):(t.updateQueue=e.updateQueue,t.flags&=-517,e.lanes&=~o,al(e,t,o))}function zi(e,t,n,r,o,a){if(null===e){var i=n.type;return"function"!=typeof i||qs(i)||void 0!==i.defaultProps||null!==n.compare||void 0!==n.defaultProps?((e=Ws(n.type,null,r,t,t.mode,a)).ref=t.ref,e.return=t,t.child=e):(t.tag=15,t.type=i,$i(e,t,i,r,o,a))}return i=e.child,0==(o&a)&&(o=i.memoizedProps,(n=null!==(n=n.compare)?n:fr)(o,r)&&e.ref===t.ref)?al(e,t,a):(t.flags|=1,(e=Gs(i,r)).ref=t.ref,e.return=t,t.child=e)}function $i(e,t,n,r,o,a){if(null!==e&&fr(e.memoizedProps,r)&&e.ref===t.ref){if(Mi=!1,0==(a&o))return t.lanes=e.lanes,al(e,t,a);0!=(16384&e.flags)&&(Mi=!0)}return Vi(e,t,n,r,a)}function Ui(e,t,n){var r=t.pendingProps,o=r.children,a=null!==e?e.memoizedState:null;if("hidden"===r.mode||"unstable-defer-without-hiding"===r.mode)if(0==(4&t.mode))t.memoizedState={baseLanes:0},_s(t,n);else{if(0==(1073741824&n))return e=null!==a?a.baseLanes|n:n,t.lanes=t.childLanes=1073741824,t.memoizedState={baseLanes:e},_s(t,e),null;t.memoizedState={baseLanes:0},_s(t,null!==a?a.baseLanes:n)}else null!==a?(r=a.baseLanes|n,t.memoizedState=null):r=n,_s(t,r);return Fi(e,t,o,n),t.child}function Hi(e,t){var n=t.ref;(null===e&&null!==n||null!==e&&e.ref!==n)&&(t.flags|=128)}function Vi(e,t,n,r,o){var a=bo(n)?go:ho.current;return a=vo(t,a),ia(t,o),n=li(e,t,n,r,a,o),null===e||Mi?(t.flags|=1,Fi(e,t,n,o),t.child):(t.updateQueue=e.updateQueue,t.flags&=-517,e.lanes&=~o,al(e,t,o))}function qi(e,t,n,r,o){if(bo(n)){var a=!0;_o(t)}else a=!1;if(ia(t,o),null===t.stateNode)null!==e&&(e.alternate=null,t.alternate=null,t.flags|=2),wa(t,n,r),_a(t,n,r,o),r=!0;else if(null===e){var i=t.stateNode,l=t.memoizedProps;i.props=l;var s=i.context,u=n.contextType;"object"==typeof u&&null!==u?u=la(u):u=vo(t,u=bo(n)?go:ho.current);var c=n.getDerivedStateFromProps,d="function"==typeof c||"function"==typeof i.getSnapshotBeforeUpdate;d||"function"!=typeof i.UNSAFE_componentWillReceiveProps&&"function"!=typeof i.componentWillReceiveProps||(l!==r||s!==u)&&xa(t,i,r,u),sa=!1;var f=t.memoizedState;i.state=f,ha(t,r,i,o),s=t.memoizedState,l!==r||f!==s||mo.current||sa?("function"==typeof c&&(va(t,n,c,r),s=t.memoizedState),(l=sa||ya(t,n,l,r,f,s,u))?(d||"function"!=typeof i.UNSAFE_componentWillMount&&"function"!=typeof i.componentWillMount||("function"==typeof i.componentWillMount&&i.componentWillMount(),"function"==typeof i.UNSAFE_componentWillMount&&i.UNSAFE_componentWillMount()),"function"==typeof i.componentDidMount&&(t.flags|=4)):("function"==typeof i.componentDidMount&&(t.flags|=4),t.memoizedProps=r,t.memoizedState=s),i.props=r,i.state=s,i.context=u,r=l):("function"==typeof i.componentDidMount&&(t.flags|=4),r=!1)}else{i=t.stateNode,ca(e,t),l=t.memoizedProps,u=t.type===t.elementType?l:Ko(t.type,l),i.props=u,d=t.pendingProps,f=i.context,"object"==typeof(s=n.contextType)&&null!==s?s=la(s):s=vo(t,s=bo(n)?go:ho.current);var p=n.getDerivedStateFromProps;(c="function"==typeof p||"function"==typeof i.getSnapshotBeforeUpdate)||"function"!=typeof i.UNSAFE_componentWillReceiveProps&&"function"!=typeof i.componentWillReceiveProps||(l!==d||f!==s)&&xa(t,i,r,s),sa=!1,f=t.memoizedState,i.state=f,ha(t,r,i,o);var h=t.memoizedState;l!==d||f!==h||mo.current||sa?("function"==typeof p&&(va(t,n,p,r),h=t.memoizedState),(u=sa||ya(t,n,u,r,f,h,s))?(c||"function"!=typeof i.UNSAFE_componentWillUpdate&&"function"!=typeof i.componentWillUpdate||("function"==typeof i.componentWillUpdate&&i.componentWillUpdate(r,h,s),"function"==typeof i.UNSAFE_componentWillUpdate&&i.UNSAFE_componentWillUpdate(r,h,s)),"function"==typeof i.componentDidUpdate&&(t.flags|=4),"function"==typeof i.getSnapshotBeforeUpdate&&(t.flags|=256)):("function"!=typeof i.componentDidUpdate||l===e.memoizedProps&&f===e.memoizedState||(t.flags|=4),"function"!=typeof i.getSnapshotBeforeUpdate||l===e.memoizedProps&&f===e.memoizedState||(t.flags|=256),t.memoizedProps=r,t.memoizedState=h),i.props=r,i.state=h,i.context=s,r=u):("function"!=typeof i.componentDidUpdate||l===e.memoizedProps&&f===e.memoizedState||(t.flags|=4),"function"!=typeof i.getSnapshotBeforeUpdate||l===e.memoizedProps&&f===e.memoizedState||(t.flags|=256),r=!1)}return Gi(e,t,n,r,a,o)}function Gi(e,t,n,r,o,a){Hi(e,t);var i=0!=(64&t.flags);if(!r&&!i)return o&&ko(t,n,!1),al(e,t,a);r=t.stateNode,ji.current=t;var l=i&&"function"!=typeof n.getDerivedStateFromError?null:r.render();return t.flags|=1,null!==e&&i?(t.child=Ta(t,e.child,null,a),t.child=Ta(t,null,l,a)):Fi(e,t,l,a),t.memoizedState=r.state,o&&ko(t,n,!0),t.child}function Wi(e){var t=e.stateNode;t.pendingContext?wo(0,t.pendingContext,t.pendingContext!==t.context):t.context&&wo(0,t.context,!1),La(e,t.containerInfo)}var Zi,Qi,Yi,Xi={dehydrated:null,retryLane:0};function Ki(e,t,n){var r,o=t.pendingProps,a=Fa.current,i=!1;return(r=0!=(64&t.flags))||(r=(null===e||null!==e.memoizedState)&&0!=(2&a)),r?(i=!0,t.flags&=-65):null!==e&&null===e.memoizedState||void 0===o.fallback||!0===o.unstable_avoidThisFallback||(a|=1),fo(Fa,1&a),null===e?(void 0!==o.fallback&&qa(t),e=o.children,a=o.fallback,i?(e=Ji(t,e,a,n),t.child.memoizedState={baseLanes:n},t.memoizedState=Xi,e):"number"==typeof o.unstable_expectedLoadTime?(e=Ji(t,e,a,n),t.child.memoizedState={baseLanes:n},t.memoizedState=Xi,t.lanes=33554432,e):((n=Qs({mode:"visible",children:e},t.mode,n,null)).return=t,t.child=n)):(e.memoizedState,i?(o=tl(e,t,o.children,o.fallback,n),i=t.child,a=e.child.memoizedState,i.memoizedState=null===a?{baseLanes:n}:{baseLanes:a.baseLanes|n},i.childLanes=e.childLanes&~n,t.memoizedState=Xi,o):(n=el(e,t,o.children,n),t.memoizedState=null,n))}function Ji(e,t,n,r){var o=e.mode,a=e.child;return t={mode:"hidden",children:t},0==(2&o)&&null!==a?(a.childLanes=0,a.pendingProps=t):a=Qs(t,o,0,null),n=Zs(n,o,r,null),a.return=e,n.return=e,a.sibling=n,e.child=a,n}function el(e,t,n,r){var o=e.child;return e=o.sibling,n=Gs(o,{mode:"visible",children:n}),0==(2&t.mode)&&(n.lanes=r),n.return=t,n.sibling=null,null!==e&&(e.nextEffect=null,e.flags=8,t.firstEffect=t.lastEffect=e),t.child=n}function tl(e,t,n,r,o){var a=t.mode,i=e.child;e=i.sibling;var l={mode:"hidden",children:n};return 0==(2&a)&&t.child!==i?((n=t.child).childLanes=0,n.pendingProps=l,null!==(i=n.lastEffect)?(t.firstEffect=n.firstEffect,t.lastEffect=i,i.nextEffect=null):t.firstEffect=t.lastEffect=null):n=Gs(i,l),null!==e?r=Gs(e,r):(r=Zs(r,a,o,null)).flags|=2,r.return=t,n.return=t,n.sibling=r,t.child=n,r}function nl(e,t){e.lanes|=t;var n=e.alternate;null!==n&&(n.lanes|=t),aa(e.return,t)}function rl(e,t,n,r,o,a){var i=e.memoizedState;null===i?e.memoizedState={isBackwards:t,rendering:null,renderingStartTime:0,last:r,tail:n,tailMode:o,lastEffect:a}:(i.isBackwards=t,i.rendering=null,i.renderingStartTime=0,i.last=r,i.tail=n,i.tailMode=o,i.lastEffect=a)}function ol(e,t,n){var r=t.pendingProps,o=r.revealOrder,a=r.tail;if(Fi(e,t,r.children,n),0!=(2&(r=Fa.current)))r=1&r|2,t.flags|=64;else{if(null!==e&&0!=(64&e.flags))e:for(e=t.child;null!==e;){if(13===e.tag)null!==e.memoizedState&&nl(e,n);else if(19===e.tag)nl(e,n);else if(null!==e.child){e.child.return=e,e=e.child;continue}if(e===t)break e;for(;null===e.sibling;){if(null===e.return||e.return===t)break e;e=e.return}e.sibling.return=e.return,e=e.sibling}r&=1}if(fo(Fa,r),0==(2&t.mode))t.memoizedState=null;else switch(o){case"forwards":for(n=t.child,o=null;null!==n;)null!==(e=n.alternate)&&null===Ba(e)&&(o=n),n=n.sibling;null===(n=o)?(o=t.child,t.child=null):(o=n.sibling,n.sibling=null),rl(t,!1,o,n,a,t.lastEffect);break;case"backwards":for(n=null,o=t.child,t.child=null;null!==o;){if(null!==(e=o.alternate)&&null===Ba(e)){t.child=o;break}e=o.sibling,o.sibling=n,n=o,o=e}rl(t,!0,n,null,a,t.lastEffect);break;case"together":rl(t,!1,null,null,void 0,t.lastEffect);break;default:t.memoizedState=null}return t.child}function al(e,t,n){if(null!==e&&(t.dependencies=e.dependencies),$l|=t.lanes,0!=(n&t.childLanes)){if(null!==e&&t.child!==e.child)throw Error(i(153));if(null!==t.child){for(n=Gs(e=t.child,e.pendingProps),t.child=n,n.return=t;null!==e.sibling;)e=e.sibling,(n=n.sibling=Gs(e,e.pendingProps)).return=t;n.sibling=null}return t.child}return null}function il(e,t){if(!Ua)switch(e.tailMode){case"hidden":t=e.tail;for(var n=null;null!==t;)null!==t.alternate&&(n=t),t=t.sibling;null===n?e.tail=null:n.sibling=null;break;case"collapsed":n=e.tail;for(var r=null;null!==n;)null!==n.alternate&&(r=n),n=n.sibling;null===r?t||null===e.tail?e.tail=null:e.tail.sibling=null:r.sibling=null}}function ll(e,t,n){var r=t.pendingProps;switch(t.tag){case 2:case 16:case 15:case 0:case 11:case 7:case 8:case 12:case 9:case 14:return null;case 1:case 17:return bo(t.type)&&yo(),null;case 3:return Ra(),co(mo),co(ho),Ya(),(r=t.stateNode).pendingContext&&(r.context=r.pendingContext,r.pendingContext=null),null!==e&&null!==e.child||(Wa(t)?t.flags|=4:r.hydrate||(t.flags|=256)),null;case 5:Ma(t);var a=Ia(Aa.current);if(n=t.type,null!==e&&null!=t.stateNode)Qi(e,t,n,r),e.ref!==t.ref&&(t.flags|=128);else{if(!r){if(null===t.stateNode)throw Error(i(166));return null}if(e=Ia(Pa.current),Wa(t)){r=t.stateNode,n=t.type;var l=t.memoizedProps;switch(r[Kr]=t,r[Jr]=l,n){case"dialog":Pr("cancel",r),Pr("close",r);break;case"iframe":case"object":case"embed":Pr("load",r);break;case"video":case"audio":for(e=0;e<Cr.length;e++)Pr(Cr[e],r);break;case"source":Pr("error",r);break;case"img":case"image":case"link":Pr("error",r),Pr("load",r);break;case"details":Pr("toggle",r);break;case"input":ee(r,l),Pr("invalid",r);break;case"select":r._wrapperState={wasMultiple:!!l.multiple},Pr("invalid",r);break;case"textarea":se(r,l),Pr("invalid",r)}for(var u in Ee(n,l),e=null,l)l.hasOwnProperty(u)&&(a=l[u],"children"===u?"string"==typeof a?r.textContent!==a&&(e=["children",a]):"number"==typeof a&&r.textContent!==""+a&&(e=["children",""+a]):s.hasOwnProperty(u)&&null!=a&&"onScroll"===u&&Pr("scroll",r));switch(n){case"input":Y(r),re(r,l,!0);break;case"textarea":Y(r),ce(r);break;case"select":case"option":break;default:"function"==typeof l.onClick&&(r.onclick=zr)}r=e,t.updateQueue=r,null!==r&&(t.flags|=4)}else{switch(u=9===a.nodeType?a:a.ownerDocument,e===de&&(e=pe(n)),e===de?"script"===n?((e=u.createElement("div")).innerHTML="<script><\/script>",e=e.removeChild(e.firstChild)):"string"==typeof r.is?e=u.createElement(n,{is:r.is}):(e=u.createElement(n),"select"===n&&(u=e,r.multiple?u.multiple=!0:r.size&&(u.size=r.size))):e=u.createElementNS(e,n),e[Kr]=t,e[Jr]=r,Zi(e,t),t.stateNode=e,u=Se(n,r),n){case"dialog":Pr("cancel",e),Pr("close",e),a=r;break;case"iframe":case"object":case"embed":Pr("load",e),a=r;break;case"video":case"audio":for(a=0;a<Cr.length;a++)Pr(Cr[a],e);a=r;break;case"source":Pr("error",e),a=r;break;case"img":case"image":case"link":Pr("error",e),Pr("load",e),a=r;break;case"details":Pr("toggle",e),a=r;break;case"input":ee(e,r),a=J(e,r),Pr("invalid",e);break;case"option":a=ae(e,r);break;case"select":e._wrapperState={wasMultiple:!!r.multiple},a=o({},r,{value:void 0}),Pr("invalid",e);break;case"textarea":se(e,r),a=le(e,r),Pr("invalid",e);break;default:a=r}Ee(n,a);var c=a;for(l in c)if(c.hasOwnProperty(l)){var d=c[l];"style"===l?_e(e,d):"dangerouslySetInnerHTML"===l?null!=(d=d?d.__html:void 0)&&ve(e,d):"children"===l?"string"==typeof d?("textarea"!==n||""!==d)&&be(e,d):"number"==typeof d&&be(e,""+d):"suppressContentEditableWarning"!==l&&"suppressHydrationWarning"!==l&&"autoFocus"!==l&&(s.hasOwnProperty(l)?null!=d&&"onScroll"===l&&Pr("scroll",e):null!=d&&w(e,l,d,u))}switch(n){case"input":Y(e),re(e,r,!1);break;case"textarea":Y(e),ce(e);break;case"option":null!=r.value&&e.setAttribute("value",""+Z(r.value));break;case"select":e.multiple=!!r.multiple,null!=(l=r.value)?ie(e,!!r.multiple,l,!1):null!=r.defaultValue&&ie(e,!!r.multiple,r.defaultValue,!0);break;default:"function"==typeof a.onClick&&(e.onclick=zr)}Hr(n,r)&&(t.flags|=4)}null!==t.ref&&(t.flags|=128)}return null;case 6:if(e&&null!=t.stateNode)Yi(0,t,e.memoizedProps,r);else{if("string"!=typeof r&&null===t.stateNode)throw Error(i(166));n=Ia(Aa.current),Ia(Pa.current),Wa(t)?(r=t.stateNode,n=t.memoizedProps,r[Kr]=t,r.nodeValue!==n&&(t.flags|=4)):((r=(9===n.nodeType?n:n.ownerDocument).createTextNode(r))[Kr]=t,t.stateNode=r)}return null;case 13:return co(Fa),r=t.memoizedState,0!=(64&t.flags)?(t.lanes=n,t):(r=null!==r,n=!1,null===e?void 0!==t.memoizedProps.fallback&&Wa(t):n=null!==e.memoizedState,r&&!n&&0!=(2&t.mode)&&(null===e&&!0!==t.memoizedProps.unstable_avoidThisFallback||0!=(1&Fa.current)?0===Fl&&(Fl=3):(0!==Fl&&3!==Fl||(Fl=4),null===Il||0==(134217727&$l)&&0==(134217727&Ul)||bs(Il,Rl))),(r||n)&&(t.flags|=4),null);case 4:return Ra(),null===e&&Ar(t.stateNode.containerInfo),null;case 10:return oa(t),null;case 19:if(co(Fa),null===(r=t.memoizedState))return null;if(l=0!=(64&t.flags),null===(u=r.rendering))if(l)il(r,!1);else{if(0!==Fl||null!==e&&0!=(64&e.flags))for(e=t.child;null!==e;){if(null!==(u=Ba(e))){for(t.flags|=64,il(r,!1),null!==(l=u.updateQueue)&&(t.updateQueue=l,t.flags|=4),null===r.lastEffect&&(t.firstEffect=null),t.lastEffect=r.lastEffect,r=n,n=t.child;null!==n;)e=r,(l=n).flags&=2,l.nextEffect=null,l.firstEffect=null,l.lastEffect=null,null===(u=l.alternate)?(l.childLanes=0,l.lanes=e,l.child=null,l.memoizedProps=null,l.memoizedState=null,l.updateQueue=null,l.dependencies=null,l.stateNode=null):(l.childLanes=u.childLanes,l.lanes=u.lanes,l.child=u.child,l.memoizedProps=u.memoizedProps,l.memoizedState=u.memoizedState,l.updateQueue=u.updateQueue,l.type=u.type,e=u.dependencies,l.dependencies=null===e?null:{lanes:e.lanes,firstContext:e.firstContext}),n=n.sibling;return fo(Fa,1&Fa.current|2),t.child}e=e.sibling}null!==r.tail&&Vo()>Gl&&(t.flags|=64,l=!0,il(r,!1),t.lanes=33554432)}else{if(!l)if(null!==(e=Ba(u))){if(t.flags|=64,l=!0,null!==(n=e.updateQueue)&&(t.updateQueue=n,t.flags|=4),il(r,!0),null===r.tail&&"hidden"===r.tailMode&&!u.alternate&&!Ua)return null!==(t=t.lastEffect=r.lastEffect)&&(t.nextEffect=null),null}else 2*Vo()-r.renderingStartTime>Gl&&1073741824!==n&&(t.flags|=64,l=!0,il(r,!1),t.lanes=33554432);r.isBackwards?(u.sibling=t.child,t.child=u):(null!==(n=r.last)?n.sibling=u:t.child=u,r.last=u)}return null!==r.tail?(n=r.tail,r.rendering=n,r.tail=n.sibling,r.lastEffect=t.lastEffect,r.renderingStartTime=Vo(),n.sibling=null,t=Fa.current,fo(Fa,l?1&t|2:1&t),n):null;case 23:case 24:return ks(),null!==e&&null!==e.memoizedState!=(null!==t.memoizedState)&&"unstable-defer-without-hiding"!==r.mode&&(t.flags|=4),null}throw Error(i(156,t.tag))}function sl(e){switch(e.tag){case 1:bo(e.type)&&yo();var t=e.flags;return 4096&t?(e.flags=-4097&t|64,e):null;case 3:if(Ra(),co(mo),co(ho),Ya(),0!=(64&(t=e.flags)))throw Error(i(285));return e.flags=-4097&t|64,e;case 5:return Ma(e),null;case 13:return co(Fa),4096&(t=e.flags)?(e.flags=-4097&t|64,e):null;case 19:return co(Fa),null;case 4:return Ra(),null;case 10:return oa(e),null;case 23:case 24:return ks(),null;default:return null}}function ul(e,t){try{var n="",r=t;do{n+=G(r),r=r.return}while(r);var o=n}catch(a){o="\nError generating stack: "+a.message+"\n"+a.stack}return{value:e,source:t,stack:o}}function cl(e,t){try{console.error(t.value)}catch(n){setTimeout((function(){throw n}))}}Zi=function(e,t){for(var n=t.child;null!==n;){if(5===n.tag||6===n.tag)e.appendChild(n.stateNode);else if(4!==n.tag&&null!==n.child){n.child.return=n,n=n.child;continue}if(n===t)break;for(;null===n.sibling;){if(null===n.return||n.return===t)return;n=n.return}n.sibling.return=n.return,n=n.sibling}},Qi=function(e,t,n,r){var a=e.memoizedProps;if(a!==r){e=t.stateNode,Ia(Pa.current);var i,l=null;switch(n){case"input":a=J(e,a),r=J(e,r),l=[];break;case"option":a=ae(e,a),r=ae(e,r),l=[];break;case"select":a=o({},a,{value:void 0}),r=o({},r,{value:void 0}),l=[];break;case"textarea":a=le(e,a),r=le(e,r),l=[];break;default:"function"!=typeof a.onClick&&"function"==typeof r.onClick&&(e.onclick=zr)}for(d in Ee(n,r),n=null,a)if(!r.hasOwnProperty(d)&&a.hasOwnProperty(d)&&null!=a[d])if("style"===d){var u=a[d];for(i in u)u.hasOwnProperty(i)&&(n||(n={}),n[i]="")}else"dangerouslySetInnerHTML"!==d&&"children"!==d&&"suppressContentEditableWarning"!==d&&"suppressHydrationWarning"!==d&&"autoFocus"!==d&&(s.hasOwnProperty(d)?l||(l=[]):(l=l||[]).push(d,null));for(d in r){var c=r[d];if(u=null!=a?a[d]:void 0,r.hasOwnProperty(d)&&c!==u&&(null!=c||null!=u))if("style"===d)if(u){for(i in u)!u.hasOwnProperty(i)||c&&c.hasOwnProperty(i)||(n||(n={}),n[i]="");for(i in c)c.hasOwnProperty(i)&&u[i]!==c[i]&&(n||(n={}),n[i]=c[i])}else n||(l||(l=[]),l.push(d,n)),n=c;else"dangerouslySetInnerHTML"===d?(c=c?c.__html:void 0,u=u?u.__html:void 0,null!=c&&u!==c&&(l=l||[]).push(d,c)):"children"===d?"string"!=typeof c&&"number"!=typeof c||(l=l||[]).push(d,""+c):"suppressContentEditableWarning"!==d&&"suppressHydrationWarning"!==d&&(s.hasOwnProperty(d)?(null!=c&&"onScroll"===d&&Pr("scroll",e),l||u===c||(l=[])):"object"==typeof c&&null!==c&&c.$$typeof===R?c.toString():(l=l||[]).push(d,c))}n&&(l=l||[]).push("style",n);var d=l;(t.updateQueue=d)&&(t.flags|=4)}},Yi=function(e,t,n,r){n!==r&&(t.flags|=4)};var dl="function"==typeof WeakMap?WeakMap:Map;function fl(e,t,n){(n=da(-1,n)).tag=3,n.payload={element:null};var r=t.value;return n.callback=function(){Yl||(Yl=!0,Xl=r),cl(0,t)},n}function pl(e,t,n){(n=da(-1,n)).tag=3;var r=e.type.getDerivedStateFromError;if("function"==typeof r){var o=t.value;n.payload=function(){return cl(0,t),r(o)}}var a=e.stateNode;return null!==a&&"function"==typeof a.componentDidCatch&&(n.callback=function(){"function"!=typeof r&&(null===Kl?Kl=new Set([this]):Kl.add(this),cl(0,t));var e=t.stack;this.componentDidCatch(t.value,{componentStack:null!==e?e:""})}),n}var hl="function"==typeof WeakSet?WeakSet:Set;function ml(e){var t=e.ref;if(null!==t)if("function"==typeof t)try{t(null)}catch(n){zs(e,n)}else t.current=null}function gl(e,t){switch(t.tag){case 0:case 11:case 15:case 22:case 5:case 6:case 4:case 17:return;case 1:if(256&t.flags&&null!==e){var n=e.memoizedProps,r=e.memoizedState;t=(e=t.stateNode).getSnapshotBeforeUpdate(t.elementType===t.type?n:Ko(t.type,n),r),e.__reactInternalSnapshotBeforeUpdate=t}return;case 3:return void(256&t.flags&&Wr(t.stateNode.containerInfo))}throw Error(i(163))}function vl(e,t,n){switch(n.tag){case 0:case 11:case 15:case 22:if(null!==(t=null!==(t=n.updateQueue)?t.lastEffect:null)){e=t=t.next;do{if(3==(3&e.tag)){var r=e.create;e.destroy=r()}e=e.next}while(e!==t)}if(null!==(t=null!==(t=n.updateQueue)?t.lastEffect:null)){e=t=t.next;do{var o=e;r=o.next,0!=(4&(o=o.tag))&&0!=(1&o)&&(Ms(n,e),js(n,e)),e=r}while(e!==t)}return;case 1:return e=n.stateNode,4&n.flags&&(null===t?e.componentDidMount():(r=n.elementType===n.type?t.memoizedProps:Ko(n.type,t.memoizedProps),e.componentDidUpdate(r,t.memoizedState,e.__reactInternalSnapshotBeforeUpdate))),void(null!==(t=n.updateQueue)&&ma(n,t,e));case 3:if(null!==(t=n.updateQueue)){if(e=null,null!==n.child)switch(n.child.tag){case 5:case 1:e=n.child.stateNode}ma(n,t,e)}return;case 5:return e=n.stateNode,void(null===t&&4&n.flags&&Hr(n.type,n.memoizedProps)&&e.focus());case 6:case 4:case 12:case 19:case 17:case 20:case 21:case 23:case 24:return;case 13:return void(null===n.memoizedState&&(n=n.alternate,null!==n&&(n=n.memoizedState,null!==n&&(n=n.dehydrated,null!==n&&_t(n)))))}throw Error(i(163))}function bl(e,t){for(var n=e;;){if(5===n.tag){var r=n.stateNode;if(t)"function"==typeof(r=r.style).setProperty?r.setProperty("display","none","important"):r.display="none";else{r=n.stateNode;var o=n.memoizedProps.style;o=null!=o&&o.hasOwnProperty("display")?o.display:null,r.style.display=xe("display",o)}}else if(6===n.tag)n.stateNode.nodeValue=t?"":n.memoizedProps;else if((23!==n.tag&&24!==n.tag||null===n.memoizedState||n===e)&&null!==n.child){n.child.return=n,n=n.child;continue}if(n===e)break;for(;null===n.sibling;){if(null===n.return||n.return===e)return;n=n.return}n.sibling.return=n.return,n=n.sibling}}function yl(e,t){if(So&&"function"==typeof So.onCommitFiberUnmount)try{So.onCommitFiberUnmount(Eo,t)}catch(a){}switch(t.tag){case 0:case 11:case 14:case 15:case 22:if(null!==(e=t.updateQueue)&&null!==(e=e.lastEffect)){var n=e=e.next;do{var r=n,o=r.destroy;if(r=r.tag,void 0!==o)if(0!=(4&r))Ms(t,n);else{r=t;try{o()}catch(a){zs(r,a)}}n=n.next}while(n!==e)}break;case 1:if(ml(t),"function"==typeof(e=t.stateNode).componentWillUnmount)try{e.props=t.memoizedProps,e.state=t.memoizedState,e.componentWillUnmount()}catch(a){zs(t,a)}break;case 5:ml(t);break;case 4:Sl(e,t)}}function wl(e){e.alternate=null,e.child=null,e.dependencies=null,e.firstEffect=null,e.lastEffect=null,e.memoizedProps=null,e.memoizedState=null,e.pendingProps=null,e.return=null,e.updateQueue=null}function xl(e){return 5===e.tag||3===e.tag||4===e.tag}function _l(e){e:{for(var t=e.return;null!==t;){if(xl(t))break e;t=t.return}throw Error(i(160))}var n=t;switch(t=n.stateNode,n.tag){case 5:var r=!1;break;case 3:case 4:t=t.containerInfo,r=!0;break;default:throw Error(i(161))}16&n.flags&&(be(t,""),n.flags&=-17);e:t:for(n=e;;){for(;null===n.sibling;){if(null===n.return||xl(n.return)){n=null;break e}n=n.return}for(n.sibling.return=n.return,n=n.sibling;5!==n.tag&&6!==n.tag&&18!==n.tag;){if(2&n.flags)continue t;if(null===n.child||4===n.tag)continue t;n.child.return=n,n=n.child}if(!(2&n.flags)){n=n.stateNode;break e}}r?kl(e,n,t):El(e,n,t)}function kl(e,t,n){var r=e.tag,o=5===r||6===r;if(o)e=o?e.stateNode:e.stateNode.instance,t?8===n.nodeType?n.parentNode.insertBefore(e,t):n.insertBefore(e,t):(8===n.nodeType?(t=n.parentNode).insertBefore(e,n):(t=n).appendChild(e),null!=(n=n._reactRootContainer)||null!==t.onclick||(t.onclick=zr));else if(4!==r&&null!==(e=e.child))for(kl(e,t,n),e=e.sibling;null!==e;)kl(e,t,n),e=e.sibling}function El(e,t,n){var r=e.tag,o=5===r||6===r;if(o)e=o?e.stateNode:e.stateNode.instance,t?n.insertBefore(e,t):n.appendChild(e);else if(4!==r&&null!==(e=e.child))for(El(e,t,n),e=e.sibling;null!==e;)El(e,t,n),e=e.sibling}function Sl(e,t){for(var n,r,o=t,a=!1;;){if(!a){a=o.return;e:for(;;){if(null===a)throw Error(i(160));switch(n=a.stateNode,a.tag){case 5:r=!1;break e;case 3:case 4:n=n.containerInfo,r=!0;break e}a=a.return}a=!0}if(5===o.tag||6===o.tag){e:for(var l=e,s=o,u=s;;)if(yl(l,u),null!==u.child&&4!==u.tag)u.child.return=u,u=u.child;else{if(u===s)break e;for(;null===u.sibling;){if(null===u.return||u.return===s)break e;u=u.return}u.sibling.return=u.return,u=u.sibling}r?(l=n,s=o.stateNode,8===l.nodeType?l.parentNode.removeChild(s):l.removeChild(s)):n.removeChild(o.stateNode)}else if(4===o.tag){if(null!==o.child){n=o.stateNode.containerInfo,r=!0,o.child.return=o,o=o.child;continue}}else if(yl(e,o),null!==o.child){o.child.return=o,o=o.child;continue}if(o===t)break;for(;null===o.sibling;){if(null===o.return||o.return===t)return;4===(o=o.return).tag&&(a=!1)}o.sibling.return=o.return,o=o.sibling}}function Cl(e,t){switch(t.tag){case 0:case 11:case 14:case 15:case 22:var n=t.updateQueue;if(null!==(n=null!==n?n.lastEffect:null)){var r=n=n.next;do{3==(3&r.tag)&&(e=r.destroy,r.destroy=void 0,void 0!==e&&e()),r=r.next}while(r!==n)}return;case 1:case 12:case 17:return;case 5:if(null!=(n=t.stateNode)){r=t.memoizedProps;var o=null!==e?e.memoizedProps:r;e=t.type;var a=t.updateQueue;if(t.updateQueue=null,null!==a){for(n[Jr]=r,"input"===e&&"radio"===r.type&&null!=r.name&&te(n,r),Se(e,o),t=Se(e,r),o=0;o<a.length;o+=2){var l=a[o],s=a[o+1];"style"===l?_e(n,s):"dangerouslySetInnerHTML"===l?ve(n,s):"children"===l?be(n,s):w(n,l,s,t)}switch(e){case"input":ne(n,r);break;case"textarea":ue(n,r);break;case"select":e=n._wrapperState.wasMultiple,n._wrapperState.wasMultiple=!!r.multiple,null!=(a=r.value)?ie(n,!!r.multiple,a,!1):e!==!!r.multiple&&(null!=r.defaultValue?ie(n,!!r.multiple,r.defaultValue,!0):ie(n,!!r.multiple,r.multiple?[]:"",!1))}}}return;case 6:if(null===t.stateNode)throw Error(i(162));return void(t.stateNode.nodeValue=t.memoizedProps);case 3:return void((n=t.stateNode).hydrate&&(n.hydrate=!1,_t(n.containerInfo)));case 13:return null!==t.memoizedState&&(ql=Vo(),bl(t.child,!0)),void Tl(t);case 19:return void Tl(t);case 23:case 24:return void bl(t,null!==t.memoizedState)}throw Error(i(163))}function Tl(e){var t=e.updateQueue;if(null!==t){e.updateQueue=null;var n=e.stateNode;null===n&&(n=e.stateNode=new hl),t.forEach((function(t){var r=Us.bind(null,e,t);n.has(t)||(n.add(t),t.then(r,r))}))}}function Ol(e,t){return null!==e&&(null===(e=e.memoizedState)||null!==e.dehydrated)&&(null!==(t=t.memoizedState)&&null===t.dehydrated)}var Dl=Math.ceil,Pl=x.ReactCurrentDispatcher,Nl=x.ReactCurrentOwner,Al=0,Il=null,Ll=null,Rl=0,jl=0,Ml=uo(0),Fl=0,Bl=null,zl=0,$l=0,Ul=0,Hl=0,Vl=null,ql=0,Gl=1/0;function Wl(){Gl=Vo()+500}var Zl,Ql=null,Yl=!1,Xl=null,Kl=null,Jl=!1,es=null,ts=90,ns=[],rs=[],os=null,as=0,is=null,ls=-1,ss=0,us=0,cs=null,ds=!1;function fs(){return 0!=(48&Al)?Vo():-1!==ls?ls:ls=Vo()}function ps(e){if(0==(2&(e=e.mode)))return 1;if(0==(4&e))return 99===qo()?1:2;if(0===ss&&(ss=zl),0!==Xo.transition){0!==us&&(us=null!==Vl?Vl.pendingLanes:0),e=ss;var t=4186112&~us;return 0===(t&=-t)&&(0===(t=(e=4186112&~e)&-e)&&(t=8192)),t}return e=qo(),0!=(4&Al)&&98===e?e=zt(12,ss):e=zt(e=function(e){switch(e){case 99:return 15;case 98:return 10;case 97:case 96:return 8;case 95:return 2;default:return 0}}(e),ss),e}function hs(e,t,n){if(50<as)throw as=0,is=null,Error(i(185));if(null===(e=ms(e,t)))return null;Ht(e,t,n),e===Il&&(Ul|=t,4===Fl&&bs(e,Rl));var r=qo();1===t?0!=(8&Al)&&0==(48&Al)?ys(e):(gs(e,n),0===Al&&(Wl(),Qo())):(0==(4&Al)||98!==r&&99!==r||(null===os?os=new Set([e]):os.add(e)),gs(e,n)),Vl=e}function ms(e,t){e.lanes|=t;var n=e.alternate;for(null!==n&&(n.lanes|=t),n=e,e=e.return;null!==e;)e.childLanes|=t,null!==(n=e.alternate)&&(n.childLanes|=t),n=e,e=e.return;return 3===n.tag?n.stateNode:null}function gs(e,t){for(var n=e.callbackNode,r=e.suspendedLanes,o=e.pingedLanes,a=e.expirationTimes,l=e.pendingLanes;0<l;){var s=31-Vt(l),u=1<<s,c=a[s];if(-1===c){if(0==(u&r)||0!=(u&o)){c=t,Mt(u);var d=jt;a[s]=10<=d?c+250:6<=d?c+5e3:-1}}else c<=t&&(e.expiredLanes|=u);l&=~u}if(r=Ft(e,e===Il?Rl:0),t=jt,0===r)null!==n&&(n!==Fo&&Oo(n),e.callbackNode=null,e.callbackPriority=0);else{if(null!==n){if(e.callbackPriority===t)return;n!==Fo&&Oo(n)}15===t?(n=ys.bind(null,e),null===zo?(zo=[n],$o=To(Io,Yo)):zo.push(n),n=Fo):14===t?n=Zo(99,ys.bind(null,e)):(n=function(e){switch(e){case 15:case 14:return 99;case 13:case 12:case 11:case 10:return 98;case 9:case 8:case 7:case 6:case 4:case 5:return 97;case 3:case 2:case 1:return 95;case 0:return 90;default:throw Error(i(358,e))}}(t),n=Zo(n,vs.bind(null,e))),e.callbackPriority=t,e.callbackNode=n}}function vs(e){if(ls=-1,us=ss=0,0!=(48&Al))throw Error(i(327));var t=e.callbackNode;if(Rs()&&e.callbackNode!==t)return null;var n=Ft(e,e===Il?Rl:0);if(0===n)return null;var r=n,o=Al;Al|=16;var a=Cs();for(Il===e&&Rl===r||(Wl(),Es(e,r));;)try{Ds();break}catch(s){Ss(e,s)}if(ra(),Pl.current=a,Al=o,null!==Ll?r=0:(Il=null,Rl=0,r=Fl),0!=(zl&Ul))Es(e,0);else if(0!==r){if(2===r&&(Al|=64,e.hydrate&&(e.hydrate=!1,Wr(e.containerInfo)),0!==(n=Bt(e))&&(r=Ts(e,n))),1===r)throw t=Bl,Es(e,0),bs(e,n),gs(e,Vo()),t;switch(e.finishedWork=e.current.alternate,e.finishedLanes=n,r){case 0:case 1:throw Error(i(345));case 2:case 5:As(e);break;case 3:if(bs(e,n),(62914560&n)===n&&10<(r=ql+500-Vo())){if(0!==Ft(e,0))break;if(((o=e.suspendedLanes)&n)!==n){fs(),e.pingedLanes|=e.suspendedLanes&o;break}e.timeoutHandle=qr(As.bind(null,e),r);break}As(e);break;case 4:if(bs(e,n),(4186112&n)===n)break;for(r=e.eventTimes,o=-1;0<n;){var l=31-Vt(n);a=1<<l,(l=r[l])>o&&(o=l),n&=~a}if(n=o,10<(n=(120>(n=Vo()-n)?120:480>n?480:1080>n?1080:1920>n?1920:3e3>n?3e3:4320>n?4320:1960*Dl(n/1960))-n)){e.timeoutHandle=qr(As.bind(null,e),n);break}As(e);break;default:throw Error(i(329))}}return gs(e,Vo()),e.callbackNode===t?vs.bind(null,e):null}function bs(e,t){for(t&=~Hl,t&=~Ul,e.suspendedLanes|=t,e.pingedLanes&=~t,e=e.expirationTimes;0<t;){var n=31-Vt(t),r=1<<n;e[n]=-1,t&=~r}}function ys(e){if(0!=(48&Al))throw Error(i(327));if(Rs(),e===Il&&0!=(e.expiredLanes&Rl)){var t=Rl,n=Ts(e,t);0!=(zl&Ul)&&(n=Ts(e,t=Ft(e,t)))}else n=Ts(e,t=Ft(e,0));if(0!==e.tag&&2===n&&(Al|=64,e.hydrate&&(e.hydrate=!1,Wr(e.containerInfo)),0!==(t=Bt(e))&&(n=Ts(e,t))),1===n)throw n=Bl,Es(e,0),bs(e,t),gs(e,Vo()),n;return e.finishedWork=e.current.alternate,e.finishedLanes=t,As(e),gs(e,Vo()),null}function ws(e,t){var n=Al;Al|=1;try{return e(t)}finally{0===(Al=n)&&(Wl(),Qo())}}function xs(e,t){var n=Al;Al&=-2,Al|=8;try{return e(t)}finally{0===(Al=n)&&(Wl(),Qo())}}function _s(e,t){fo(Ml,jl),jl|=t,zl|=t}function ks(){jl=Ml.current,co(Ml)}function Es(e,t){e.finishedWork=null,e.finishedLanes=0;var n=e.timeoutHandle;if(-1!==n&&(e.timeoutHandle=-1,Gr(n)),null!==Ll)for(n=Ll.return;null!==n;){var r=n;switch(r.tag){case 1:null!=(r=r.type.childContextTypes)&&yo();break;case 3:Ra(),co(mo),co(ho),Ya();break;case 5:Ma(r);break;case 4:Ra();break;case 13:case 19:co(Fa);break;case 10:oa(r);break;case 23:case 24:ks()}n=n.return}Il=e,Ll=Gs(e.current,null),Rl=jl=zl=t,Fl=0,Bl=null,Hl=Ul=$l=0}function Ss(e,t){for(;;){var n=Ll;try{if(ra(),Xa.current=Ai,ri){for(var r=ei.memoizedState;null!==r;){var o=r.queue;null!==o&&(o.pending=null),r=r.next}ri=!1}if(Ja=0,ni=ti=ei=null,oi=!1,Nl.current=null,null===n||null===n.return){Fl=1,Bl=t,Ll=null;break}e:{var a=e,i=n.return,l=n,s=t;if(t=Rl,l.flags|=2048,l.firstEffect=l.lastEffect=null,null!==s&&"object"==typeof s&&"function"==typeof s.then){var u=s;if(0==(2&l.mode)){var c=l.alternate;c?(l.updateQueue=c.updateQueue,l.memoizedState=c.memoizedState,l.lanes=c.lanes):(l.updateQueue=null,l.memoizedState=null)}var d=0!=(1&Fa.current),f=i;do{var p;if(p=13===f.tag){var h=f.memoizedState;if(null!==h)p=null!==h.dehydrated;else{var m=f.memoizedProps;p=void 0!==m.fallback&&(!0!==m.unstable_avoidThisFallback||!d)}}if(p){var g=f.updateQueue;if(null===g){var v=new Set;v.add(u),f.updateQueue=v}else g.add(u);if(0==(2&f.mode)){if(f.flags|=64,l.flags|=16384,l.flags&=-2981,1===l.tag)if(null===l.alternate)l.tag=17;else{var b=da(-1,1);b.tag=2,fa(l,b)}l.lanes|=1;break e}s=void 0,l=t;var y=a.pingCache;if(null===y?(y=a.pingCache=new dl,s=new Set,y.set(u,s)):void 0===(s=y.get(u))&&(s=new Set,y.set(u,s)),!s.has(l)){s.add(l);var w=$s.bind(null,a,u,l);u.then(w,w)}f.flags|=4096,f.lanes=t;break e}f=f.return}while(null!==f);s=Error((W(l.type)||"A React component")+" suspended while rendering, but no fallback UI was specified.\n\nAdd a <Suspense fallback=...> component higher in the tree to provide a loading indicator or placeholder to display.")}5!==Fl&&(Fl=2),s=ul(s,l),f=i;do{switch(f.tag){case 3:a=s,f.flags|=4096,t&=-t,f.lanes|=t,pa(f,fl(0,a,t));break e;case 1:a=s;var x=f.type,_=f.stateNode;if(0==(64&f.flags)&&("function"==typeof x.getDerivedStateFromError||null!==_&&"function"==typeof _.componentDidCatch&&(null===Kl||!Kl.has(_)))){f.flags|=4096,t&=-t,f.lanes|=t,pa(f,pl(f,a,t));break e}}f=f.return}while(null!==f)}Ns(n)}catch(k){t=k,Ll===n&&null!==n&&(Ll=n=n.return);continue}break}}function Cs(){var e=Pl.current;return Pl.current=Ai,null===e?Ai:e}function Ts(e,t){var n=Al;Al|=16;var r=Cs();for(Il===e&&Rl===t||Es(e,t);;)try{Os();break}catch(o){Ss(e,o)}if(ra(),Al=n,Pl.current=r,null!==Ll)throw Error(i(261));return Il=null,Rl=0,Fl}function Os(){for(;null!==Ll;)Ps(Ll)}function Ds(){for(;null!==Ll&&!Do();)Ps(Ll)}function Ps(e){var t=Zl(e.alternate,e,jl);e.memoizedProps=e.pendingProps,null===t?Ns(e):Ll=t,Nl.current=null}function Ns(e){var t=e;do{var n=t.alternate;if(e=t.return,0==(2048&t.flags)){if(null!==(n=ll(n,t,jl)))return void(Ll=n);if(24!==(n=t).tag&&23!==n.tag||null===n.memoizedState||0!=(1073741824&jl)||0==(4&n.mode)){for(var r=0,o=n.child;null!==o;)r|=o.lanes|o.childLanes,o=o.sibling;n.childLanes=r}null!==e&&0==(2048&e.flags)&&(null===e.firstEffect&&(e.firstEffect=t.firstEffect),null!==t.lastEffect&&(null!==e.lastEffect&&(e.lastEffect.nextEffect=t.firstEffect),e.lastEffect=t.lastEffect),1<t.flags&&(null!==e.lastEffect?e.lastEffect.nextEffect=t:e.firstEffect=t,e.lastEffect=t))}else{if(null!==(n=sl(t)))return n.flags&=2047,void(Ll=n);null!==e&&(e.firstEffect=e.lastEffect=null,e.flags|=2048)}if(null!==(t=t.sibling))return void(Ll=t);Ll=t=e}while(null!==t);0===Fl&&(Fl=5)}function As(e){var t=qo();return Wo(99,Is.bind(null,e,t)),null}function Is(e,t){do{Rs()}while(null!==es);if(0!=(48&Al))throw Error(i(327));var n=e.finishedWork;if(null===n)return null;if(e.finishedWork=null,e.finishedLanes=0,n===e.current)throw Error(i(177));e.callbackNode=null;var r=n.lanes|n.childLanes,o=r,a=e.pendingLanes&~o;e.pendingLanes=o,e.suspendedLanes=0,e.pingedLanes=0,e.expiredLanes&=o,e.mutableReadLanes&=o,e.entangledLanes&=o,o=e.entanglements;for(var l=e.eventTimes,s=e.expirationTimes;0<a;){var u=31-Vt(a),c=1<<u;o[u]=0,l[u]=-1,s[u]=-1,a&=~c}if(null!==os&&0==(24&r)&&os.has(e)&&os.delete(e),e===Il&&(Ll=Il=null,Rl=0),1<n.flags?null!==n.lastEffect?(n.lastEffect.nextEffect=n,r=n.firstEffect):r=n:r=n.firstEffect,null!==r){if(o=Al,Al|=32,Nl.current=null,$r=Qt,vr(l=gr())){if("selectionStart"in l)s={start:l.selectionStart,end:l.selectionEnd};else e:if(s=(s=l.ownerDocument)&&s.defaultView||window,(c=s.getSelection&&s.getSelection())&&0!==c.rangeCount){s=c.anchorNode,a=c.anchorOffset,u=c.focusNode,c=c.focusOffset;try{s.nodeType,u.nodeType}catch(C){s=null;break e}var d=0,f=-1,p=-1,h=0,m=0,g=l,v=null;t:for(;;){for(var b;g!==s||0!==a&&3!==g.nodeType||(f=d+a),g!==u||0!==c&&3!==g.nodeType||(p=d+c),3===g.nodeType&&(d+=g.nodeValue.length),null!==(b=g.firstChild);)v=g,g=b;for(;;){if(g===l)break t;if(v===s&&++h===a&&(f=d),v===u&&++m===c&&(p=d),null!==(b=g.nextSibling))break;v=(g=v).parentNode}g=b}s=-1===f||-1===p?null:{start:f,end:p}}else s=null;s=s||{start:0,end:0}}else s=null;Ur={focusedElem:l,selectionRange:s},Qt=!1,cs=null,ds=!1,Ql=r;do{try{Ls()}catch(C){if(null===Ql)throw Error(i(330));zs(Ql,C),Ql=Ql.nextEffect}}while(null!==Ql);cs=null,Ql=r;do{try{for(l=e;null!==Ql;){var y=Ql.flags;if(16&y&&be(Ql.stateNode,""),128&y){var w=Ql.alternate;if(null!==w){var x=w.ref;null!==x&&("function"==typeof x?x(null):x.current=null)}}switch(1038&y){case 2:_l(Ql),Ql.flags&=-3;break;case 6:_l(Ql),Ql.flags&=-3,Cl(Ql.alternate,Ql);break;case 1024:Ql.flags&=-1025;break;case 1028:Ql.flags&=-1025,Cl(Ql.alternate,Ql);break;case 4:Cl(Ql.alternate,Ql);break;case 8:Sl(l,s=Ql);var _=s.alternate;wl(s),null!==_&&wl(_)}Ql=Ql.nextEffect}}catch(C){if(null===Ql)throw Error(i(330));zs(Ql,C),Ql=Ql.nextEffect}}while(null!==Ql);if(x=Ur,w=gr(),y=x.focusedElem,l=x.selectionRange,w!==y&&y&&y.ownerDocument&&mr(y.ownerDocument.documentElement,y)){null!==l&&vr(y)&&(w=l.start,void 0===(x=l.end)&&(x=w),"selectionStart"in y?(y.selectionStart=w,y.selectionEnd=Math.min(x,y.value.length)):(x=(w=y.ownerDocument||document)&&w.defaultView||window).getSelection&&(x=x.getSelection(),s=y.textContent.length,_=Math.min(l.start,s),l=void 0===l.end?_:Math.min(l.end,s),!x.extend&&_>l&&(s=l,l=_,_=s),s=hr(y,_),a=hr(y,l),s&&a&&(1!==x.rangeCount||x.anchorNode!==s.node||x.anchorOffset!==s.offset||x.focusNode!==a.node||x.focusOffset!==a.offset)&&((w=w.createRange()).setStart(s.node,s.offset),x.removeAllRanges(),_>l?(x.addRange(w),x.extend(a.node,a.offset)):(w.setEnd(a.node,a.offset),x.addRange(w))))),w=[];for(x=y;x=x.parentNode;)1===x.nodeType&&w.push({element:x,left:x.scrollLeft,top:x.scrollTop});for("function"==typeof y.focus&&y.focus(),y=0;y<w.length;y++)(x=w[y]).element.scrollLeft=x.left,x.element.scrollTop=x.top}Qt=!!$r,Ur=$r=null,e.current=n,Ql=r;do{try{for(y=e;null!==Ql;){var k=Ql.flags;if(36&k&&vl(y,Ql.alternate,Ql),128&k){w=void 0;var E=Ql.ref;if(null!==E){var S=Ql.stateNode;Ql.tag,w=S,"function"==typeof E?E(w):E.current=w}}Ql=Ql.nextEffect}}catch(C){if(null===Ql)throw Error(i(330));zs(Ql,C),Ql=Ql.nextEffect}}while(null!==Ql);Ql=null,Bo(),Al=o}else e.current=n;if(Jl)Jl=!1,es=e,ts=t;else for(Ql=r;null!==Ql;)t=Ql.nextEffect,Ql.nextEffect=null,8&Ql.flags&&((k=Ql).sibling=null,k.stateNode=null),Ql=t;if(0===(r=e.pendingLanes)&&(Kl=null),1===r?e===is?as++:(as=0,is=e):as=0,n=n.stateNode,So&&"function"==typeof So.onCommitFiberRoot)try{So.onCommitFiberRoot(Eo,n,void 0,64==(64&n.current.flags))}catch(C){}if(gs(e,Vo()),Yl)throw Yl=!1,e=Xl,Xl=null,e;return 0!=(8&Al)||Qo(),null}function Ls(){for(;null!==Ql;){var e=Ql.alternate;ds||null===cs||(0!=(8&Ql.flags)?et(Ql,cs)&&(ds=!0):13===Ql.tag&&Ol(e,Ql)&&et(Ql,cs)&&(ds=!0));var t=Ql.flags;0!=(256&t)&&gl(e,Ql),0==(512&t)||Jl||(Jl=!0,Zo(97,(function(){return Rs(),null}))),Ql=Ql.nextEffect}}function Rs(){if(90!==ts){var e=97<ts?97:ts;return ts=90,Wo(e,Fs)}return!1}function js(e,t){ns.push(t,e),Jl||(Jl=!0,Zo(97,(function(){return Rs(),null})))}function Ms(e,t){rs.push(t,e),Jl||(Jl=!0,Zo(97,(function(){return Rs(),null})))}function Fs(){if(null===es)return!1;var e=es;if(es=null,0!=(48&Al))throw Error(i(331));var t=Al;Al|=32;var n=rs;rs=[];for(var r=0;r<n.length;r+=2){var o=n[r],a=n[r+1],l=o.destroy;if(o.destroy=void 0,"function"==typeof l)try{l()}catch(u){if(null===a)throw Error(i(330));zs(a,u)}}for(n=ns,ns=[],r=0;r<n.length;r+=2){o=n[r],a=n[r+1];try{var s=o.create;o.destroy=s()}catch(u){if(null===a)throw Error(i(330));zs(a,u)}}for(s=e.current.firstEffect;null!==s;)e=s.nextEffect,s.nextEffect=null,8&s.flags&&(s.sibling=null,s.stateNode=null),s=e;return Al=t,Qo(),!0}function Bs(e,t,n){fa(e,t=fl(0,t=ul(n,t),1)),t=fs(),null!==(e=ms(e,1))&&(Ht(e,1,t),gs(e,t))}function zs(e,t){if(3===e.tag)Bs(e,e,t);else for(var n=e.return;null!==n;){if(3===n.tag){Bs(n,e,t);break}if(1===n.tag){var r=n.stateNode;if("function"==typeof n.type.getDerivedStateFromError||"function"==typeof r.componentDidCatch&&(null===Kl||!Kl.has(r))){var o=pl(n,e=ul(t,e),1);if(fa(n,o),o=fs(),null!==(n=ms(n,1)))Ht(n,1,o),gs(n,o);else if("function"==typeof r.componentDidCatch&&(null===Kl||!Kl.has(r)))try{r.componentDidCatch(t,e)}catch(a){}break}}n=n.return}}function $s(e,t,n){var r=e.pingCache;null!==r&&r.delete(t),t=fs(),e.pingedLanes|=e.suspendedLanes&n,Il===e&&(Rl&n)===n&&(4===Fl||3===Fl&&(62914560&Rl)===Rl&&500>Vo()-ql?Es(e,0):Hl|=n),gs(e,t)}function Us(e,t){var n=e.stateNode;null!==n&&n.delete(t),0===(t=0)&&(0==(2&(t=e.mode))?t=1:0==(4&t)?t=99===qo()?1:2:(0===ss&&(ss=zl),0===(t=$t(62914560&~ss))&&(t=4194304))),n=fs(),null!==(e=ms(e,t))&&(Ht(e,t,n),gs(e,n))}function Hs(e,t,n,r){this.tag=e,this.key=n,this.sibling=this.child=this.return=this.stateNode=this.type=this.elementType=null,this.index=0,this.ref=null,this.pendingProps=t,this.dependencies=this.memoizedState=this.updateQueue=this.memoizedProps=null,this.mode=r,this.flags=0,this.lastEffect=this.firstEffect=this.nextEffect=null,this.childLanes=this.lanes=0,this.alternate=null}function Vs(e,t,n,r){return new Hs(e,t,n,r)}function qs(e){return!(!(e=e.prototype)||!e.isReactComponent)}function Gs(e,t){var n=e.alternate;return null===n?((n=Vs(e.tag,t,e.key,e.mode)).elementType=e.elementType,n.type=e.type,n.stateNode=e.stateNode,n.alternate=e,e.alternate=n):(n.pendingProps=t,n.type=e.type,n.flags=0,n.nextEffect=null,n.firstEffect=null,n.lastEffect=null),n.childLanes=e.childLanes,n.lanes=e.lanes,n.child=e.child,n.memoizedProps=e.memoizedProps,n.memoizedState=e.memoizedState,n.updateQueue=e.updateQueue,t=e.dependencies,n.dependencies=null===t?null:{lanes:t.lanes,firstContext:t.firstContext},n.sibling=e.sibling,n.index=e.index,n.ref=e.ref,n}function Ws(e,t,n,r,o,a){var l=2;if(r=e,"function"==typeof e)qs(e)&&(l=1);else if("string"==typeof e)l=5;else e:switch(e){case E:return Zs(n.children,o,a,t);case j:l=8,o|=16;break;case S:l=8,o|=1;break;case C:return(e=Vs(12,n,t,8|o)).elementType=C,e.type=C,e.lanes=a,e;case P:return(e=Vs(13,n,t,o)).type=P,e.elementType=P,e.lanes=a,e;case N:return(e=Vs(19,n,t,o)).elementType=N,e.lanes=a,e;case M:return Qs(n,o,a,t);case F:return(e=Vs(24,n,t,o)).elementType=F,e.lanes=a,e;default:if("object"==typeof e&&null!==e)switch(e.$$typeof){case T:l=10;break e;case O:l=9;break e;case D:l=11;break e;case A:l=14;break e;case I:l=16,r=null;break e;case L:l=22;break e}throw Error(i(130,null==e?e:typeof e,""))}return(t=Vs(l,n,t,o)).elementType=e,t.type=r,t.lanes=a,t}function Zs(e,t,n,r){return(e=Vs(7,e,r,t)).lanes=n,e}function Qs(e,t,n,r){return(e=Vs(23,e,r,t)).elementType=M,e.lanes=n,e}function Ys(e,t,n){return(e=Vs(6,e,null,t)).lanes=n,e}function Xs(e,t,n){return(t=Vs(4,null!==e.children?e.children:[],e.key,t)).lanes=n,t.stateNode={containerInfo:e.containerInfo,pendingChildren:null,implementation:e.implementation},t}function Ks(e,t,n){this.tag=t,this.containerInfo=e,this.finishedWork=this.pingCache=this.current=this.pendingChildren=null,this.timeoutHandle=-1,this.pendingContext=this.context=null,this.hydrate=n,this.callbackNode=null,this.callbackPriority=0,this.eventTimes=Ut(0),this.expirationTimes=Ut(-1),this.entangledLanes=this.finishedLanes=this.mutableReadLanes=this.expiredLanes=this.pingedLanes=this.suspendedLanes=this.pendingLanes=0,this.entanglements=Ut(0),this.mutableSourceEagerHydrationData=null}function Js(e,t,n){var r=3<arguments.length&&void 0!==arguments[3]?arguments[3]:null;return{$$typeof:k,key:null==r?null:""+r,children:e,containerInfo:t,implementation:n}}function eu(e,t,n,r){var o=t.current,a=fs(),l=ps(o);e:if(n){t:{if(Ye(n=n._reactInternals)!==n||1!==n.tag)throw Error(i(170));var s=n;do{switch(s.tag){case 3:s=s.stateNode.context;break t;case 1:if(bo(s.type)){s=s.stateNode.__reactInternalMemoizedMergedChildContext;break t}}s=s.return}while(null!==s);throw Error(i(171))}if(1===n.tag){var u=n.type;if(bo(u)){n=xo(n,u,s);break e}}n=s}else n=po;return null===t.context?t.context=n:t.pendingContext=n,(t=da(a,l)).payload={element:e},null!==(r=void 0===r?null:r)&&(t.callback=r),fa(o,t),hs(o,l,a),l}function tu(e){return(e=e.current).child?(e.child.tag,e.child.stateNode):null}function nu(e,t){if(null!==(e=e.memoizedState)&&null!==e.dehydrated){var n=e.retryLane;e.retryLane=0!==n&&n<t?n:t}}function ru(e,t){nu(e,t),(e=e.alternate)&&nu(e,t)}function ou(e,t,n){var r=null!=n&&null!=n.hydrationOptions&&n.hydrationOptions.mutableSources||null;if(n=new Ks(e,t,null!=n&&!0===n.hydrate),t=Vs(3,null,null,2===t?7:1===t?3:0),n.current=t,t.stateNode=n,ua(t),e[eo]=n.current,Ar(8===e.nodeType?e.parentNode:e),r)for(e=0;e<r.length;e++){var o=(t=r[e])._getVersion;o=o(t._source),null==n.mutableSourceEagerHydrationData?n.mutableSourceEagerHydrationData=[t,o]:n.mutableSourceEagerHydrationData.push(t,o)}this._internalRoot=n}function au(e){return!(!e||1!==e.nodeType&&9!==e.nodeType&&11!==e.nodeType&&(8!==e.nodeType||" react-mount-point-unstable "!==e.nodeValue))}function iu(e,t,n,r,o){var a=n._reactRootContainer;if(a){var i=a._internalRoot;if("function"==typeof o){var l=o;o=function(){var e=tu(i);l.call(e)}}eu(t,i,e,o)}else{if(a=n._reactRootContainer=function(e,t){if(t||(t=!(!(t=e?9===e.nodeType?e.documentElement:e.firstChild:null)||1!==t.nodeType||!t.hasAttribute("data-reactroot"))),!t)for(var n;n=e.lastChild;)e.removeChild(n);return new ou(e,0,t?{hydrate:!0}:void 0)}(n,r),i=a._internalRoot,"function"==typeof o){var s=o;o=function(){var e=tu(i);s.call(e)}}xs((function(){eu(t,i,e,o)}))}return tu(i)}function lu(e,t){var n=2<arguments.length&&void 0!==arguments[2]?arguments[2]:null;if(!au(t))throw Error(i(200));return Js(e,t,null,n)}Zl=function(e,t,n){var r=t.lanes;if(null!==e)if(e.memoizedProps!==t.pendingProps||mo.current)Mi=!0;else{if(0==(n&r)){switch(Mi=!1,t.tag){case 3:Wi(t),Za();break;case 5:ja(t);break;case 1:bo(t.type)&&_o(t);break;case 4:La(t,t.stateNode.containerInfo);break;case 10:r=t.memoizedProps.value;var o=t.type._context;fo(Jo,o._currentValue),o._currentValue=r;break;case 13:if(null!==t.memoizedState)return 0!=(n&t.child.childLanes)?Ki(e,t,n):(fo(Fa,1&Fa.current),null!==(t=al(e,t,n))?t.sibling:null);fo(Fa,1&Fa.current);break;case 19:if(r=0!=(n&t.childLanes),0!=(64&e.flags)){if(r)return ol(e,t,n);t.flags|=64}if(null!==(o=t.memoizedState)&&(o.rendering=null,o.tail=null,o.lastEffect=null),fo(Fa,Fa.current),r)break;return null;case 23:case 24:return t.lanes=0,Ui(e,t,n)}return al(e,t,n)}Mi=0!=(16384&e.flags)}else Mi=!1;switch(t.lanes=0,t.tag){case 2:if(r=t.type,null!==e&&(e.alternate=null,t.alternate=null,t.flags|=2),e=t.pendingProps,o=vo(t,ho.current),ia(t,n),o=li(null,t,r,e,o,n),t.flags|=1,"object"==typeof o&&null!==o&&"function"==typeof o.render&&void 0===o.$$typeof){if(t.tag=1,t.memoizedState=null,t.updateQueue=null,bo(r)){var a=!0;_o(t)}else a=!1;t.memoizedState=null!==o.state&&void 0!==o.state?o.state:null,ua(t);var l=r.getDerivedStateFromProps;"function"==typeof l&&va(t,r,l,e),o.updater=ba,t.stateNode=o,o._reactInternals=t,_a(t,r,e,n),t=Gi(null,t,r,!0,a,n)}else t.tag=0,Fi(null,t,o,n),t=t.child;return t;case 16:o=t.elementType;e:{switch(null!==e&&(e.alternate=null,t.alternate=null,t.flags|=2),e=t.pendingProps,o=(a=o._init)(o._payload),t.type=o,a=t.tag=function(e){if("function"==typeof e)return qs(e)?1:0;if(null!=e){if((e=e.$$typeof)===D)return 11;if(e===A)return 14}return 2}(o),e=Ko(o,e),a){case 0:t=Vi(null,t,o,e,n);break e;case 1:t=qi(null,t,o,e,n);break e;case 11:t=Bi(null,t,o,e,n);break e;case 14:t=zi(null,t,o,Ko(o.type,e),r,n);break e}throw Error(i(306,o,""))}return t;case 0:return r=t.type,o=t.pendingProps,Vi(e,t,r,o=t.elementType===r?o:Ko(r,o),n);case 1:return r=t.type,o=t.pendingProps,qi(e,t,r,o=t.elementType===r?o:Ko(r,o),n);case 3:if(Wi(t),r=t.updateQueue,null===e||null===r)throw Error(i(282));if(r=t.pendingProps,o=null!==(o=t.memoizedState)?o.element:null,ca(e,t),ha(t,r,null,n),(r=t.memoizedState.element)===o)Za(),t=al(e,t,n);else{if((a=(o=t.stateNode).hydrate)&&($a=Zr(t.stateNode.containerInfo.firstChild),za=t,a=Ua=!0),a){if(null!=(e=o.mutableSourceEagerHydrationData))for(o=0;o<e.length;o+=2)(a=e[o])._workInProgressVersionPrimary=e[o+1],Qa.push(a);for(n=Oa(t,null,r,n),t.child=n;n;)n.flags=-3&n.flags|1024,n=n.sibling}else Fi(e,t,r,n),Za();t=t.child}return t;case 5:return ja(t),null===e&&qa(t),r=t.type,o=t.pendingProps,a=null!==e?e.memoizedProps:null,l=o.children,Vr(r,o)?l=null:null!==a&&Vr(r,a)&&(t.flags|=16),Hi(e,t),Fi(e,t,l,n),t.child;case 6:return null===e&&qa(t),null;case 13:return Ki(e,t,n);case 4:return La(t,t.stateNode.containerInfo),r=t.pendingProps,null===e?t.child=Ta(t,null,r,n):Fi(e,t,r,n),t.child;case 11:return r=t.type,o=t.pendingProps,Bi(e,t,r,o=t.elementType===r?o:Ko(r,o),n);case 7:return Fi(e,t,t.pendingProps,n),t.child;case 8:case 12:return Fi(e,t,t.pendingProps.children,n),t.child;case 10:e:{r=t.type._context,o=t.pendingProps,l=t.memoizedProps,a=o.value;var s=t.type._context;if(fo(Jo,s._currentValue),s._currentValue=a,null!==l)if(s=l.value,0===(a=cr(s,a)?0:0|("function"==typeof r._calculateChangedBits?r._calculateChangedBits(s,a):1073741823))){if(l.children===o.children&&!mo.current){t=al(e,t,n);break e}}else for(null!==(s=t.child)&&(s.return=t);null!==s;){var u=s.dependencies;if(null!==u){l=s.child;for(var c=u.firstContext;null!==c;){if(c.context===r&&0!=(c.observedBits&a)){1===s.tag&&((c=da(-1,n&-n)).tag=2,fa(s,c)),s.lanes|=n,null!==(c=s.alternate)&&(c.lanes|=n),aa(s.return,n),u.lanes|=n;break}c=c.next}}else l=10===s.tag&&s.type===t.type?null:s.child;if(null!==l)l.return=s;else for(l=s;null!==l;){if(l===t){l=null;break}if(null!==(s=l.sibling)){s.return=l.return,l=s;break}l=l.return}s=l}Fi(e,t,o.children,n),t=t.child}return t;case 9:return o=t.type,r=(a=t.pendingProps).children,ia(t,n),r=r(o=la(o,a.unstable_observedBits)),t.flags|=1,Fi(e,t,r,n),t.child;case 14:return a=Ko(o=t.type,t.pendingProps),zi(e,t,o,a=Ko(o.type,a),r,n);case 15:return $i(e,t,t.type,t.pendingProps,r,n);case 17:return r=t.type,o=t.pendingProps,o=t.elementType===r?o:Ko(r,o),null!==e&&(e.alternate=null,t.alternate=null,t.flags|=2),t.tag=1,bo(r)?(e=!0,_o(t)):e=!1,ia(t,n),wa(t,r,o),_a(t,r,o,n),Gi(null,t,r,!0,e,n);case 19:return ol(e,t,n);case 23:case 24:return Ui(e,t,n)}throw Error(i(156,t.tag))},ou.prototype.render=function(e){eu(e,this._internalRoot,null,null)},ou.prototype.unmount=function(){var e=this._internalRoot,t=e.containerInfo;eu(null,e,null,(function(){t[eo]=null}))},tt=function(e){13===e.tag&&(hs(e,4,fs()),ru(e,4))},nt=function(e){13===e.tag&&(hs(e,67108864,fs()),ru(e,67108864))},rt=function(e){if(13===e.tag){var t=fs(),n=ps(e);hs(e,n,t),ru(e,n)}},ot=function(e,t){return t()},Te=function(e,t,n){switch(t){case"input":if(ne(e,n),t=n.name,"radio"===n.type&&null!=t){for(n=e;n.parentNode;)n=n.parentNode;for(n=n.querySelectorAll("input[name="+JSON.stringify(""+t)+'][type="radio"]'),t=0;t<n.length;t++){var r=n[t];if(r!==e&&r.form===e.form){var o=ao(r);if(!o)throw Error(i(90));X(r),ne(r,o)}}}break;case"textarea":ue(e,n);break;case"select":null!=(t=n.value)&&ie(e,!!n.multiple,t,!1)}},Ie=ws,Le=function(e,t,n,r,o){var a=Al;Al|=4;try{return Wo(98,e.bind(null,t,n,r,o))}finally{0===(Al=a)&&(Wl(),Qo())}},Re=function(){0==(49&Al)&&(function(){if(null!==os){var e=os;os=null,e.forEach((function(e){e.expiredLanes|=24&e.pendingLanes,gs(e,Vo())}))}Qo()}(),Rs())},je=function(e,t){var n=Al;Al|=2;try{return e(t)}finally{0===(Al=n)&&(Wl(),Qo())}};var su={Events:[ro,oo,ao,Ne,Ae,Rs,{current:!1}]},uu={findFiberByHostInstance:no,bundleType:0,version:"17.0.2",rendererPackageName:"react-dom"},cu={bundleType:uu.bundleType,version:uu.version,rendererPackageName:uu.rendererPackageName,rendererConfig:uu.rendererConfig,overrideHookState:null,overrideHookStateDeletePath:null,overrideHookStateRenamePath:null,overrideProps:null,overridePropsDeletePath:null,overridePropsRenamePath:null,setSuspenseHandler:null,scheduleUpdate:null,currentDispatcherRef:x.ReactCurrentDispatcher,findHostInstanceByFiber:function(e){return null===(e=Je(e))?null:e.stateNode},findFiberByHostInstance:uu.findFiberByHostInstance||function(){return null},findHostInstancesForRefresh:null,scheduleRefresh:null,scheduleRoot:null,setRefreshHandler:null,getCurrentFiber:null};if("undefined"!=typeof __REACT_DEVTOOLS_GLOBAL_HOOK__){var du=__REACT_DEVTOOLS_GLOBAL_HOOK__;if(!du.isDisabled&&du.supportsFiber)try{Eo=du.inject(cu),So=du}catch(ge){}}t.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED=su,t.createPortal=lu,t.findDOMNode=function(e){if(null==e)return null;if(1===e.nodeType)return e;var t=e._reactInternals;if(void 0===t){if("function"==typeof e.render)throw Error(i(188));throw Error(i(268,Object.keys(e)))}return e=null===(e=Je(t))?null:e.stateNode},t.flushSync=function(e,t){var n=Al;if(0!=(48&n))return e(t);Al|=1;try{if(e)return Wo(99,e.bind(null,t))}finally{Al=n,Qo()}},t.hydrate=function(e,t,n){if(!au(t))throw Error(i(200));return iu(null,e,t,!0,n)},t.render=function(e,t,n){if(!au(t))throw Error(i(200));return iu(null,e,t,!1,n)},t.unmountComponentAtNode=function(e){if(!au(e))throw Error(i(40));return!!e._reactRootContainer&&(xs((function(){iu(null,null,e,!1,(function(){e._reactRootContainer=null,e[eo]=null}))})),!0)},t.unstable_batchedUpdates=ws,t.unstable_createPortal=function(e,t){return lu(e,t,2<arguments.length&&void 0!==arguments[2]?arguments[2]:null)},t.unstable_renderSubtreeIntoContainer=function(e,t,n,r){if(!au(n))throw Error(i(200));if(null==e||void 0===e._reactInternals)throw Error(i(38));return iu(e,t,n,!1,r)},t.version="17.0.2"},73935:(e,t,n)=>{"use strict";!function e(){if("undefined"!=typeof __REACT_DEVTOOLS_GLOBAL_HOOK__&&"function"==typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE)try{__REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE(e)}catch(t){console.error(t)}}(),e.exports=n(64448)},69590:e=>{var t="undefined"!=typeof Element,n="function"==typeof Map,r="function"==typeof Set,o="function"==typeof ArrayBuffer&&!!ArrayBuffer.isView;function a(e,i){if(e===i)return!0;if(e&&i&&"object"==typeof e&&"object"==typeof i){if(e.constructor!==i.constructor)return!1;var l,s,u,c;if(Array.isArray(e)){if((l=e.length)!=i.length)return!1;for(s=l;0!=s--;)if(!a(e[s],i[s]))return!1;return!0}if(n&&e instanceof Map&&i instanceof Map){if(e.size!==i.size)return!1;for(c=e.entries();!(s=c.next()).done;)if(!i.has(s.value[0]))return!1;for(c=e.entries();!(s=c.next()).done;)if(!a(s.value[1],i.get(s.value[0])))return!1;return!0}if(r&&e instanceof Set&&i instanceof Set){if(e.size!==i.size)return!1;for(c=e.entries();!(s=c.next()).done;)if(!i.has(s.value[0]))return!1;return!0}if(o&&ArrayBuffer.isView(e)&&ArrayBuffer.isView(i)){if((l=e.length)!=i.length)return!1;for(s=l;0!=s--;)if(e[s]!==i[s])return!1;return!0}if(e.constructor===RegExp)return e.source===i.source&&e.flags===i.flags;if(e.valueOf!==Object.prototype.valueOf)return e.valueOf()===i.valueOf();if(e.toString!==Object.prototype.toString)return e.toString()===i.toString();if((l=(u=Object.keys(e)).length)!==Object.keys(i).length)return!1;for(s=l;0!=s--;)if(!Object.prototype.hasOwnProperty.call(i,u[s]))return!1;if(t&&e instanceof Element)return!1;for(s=l;0!=s--;)if(("_owner"!==u[s]&&"__v"!==u[s]&&"__o"!==u[s]||!e.$$typeof)&&!a(e[u[s]],i[u[s]]))return!1;return!0}return e!=e&&i!=i}e.exports=function(e,t){try{return a(e,t)}catch(n){if((n.message||"").match(/stack|recursion/i))return console.warn("react-fast-compare cannot handle circular refs"),!1;throw n}}},70405:(e,t,n)=>{"use strict";n.d(t,{B6:()=>q,ql:()=>J});var r=n(67294),o=n(45697),a=n.n(o),i=n(69590),l=n.n(i),s=n(41143),u=n.n(s),c=n(96774),d=n.n(c);function f(){return f=Object.assign||function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e},f.apply(this,arguments)}function p(e,t){e.prototype=Object.create(t.prototype),e.prototype.constructor=e,h(e,t)}function h(e,t){return h=Object.setPrototypeOf||function(e,t){return e.__proto__=t,e},h(e,t)}function m(e,t){if(null==e)return{};var n,r,o={},a=Object.keys(e);for(r=0;r<a.length;r++)t.indexOf(n=a[r])>=0||(o[n]=e[n]);return o}var g={BASE:"base",BODY:"body",HEAD:"head",HTML:"html",LINK:"link",META:"meta",NOSCRIPT:"noscript",SCRIPT:"script",STYLE:"style",TITLE:"title",FRAGMENT:"Symbol(react.fragment)"},v={rel:["amphtml","canonical","alternate"]},b={type:["application/ld+json"]},y={charset:"",name:["robots","description"],property:["og:type","og:title","og:url","og:image","og:image:alt","og:description","twitter:url","twitter:title","twitter:description","twitter:image","twitter:image:alt","twitter:card","twitter:site"]},w=Object.keys(g).map((function(e){return g[e]})),x={accesskey:"accessKey",charset:"charSet",class:"className",contenteditable:"contentEditable",contextmenu:"contextMenu","http-equiv":"httpEquiv",itemprop:"itemProp",tabindex:"tabIndex"},_=Object.keys(x).reduce((function(e,t){return e[x[t]]=t,e}),{}),k=function(e,t){for(var n=e.length-1;n>=0;n-=1){var r=e[n];if(Object.prototype.hasOwnProperty.call(r,t))return r[t]}return null},E=function(e){var t=k(e,g.TITLE),n=k(e,"titleTemplate");if(Array.isArray(t)&&(t=t.join("")),n&&t)return n.replace(/%s/g,(function(){return t}));var r=k(e,"defaultTitle");return t||r||void 0},S=function(e){return k(e,"onChangeClientState")||function(){}},C=function(e,t){return t.filter((function(t){return void 0!==t[e]})).map((function(t){return t[e]})).reduce((function(e,t){return f({},e,t)}),{})},T=function(e,t){return t.filter((function(e){return void 0!==e[g.BASE]})).map((function(e){return e[g.BASE]})).reverse().reduce((function(t,n){if(!t.length)for(var r=Object.keys(n),o=0;o<r.length;o+=1){var a=r[o].toLowerCase();if(-1!==e.indexOf(a)&&n[a])return t.concat(n)}return t}),[])},O=function(e,t,n){var r={};return n.filter((function(t){return!!Array.isArray(t[e])||(void 0!==t[e]&&console&&"function"==typeof console.warn&&console.warn("Helmet: "+e+' should be of type "Array". Instead found type "'+typeof t[e]+'"'),!1)})).map((function(t){return t[e]})).reverse().reduce((function(e,n){var o={};n.filter((function(e){for(var n,a=Object.keys(e),i=0;i<a.length;i+=1){var l=a[i],s=l.toLowerCase();-1===t.indexOf(s)||"rel"===n&&"canonical"===e[n].toLowerCase()||"rel"===s&&"stylesheet"===e[s].toLowerCase()||(n=s),-1===t.indexOf(l)||"innerHTML"!==l&&"cssText"!==l&&"itemprop"!==l||(n=l)}if(!n||!e[n])return!1;var u=e[n].toLowerCase();return r[n]||(r[n]={}),o[n]||(o[n]={}),!r[n][u]&&(o[n][u]=!0,!0)})).reverse().forEach((function(t){return e.push(t)}));for(var a=Object.keys(o),i=0;i<a.length;i+=1){var l=a[i],s=f({},r[l],o[l]);r[l]=s}return e}),[]).reverse()},D=function(e,t){if(Array.isArray(e)&&e.length)for(var n=0;n<e.length;n+=1)if(e[n][t])return!0;return!1},P=function(e){return Array.isArray(e)?e.join(""):e},N=function(e,t){return Array.isArray(e)?e.reduce((function(e,n){return function(e,t){for(var n=Object.keys(e),r=0;r<n.length;r+=1)if(t[n[r]]&&t[n[r]].includes(e[n[r]]))return!0;return!1}(n,t)?e.priority.push(n):e.default.push(n),e}),{priority:[],default:[]}):{default:e}},A=function(e,t){var n;return f({},e,((n={})[t]=void 0,n))},I=[g.NOSCRIPT,g.SCRIPT,g.STYLE],L=function(e,t){return void 0===t&&(t=!0),!1===t?String(e):String(e).replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""").replace(/'/g,"'")},R=function(e){return Object.keys(e).reduce((function(t,n){var r=void 0!==e[n]?n+'="'+e[n]+'"':""+n;return t?t+" "+r:r}),"")},j=function(e,t){return void 0===t&&(t={}),Object.keys(e).reduce((function(t,n){return t[x[n]||n]=e[n],t}),t)},M=function(e,t){return t.map((function(t,n){var o,a=((o={key:n})["data-rh"]=!0,o);return Object.keys(t).forEach((function(e){var n=x[e]||e;"innerHTML"===n||"cssText"===n?a.dangerouslySetInnerHTML={__html:t.innerHTML||t.cssText}:a[n]=t[e]})),r.createElement(e,a)}))},F=function(e,t,n){switch(e){case g.TITLE:return{toComponent:function(){return n=t.titleAttributes,(o={key:e=t.title})["data-rh"]=!0,a=j(n,o),[r.createElement(g.TITLE,a,e)];var e,n,o,a},toString:function(){return function(e,t,n,r){var o=R(n),a=P(t);return o?"<"+e+' data-rh="true" '+o+">"+L(a,r)+"</"+e+">":"<"+e+' data-rh="true">'+L(a,r)+"</"+e+">"}(e,t.title,t.titleAttributes,n)}};case"bodyAttributes":case"htmlAttributes":return{toComponent:function(){return j(t)},toString:function(){return R(t)}};default:return{toComponent:function(){return M(e,t)},toString:function(){return function(e,t,n){return t.reduce((function(t,r){var o=Object.keys(r).filter((function(e){return!("innerHTML"===e||"cssText"===e)})).reduce((function(e,t){var o=void 0===r[t]?t:t+'="'+L(r[t],n)+'"';return e?e+" "+o:o}),""),a=r.innerHTML||r.cssText||"",i=-1===I.indexOf(e);return t+"<"+e+' data-rh="true" '+o+(i?"/>":">"+a+"</"+e+">")}),"")}(e,t,n)}}}},B=function(e){var t=e.baseTag,n=e.bodyAttributes,r=e.encode,o=e.htmlAttributes,a=e.noscriptTags,i=e.styleTags,l=e.title,s=void 0===l?"":l,u=e.titleAttributes,c=e.linkTags,d=e.metaTags,f=e.scriptTags,p={toComponent:function(){},toString:function(){return""}};if(e.prioritizeSeoTags){var h=function(e){var t=e.linkTags,n=e.scriptTags,r=e.encode,o=N(e.metaTags,y),a=N(t,v),i=N(n,b);return{priorityMethods:{toComponent:function(){return[].concat(M(g.META,o.priority),M(g.LINK,a.priority),M(g.SCRIPT,i.priority))},toString:function(){return F(g.META,o.priority,r)+" "+F(g.LINK,a.priority,r)+" "+F(g.SCRIPT,i.priority,r)}},metaTags:o.default,linkTags:a.default,scriptTags:i.default}}(e);p=h.priorityMethods,c=h.linkTags,d=h.metaTags,f=h.scriptTags}return{priority:p,base:F(g.BASE,t,r),bodyAttributes:F("bodyAttributes",n,r),htmlAttributes:F("htmlAttributes",o,r),link:F(g.LINK,c,r),meta:F(g.META,d,r),noscript:F(g.NOSCRIPT,a,r),script:F(g.SCRIPT,f,r),style:F(g.STYLE,i,r),title:F(g.TITLE,{title:s,titleAttributes:u},r)}},z=[],$=function(e,t){var n=this;void 0===t&&(t="undefined"!=typeof document),this.instances=[],this.value={setHelmet:function(e){n.context.helmet=e},helmetInstances:{get:function(){return n.canUseDOM?z:n.instances},add:function(e){(n.canUseDOM?z:n.instances).push(e)},remove:function(e){var t=(n.canUseDOM?z:n.instances).indexOf(e);(n.canUseDOM?z:n.instances).splice(t,1)}}},this.context=e,this.canUseDOM=t,t||(e.helmet=B({baseTag:[],bodyAttributes:{},encodeSpecialCharacters:!0,htmlAttributes:{},linkTags:[],metaTags:[],noscriptTags:[],scriptTags:[],styleTags:[],title:"",titleAttributes:{}}))},U=r.createContext({}),H=a().shape({setHelmet:a().func,helmetInstances:a().shape({get:a().func,add:a().func,remove:a().func})}),V="undefined"!=typeof document,q=function(e){function t(n){var r;return(r=e.call(this,n)||this).helmetData=new $(r.props.context,t.canUseDOM),r}return p(t,e),t.prototype.render=function(){return r.createElement(U.Provider,{value:this.helmetData.value},this.props.children)},t}(r.Component);q.canUseDOM=V,q.propTypes={context:a().shape({helmet:a().shape()}),children:a().node.isRequired},q.defaultProps={context:{}},q.displayName="HelmetProvider";var G=function(e,t){var n,r=document.head||document.querySelector(g.HEAD),o=r.querySelectorAll(e+"[data-rh]"),a=[].slice.call(o),i=[];return t&&t.length&&t.forEach((function(t){var r=document.createElement(e);for(var o in t)Object.prototype.hasOwnProperty.call(t,o)&&("innerHTML"===o?r.innerHTML=t.innerHTML:"cssText"===o?r.styleSheet?r.styleSheet.cssText=t.cssText:r.appendChild(document.createTextNode(t.cssText)):r.setAttribute(o,void 0===t[o]?"":t[o]));r.setAttribute("data-rh","true"),a.some((function(e,t){return n=t,r.isEqualNode(e)}))?a.splice(n,1):i.push(r)})),a.forEach((function(e){return e.parentNode.removeChild(e)})),i.forEach((function(e){return r.appendChild(e)})),{oldTags:a,newTags:i}},W=function(e,t){var n=document.getElementsByTagName(e)[0];if(n){for(var r=n.getAttribute("data-rh"),o=r?r.split(","):[],a=[].concat(o),i=Object.keys(t),l=0;l<i.length;l+=1){var s=i[l],u=t[s]||"";n.getAttribute(s)!==u&&n.setAttribute(s,u),-1===o.indexOf(s)&&o.push(s);var c=a.indexOf(s);-1!==c&&a.splice(c,1)}for(var d=a.length-1;d>=0;d-=1)n.removeAttribute(a[d]);o.length===a.length?n.removeAttribute("data-rh"):n.getAttribute("data-rh")!==i.join(",")&&n.setAttribute("data-rh",i.join(","))}},Z=function(e,t){var n=e.baseTag,r=e.htmlAttributes,o=e.linkTags,a=e.metaTags,i=e.noscriptTags,l=e.onChangeClientState,s=e.scriptTags,u=e.styleTags,c=e.title,d=e.titleAttributes;W(g.BODY,e.bodyAttributes),W(g.HTML,r),function(e,t){void 0!==e&&document.title!==e&&(document.title=P(e)),W(g.TITLE,t)}(c,d);var f={baseTag:G(g.BASE,n),linkTags:G(g.LINK,o),metaTags:G(g.META,a),noscriptTags:G(g.NOSCRIPT,i),scriptTags:G(g.SCRIPT,s),styleTags:G(g.STYLE,u)},p={},h={};Object.keys(f).forEach((function(e){var t=f[e],n=t.newTags,r=t.oldTags;n.length&&(p[e]=n),r.length&&(h[e]=f[e].oldTags)})),t&&t(),l(e,p,h)},Q=null,Y=function(e){function t(){for(var t,n=arguments.length,r=new Array(n),o=0;o<n;o++)r[o]=arguments[o];return(t=e.call.apply(e,[this].concat(r))||this).rendered=!1,t}p(t,e);var n=t.prototype;return n.shouldComponentUpdate=function(e){return!d()(e,this.props)},n.componentDidUpdate=function(){this.emitChange()},n.componentWillUnmount=function(){this.props.context.helmetInstances.remove(this),this.emitChange()},n.emitChange=function(){var e,t,n=this.props.context,r=n.setHelmet,o=null,a=(e=n.helmetInstances.get().map((function(e){var t=f({},e.props);return delete t.context,t})),{baseTag:T(["href"],e),bodyAttributes:C("bodyAttributes",e),defer:k(e,"defer"),encode:k(e,"encodeSpecialCharacters"),htmlAttributes:C("htmlAttributes",e),linkTags:O(g.LINK,["rel","href"],e),metaTags:O(g.META,["name","charset","http-equiv","property","itemprop"],e),noscriptTags:O(g.NOSCRIPT,["innerHTML"],e),onChangeClientState:S(e),scriptTags:O(g.SCRIPT,["src","innerHTML"],e),styleTags:O(g.STYLE,["cssText"],e),title:E(e),titleAttributes:C("titleAttributes",e),prioritizeSeoTags:D(e,"prioritizeSeoTags")});q.canUseDOM?(t=a,Q&&cancelAnimationFrame(Q),t.defer?Q=requestAnimationFrame((function(){Z(t,(function(){Q=null}))})):(Z(t),Q=null)):B&&(o=B(a)),r(o)},n.init=function(){this.rendered||(this.rendered=!0,this.props.context.helmetInstances.add(this),this.emitChange())},n.render=function(){return this.init(),null},t}(r.Component);Y.propTypes={context:H.isRequired},Y.displayName="HelmetDispatcher";var X=["children"],K=["children"],J=function(e){function t(){return e.apply(this,arguments)||this}p(t,e);var n=t.prototype;return n.shouldComponentUpdate=function(e){return!l()(A(this.props,"helmetData"),A(e,"helmetData"))},n.mapNestedChildrenToProps=function(e,t){if(!t)return null;switch(e.type){case g.SCRIPT:case g.NOSCRIPT:return{innerHTML:t};case g.STYLE:return{cssText:t};default:throw new Error("<"+e.type+" /> elements are self-closing and can not contain children. Refer to our API for more information.")}},n.flattenArrayTypeChildren=function(e){var t,n=e.child,r=e.arrayTypeChildren;return f({},r,((t={})[n.type]=[].concat(r[n.type]||[],[f({},e.newChildProps,this.mapNestedChildrenToProps(n,e.nestedChildren))]),t))},n.mapObjectTypeChildren=function(e){var t,n,r=e.child,o=e.newProps,a=e.newChildProps,i=e.nestedChildren;switch(r.type){case g.TITLE:return f({},o,((t={})[r.type]=i,t.titleAttributes=f({},a),t));case g.BODY:return f({},o,{bodyAttributes:f({},a)});case g.HTML:return f({},o,{htmlAttributes:f({},a)});default:return f({},o,((n={})[r.type]=f({},a),n))}},n.mapArrayTypeChildrenToProps=function(e,t){var n=f({},t);return Object.keys(e).forEach((function(t){var r;n=f({},n,((r={})[t]=e[t],r))})),n},n.warnOnInvalidChildren=function(e,t){return u()(w.some((function(t){return e.type===t})),"function"==typeof e.type?"You may be attempting to nest <Helmet> components within each other, which is not allowed. Refer to our API for more information.":"Only elements types "+w.join(", ")+" are allowed. Helmet does not support rendering <"+e.type+"> elements. Refer to our API for more information."),u()(!t||"string"==typeof t||Array.isArray(t)&&!t.some((function(e){return"string"!=typeof e})),"Helmet expects a string as a child of <"+e.type+">. Did you forget to wrap your children in braces? ( <"+e.type+">{``}</"+e.type+"> ) Refer to our API for more information."),!0},n.mapChildrenToProps=function(e,t){var n=this,o={};return r.Children.forEach(e,(function(e){if(e&&e.props){var r=e.props,a=r.children,i=m(r,X),l=Object.keys(i).reduce((function(e,t){return e[_[t]||t]=i[t],e}),{}),s=e.type;switch("symbol"==typeof s?s=s.toString():n.warnOnInvalidChildren(e,a),s){case g.FRAGMENT:t=n.mapChildrenToProps(a,t);break;case g.LINK:case g.META:case g.NOSCRIPT:case g.SCRIPT:case g.STYLE:o=n.flattenArrayTypeChildren({child:e,arrayTypeChildren:o,newChildProps:l,nestedChildren:a});break;default:t=n.mapObjectTypeChildren({child:e,newProps:t,newChildProps:l,nestedChildren:a})}}})),this.mapArrayTypeChildrenToProps(o,t)},n.render=function(){var e=this.props,t=e.children,n=m(e,K),o=f({},n),a=n.helmetData;return t&&(o=this.mapChildrenToProps(t,o)),!a||a instanceof $||(a=new $(a.context,a.instances)),a?r.createElement(Y,f({},o,{context:a.value,helmetData:void 0})):r.createElement(U.Consumer,null,(function(e){return r.createElement(Y,f({},o,{context:e}))}))},t}(r.Component);J.propTypes={base:a().object,bodyAttributes:a().object,children:a().oneOfType([a().arrayOf(a().node),a().node]),defaultTitle:a().string,defer:a().bool,encodeSpecialCharacters:a().bool,htmlAttributes:a().object,link:a().arrayOf(a().object),meta:a().arrayOf(a().object),noscript:a().arrayOf(a().object),onChangeClientState:a().func,script:a().arrayOf(a().object),style:a().arrayOf(a().object),title:a().string,titleAttributes:a().object,titleTemplate:a().string,prioritizeSeoTags:a().bool,helmetData:a().object},J.defaultProps={defer:!0,encodeSpecialCharacters:!0,prioritizeSeoTags:!1},J.displayName="Helmet"},69921:(e,t)=>{"use strict";var n="function"==typeof Symbol&&Symbol.for,r=n?Symbol.for("react.element"):60103,o=n?Symbol.for("react.portal"):60106,a=n?Symbol.for("react.fragment"):60107,i=n?Symbol.for("react.strict_mode"):60108,l=n?Symbol.for("react.profiler"):60114,s=n?Symbol.for("react.provider"):60109,u=n?Symbol.for("react.context"):60110,c=n?Symbol.for("react.async_mode"):60111,d=n?Symbol.for("react.concurrent_mode"):60111,f=n?Symbol.for("react.forward_ref"):60112,p=n?Symbol.for("react.suspense"):60113,h=n?Symbol.for("react.suspense_list"):60120,m=n?Symbol.for("react.memo"):60115,g=n?Symbol.for("react.lazy"):60116,v=n?Symbol.for("react.block"):60121,b=n?Symbol.for("react.fundamental"):60117,y=n?Symbol.for("react.responder"):60118,w=n?Symbol.for("react.scope"):60119;function x(e){if("object"==typeof e&&null!==e){var t=e.$$typeof;switch(t){case r:switch(e=e.type){case c:case d:case a:case l:case i:case p:return e;default:switch(e=e&&e.$$typeof){case u:case f:case g:case m:case s:return e;default:return t}}case o:return t}}}function _(e){return x(e)===d}t.AsyncMode=c,t.ConcurrentMode=d,t.ContextConsumer=u,t.ContextProvider=s,t.Element=r,t.ForwardRef=f,t.Fragment=a,t.Lazy=g,t.Memo=m,t.Portal=o,t.Profiler=l,t.StrictMode=i,t.Suspense=p,t.isAsyncMode=function(e){return _(e)||x(e)===c},t.isConcurrentMode=_,t.isContextConsumer=function(e){return x(e)===u},t.isContextProvider=function(e){return x(e)===s},t.isElement=function(e){return"object"==typeof e&&null!==e&&e.$$typeof===r},t.isForwardRef=function(e){return x(e)===f},t.isFragment=function(e){return x(e)===a},t.isLazy=function(e){return x(e)===g},t.isMemo=function(e){return x(e)===m},t.isPortal=function(e){return x(e)===o},t.isProfiler=function(e){return x(e)===l},t.isStrictMode=function(e){return x(e)===i},t.isSuspense=function(e){return x(e)===p},t.isValidElementType=function(e){return"string"==typeof e||"function"==typeof e||e===a||e===d||e===l||e===i||e===p||e===h||"object"==typeof e&&null!==e&&(e.$$typeof===g||e.$$typeof===m||e.$$typeof===s||e.$$typeof===u||e.$$typeof===f||e.$$typeof===b||e.$$typeof===y||e.$$typeof===w||e.$$typeof===v)},t.typeOf=x},59864:(e,t,n)=>{"use strict";e.exports=n(69921)},68356:(e,t,n)=>{"use strict";function r(e,t){e.prototype=Object.create(t.prototype),e.prototype.constructor=e,e.__proto__=t}function o(e){if(void 0===e)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return e}function a(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function i(){return i=Object.assign||function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e},i.apply(this,arguments)}var l=n(67294),s=n(45697),u=[],c=[];function d(e){var t=e(),n={loading:!0,loaded:null,error:null};return n.promise=t.then((function(e){return n.loading=!1,n.loaded=e,e})).catch((function(e){throw n.loading=!1,n.error=e,e})),n}function f(e){var t={loading:!1,loaded:{},error:null},n=[];try{Object.keys(e).forEach((function(r){var o=d(e[r]);o.loading?t.loading=!0:(t.loaded[r]=o.loaded,t.error=o.error),n.push(o.promise),o.promise.then((function(e){t.loaded[r]=e})).catch((function(e){t.error=e}))}))}catch(r){t.error=r}return t.promise=Promise.all(n).then((function(e){return t.loading=!1,e})).catch((function(e){throw t.loading=!1,e})),t}function p(e,t){return l.createElement((n=e)&&n.__esModule?n.default:n,t);var n}function h(e,t){var d,f;if(!t.loading)throw new Error("react-loadable requires a `loading` component");var h=i({loader:null,loading:null,delay:200,timeout:null,render:p,webpack:null,modules:null},t),m=null;function g(){return m||(m=e(h.loader)),m.promise}return u.push(g),"function"==typeof h.webpack&&c.push((function(){if((0,h.webpack)().every((function(e){return void 0!==e&&void 0!==n.m[e]})))return g()})),f=d=function(t){function n(n){var r;return a(o(o(r=t.call(this,n)||this)),"retry",(function(){r.setState({error:null,loading:!0,timedOut:!1}),m=e(h.loader),r._loadModule()})),g(),r.state={error:m.error,pastDelay:!1,timedOut:!1,loading:m.loading,loaded:m.loaded},r}r(n,t),n.preload=function(){return g()};var i=n.prototype;return i.UNSAFE_componentWillMount=function(){this._loadModule()},i.componentDidMount=function(){this._mounted=!0},i._loadModule=function(){var e=this;if(this.context.loadable&&Array.isArray(h.modules)&&h.modules.forEach((function(t){e.context.loadable.report(t)})),m.loading){var t=function(t){e._mounted&&e.setState(t)};"number"==typeof h.delay&&(0===h.delay?this.setState({pastDelay:!0}):this._delay=setTimeout((function(){t({pastDelay:!0})}),h.delay)),"number"==typeof h.timeout&&(this._timeout=setTimeout((function(){t({timedOut:!0})}),h.timeout));var n=function(){t({error:m.error,loaded:m.loaded,loading:m.loading}),e._clearTimeouts()};m.promise.then((function(){return n(),null})).catch((function(e){return n(),null}))}},i.componentWillUnmount=function(){this._mounted=!1,this._clearTimeouts()},i._clearTimeouts=function(){clearTimeout(this._delay),clearTimeout(this._timeout)},i.render=function(){return this.state.loading||this.state.error?l.createElement(h.loading,{isLoading:this.state.loading,pastDelay:this.state.pastDelay,timedOut:this.state.timedOut,error:this.state.error,retry:this.retry}):this.state.loaded?h.render(this.state.loaded,this.props):null},n}(l.Component),a(d,"contextTypes",{loadable:s.shape({report:s.func.isRequired})}),f}function m(e){return h(d,e)}m.Map=function(e){if("function"!=typeof e.render)throw new Error("LoadableMap requires a `render(loaded, props)` function");return h(f,e)};var g=function(e){function t(){return e.apply(this,arguments)||this}r(t,e);var n=t.prototype;return n.getChildContext=function(){return{loadable:{report:this.props.report}}},n.render=function(){return l.Children.only(this.props.children)},t}(l.Component);function v(e){for(var t=[];e.length;){var n=e.pop();t.push(n())}return Promise.all(t).then((function(){if(e.length)return v(e)}))}a(g,"propTypes",{report:s.func.isRequired}),a(g,"childContextTypes",{loadable:s.shape({report:s.func.isRequired}).isRequired}),m.Capture=g,m.preloadAll=function(){return new Promise((function(e,t){v(u).then(e,t)}))},m.preloadReady=function(){return new Promise((function(e,t){v(c).then(e,e)}))},e.exports=m},33199:(e,t,n)=>{"use strict";n.r(t),n.d(t,{default:()=>B,hasTranslate3DSupport:()=>h,isTouch:()=>d,make2dTransformValue:()=>f,make3dTransformValue:()=>p});var r=function(e,t){return r=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(e,t){e.__proto__=t}||function(e,t){for(var n in t)Object.prototype.hasOwnProperty.call(t,n)&&(e[n]=t[n])},r(e,t)};function o(e,t){if("function"!=typeof t&&null!==t)throw new TypeError("Class extends value "+String(t)+" is not a constructor or null");function n(){this.constructor=e}r(e,t),e.prototype=null===t?Object.create(t):(n.prototype=t.prototype,new n)}var a=function(){return a=Object.assign||function(e){for(var t,n=1,r=arguments.length;n<r;n++)for(var o in t=arguments[n])Object.prototype.hasOwnProperty.call(t,o)&&(e[o]=t[o]);return e},a.apply(this,arguments)};Object.create;Object.create;var i=n(67294),l="kvfysmfp",s="ufhsfnkm",u=".".concat(l,"{overflow:hidden;touch-action:none}.").concat(s,"{transform-origin: 0 0}"),c="undefined"==typeof window,d=function(){return!c&&("ontouchstart"in window||navigator.maxTouchPoints>0)},f=function(e){var t=e.x,n=e.y,r=e.scale;return"scale(".concat(r,") translate(").concat(t,"px, ").concat(n,"px)")},p=function(e){var t=e.x,n=e.y,r=e.scale;return"scale3d(".concat(r,",").concat(r,", 1) translate3d(").concat(t,"px, ").concat(n,"px, 0)")},h=function(){var e=!c&&window.CSS;return e&&e.supports&&e.supports("transform","translate3d(0,0,0)")},m=Math.min,g=Math.max;function v(e){var t=e.containerDimension,n=e.childDimension,r=e.padding,o=e.centerContained,a=n-t;return a+2*r<=0&&o?[a/2,a/2]:[m(a+r,0)-r,g(0,a+r)]}var b=function(e,t){return t?"".concat(e," ").concat(t):e},y=Math.abs,w=Math.min,x=Math.sqrt,_="undefined"==typeof window,k=!_&&/(Mac)/i.test(navigator.platform),E=function(e){return"drag"===e},S=function(e){return"zoom"===e},C=function(e){return k&&e.ctrlKey},T=function(e){e.stopPropagation(),e.preventDefault()},O=function(e,t){var n=e.x-t.x,r=e.y-t.y;return x(n*n+r*r)},D=function(e,t){var n=O(e[0],e[1]);return O(t[0],t[1])/n},P=function(e){return-Math.cos(e*Math.PI)/2+.5},N=function(e){return{x:e.pageX,y:e.pageY}},A=function(e){return Array.from(e).map(N)},I=function(e,t){return e+t},L=function(e,t,n){return n<e?e:n>t?t:n},R=function(e){return!(e.ctrlKey||e.metaKey)},j=function(){},M={x:0,y:0},F=function(e){function t(){var t=null!==e&&e.apply(this,arguments)||this;return t._prevDragMovePoint=null,t._containerObserver=null,t._fingers=0,t._firstMove=!0,t._initialOffset=a({},M),t._interaction=null,t._isDoubleTap=!1,t._isOffsetsSet=!1,t._lastDragPosition=null,t._lastScale=1,t._lastTouchStart=0,t._lastZoomCenter=null,t._listenMouseMove=!1,t._nthZoom=0,t._offset=a({},M),t._startOffset=a({},M),t._startTouches=null,t._updatePlaned=!1,t._wheelTimeOut=null,t._zoomFactor=1,t._initialZoomFactor=1,t._draggingPoint=a({},M),t._ignoreNextClick=!1,t._containerRef=i.createRef(),t._handleClick=function(e){t._ignoreNextClick&&(t._ignoreNextClick=!1,e.stopPropagation())},t._onResize=function(){var e;(null===(e=t._containerRef)||void 0===e?void 0:e.current)&&(t._updateInitialZoomFactor(),t._setupOffsets(),t._update())},t._handlerOnTouchEnd=t._handlerIfEnable((function(e){t._fingers=e.touches.length,t.props.shouldCancelHandledTouchEndEvents&&(S(t._interaction)||E(t._interaction)&&(t._startOffset.x!==t._offset.x||t._startOffset.y!==t._offset.y))&&T(e),E(t._interaction)&&!t._enoughToDrag()&&t._handleClick(e),t._updateInteraction(e)})),t._handlerOnTouchStart=t._handlerIfEnable((function(e){t._firstMove=!0,t._fingers=e.touches.length,t._detectDoubleTap(e)})),t._handlerOnTouchMove=t._handlerIfEnable((function(e){t._isDoubleTap||(t._collectInertia(e),t._firstMove?(t._updateInteraction(e),t._interaction&&T(e),t._startOffset=a({},t._offset),t._startTouches=A(e.touches)):(S(t._interaction)?t._startTouches&&2===t._startTouches.length&&2===e.touches.length&&t._handleZoom(e,D(t._startTouches,A(e.touches))):E(t._interaction)&&t._handleDrag(e),t._interaction&&(T(e),t._update())),t._firstMove=!1)})),t._handlerWheel=function(e){if(!t.props.shouldInterceptWheel(e)){T(e);var n=e.pageX,r=e.pageY,o=e.deltaY,a=e.deltaMode,i=1;(C(e)||1===a)&&(i=15);var l={touches:[{pageX:n,pageY:r}]},s=t._getOffsetByFirstTouch(l),u=o*i;t._stopAnimation(),t._scaleTo(t._zoomFactor-u/t.props.wheelScaleFactor,s),t._update(),clearTimeout(t._wheelTimeOut),t._wheelTimeOut=setTimeout((function(){return t._sanitize()}),100)}},t._handlers=t.props.isTouch()?[["touchstart",t._handlerOnTouchStart],["touchend",t._handlerOnTouchEnd],["touchmove",t._handlerOnTouchMove]]:[["mousemove",t.simulate(t._handlerOnTouchMove),t.props._document],["mouseup",t.simulate(t._handlerOnTouchEnd),t.props._document],["mousedown",t.simulate(t._handlerOnTouchStart)],["click",t._handleClick],["wheel",t._handlerWheel]],t}return o(t,e),t.prototype._handleDragStart=function(e){this._ignoreNextClick=!0,this.props.onDragStart(),this._stopAnimation(),this._resetInertia(),this._lastDragPosition=null,this._hasInteraction=!0,this._draggingPoint=this._offset,this._handleDrag(e)},t.prototype._handleDrag=function(e){var t=this._getOffsetByFirstTouch(e);this._enoughToDrag()?this._drag(t,this._lastDragPosition):this._virtualDrag(t,this._lastDragPosition),this._offset=this._sanitizeOffset(this._offset),this._lastDragPosition=t},t.prototype._resetInertia=function(){this._velocity=null,this._prevDragMovePoint=null},t.prototype._realizeInertia=function(){var e=this,t=this.props,n=t.inertiaFriction;if(t.inertia&&this._velocity){var r=this._velocity,o=r.x,i=r.y;if(o||i){this._stopAnimation(),this._resetInertia();this._animate((function(){if(i*=n,!(o*=n)&&!i)return e._stopAnimation();var t,r,l=a({},e._offset);if(e._addOffset({x:o,y:i}),e._offset=e._sanitizeOffset(e._offset),t=l,r=e._offset,t.x===r.x&&t.y===r.y)return e._stopAnimation();e._update({isAnimation:!0})}),{duration:9999})}}},t.prototype._collectInertia=function(e){var t=e.touches;if(this.props.inertia){var n,r,o=A(t)[0],a=this._prevDragMovePoint;a&&(this._velocity=(n=o,{x:(r=a).x-n.x,y:r.y-n.y})),this._prevDragMovePoint=o}},t.prototype._handleDragEnd=function(){this.props.onDragEnd(),this._end(),this._realizeInertia()},t.prototype._handleZoomStart=function(){this.props.onZoomStart(),this._stopAnimation(),this._lastScale=1,this._nthZoom=0,this._lastZoomCenter=null,this._hasInteraction=!0},t.prototype._handleZoom=function(e,t){var n,r={x:(n=this._getOffsetTouches(e)).map((function(e){return e.x})).reduce(I,0)/n.length,y:n.map((function(e){return e.y})).reduce(I,0)/n.length},o=t/this._lastScale;this._lastScale=t,this._nthZoom+=1,this._nthZoom>3&&(this._scale(o,r),this._drag(r,this._lastZoomCenter),this.props.enforceBoundsDuringZoom&&(this._offset=this._sanitizeOffset(this._offset))),this._lastZoomCenter=r},t.prototype._handleZoomEnd=function(){this.props.onZoomEnd(),this._end()},t.prototype._handleDoubleTap=function(e){var t=this;if(!this._hasInteraction&&0!==this.props.tapZoomFactor){var n=this.props.doubleTapZoomOutOnMaxScale&&this._zoomFactor===this.props.maxZoom||this.props.doubleTapToggleZoom&&this._zoomFactor>1;this.props.onDoubleTap(),this._ignoreNextClick=!0;var r=this._zoomFactor+this.props.tapZoomFactor,o=this._zoomFactor,a=this._getOffsetByFirstTouch(e);this._isDoubleTap=!0,o>r&&(a=this._getCurrentZoomCenter()),n?this._zoomOutAnimation():this._animate((function(e){t._scaleTo(o+e*(r-o),a)}))}},t.prototype._computeInitialOffset=function(){var e=this._getContainerRect(),t=this._getChildSize(),n=t.width,r=t.height,o=-y(n*this._getInitialZoomFactor()-e.width)/2,a=-y(r*this._getInitialZoomFactor()-e.height)/2;this._initialOffset={x:o,y:a}},t.prototype._resetOffset=function(){this._offset=a({},this._initialOffset)},t.prototype._setupOffsets=function(){this.props.setOffsetsOnce&&this._isOffsetsSet||(this._isOffsetsSet=!0,this._computeInitialOffset(),this._resetOffset())},t.prototype._sanitizeOffset=function(e){var t=this._getContainerRect(),n=this._getChildSize(),r=n.width,o=n.height,a=r*this._getInitialZoomFactor()*this._zoomFactor,i=o*this._getInitialZoomFactor()*this._zoomFactor,l=v({containerDimension:t.width,childDimension:a,padding:this.props.horizontalPadding,centerContained:this.props.centerContained}),s=l[0],u=l[1],c=v({containerDimension:t.height,childDimension:i,padding:this.props.verticalPadding,centerContained:this.props.centerContained}),d=c[0],f=c[1];return{x:L(s,u,e.x),y:L(d,f,e.y)}},t.prototype.alignCenter=function(e){var t=this,n=a({duration:250,animated:!0},e),r=n.x,o=n.y,i=n.scale,l=n.animated,s=n.duration,u=this._zoomFactor,c=a({},this._offset),d=this._getContainerRect(),f={x:d.width/2,y:d.height/2};if(this._zoomFactor=1,this._offset={x:-(f.x-r),y:-(f.y-o)},this._scaleTo(i,f),this._stopAnimation(),!l)return this._update();var p=this._zoomFactor-u,h=this._offset.x-c.x,m=this._offset.y-c.y;this._zoomFactor=u,this._offset=a({},c);this._animate((function(e){var n=c.x+h*e,r=c.y+m*e;t._zoomFactor=u+p*e,t._offset=t._sanitizeOffset({x:n,y:r}),t._update()}),{callback:function(){return t._sanitize()},duration:s})},t.prototype.scaleTo=function(e){var t=this,n=a({duration:250,animated:!0},e),r=n.x,o=n.y,i=n.scale,l=n.animated,s=n.duration,u=this._zoomFactor,c=a({},this._offset);if(this._zoomFactor=1,this._offset={x:0,y:0},this._scaleTo(i,{x:r,y:o}),this._stopAnimation(),!l)return this._update();var d=this._zoomFactor-u,f=this._offset.x-c.x,p=this._offset.y-c.y;this._zoomFactor=u,this._offset=a({},c);this._animate((function(e){var n=c.x+f*e,r=c.y+p*e;t._zoomFactor=u+d*e,t._offset={x:n,y:r},t._update()}),{callback:function(){return t._sanitize()},duration:s})},t.prototype._scaleTo=function(e,t){this._scale(e/this._zoomFactor,t),this._offset=this._sanitizeOffset(this._offset)},t.prototype._scale=function(e,t){e=this._scaleZoomFactor(e),this._addOffset({x:(e-1)*(t.x+this._offset.x),y:(e-1)*(t.y+this._offset.y)}),this.props.onZoomUpdate()},t.prototype._scaleZoomFactor=function(e){var t=this._zoomFactor;return this._zoomFactor*=e,this._zoomFactor=L(this.props.minZoom,this.props.maxZoom,this._zoomFactor),this._zoomFactor/t},t.prototype._canDrag=function(){return this.props.draggableUnZoomed||!((e=this._zoomFactor)>(t=1)-.01&&e<t+.01);var e,t},t.prototype._drag=function(e,t){if(t){var n=-(e.y-t.y),r=-(e.x-t.x);this.props.lockDragAxis?y(r)>y(n)?this._addOffset({x:r,y:0}):this._addOffset({y:n,x:0}):this._addOffset({x:r,y:n}),this.props.onDragUpdate()}},t.prototype._virtualDrag=function(e,t){if(t){var n=-(e.y-t.y),r=-(e.x-t.x);this._draggingPoint={x:r+this._draggingPoint.x,y:n+this._draggingPoint.y}}},t.prototype._addOffset=function(e){var t=this._offset,n=t.x,r=t.y;this._offset={x:n+e.x,y:r+e.y}},t.prototype._sanitize=function(){this._zoomFactor<this.props.zoomOutFactor?(this._resetInertia(),this._zoomOutAnimation()):this._isInsaneOffset()&&this._sanitizeOffsetAnimation()},t.prototype._isInsaneOffset=function(){var e=this._offset,t=this._sanitizeOffset(e);return t.x!==e.x||t.y!==e.y},t.prototype._sanitizeOffsetAnimation=function(){var e=this,t=this._sanitizeOffset(this._offset),n=a({},this._offset);this._animate((function(r){var o=n.x+r*(t.x-n.x),a=n.y+r*(t.y-n.y);e._offset={x:o,y:a},e._update()}))},t.prototype._zoomOutAnimation=function(){var e=this;if(1!==this._zoomFactor){var t=this._zoomFactor,n=this._getCurrentZoomCenter();this._animate((function(r){var o=t+r*(1-t);e._scaleTo(o,n)}))}},t.prototype._getInitialZoomFactor=function(){return this._initialZoomFactor},t.prototype._getCurrentZoomCenter=function(){var e=this._offset,t=e.x,n=e.y,r=t-this._initialOffset.x,o=n-this._initialOffset.y;return{x:-1*t-r/(1/this._zoomFactor-1),y:-1*n-o/(1/this._zoomFactor-1)}},t.prototype._getOffsetByFirstTouch=function(e){return this._getOffsetTouches(e)[0]},t.prototype._getOffsetTouches=function(e){var t=this.props._document,n=t.documentElement,r=t.body,o=this._getContainerRect(),a=o.top,i=o.left,l=n.scrollTop||r.scrollTop,s=n.scrollLeft||r.scrollLeft,u=a+l,c=i+s;return A(e.touches).map((function(e){var t=e.x,n=e.y;return{x:t-c,y:n-u}}))},t.prototype._animate=function(e,t){var n=this,r=(new Date).getTime(),o=a({timeFn:P,callback:function(){},duration:this.props.animationDuration},t),i=o.timeFn,l=o.callback,s=o.duration,u=function(){if(n._inAnimation){var t=(new Date).getTime()-r,o=t/s;t>=s?(e(1),n._stopAnimation(),l(),n._update()):(o=i(o),e(o),n._update({isAnimation:!0}),requestAnimationFrame(u))}};this._inAnimation=!0,requestAnimationFrame(u)},t.prototype._stopAnimation=function(){this._inAnimation=!1},t.prototype._end=function(){this._hasInteraction=!1,this._sanitize(),this._update()},t.prototype._getContainerRect=function(){return this._containerRef.current.getBoundingClientRect()},t.prototype._getChildSize=function(){var e=this._containerRef.current;return function(e){if(e){var t=e.offsetWidth,n=e.offsetHeight;if(t&&n)return{width:t,height:n};var r=getComputedStyle(e),o=parseFloat(r.width),a=parseFloat(r.height);if(a&&o)return{width:o,height:a}}return{width:0,height:0}}(null==e?void 0:e.firstElementChild)},t.prototype._updateInitialZoomFactor=function(){var e=this._getContainerRect(),t=this._getChildSize(),n=e.width/t.width,r=e.height/t.height;this._initialZoomFactor=w(n,r)},t.prototype._bindEvents=function(){var e=this,t=this._containerRef.current;window.ResizeObserver?(this._containerObserver=new ResizeObserver(this._onResize),this._containerObserver.observe(t)):window.addEventListener("resize",this._onResize),this._handlers.forEach((function(e){var n=e[0],r=e[1];(e[2]||t).addEventListener(n,r,!0)})),Array.from(t.querySelectorAll("img")).forEach((function(t){return t.addEventListener("load",e._onResize)}))},t.prototype._unSubscribe=function(){var e=this,t=this._containerRef.current;this._containerObserver&&(this._containerObserver.disconnect(),this._containerObserver=null),window.removeEventListener("resize",this._onResize),this._handlers.forEach((function(e){var n=e[0],r=e[1];(e[2]||t).removeEventListener(n,r,!0)})),Array.from(t.querySelectorAll("img")).forEach((function(t){return t.removeEventListener("load",e._onResize)}))},t.prototype._update=function(e){var t=this;if(!this._updatePlaned){var n=function(){var e=t._getInitialZoomFactor()*t._zoomFactor,n=-t._offset.x/e,r=-t._offset.y/e;t.props.onUpdate({scale:e,x:n,y:r})};if(null==e?void 0:e.isAnimation)return n();this._updatePlaned=!0,requestAnimationFrame((function(){t._updatePlaned=!1,n()}))}},t.prototype._handlerIfEnable=function(e){var t=this;return function(){for(var n=[],r=0;r<arguments.length;r++)n[r]=arguments[r];t.props.enabled&&e.apply(void 0,n)}},t.prototype._setInteraction=function(e,t){var n=this._interaction;n!==e&&(n&&!e&&(S(n)?this._handleZoomEnd():E(n)&&this._handleDragEnd()),S(e)?this._handleZoomStart():E(e)&&this._handleDragStart(t)),this._interaction=e},t.prototype._distanceBetweenNumbers=function(e,t){return e>t?e-t:t-e},t.prototype._enoughToDrag=function(){return this._distanceBetweenNumbers(this._startOffset.x,this._draggingPoint.x)>5||this._distanceBetweenNumbers(this._startOffset.y,this._draggingPoint.y)>5},t.prototype._updateInteraction=function(e){var t=this._fingers;return 2===t?this._setInteraction("zoom",e):1===t&&this._canDrag()?this._setInteraction("drag",e):void this._setInteraction(null,e)},t.prototype._detectDoubleTap=function(e){var t=(new Date).getTime();this._fingers>1&&(this._lastTouchStart=0),t-this._lastTouchStart<300?(T(e),this._handleDoubleTap(e),S(this._interaction)?this._handleZoomEnd():E(this._interaction)&&this._handleDragEnd()):this._isDoubleTap=!1,1===this._fingers&&(this._lastTouchStart=t)},t.prototype.simulate=function(e){var t=this;return function(n){var r=n.pageX,o=n.pageY,a=n.type,i="mouseup"===a;"mousedown"===a&&(n.preventDefault(),t._listenMouseMove=!0),t._listenMouseMove&&(n.touches=i?[]:[{pageX:r,pageY:o}],e(n)),i&&(t._listenMouseMove=!1)}},t.prototype.componentDidMount=function(){this._bindEvents(),this._update()},t.prototype.componentWillUnmount=function(){this._stopAnimation(),this._unSubscribe()},t.prototype.render=function(){var e=this.props,t=e.children,n=e.containerProps,r=i.Children.only(t),o=n||{};return i.createElement(i.Fragment,null,i.createElement("style",null,u),i.createElement("div",a({},o,{ref:this._containerRef,className:b(l,o.className)}),i.cloneElement(r,{className:b(s,r.props.className)})))},t.defaultProps={animationDuration:250,draggableUnZoomed:!0,enforceBoundsDuringZoom:!1,centerContained:!1,enabled:!0,inertia:!0,inertiaFriction:.96,horizontalPadding:0,isTouch:d,lockDragAxis:!1,maxZoom:5,minZoom:.5,onDoubleTap:j,onDragEnd:j,onDragStart:j,onDragUpdate:j,onZoomEnd:j,onZoomStart:j,onZoomUpdate:j,setOffsetsOnce:!1,shouldInterceptWheel:R,shouldCancelHandledTouchEndEvents:!1,tapZoomFactor:1,verticalPadding:0,wheelScaleFactor:1500,zoomOutFactor:1.3,doubleTapZoomOutOnMaxScale:!1,doubleTapToggleZoom:!1,_document:_?null:window.document},t}(i.Component);const B=F},18790:(e,t,n)=>{"use strict";n.d(t,{H:()=>l,f:()=>i});var r=n(16550),o=n(87462),a=n(67294);function i(e,t,n){return void 0===n&&(n=[]),e.some((function(e){var o=e.path?(0,r.LX)(t,e):n.length?n[n.length-1].match:r.F0.computeRootMatch(t);return o&&(n.push({route:e,match:o}),e.routes&&i(e.routes,t,n)),o})),n}function l(e,t,n){return void 0===t&&(t={}),void 0===n&&(n={}),e?a.createElement(r.rs,n,e.map((function(e,n){return a.createElement(r.AW,{key:e.key||n,path:e.path,exact:e.exact,strict:e.strict,render:function(n){return e.render?e.render((0,o.Z)({},n,{},t,{route:e})):a.createElement(e.component,(0,o.Z)({},n,t,{route:e}))}})}))):null}},73727:(e,t,n)=>{"use strict";n.d(t,{OL:()=>y,VK:()=>c,rU:()=>g});var r=n(16550),o=n(75068),a=n(67294),i=n(42358),l=n(87462),s=n(63366),u=n(38776),c=function(e){function t(){for(var t,n=arguments.length,r=new Array(n),o=0;o<n;o++)r[o]=arguments[o];return(t=e.call.apply(e,[this].concat(r))||this).history=(0,i.lX)(t.props),t}return(0,o.Z)(t,e),t.prototype.render=function(){return a.createElement(r.F0,{history:this.history,children:this.props.children})},t}(a.Component);a.Component;var d=function(e,t){return"function"==typeof e?e(t):e},f=function(e,t){return"string"==typeof e?(0,i.ob)(e,null,null,t):e},p=function(e){return e},h=a.forwardRef;void 0===h&&(h=p);var m=h((function(e,t){var n=e.innerRef,r=e.navigate,o=e.onClick,i=(0,s.Z)(e,["innerRef","navigate","onClick"]),u=i.target,c=(0,l.Z)({},i,{onClick:function(e){try{o&&o(e)}catch(t){throw e.preventDefault(),t}e.defaultPrevented||0!==e.button||u&&"_self"!==u||function(e){return!!(e.metaKey||e.altKey||e.ctrlKey||e.shiftKey)}(e)||(e.preventDefault(),r())}});return c.ref=p!==h&&t||n,a.createElement("a",c)}));var g=h((function(e,t){var n=e.component,o=void 0===n?m:n,c=e.replace,g=e.to,v=e.innerRef,b=(0,s.Z)(e,["component","replace","to","innerRef"]);return a.createElement(r.s6.Consumer,null,(function(e){e||(0,u.Z)(!1);var n=e.history,r=f(d(g,e.location),e.location),s=r?n.createHref(r):"",m=(0,l.Z)({},b,{href:s,navigate:function(){var t=d(g,e.location),r=(0,i.Ep)(e.location)===(0,i.Ep)(f(t));(c||r?n.replace:n.push)(t)}});return p!==h?m.ref=t||v:m.innerRef=v,a.createElement(o,m)}))})),v=function(e){return e},b=a.forwardRef;void 0===b&&(b=v);var y=b((function(e,t){var n=e["aria-current"],o=void 0===n?"page":n,i=e.activeClassName,c=void 0===i?"active":i,p=e.activeStyle,h=e.className,m=e.exact,y=e.isActive,w=e.location,x=e.sensitive,_=e.strict,k=e.style,E=e.to,S=e.innerRef,C=(0,s.Z)(e,["aria-current","activeClassName","activeStyle","className","exact","isActive","location","sensitive","strict","style","to","innerRef"]);return a.createElement(r.s6.Consumer,null,(function(e){e||(0,u.Z)(!1);var n=w||e.location,i=f(d(E,n),n),s=i.pathname,T=s&&s.replace(/([.+*?=^!:${}()[\]|/\\])/g,"\\$1"),O=T?(0,r.LX)(n.pathname,{path:T,exact:m,sensitive:x,strict:_}):null,D=!!(y?y(O,n):O),P="function"==typeof h?h(D):h,N="function"==typeof k?k(D):k;D&&(P=function(){for(var e=arguments.length,t=new Array(e),n=0;n<e;n++)t[n]=arguments[n];return t.filter((function(e){return e})).join(" ")}(P,c),N=(0,l.Z)({},N,p));var A=(0,l.Z)({"aria-current":D&&o||null,className:P,style:N,to:i},C);return v!==b?A.ref=t||S:A.innerRef=S,a.createElement(g,A)}))}))},16550:(e,t,n)=>{"use strict";n.d(t,{AW:()=>D,F0:()=>w,LX:()=>O,TH:()=>F,k6:()=>M,l_:()=>S,rs:()=>R,s6:()=>y});var r=n(75068),o=n(67294),a=n(45697),i=n.n(a),l=n(42358),s=n(38776),u=n(87462),c=n(39658),d=n.n(c),f=(n(59864),n(63366)),p=(n(8679),1073741823),h="undefined"!=typeof globalThis?globalThis:"undefined"!=typeof window?window:void 0!==n.g?n.g:{};function m(e){var t=[];return{on:function(e){t.push(e)},off:function(e){t=t.filter((function(t){return t!==e}))},get:function(){return e},set:function(n,r){e=n,t.forEach((function(t){return t(e,r)}))}}}var g=o.createContext||function(e,t){var n,a,l="__create-react-context-"+function(){var e="__global_unique_id__";return h[e]=(h[e]||0)+1}()+"__",s=function(e){function n(){for(var t,n=arguments.length,r=new Array(n),o=0;o<n;o++)r[o]=arguments[o];return(t=e.call.apply(e,[this].concat(r))||this).emitter=m(t.props.value),t}(0,r.Z)(n,e);var o=n.prototype;return o.getChildContext=function(){var e;return(e={})[l]=this.emitter,e},o.componentWillReceiveProps=function(e){if(this.props.value!==e.value){var n,r=this.props.value,o=e.value;((a=r)===(i=o)?0!==a||1/a==1/i:a!=a&&i!=i)?n=0:(n="function"==typeof t?t(r,o):p,0!==(n|=0)&&this.emitter.set(e.value,n))}var a,i},o.render=function(){return this.props.children},n}(o.Component);s.childContextTypes=((n={})[l]=i().object.isRequired,n);var u=function(t){function n(){for(var e,n=arguments.length,r=new Array(n),o=0;o<n;o++)r[o]=arguments[o];return(e=t.call.apply(t,[this].concat(r))||this).observedBits=void 0,e.state={value:e.getValue()},e.onUpdate=function(t,n){0!=((0|e.observedBits)&n)&&e.setState({value:e.getValue()})},e}(0,r.Z)(n,t);var o=n.prototype;return o.componentWillReceiveProps=function(e){var t=e.observedBits;this.observedBits=null==t?p:t},o.componentDidMount=function(){this.context[l]&&this.context[l].on(this.onUpdate);var e=this.props.observedBits;this.observedBits=null==e?p:e},o.componentWillUnmount=function(){this.context[l]&&this.context[l].off(this.onUpdate)},o.getValue=function(){return this.context[l]?this.context[l].get():e},o.render=function(){return(e=this.props.children,Array.isArray(e)?e[0]:e)(this.state.value);var e},n}(o.Component);return u.contextTypes=((a={})[l]=i().object,a),{Provider:s,Consumer:u}},v=function(e){var t=g();return t.displayName=e,t},b=v("Router-History"),y=v("Router"),w=function(e){function t(t){var n;return(n=e.call(this,t)||this).state={location:t.history.location},n._isMounted=!1,n._pendingLocation=null,t.staticContext||(n.unlisten=t.history.listen((function(e){n._pendingLocation=e}))),n}(0,r.Z)(t,e),t.computeRootMatch=function(e){return{path:"/",url:"/",params:{},isExact:"/"===e}};var n=t.prototype;return n.componentDidMount=function(){var e=this;this._isMounted=!0,this.unlisten&&this.unlisten(),this.props.staticContext||(this.unlisten=this.props.history.listen((function(t){e._isMounted&&e.setState({location:t})}))),this._pendingLocation&&this.setState({location:this._pendingLocation})},n.componentWillUnmount=function(){this.unlisten&&(this.unlisten(),this._isMounted=!1,this._pendingLocation=null)},n.render=function(){return o.createElement(y.Provider,{value:{history:this.props.history,location:this.state.location,match:t.computeRootMatch(this.state.location.pathname),staticContext:this.props.staticContext}},o.createElement(b.Provider,{children:this.props.children||null,value:this.props.history}))},t}(o.Component);o.Component;var x=function(e){function t(){return e.apply(this,arguments)||this}(0,r.Z)(t,e);var n=t.prototype;return n.componentDidMount=function(){this.props.onMount&&this.props.onMount.call(this,this)},n.componentDidUpdate=function(e){this.props.onUpdate&&this.props.onUpdate.call(this,this,e)},n.componentWillUnmount=function(){this.props.onUnmount&&this.props.onUnmount.call(this,this)},n.render=function(){return null},t}(o.Component);var _={},k=0;function E(e,t){return void 0===e&&(e="/"),void 0===t&&(t={}),"/"===e?e:function(e){if(_[e])return _[e];var t=d().compile(e);return k<1e4&&(_[e]=t,k++),t}(e)(t,{pretty:!0})}function S(e){var t=e.computedMatch,n=e.to,r=e.push,a=void 0!==r&&r;return o.createElement(y.Consumer,null,(function(e){e||(0,s.Z)(!1);var r=e.history,i=e.staticContext,c=a?r.push:r.replace,d=(0,l.ob)(t?"string"==typeof n?E(n,t.params):(0,u.Z)({},n,{pathname:E(n.pathname,t.params)}):n);return i?(c(d),null):o.createElement(x,{onMount:function(){c(d)},onUpdate:function(e,t){var n=(0,l.ob)(t.to);(0,l.Hp)(n,(0,u.Z)({},d,{key:n.key}))||c(d)},to:n})}))}var C={},T=0;function O(e,t){void 0===t&&(t={}),("string"==typeof t||Array.isArray(t))&&(t={path:t});var n=t,r=n.path,o=n.exact,a=void 0!==o&&o,i=n.strict,l=void 0!==i&&i,s=n.sensitive,u=void 0!==s&&s;return[].concat(r).reduce((function(t,n){if(!n&&""!==n)return null;if(t)return t;var r=function(e,t){var n=""+t.end+t.strict+t.sensitive,r=C[n]||(C[n]={});if(r[e])return r[e];var o=[],a={regexp:d()(e,o,t),keys:o};return T<1e4&&(r[e]=a,T++),a}(n,{end:a,strict:l,sensitive:u}),o=r.regexp,i=r.keys,s=o.exec(e);if(!s)return null;var c=s[0],f=s.slice(1),p=e===c;return a&&!p?null:{path:n,url:"/"===n&&""===c?"/":c,isExact:p,params:i.reduce((function(e,t,n){return e[t.name]=f[n],e}),{})}}),null)}var D=function(e){function t(){return e.apply(this,arguments)||this}return(0,r.Z)(t,e),t.prototype.render=function(){var e=this;return o.createElement(y.Consumer,null,(function(t){t||(0,s.Z)(!1);var n=e.props.location||t.location,r=e.props.computedMatch?e.props.computedMatch:e.props.path?O(n.pathname,e.props):t.match,a=(0,u.Z)({},t,{location:n,match:r}),i=e.props,l=i.children,c=i.component,d=i.render;return Array.isArray(l)&&function(e){return 0===o.Children.count(e)}(l)&&(l=null),o.createElement(y.Provider,{value:a},a.match?l?"function"==typeof l?l(a):l:c?o.createElement(c,a):d?d(a):null:"function"==typeof l?l(a):null)}))},t}(o.Component);function P(e){return"/"===e.charAt(0)?e:"/"+e}function N(e,t){if(!e)return t;var n=P(e);return 0!==t.pathname.indexOf(n)?t:(0,u.Z)({},t,{pathname:t.pathname.substr(n.length)})}function A(e){return"string"==typeof e?e:(0,l.Ep)(e)}function I(e){return function(){(0,s.Z)(!1)}}function L(){}o.Component;var R=function(e){function t(){return e.apply(this,arguments)||this}return(0,r.Z)(t,e),t.prototype.render=function(){var e=this;return o.createElement(y.Consumer,null,(function(t){t||(0,s.Z)(!1);var n,r,a=e.props.location||t.location;return o.Children.forEach(e.props.children,(function(e){if(null==r&&o.isValidElement(e)){n=e;var i=e.props.path||e.props.from;r=i?O(a.pathname,(0,u.Z)({},e.props,{path:i})):t.match}})),r?o.cloneElement(n,{location:a,computedMatch:r}):null}))},t}(o.Component);var j=o.useContext;function M(){return j(b)}function F(){return j(y).location}},76585:e=>{e.exports=Array.isArray||function(e){return"[object Array]"==Object.prototype.toString.call(e)}},39658:(e,t,n)=>{var r=n(76585);e.exports=p,e.exports.parse=a,e.exports.compile=function(e,t){return l(a(e,t),t)},e.exports.tokensToFunction=l,e.exports.tokensToRegExp=f;var o=new RegExp(["(\\\\.)","([\\/.])?(?:(?:\\:(\\w+)(?:\\(((?:\\\\.|[^\\\\()])+)\\))?|\\(((?:\\\\.|[^\\\\()])+)\\))([+*?])?|(\\*))"].join("|"),"g");function a(e,t){for(var n,r=[],a=0,i=0,l="",c=t&&t.delimiter||"/";null!=(n=o.exec(e));){var d=n[0],f=n[1],p=n.index;if(l+=e.slice(i,p),i=p+d.length,f)l+=f[1];else{var h=e[i],m=n[2],g=n[3],v=n[4],b=n[5],y=n[6],w=n[7];l&&(r.push(l),l="");var x=null!=m&&null!=h&&h!==m,_="+"===y||"*"===y,k="?"===y||"*"===y,E=n[2]||c,S=v||b;r.push({name:g||a++,prefix:m||"",delimiter:E,optional:k,repeat:_,partial:x,asterisk:!!w,pattern:S?u(S):w?".*":"[^"+s(E)+"]+?"})}}return i<e.length&&(l+=e.substr(i)),l&&r.push(l),r}function i(e){return encodeURI(e).replace(/[\/?#]/g,(function(e){return"%"+e.charCodeAt(0).toString(16).toUpperCase()}))}function l(e,t){for(var n=new Array(e.length),o=0;o<e.length;o++)"object"==typeof e[o]&&(n[o]=new RegExp("^(?:"+e[o].pattern+")$",d(t)));return function(t,o){for(var a="",l=t||{},s=(o||{}).pretty?i:encodeURIComponent,u=0;u<e.length;u++){var c=e[u];if("string"!=typeof c){var d,f=l[c.name];if(null==f){if(c.optional){c.partial&&(a+=c.prefix);continue}throw new TypeError('Expected "'+c.name+'" to be defined')}if(r(f)){if(!c.repeat)throw new TypeError('Expected "'+c.name+'" to not repeat, but received `'+JSON.stringify(f)+"`");if(0===f.length){if(c.optional)continue;throw new TypeError('Expected "'+c.name+'" to not be empty')}for(var p=0;p<f.length;p++){if(d=s(f[p]),!n[u].test(d))throw new TypeError('Expected all "'+c.name+'" to match "'+c.pattern+'", but received `'+JSON.stringify(d)+"`");a+=(0===p?c.prefix:c.delimiter)+d}}else{if(d=c.asterisk?encodeURI(f).replace(/[?#]/g,(function(e){return"%"+e.charCodeAt(0).toString(16).toUpperCase()})):s(f),!n[u].test(d))throw new TypeError('Expected "'+c.name+'" to match "'+c.pattern+'", but received "'+d+'"');a+=c.prefix+d}}else a+=c}return a}}function s(e){return e.replace(/([.+*?=^!:${}()[\]|\/\\])/g,"\\$1")}function u(e){return e.replace(/([=!:$\/()])/g,"\\$1")}function c(e,t){return e.keys=t,e}function d(e){return e&&e.sensitive?"":"i"}function f(e,t,n){r(t)||(n=t||n,t=[]);for(var o=(n=n||{}).strict,a=!1!==n.end,i="",l=0;l<e.length;l++){var u=e[l];if("string"==typeof u)i+=s(u);else{var f=s(u.prefix),p="(?:"+u.pattern+")";t.push(u),u.repeat&&(p+="(?:"+f+p+")*"),i+=p=u.optional?u.partial?f+"("+p+")?":"(?:"+f+"("+p+"))?":f+"("+p+")"}}var h=s(n.delimiter||"/"),m=i.slice(-h.length)===h;return o||(i=(m?i.slice(0,-h.length):i)+"(?:"+h+"(?=$))?"),i+=a?"$":o&&m?"":"(?="+h+"|$)",c(new RegExp("^"+i,d(n)),t)}function p(e,t,n){return r(t)||(n=t||n,t=[]),n=n||{},e instanceof RegExp?function(e,t){var n=e.source.match(/\((?!\?)/g);if(n)for(var r=0;r<n.length;r++)t.push({name:r,prefix:null,delimiter:null,optional:!1,repeat:!1,partial:!1,asterisk:!1,pattern:null});return c(e,t)}(e,t):r(e)?function(e,t,n){for(var r=[],o=0;o<e.length;o++)r.push(p(e[o],t,n).source);return c(new RegExp("(?:"+r.join("|")+")",d(n)),t)}(e,t,n):function(e,t,n){return f(a(e,n),t,n)}(e,t,n)}},86718:(e,t,n)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0});var r=n(70655).__importDefault(n(45503));t.default=function(e){return!e.prototype?r.default(e):e}},27162:(e,t,n)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.divWrapper=void 0;var r=n(70655),o=r.__importStar(n(67294)),a=r.__importDefault(n(86718)),i=o.createElement,l=function(e,t,n,o){var a;return i(e,t?r.__assign(((a={})[t]=o,a),n):r.__assign(r.__assign({},o),n))};t.divWrapper=function(e,t,n,r){return i("div",null,l(e,t,n,r))};t.default=function(e,t,n){void 0===n&&(n=l);var r=function(o,l,s){void 0===l&&(l=t),void 0===s&&(s=null);var u="string"==typeof o;if(u)return function(e){return r(e,o||t,l)};var c=function(t){return i(e,s,(function(e){return n(o,l,t,e)}))};return u?a.default(c):c};return r}},3:(e,t,n)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0});var r=n(70655).__importDefault(n(95364)),o=function(e){return[e]};t.default=function(e,t){return void 0===t&&(t=o),function(n){return r.default(n,e.apply(void 0,t(n)))}}},96260:(e,t,n)=>{"use strict";var r=n(70655);r.__importDefault(n(95364)).default,r.__importDefault(n(27162)).default,r.__importDefault(n(3)).default},95364:(e,t,n)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0});var r=n(70655),o=n(67294),a=parseInt(o.version.substr(0,o.version.indexOf(".")))>15,i=function(e){return"function"==typeof e};t.default=function(e,t){for(var n=[],l=2;l<arguments.length;l++)n[l-2]=arguments[l];var s=e.render,u=e.children,c=void 0===u?s:u,d=e.component,f=e.comp,p=void 0===f?d:f;return i(c)?c.apply(void 0,r.__spreadArrays([t],n)):p?o.createElement(p,t):c instanceof Array?a?c:o.createElement.apply(void 0,r.__spreadArrays(["div",null],c)):c&&c instanceof Object?"string"==typeof c.type?c:o.cloneElement(c,Object.assign({},c.props,t)):c||null}},45503:(e,t,n)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0});var r=n(70655),o=r.__importStar(n(67294));t.default=function(e){var t=function(t){function n(){return null!==t&&t.apply(this,arguments)||this}return r.__extends(n,t),n.prototype.render=function(){return e(this.props,this.context)},n}(o.Component);return t}},89164:(e,t,n)=>{"use strict";n.r(t),n.d(t,{createBreakpoint:()=>Le,createGlobalState:()=>_n,createMemo:()=>a,createReducer:()=>c,createReducerContext:()=>i,createStateContext:()=>d,ensuredForwardRef:()=>ce,useAsync:()=>m,useAsyncFn:()=>h,useAsyncRetry:()=>g,useAudio:()=>w,useBattery:()=>D,useBeforeUnload:()=>P,useBoolean:()=>I,useClickAway:()=>R,useCookie:()=>F,useCopyToClipboard:()=>$,useCounter:()=>G,useCss:()=>ee,useCustomCompareEffect:()=>te,useDebounce:()=>re,useDeepCompareEffect:()=>oe,useDefault:()=>ae,useDrop:()=>ie,useDropArea:()=>le,useEffectOnce:()=>se,useEnsuredForwardedRef:()=>ue,useError:()=>me,useEvent:()=>he,useFavicon:()=>ge,useFirstMountState:()=>l,useFullscreen:()=>ye,useGeolocation:()=>we,useGetSet:()=>q,useGetSetState:()=>xe,useHarmonicIntervalFn:()=>Ee,useHash:()=>kn,useHover:()=>Ce,useHoverDirty:()=>Te,useIdle:()=>Pe,useIntersection:()=>Ne,useInterval:()=>Ae,useIsomorphicLayoutEffect:()=>X,useKey:()=>Ie,useKeyPress:()=>Re,useKeyPressEvent:()=>je,useLatest:()=>Me,useLifecycles:()=>Fe,useList:()=>Be,useLocalStorage:()=>ze,useLocation:()=>Ve,useLockBodyScroll:()=>Xe,useLogger:()=>Ke,useLongPress:()=>et,useMap:()=>tt,useMeasure:()=>vn,useMedia:()=>nt,useMediaDevices:()=>rt,useMediatedState:()=>ot,useMethods:()=>at,useMotion:()=>lt,useMount:()=>st,useMountedState:()=>p,useMouse:()=>dt,useMouseHovered:()=>pt,useMouseWheel:()=>ht,useMultiStateValidator:()=>pn,useNetworkState:()=>bt,useNumber:()=>yt,useObservable:()=>wt,useOrientation:()=>_t,usePageLeave:()=>kt,usePermission:()=>Et,usePinchZoom:()=>yn,usePrevious:()=>St,usePreviousDistinct:()=>Tt,usePromise:()=>Ot,useQueue:()=>Dt,useRaf:()=>Pt,useRafLoop:()=>Nt,useRafState:()=>ct,useRendersCount:()=>wn,useScratch:()=>Rt,useScroll:()=>jt,useScrollbarWidth:()=>fn,useScrolling:()=>Mt,useSearchParam:()=>It,useSessionStorage:()=>Ft,useSet:()=>xn,useSetState:()=>v,useShallowCompareEffect:()=>$t,useSize:()=>qt,useSlider:()=>Gt,useSpeech:()=>Zt,useStartTyping:()=>Qt,useStateList:()=>Xt,useStateValidator:()=>cn,useStateWithHistory:()=>Yt,useThrottle:()=>Kt,useThrottleFn:()=>Jt,useTimeout:()=>en,useTimeoutFn:()=>ne,useTitle:()=>nn,useToggle:()=>A,useTween:()=>on,useUnmount:()=>ut,useUnmountPromise:()=>an,useUpdate:()=>H,useUpdateEffect:()=>s,useUpsert:()=>ln,useVibrate:()=>sn,useVideo:()=>un,useWindowScroll:()=>hn,useWindowSize:()=>mn});var r=n(67294),o=n.t(r,2);const a=function(e){return function(){for(var t=[],n=0;n<arguments.length;n++)t[n]=arguments[n];return(0,r.useMemo)((function(){return e.apply(void 0,t)}),t)}};const i=function(e,t){var n=(0,r.createContext)(void 0);return[function(){var e=(0,r.useContext)(n);if(null==e)throw new Error("useReducerContext must be used inside a ReducerProvider.");return e},function(o){var a=o.children,i=o.initialState;return function(e,t){return(0,r.createElement)(n.Provider,e,t)}({value:(0,r.useReducer)(e,void 0!==i?i:t)},a)},n]};function l(){var e=(0,r.useRef)(!0);return e.current?(e.current=!1,!0):e.current}const s=function(e,t){var n=l();(0,r.useEffect)((function(){if(!n)return e()}),t)};function u(e){return function(t,n){return e.reduceRight((function(e,n){return n(t)(e)}),n)}}const c=function(){for(var e=[],t=0;t<arguments.length;t++)e[t]=arguments[t];var n=u(e);return function(e,t,o){void 0===o&&(o=function(e){return e});var a=(0,r.useRef)(o(t)),i=(0,r.useState)(a.current)[1],l=(0,r.useCallback)((function(t){return a.current=e(a.current,t),i(a.current),t}),[e]),u=(0,r.useRef)(n({getState:function(){return a.current},dispatch:function(){for(var e=[],t=0;t<arguments.length;t++)e[t]=arguments[t];return u.current.apply(u,e)}},l));return s((function(){u.current=n({getState:function(){return a.current},dispatch:function(){for(var e=[],t=0;t<arguments.length;t++)e[t]=arguments[t];return u.current.apply(u,e)}},l)}),[l]),[a.current,u.current]}};const d=function(e){var t=(0,r.createContext)(void 0);return[function(){var e=(0,r.useContext)(t);if(null==e)throw new Error("useStateContext must be used inside a StateProvider.");return e},function(n){var o=n.children,a=n.initialValue;return function(e,n){return(0,r.createElement)(t.Provider,e,n)}({value:(0,r.useState)(void 0!==a?a:e)},o)},t]};var f=n(70655);function p(){var e=(0,r.useRef)(!1),t=(0,r.useCallback)((function(){return e.current}),[]);return(0,r.useEffect)((function(){return e.current=!0,function(){e.current=!1}}),[]),t}function h(e,t,n){void 0===t&&(t=[]),void 0===n&&(n={loading:!1});var o=(0,r.useRef)(0),a=p(),i=(0,r.useState)(n),l=i[0],s=i[1],u=(0,r.useCallback)((function(){for(var t=[],n=0;n<arguments.length;n++)t[n]=arguments[n];var r=++o.current;return l.loading||s((function(e){return(0,f.__assign)((0,f.__assign)({},e),{loading:!0})})),e.apply(void 0,t).then((function(e){return a()&&r===o.current&&s({value:e,loading:!1}),e}),(function(e){return a()&&r===o.current&&s({error:e,loading:!1}),e}))}),t);return[l,u]}function m(e,t){void 0===t&&(t=[]);var n=h(e,t,{loading:!0}),o=n[0],a=n[1];return(0,r.useEffect)((function(){a()}),[a]),o}const g=function(e,t){void 0===t&&(t=[]);var n=(0,r.useState)(0),o=n[0],a=n[1],i=m(e,(0,f.__spreadArrays)(t,[o])),l=i.loading,s=(0,r.useCallback)((function(){l||a((function(e){return e+1}))}),(0,f.__spreadArrays)(t,[l]));return(0,f.__assign)((0,f.__assign)({},i),{retry:s})};const v=function(e){void 0===e&&(e={});var t=(0,r.useState)(e),n=t[0],o=t[1];return[n,(0,r.useCallback)((function(e){o((function(t){return Object.assign({},t,e instanceof Function?e(t):e)}))}),[])]};function b(e){for(var t=[],n=0;n<e.length;n++)t.push({start:e.start(n),end:e.end(n)});return t}function y(e){return function(t){var n,o;o=r.isValidElement(t)?(n=t).props:t;var a=v({buffered:[],time:0,duration:0,paused:!0,muted:!1,volume:1,playing:!1}),i=a[0],l=a[1],s=(0,r.useRef)(null),u=function(e,t){return function(n){try{t&&t(n)}finally{e&&e(n)}}},c=function(){return l({paused:!1})},d=function(){return l({playing:!0})},p=function(){return l({playing:!1})},h=function(){return l({paused:!0,playing:!1})},m=function(){var e=s.current;e&&l({muted:e.muted,volume:e.volume})},g=function(){var e=s.current;if(e){var t=e.duration,n=e.buffered;l({duration:t,buffered:b(n)})}},y=function(){var e=s.current;e&&l({time:e.currentTime})},w=function(){var e=s.current;e&&l({buffered:b(e.buffered)})};n=n?r.cloneElement(n,(0,f.__assign)((0,f.__assign)({controls:!1},o),{ref:s,onPlay:u(o.onPlay,c),onPlaying:u(o.onPlaying,d),onWaiting:u(o.onWaiting,p),onPause:u(o.onPause,h),onVolumeChange:u(o.onVolumeChange,m),onDurationChange:u(o.onDurationChange,g),onTimeUpdate:u(o.onTimeUpdate,y),onProgress:u(o.onProgress,w)})):r.createElement(e,(0,f.__assign)((0,f.__assign)({controls:!1},o),{ref:s,onPlay:u(o.onPlay,c),onPlaying:u(o.onPlaying,d),onWaiting:u(o.onWaiting,p),onPause:u(o.onPause,h),onVolumeChange:u(o.onVolumeChange,m),onDurationChange:u(o.onDurationChange,g),onTimeUpdate:u(o.onTimeUpdate,y),onProgress:u(o.onProgress,w)}));var x=!1,_={play:function(){var e=s.current;if(e&&!x){var t=e.play();if("object"==typeof t){x=!0;var n=function(){x=!1};t.then(n,n)}return t}},pause:function(){var e=s.current;if(e&&!x)return e.pause()},seek:function(e){var t=s.current;t&&void 0!==i.duration&&(e=Math.min(i.duration,Math.max(0,e)),t.currentTime=e)},volume:function(e){var t=s.current;t&&(e=Math.min(1,Math.max(0,e)),t.volume=e,l({volume:e}))},mute:function(){var e=s.current;e&&(e.muted=!0)},unmute:function(){var e=s.current;e&&(e.muted=!1)}};return(0,r.useEffect)((function(){var e=s.current;e&&(l({volume:e.volume,muted:e.muted,paused:e.paused}),o.autoPlay&&e.paused&&_.play())}),[o.src]),[n,i,_,s]}}const w=y("audio");var x=function(){};function _(e){for(var t=[],n=1;n<arguments.length;n++)t[n-1]=arguments[n];e&&e.addEventListener&&e.addEventListener.apply(e,t)}function k(e){for(var t=[],n=1;n<arguments.length;n++)t[n-1]=arguments[n];e&&e.removeEventListener&&e.removeEventListener.apply(e,t)}var E="undefined"!=typeof window,S="undefined"!=typeof navigator,C=n(38252);const T=n.n(C)();var O=S?navigator:void 0;const D=O&&"function"==typeof O.getBattery?function(){var e=(0,r.useState)({isSupported:!0,fetched:!1}),t=e[0],n=e[1];return(0,r.useEffect)((function(){var e=!0,r=null,o=function(){if(e&&r){var o={isSupported:!0,fetched:!0,level:r.level,charging:r.charging,dischargingTime:r.dischargingTime,chargingTime:r.chargingTime};!T(t,o)&&n(o)}};return O.getBattery().then((function(t){e&&(_(r=t,"chargingchange",o),_(r,"chargingtimechange",o),_(r,"dischargingtimechange",o),_(r,"levelchange",o),o())})),function(){e=!1,r&&(k(r,"chargingchange",o),k(r,"chargingtimechange",o),k(r,"dischargingtimechange",o),k(r,"levelchange",o))}}),[]),t}:function(){return{isSupported:!1}};const P=function(e,t){void 0===e&&(e=!0);var n=(0,r.useCallback)((function(n){if("function"!=typeof e||e())return n.preventDefault(),t&&(n.returnValue=t),t}),[e,t]);(0,r.useEffect)((function(){if(e)return _(window,"beforeunload",n),function(){return k(window,"beforeunload",n)}}),[e,n])};var N=function(e,t){return"boolean"==typeof t?t:!e};const A=function(e){return(0,r.useReducer)(N,e)},I=A;var L=["mousedown","touchstart"];const R=function(e,t,n){void 0===n&&(n=L);var o=(0,r.useRef)(t);(0,r.useEffect)((function(){o.current=t}),[t]),(0,r.useEffect)((function(){for(var t=function(t){var n=e.current;n&&!n.contains(t.target)&&o.current(t)},r=0,a=n;r<a.length;r++){var i=a[r];_(document,i,t)}return function(){for(var e=0,r=n;e<r.length;e++){var o=r[e];k(document,o,t)}}}),[n,e])};var j=n(36808),M=n.n(j);const F=function(e){var t=(0,r.useState)((function(){return M().get(e)||null})),n=t[0],o=t[1];return[n,(0,r.useCallback)((function(t,n){M().set(e,t,n),o(t)}),[e]),(0,r.useCallback)((function(){M().remove(e),o(null)}),[e])]};var B=n(20640),z=n.n(B);const $=function(){var e=p(),t=v({value:void 0,error:void 0,noUserInteraction:!0}),n=t[0],o=t[1];return[n,(0,r.useCallback)((function(t){var n,r;if(e())try{if("string"!=typeof t&&"number"!=typeof t){var a=new Error("Cannot copy typeof "+typeof t+" to clipboard, must be a string");return void o({value:t,error:a,noUserInteraction:!0})}if(""===t){a=new Error("Cannot copy empty string to clipboard.");return void o({value:t,error:a,noUserInteraction:!0})}r=t.toString(),n=z()(r),o({value:r,error:void 0,noUserInteraction:n})}catch(a){o({value:r,error:a,noUserInteraction:n})}}),[])]};var U=function(e){return(e+1)%1e6};function H(){return(0,r.useReducer)(U,0)[1]}function V(e,t){return"function"==typeof e?e.length?e(t):e():e}function q(e){var t=(0,r.useRef)(V(e)),n=H();return(0,r.useMemo)((function(){return[function(){return t.current},function(e){t.current=V(e,t.current),n()}]}),[])}function G(e,t,n){void 0===e&&(e=0),void 0===t&&(t=null),void 0===n&&(n=null);var o=V(e);"number"!=typeof o&&console.error("initialValue has to be a number, got "+typeof e),"number"==typeof n?o=Math.max(o,n):null!==n&&console.error("min has to be a number, got "+typeof n),"number"==typeof t?o=Math.min(o,t):null!==t&&console.error("max has to be a number, got "+typeof t);var a=q(o),i=a[0],l=a[1];return[i(),(0,r.useMemo)((function(){var e=function(e){var r=i(),o=V(e,r);r!==o&&("number"==typeof n&&(o=Math.max(o,n)),"number"==typeof t&&(o=Math.min(o,t)),r!==o&&l(o))};return{get:i,set:e,inc:function(t){void 0===t&&(t=1);var n=V(t,i());"number"!=typeof n&&console.error("delta has to be a number or function returning a number, got "+typeof n),e((function(e){return e+n}))},dec:function(t){void 0===t&&(t=1);var n=V(t,i());"number"!=typeof n&&console.error("delta has to be a number or function returning a number, got "+typeof n),e((function(e){return e-n}))},reset:function(t){void 0===t&&(t=o);var n=V(t,i());"number"!=typeof n&&console.error("value has to be a number or function returning a number, got "+typeof n),o=n,e(n)}}}),[o,n,t])]}var W=n(40818),Z=n(97142),Q=n(52099),Y=n(87749);const X=E?r.useLayoutEffect:r.useEffect;var K=(0,W.U)();(0,Z.I)(K),(0,Q.I)(K);var J=0;const ee=function(e){var t=(0,r.useMemo)((function(){return"react-use-css-"+(J++).toString(36)}),[]),n=(0,r.useMemo)((function(){return new K.VSheet}),[]);return X((function(){var r={};return(0,Y.z)(r,e,"."+t,""),n.diff(r),function(){n.diff({})}})),t};const te=function(e,t,n){var o=(0,r.useRef)(void 0);o.current&&n(t,o.current)||(o.current=t),(0,r.useEffect)(e,o.current)};function ne(e,t){void 0===t&&(t=0);var n=(0,r.useRef)(!1),o=(0,r.useRef)(),a=(0,r.useRef)(e),i=(0,r.useCallback)((function(){return n.current}),[]),l=(0,r.useCallback)((function(){n.current=!1,o.current&&clearTimeout(o.current),o.current=setTimeout((function(){n.current=!0,a.current()}),t)}),[t]),s=(0,r.useCallback)((function(){n.current=null,o.current&&clearTimeout(o.current)}),[]);return(0,r.useEffect)((function(){a.current=e}),[e]),(0,r.useEffect)((function(){return l(),s}),[t]),[i,s,l]}function re(e,t,n){void 0===t&&(t=0),void 0===n&&(n=[]);var o=ne(e,t),a=o[0],i=o[1],l=o[2];return(0,r.useEffect)(l,n),[a,i]}const oe=function(e,t){te(e,t,T)};const ae=function(e,t){var n=(0,r.useState)(t),o=n[0],a=n[1];return null==o?[e,a]:[o,a]};const ie=function(e,t){void 0===e&&(e={}),void 0===t&&(t=[]);var n=e.onFiles,o=e.onText,a=e.onUri,i=(0,r.useState)(!1),l=i[0],s=i[1],u=(0,r.useCallback)(s,[]),c=(0,r.useMemo)((function(){return function(e){return function(t,n){var r=t.getData("text/uri-list");if(r)(e.onUri||x)(r,n);else if(t.files&&t.files.length)(e.onFiles||x)(Array.from(t.files),n);else if(n.clipboardData){var o=n.clipboardData.getData("text");(e.onText||x)(o,n)}}}(e)}),[n,o,a]);return(0,r.useEffect)((function(){var e=function(e){e.preventDefault(),u(!0)},t=function(e){e.preventDefault(),u(!0)},n=function(){u(!1)},r=function(){u(!1)},a=function(e){e.preventDefault(),u(!1),c(e.dataTransfer,e)},i=function(e){c(e.clipboardData,e)};return _(document,"dragover",e),_(document,"dragenter",t),_(document,"dragleave",n),_(document,"dragexit",r),_(document,"drop",a),o&&_(document,"paste",i),function(){k(document,"dragover",e),k(document,"dragenter",t),k(document,"dragleave",n),k(document,"dragexit",r),k(document,"drop",a),k(document,"paste",i)}}),(0,f.__spreadArrays)([c],t)),{over:l}};const le=function(e){void 0===e&&(e={});var t=e.onFiles,n=e.onText,o=e.onUri,a=p(),i=(0,r.useState)(!1),l=i[0],s=i[1],u=(0,r.useMemo)((function(){return function(e,t){return function(n,r){var o=n.getData("text/uri-list");o?(e.onUri||x)(o,r):n.files&&n.files.length?(e.onFiles||x)(Array.from(n.files),r):n.items&&n.items.length&&n.items[0].getAsString((function(n){t&&(e.onText||x)(n,r)}))}}(e,a())}),[t,n,o]),c=(0,r.useMemo)((function(){return function(e,t){return{onDragOver:function(e){e.preventDefault()},onDragEnter:function(e){e.preventDefault(),t(!0)},onDragLeave:function(){t(!1)},onDrop:function(n){n.preventDefault(),n.persist(),t(!1),e(n.dataTransfer,n)},onPaste:function(t){t.persist(),e(t.clipboardData,t)}}}(u,s)}),[u,s]);return[c,{over:l}]};const se=function(e){(0,r.useEffect)(e,[])};function ue(e){var t=(0,r.useRef)(e&&e.current);return(0,r.useEffect)((function(){e&&(e.current=t.current)}),[e]),t}function ce(e){return(0,r.forwardRef)((function(t,n){var r=ue(n);return e(t,r)}))}var de=E?window:null,fe=function(e){return!!e.addEventListener},pe=function(e){return!!e.on};const he=function(e,t,n,o){void 0===n&&(n=de),(0,r.useEffect)((function(){if(t&&n)return fe(n)?_(n,e,t,o):pe(n)&&n.on(e,t,o),function(){fe(n)?k(n,e,t,o):pe(n)&&n.off(e,t,o)}}),[e,t,n,JSON.stringify(o)])};const me=function(){var e=(0,r.useState)(null),t=e[0],n=e[1];return(0,r.useEffect)((function(){if(t)throw t}),[t]),(0,r.useCallback)((function(e){n(e)}),[])};const ge=function(e){(0,r.useEffect)((function(){var t=document.querySelector("link[rel*='icon']")||document.createElement("link");t.type="image/x-icon",t.rel="shortcut icon",t.href=e,document.getElementsByTagName("head")[0].appendChild(t)}),[e])};var ve=n(10577),be=n.n(ve);const ye=function(e,t,n){void 0===n&&(n={});var o=n.video,a=n.onClose,i=void 0===a?x:a,l=(0,r.useState)(t),s=l[0],u=l[1];return X((function(){if(t&&e.current){var n=function(){(null==o?void 0:o.current)&&k(o.current,"webkitendfullscreen",n),i()},r=function(){if(be().isEnabled){var e=be().isFullscreen;u(e),e||i()}};if(be().isEnabled){try{be().request(e.current),u(!0)}catch(l){i(l),u(!1)}be().on("change",r)}else o&&o.current&&o.current.webkitEnterFullscreen?(o.current.webkitEnterFullscreen(),_(o.current,"webkitendfullscreen",n),u(!0)):(i(),u(!1));return function(){if(u(!1),be().isEnabled)try{be().off("change",r),be().exit()}catch(a){}else o&&o.current&&o.current.webkitExitFullscreen&&(k(o.current,"webkitendfullscreen",n),o.current.webkitExitFullscreen())}}}),[t,o,e]),s};const we=function(e){var t,n=(0,r.useState)({loading:!0,accuracy:null,altitude:null,altitudeAccuracy:null,heading:null,latitude:null,longitude:null,speed:null,timestamp:Date.now()}),o=n[0],a=n[1],i=!0,l=function(e){i&&a({loading:!1,accuracy:e.coords.accuracy,altitude:e.coords.altitude,altitudeAccuracy:e.coords.altitudeAccuracy,heading:e.coords.heading,latitude:e.coords.latitude,longitude:e.coords.longitude,speed:e.coords.speed,timestamp:e.timestamp})},s=function(e){return i&&a((function(t){return(0,f.__assign)((0,f.__assign)({},t),{loading:!1,error:e})}))};return(0,r.useEffect)((function(){return navigator.geolocation.getCurrentPosition(l,s,e),t=navigator.geolocation.watchPosition(l,s,e),function(){i=!1,navigator.geolocation.clearWatch(t)}}),[]),o};const xe=function(e){void 0===e&&(e={});var t=H(),n=(0,r.useRef)((0,f.__assign)({},e));return[(0,r.useCallback)((function(){return n.current}),[]),(0,r.useCallback)((function(e){e&&(Object.assign(n.current,e),t())}),[])]};var _e=0,ke={};const Ee=function(e,t){void 0===t&&(t=0);var n=(0,r.useRef)((function(){}));(0,r.useEffect)((function(){n.current=e})),(0,r.useEffect)((function(){if(null!==t){var e=function(e,t){var n,r=_e++;if(ke[t])ke[t].listeners[r]=e;else{var o=setInterval((function(){for(var e,n=ke[t].listeners,r=!1,o=0,a=Object.values(n);o<a.length;o++){var i=a[o];try{i()}catch(l){r=!0,e=l}}if(r)throw e}),t);ke[t]={ms:t,timer:o,listeners:(n={},n[r]=e,n)}}return{bucket:ke[t],id:r}}((function(){return n.current()}),t);return function(){return function(e){var t=e.bucket,n=e.id;delete t.listeners[n];var r=!1;for(var o in t.listeners){r=!0;break}r||(clearInterval(t.timer),delete ke[t.ms])}(e)}}}),[t])};var Se=r.useState;const Ce=function(e){var t,n,o=Se(!1),a=o[0],i=o[1];return"function"==typeof e&&(e=e(a)),[r.cloneElement(e,{onMouseEnter:(n=e.props.onMouseEnter,function(e){(n||x)(e),i(!0)}),onMouseLeave:(t=e.props.onMouseLeave,function(e){(t||x)(e),i(!1)})}),a]};const Te=function(e,t){void 0===t&&(t=!0);var n=(0,r.useState)(!1),o=n[0],a=n[1];return(0,r.useEffect)((function(){var n=function(){return a(!0)},r=function(){return a(!1)};t&&e&&e.current&&(_(e.current,"mouseover",n),_(e.current,"mouseout",r));var o=e.current;return function(){t&&o&&(k(o,"mouseover",n),k(o,"mouseout",r))}}),[t,e]),o};function Oe(e,t,n,r){var o,a=!1,i=0;function l(){o&&clearTimeout(o)}function s(){for(var s=arguments.length,u=new Array(s),c=0;c<s;c++)u[c]=arguments[c];var d=this,f=Date.now()-i;function p(){i=Date.now(),n.apply(d,u)}function h(){o=void 0}a||(r&&!o&&p(),l(),void 0===r&&f>e?p():!0!==t&&(o=setTimeout(r?h:p,void 0===r?e-f:e)))}return"boolean"!=typeof t&&(r=n,n=t,t=void 0),s.cancel=function(){l(),a=!0},s}var De=["mousemove","mousedown","resize","keydown","touchstart","wheel"];const Pe=function(e,t,n){void 0===e&&(e=6e4),void 0===t&&(t=!1),void 0===n&&(n=De);var o=(0,r.useState)(t),a=o[0],i=o[1];return(0,r.useEffect)((function(){for(var t,r=!0,o=a,l=function(e){r&&(o=e,i(e))},s=Oe(50,(function(){o&&l(!1),clearTimeout(t),t=setTimeout((function(){return l(!0)}),e)})),u=function(){document.hidden||s()},c=0;c<n.length;c++)_(window,n[c],s);return _(document,"visibilitychange",u),t=setTimeout((function(){return l(!0)}),e),function(){r=!1;for(var e=0;e<n.length;e++)k(window,n[e],s);k(document,"visibilitychange",u)}}),[e,n]),a};const Ne=function(e,t){var n=(0,r.useState)(null),o=n[0],a=n[1];return(0,r.useEffect)((function(){if(e.current&&"function"==typeof IntersectionObserver){var n=new IntersectionObserver((function(e){a(e[0])}),t);return n.observe(e.current),function(){a(null),n.disconnect()}}return function(){}}),[e.current,t.threshold,t.root,t.rootMargin]),o};const Ae=function(e,t){var n=(0,r.useRef)((function(){}));(0,r.useEffect)((function(){n.current=e})),(0,r.useEffect)((function(){if(null!==t){var e=setInterval((function(){return n.current()}),t||0);return function(){return clearInterval(e)}}}),[t])};const Ie=function(e,t,n,o){void 0===t&&(t=x),void 0===n&&(n={}),void 0===o&&(o=[e]);var a=n.event,i=void 0===a?"keydown":a,l=n.target,s=n.options,u=(0,r.useMemo)((function(){var n,r="function"==typeof(n=e)?n:"string"==typeof n?function(e){return e.key===n}:n?function(){return!0}:function(){return!1};return function(e){if(r(e))return t(e)}}),o);he(i,u,l,s)};const Le=function(e){return void 0===e&&(e={laptopL:1440,laptop:1024,tablet:768}),function(){var t=(0,r.useState)(E?window.innerWidth:0),n=t[0],o=t[1];(0,r.useEffect)((function(){var e=function(){o(window.innerWidth)};return e(),_(window,"resize",e),function(){k(window,"resize",e)}}));var a=(0,r.useMemo)((function(){return Object.entries(e).sort((function(e,t){return e[1]>=t[1]?1:-1}))}),[e]),i=a.reduce((function(e,t){var r=t[0],o=t[1];return n>=o?r:e}),a[0][0]);return i}};const Re=function(e){var t=(0,r.useState)([!1,null]),n=t[0],o=t[1];return Ie(e,(function(e){return o([!0,e])}),{event:"keydown"},[n]),Ie(e,(function(e){return o([!1,e])}),{event:"keyup"},[n]),n};const je=function(e,t,n,r){void 0===r&&(r=Re);var o=r(e),a=o[0],i=o[1];s((function(){!a&&n?n(i):a&&t&&t(i)}),[a])};const Me=function(e){var t=(0,r.useRef)(e);return t.current=e,t};const Fe=function(e,t){(0,r.useEffect)((function(){return e&&e(),function(){t&&t()}}),[])};const Be=function(e){void 0===e&&(e=[]);var t=(0,r.useRef)(V(e)),n=H(),o=(0,r.useMemo)((function(){var r={set:function(e){t.current=V(e,t.current),n()},push:function(){for(var e=[],t=0;t<arguments.length;t++)e[t]=arguments[t];e.length&&o.set((function(t){return t.concat(e)}))},updateAt:function(e,t){o.set((function(n){var r=n.slice();return r[e]=t,r}))},insertAt:function(e,t){o.set((function(n){var r=n.slice();return e>r.length?r[e]=t:r.splice(e,0,t),r}))},update:function(e,t){o.set((function(n){return n.map((function(n){return e(n,t)?t:n}))}))},updateFirst:function(e,n){var r=t.current.findIndex((function(t){return e(t,n)}));r>=0&&o.updateAt(r,n)},upsert:function(e,n){var r=t.current.findIndex((function(t){return e(t,n)}));r>=0?o.updateAt(r,n):o.push(n)},sort:function(e){o.set((function(t){return t.slice().sort(e)}))},filter:function(e,t){o.set((function(n){return n.slice().filter(e,t)}))},removeAt:function(e){o.set((function(t){var n=t.slice();return n.splice(e,1),n}))},clear:function(){o.set([])},reset:function(){o.set(V(e).slice())}};return r.remove=r.removeAt,r}),[]);return[t.current,o]};const ze=function(e,t,n){if(!E)return[t,x,x];if(!e)throw new Error("useLocalStorage key may not be falsy");var o=n?n.raw?function(e){return e}:n.deserializer:JSON.parse,a=(0,r.useRef)((function(e){try{var r=n?n.raw?String:n.serializer:JSON.stringify,a=localStorage.getItem(e);return null!==a?o(a):(t&&localStorage.setItem(e,r(t)),t)}catch(i){return t}})),i=(0,r.useState)((function(){return a.current(e)})),l=i[0],s=i[1];(0,r.useLayoutEffect)((function(){return s(a.current(e))}),[e]);var u=(0,r.useCallback)((function(t){try{var r="function"==typeof t?t(l):t;if(void 0===r)return;var a=void 0;a=n?n.raw?"string"==typeof r?r:JSON.stringify(r):n.serializer?n.serializer(r):JSON.stringify(r):JSON.stringify(r),localStorage.setItem(e,a),s(o(a))}catch(i){}}),[e,s]),c=(0,r.useCallback)((function(){try{localStorage.removeItem(e),s(void 0)}catch(i){}}),[e,s]);return[l,u,c]};var $e=function(e){var t=window.history,n=t[e];t[e]=function(t){var r=n.apply(this,arguments),o=new Event(e.toLowerCase());return o.state=t,window.dispatchEvent(o),r}};E&&($e("pushState"),$e("replaceState"));var Ue=function(e){var t=window.history,n=t.state,r=t.length,o=window.location;return{trigger:e,state:n,length:r,hash:o.hash,host:o.host,hostname:o.hostname,href:o.href,origin:o.origin,pathname:o.pathname,port:o.port,protocol:o.protocol,search:o.search}},He="function"==typeof Event;const Ve=E&&He?function(){var e=(0,r.useState)(Ue("load")),t=e[0],n=e[1];return(0,r.useEffect)((function(){var e=function(){return n(Ue("popstate"))},t=function(){return n(Ue("pushstate"))},r=function(){return n(Ue("replacestate"))};return _(window,"popstate",e),_(window,"pushstate",t),_(window,"replacestate",r),function(){k(window,"popstate",e),k(window,"pushstate",t),k(window,"replacestate",r)}}),[]),t}:function(){return{trigger:"load",length:1}};function qe(e){if(!e)return null;if("BODY"===e.tagName)return e;if("IFRAME"===e.tagName){var t=e.contentDocument;return t?t.body:null}return e.offsetParent?qe(e.offsetParent):null}function Ge(e){var t=e||window.event;return t.touches.length>1||(t.preventDefault&&t.preventDefault(),!1)}var We=E&&window.navigator&&window.navigator.platform&&/iP(ad|hone|od)/.test(window.navigator.platform),Ze=new Map,Qe="object"==typeof document?document:void 0,Ye=!1;const Xe=Qe?function(e,t){void 0===e&&(e=!0);var n=(0,r.useRef)(Qe.body);t=t||n;var o=function(e){var t=Ze.get(e);t&&(1===t.counter?(Ze.delete(e),We?(e.ontouchmove=null,Ye&&(k(document,"touchmove",Ge),Ye=!1)):e.style.overflow=t.initialOverflow):Ze.set(e,{counter:t.counter-1,initialOverflow:t.initialOverflow}))};(0,r.useEffect)((function(){var n=qe(t.current);n&&(e?function(e){var t=Ze.get(e);t?Ze.set(e,{counter:t.counter+1,initialOverflow:t.initialOverflow}):(Ze.set(e,{counter:1,initialOverflow:e.style.overflow}),We?Ye||(_(document,"touchmove",Ge,{passive:!1}),Ye=!0):e.style.overflow="hidden")}(n):o(n))}),[e,t.current]),(0,r.useEffect)((function(){var e=qe(t.current);if(e)return function(){o(e)}}),[])}:function(e,t){void 0===e&&(e=!0)};const Ke=function(e){for(var t=[],n=1;n<arguments.length;n++)t[n-1]=arguments[n];se((function(){return console.log.apply(console,(0,f.__spreadArrays)([e+" mounted"],t)),function(){return console.log(e+" unmounted")}})),s((function(){console.log.apply(console,(0,f.__spreadArrays)([e+" updated"],t))}))};var Je=function(e){(function(e){return"touches"in e})(e)&&e.touches.length<2&&e.preventDefault&&e.preventDefault()};const et=function(e,t){var n=void 0===t?{}:t,o=n.isPreventDefault,a=void 0===o||o,i=n.delay,l=void 0===i?300:i,s=(0,r.useRef)(),u=(0,r.useRef)(),c=(0,r.useCallback)((function(t){a&&t.target&&(_(t.target,"touchend",Je,{passive:!1}),u.current=t.target),s.current=setTimeout((function(){return e(t)}),l)}),[e,l,a]),d=(0,r.useCallback)((function(){s.current&&clearTimeout(s.current),a&&u.current&&k(u.current,"touchend",Je)}),[a]);return{onMouseDown:function(e){return c(e)},onTouchStart:function(e){return c(e)},onMouseUp:d,onMouseLeave:d,onTouchEnd:d}};const tt=function(e){void 0===e&&(e={});var t=(0,r.useState)(e),n=t[0],o=t[1],a=(0,r.useMemo)((function(){return{set:function(e,t){o((function(n){var r;return(0,f.__assign)((0,f.__assign)({},n),((r={})[e]=t,r))}))},setAll:function(e){o(e)},remove:function(e){o((function(t){var n=t,r=e;n[r];return(0,f.__rest)(n,["symbol"==typeof r?r:r+""])}))},reset:function(){return o(e)}}}),[o]),i=(0,f.__assign)({get:(0,r.useCallback)((function(e){return n[e]}),[n])},a);return[n,i]};const nt=function(e,t){var n=(0,r.useState)(function(e,t){return void 0!==t?t:!!E&&window.matchMedia(e).matches}(e,t)),o=n[0],a=n[1];return(0,r.useEffect)((function(){var t=!0,n=window.matchMedia(e),r=function(){t&&a(!!n.matches)};return n.addListener(r),a(n.matches),function(){t=!1,n.removeListener(r)}}),[e]),o};const rt=S&&navigator.mediaDevices?function(){var e=(0,r.useState)({}),t=e[0],n=e[1];return(0,r.useEffect)((function(){var e=!0,t=function(){navigator.mediaDevices.enumerateDevices().then((function(t){e&&n({devices:t.map((function(e){return{deviceId:e.deviceId,groupId:e.groupId,kind:e.kind,label:e.label}}))})})).catch(x)};return _(navigator.mediaDevices,"devicechange",t),t(),function(){e=!1,k(navigator.mediaDevices,"devicechange",t)}}),[]),t}:function(){return{}};function ot(e,t){var n=(0,r.useRef)(e),o=(0,r.useState)(t),a=o[0],i=o[1];return[a,(0,r.useCallback)((function(e){2===n.current.length?n.current(e,i):i(n.current(e))}),[a])]}const at=function(e,t){var n=(0,r.useMemo)((function(){return function(t,n){var r;return(r=e(t))[n.type].apply(r,n.payload)}}),[e]),o=(0,r.useReducer)(n,t),a=o[0],i=o[1],l=(0,r.useMemo)((function(){return Object.keys(e(t)).reduce((function(e,t){return e[t]=function(){for(var e=[],n=0;n<arguments.length;n++)e[n]=arguments[n];return i({type:t,payload:e})},e}),{})}),[e,t]);return[a,l]};var it={acceleration:{x:null,y:null,z:null},accelerationIncludingGravity:{x:null,y:null,z:null},rotationRate:{alpha:null,beta:null,gamma:null},interval:16};const lt=function(e){void 0===e&&(e=it);var t=(0,r.useState)(e),n=t[0],o=t[1];return(0,r.useEffect)((function(){var e=function(e){var t=e.acceleration,n=e.accelerationIncludingGravity,r=e.rotationRate,a=e.interval;o({acceleration:{x:t.x,y:t.y,z:t.z},accelerationIncludingGravity:{x:n.x,y:n.y,z:n.z},rotationRate:{alpha:r.alpha,beta:r.beta,gamma:r.gamma},interval:a})};return _(window,"devicemotion",e),function(){k(window,"devicemotion",e)}}),[]),n};const st=function(e){se((function(){e()}))};const ut=function(e){var t=(0,r.useRef)(e);t.current=e,se((function(){return function(){return t.current()}}))};const ct=function(e){var t=(0,r.useRef)(0),n=(0,r.useState)(e),o=n[0],a=n[1],i=(0,r.useCallback)((function(e){cancelAnimationFrame(t.current),t.current=requestAnimationFrame((function(){a(e)}))}),[]);return ut((function(){cancelAnimationFrame(t.current)})),[o,i]};const dt=function(e){var t=ct({docX:0,docY:0,posX:0,posY:0,elX:0,elY:0,elH:0,elW:0}),n=t[0],o=t[1];return(0,r.useEffect)((function(){var t=function(t){if(e&&e.current){var n=e.current.getBoundingClientRect(),r=n.left,a=n.top,i=n.width,l=n.height,s=r+window.pageXOffset,u=a+window.pageYOffset,c=t.pageX-s,d=t.pageY-u;o({docX:t.pageX,docY:t.pageY,posX:s,posY:u,elX:c,elY:d,elH:l,elW:i})}};return _(document,"mousemove",t),function(){k(document,"mousemove",t)}}),[e]),n};var ft={current:null};const pt=function(e,t){void 0===t&&(t={});var n=!!t.whenHovered,r=!!t.bound,o=Te(e,n),a=dt(n&&!o?ft:e);return r&&(a.elX=Math.max(0,Math.min(a.elX,a.elW)),a.elY=Math.max(0,Math.min(a.elY,a.elH))),a},ht=function(){var e=(0,r.useState)(0),t=e[0],n=e[1];return(0,r.useEffect)((function(){var e=function(e){n(e.deltaY+t)};return _(window,"wheel",e,!1),function(){return k(window,"wheel",e)}})),t};var mt=S?navigator:void 0,gt=mt&&(mt.connection||mt.mozConnection||mt.webkitConnection);function vt(e){var t=null==mt?void 0:mt.onLine,n=null==e?void 0:e.online;return{online:t,previous:n,since:t!==n?new Date:null==e?void 0:e.since,downlink:null==gt?void 0:gt.downlink,downlinkMax:null==gt?void 0:gt.downlinkMax,effectiveType:null==gt?void 0:gt.effectiveType,rtt:null==gt?void 0:gt.rtt,saveData:null==gt?void 0:gt.saveData,type:null==gt?void 0:gt.type}}function bt(e){var t=(0,r.useState)(null!=e?e:vt),n=t[0],o=t[1];return(0,r.useEffect)((function(){var e=function(){o(vt)};return _(window,"online",e,{passive:!0}),_(window,"offline",e,{passive:!0}),gt&&_(gt,"change",e,{passive:!0}),function(){k(window,"online",e),k(window,"offline",e),gt&&k(gt,"change",e)}}),[]),n}const yt=G;const wt=function(e,t){var n=(0,r.useState)(t),o=n[0],a=n[1];return X((function(){var t=e.subscribe(a);return function(){return t.unsubscribe()}}),[e]),o};var xt={angle:0,type:"landscape-primary"};const _t=function(e){void 0===e&&(e=xt);var t=(0,r.useState)(e),n=t[0],o=t[1];return(0,r.useEffect)((function(){var t=window.screen,n=!0,r=function(){if(n){var r=t.orientation;if(r){var a=r.angle,i=r.type;o({angle:a,type:i})}else void 0!==window.orientation?o({angle:"number"==typeof window.orientation?window.orientation:0,type:""}):o(e)}};return _(window,"orientationchange",r),r(),function(){n=!1,k(window,"orientationchange",r)}}),[]),n};const kt=function(e,t){void 0===t&&(t=[]),(0,r.useEffect)((function(){if(e){var t=function(t){var n=(t=t||window.event).relatedTarget||t.toElement;n&&"HTML"!==n.nodeName||e()};return _(document,"mouseout",t),function(){k(document,"mouseout",t)}}}),t)};const Et=function(e){var t=(0,r.useState)(""),n=t[0],o=t[1];return(0,r.useEffect)((function(){var t=!0,n=null,r=function(){t&&o((function(){var e;return null!==(e=null==n?void 0:n.state)&&void 0!==e?e:""}))};return navigator.permissions.query(e).then((function(e){_(n=e,"change",r),r()})).catch(x),function(){n&&k(n,"change",r),t=!1,n=null}}),[e]),n};function St(e){var t=(0,r.useRef)();return(0,r.useEffect)((function(){t.current=e})),t.current}var Ct=function(e,t){return e===t};function Tt(e,t){void 0===t&&(t=Ct);var n=(0,r.useRef)(),o=(0,r.useRef)(e);return l()||t(o.current,e)||(n.current=o.current,o.current=e),n.current}const Ot=function(){var e=p();return(0,r.useCallback)((function(t){return new Promise((function(n,r){t.then((function(t){e()&&n(t)}),(function(t){e()&&r(t)}))}))}),[])};const Dt=function(e){void 0===e&&(e=[]);var t=(0,r.useState)(e),n=t[0],o=t[1];return{add:function(e){o((function(t){return(0,f.__spreadArrays)(t,[e])}))},remove:function(){var e;return o((function(t){var n=t[0],r=t.slice(1);return e=n,r})),e},get first(){return n[0]},get last(){return n[n.length-1]},get size(){return n.length}}};const Pt=function(e,t){void 0===e&&(e=1e12),void 0===t&&(t=0);var n=(0,r.useState)(0),o=n[0],a=n[1];return X((function(){var n,r,o,i=function(){var t=Math.min(1,(Date.now()-o)/e);a(t),l()},l=function(){n=requestAnimationFrame(i)},s=setTimeout((function(){r=setTimeout((function(){cancelAnimationFrame(n),a(1)}),e),o=Date.now(),l()}),t);return function(){clearTimeout(r),clearTimeout(s),cancelAnimationFrame(n)}}),[e,t]),o};function Nt(e,t){void 0===t&&(t=!0);var n=(0,r.useRef)(null),o=(0,r.useRef)(!1),a=(0,r.useRef)(e);a.current=e;var i=(0,r.useCallback)((function(e){o.current&&(a.current(e),n.current=requestAnimationFrame(i))}),[]),l=(0,r.useMemo)((function(){return[function(){o.current&&(o.current=!1,n.current&&cancelAnimationFrame(n.current))},function(){o.current||(o.current=!0,n.current=requestAnimationFrame(i))},function(){return o.current}]}),[]);return(0,r.useEffect)((function(){return t&&l[1](),l[0]}),[]),l}var At=function(e,t){return new URLSearchParams(e).get(t)};const It=E?function(e){var t=window.location,n=(0,r.useState)((function(){return At(t.search,e)})),o=n[0],a=n[1];return(0,r.useEffect)((function(){var n=function(){a(At(t.search,e))};return _(window,"popstate",n),_(window,"pushstate",n),_(window,"replacestate",n),function(){k(window,"popstate",n),k(window,"pushstate",n),k(window,"replacestate",n)}}),[]),o}:function(){return null};n(96260);var Lt=function(e){void 0===e&&(e={});var t=e.disabled,n=Me(e),o=(0,r.useState)({isScratching:!1}),a=o[0],i=o[1],l=(0,r.useRef)(a),s=(0,r.useRef)(!1),u=(0,r.useRef)(null),c=(0,r.useState)(null),d=c[0],p=c[1];return(0,r.useEffect)((function(){if(!t&&d){var e,r,o=function(e,t){cancelAnimationFrame(u.current),u.current=requestAnimationFrame((function(){var r=d.getBoundingClientRect(),o=r.left,a=r.top,s=o+window.scrollX,u=a+window.scrollY,c=e-s,p=t-u;i((function(e){var t=(0,f.__assign)((0,f.__assign)({},e),{dx:c-(e.x||0),dy:p-(e.y||0),end:Date.now(),isScratching:!0});return l.current=t,(n.current.onScratch||x)(t),t}))}))},a=function(e){o(e.pageX,e.pageY)},c=function(e){o(e.changedTouches[0].pageX,e.changedTouches[0].pageY)},p=function(){s.current&&(s.current=!1,l.current=(0,f.__assign)((0,f.__assign)({},l.current),{isScratching:!1}),(n.current.onScratchEnd||x)(l.current),i({isScratching:!1}),k(window,"mousemove",a),k(window,"touchmove",c),k(window,"mouseup",e),k(window,"touchend",r))};e=p,r=p;var h=function(t,o){if(s.current){var u=d.getBoundingClientRect(),f=u.left,p=u.top,h=f+window.scrollX,m=p+window.scrollY,g=t-h,v=o-m,b=Date.now(),y={isScratching:!0,start:b,end:b,docX:t,docY:o,x:g,y:v,dx:0,dy:0,elH:d.offsetHeight,elW:d.offsetWidth,elX:h,elY:m};l.current=y,(n.current.onScratchStart||x)(y),i(y),_(window,"mousemove",a),_(window,"touchmove",c),_(window,"mouseup",e),_(window,"touchend",r)}},m=function(e){s.current=!0,h(e.pageX,e.pageY)},g=function(e){s.current=!0,h(e.changedTouches[0].pageX,e.changedTouches[0].pageY)};return _(d,"mousedown",m),_(d,"touchstart",g),function(){k(d,"mousedown",m),k(d,"touchstart",g),k(window,"mousemove",a),k(window,"touchmove",c),k(window,"mouseup",e),k(window,"touchend",r),u.current&&cancelAnimationFrame(u.current),u.current=null,s.current=!1,l.current={isScratching:!1},i(l.current)}}}),[d,t,n]),[p,a]};const Rt=Lt;const jt=function(e){var t=ct({x:0,y:0}),n=t[0],o=t[1];return(0,r.useEffect)((function(){var t=function(){e.current&&o({x:e.current.scrollLeft,y:e.current.scrollTop})};return e.current&&_(e.current,"scroll",t,{capture:!1,passive:!0}),function(){e.current&&k(e.current,"scroll",t)}}),[e]),n};const Mt=function(e){var t=(0,r.useState)(!1),n=t[0],o=t[1];return(0,r.useEffect)((function(){if(e.current){var t,n=function(){o(!0),clearTimeout(t),t=setTimeout((function(){o(!1)}),150)};return _(e.current,"scroll",n,!1),function(){e.current&&k(e.current,"scroll",n,!1)}}return function(){}}),[e]),n};const Ft=function(e,t,n){if(!E)return[t,function(){}];var o=(0,r.useState)((function(){try{var r=sessionStorage.getItem(e);return"string"!=typeof r?(sessionStorage.setItem(e,n?String(t):JSON.stringify(t)),t):n?r:JSON.parse(r||"null")}catch(o){return t}})),a=o[0],i=o[1];return(0,r.useEffect)((function(){try{var t=n?String(a):JSON.stringify(a);sessionStorage.setItem(e,t)}catch(o){}})),[a,i]};var Bt=n(99376),zt=function(e,t){return e.every((function(e,n){return(0,Bt.D)(e,t[n])}))};const $t=function(e,t){te(e,t,zt)};var Ut=r.useState,Ht=r.useEffect,Vt=r.useRef;const qt=function(e,t){var n=void 0===t?{}:t,a=n.width,i=void 0===a?1/0:a,l=n.height,s=void 0===l?1/0:l;if(!E)return["function"==typeof e?e({width:i,height:s}):e,{width:i,height:s}];var u=Ut({width:i,height:s}),c=u[0],d=u[1];"function"==typeof e&&(e=e(c));var p=e.props.style||{},h=Vt(null),m=null,g=function(){var e=h.current,t=e?{width:e.offsetWidth,height:e.offsetHeight}:{width:i,height:s};d(t)},v=function(e){_(e,"resize",g),setTimeout(g,35)};return Ht((function(){var e=h.current;if(e){if(e.contentWindow)m=e.contentWindow,v(m);else{var t=function(){_(e,"load",t),m=e.contentWindow,v(m)};k(e,"load",t)}return function(){m&&m.removeEventListener&&k(m,"resize",g)}}}),[]),p.position="relative",[r.cloneElement.apply(o,(0,f.__spreadArrays)([e,{style:p}],(0,f.__spreadArrays)([r.createElement("iframe",{ref:h,style:{background:"transparent",border:"none",height:"100%",left:0,position:"absolute",top:0,width:"100%",zIndex:-1}})],r.Children.toArray(e.props.children)))),c]};const Gt=function(e,t){void 0===t&&(t={});var n=p(),o=(0,r.useRef)(!1),a=(0,r.useRef)(0),i=(0,r.useRef)(0),l=v({isSliding:!1,value:0}),s=l[0],u=l[1];return a.current=s.value,(0,r.useEffect)((function(){if(E){var r=void 0===t.styles||t.styles,l=void 0!==t.reverse&&t.reverse;e.current&&r&&(e.current.style.userSelect="none");var s=function(){!o.current&&n()&&((t.onScrubStart||x)(),o.current=!0,u({isSliding:!0}),m())},c=function(){o.current&&n()&&((t.onScrubStop||x)(a.current),o.current=!1,u({isSliding:!1}),g())},d=function(e){s(),f(e)},f=t.vertical?function(e){return v(e.clientY)}:function(e){return v(e.clientX)},p=function(e){s(),h(e)},h=t.vertical?function(e){return v(e.changedTouches[0].clientY)}:function(e){return v(e.changedTouches[0].clientX)},m=function(){_(document,"mousemove",f),_(document,"mouseup",c),_(document,"touchmove",h),_(document,"touchend",c)},g=function(){k(document,"mousemove",f),k(document,"mouseup",c),k(document,"touchmove",h),k(document,"touchend",c)},v=function(r){cancelAnimationFrame(i.current),i.current=requestAnimationFrame((function(){if(n()&&e.current){var o=e.current.getBoundingClientRect(),a=t.vertical?o.top:o.left,i=t.vertical?o.height:o.width;if(!i)return;var s=(r-a)/i;s>1?s=1:s<0&&(s=0),l&&(s=1-s),u({value:s}),(t.onScrub||x)(s)}}))};return _(e.current,"mousedown",d),_(e.current,"touchstart",p),function(){k(e.current,"mousedown",d),k(e.current,"touchstart",p)}}}),[e,t.vertical]),s};var Wt;!function(e){e[e.init=0]="init",e[e.play=1]="play",e[e.pause=2]="pause",e[e.end=3]="end"}(Wt||(Wt={}));const Zt=function(e,t){var n=(0,r.useRef)(!1),o=(0,r.useState)((function(){var e=t.voice||{},n=e.lang,r=void 0===n?"default":n,o=e.name,a=void 0===o?"":o;return{isPlaying:!1,status:Wt[Wt.init],lang:t.lang||"default",voiceInfo:{lang:r,name:a},rate:t.rate||1,pitch:t.pitch||1,volume:t.volume||1}})),a=o[0],i=o[1],l=(0,r.useCallback)((function(){n.current&&i((function(e){return(0,f.__assign)((0,f.__assign)({},e),{isPlaying:!0,status:Wt[Wt.play]})}))}),[]),s=(0,r.useCallback)((function(){n.current&&i((function(e){return(0,f.__assign)((0,f.__assign)({},e),{isPlaying:!1,status:Wt[Wt.pause]})}))}),[]),u=(0,r.useCallback)((function(){n.current&&i((function(e){return(0,f.__assign)((0,f.__assign)({},e),{isPlaying:!1,status:Wt[Wt.end]})}))}),[]);return(0,r.useEffect)((function(){n.current=!0;var r=new SpeechSynthesisUtterance(e);return t.lang&&(r.lang=t.lang),t.voice&&(r.voice=t.voice),r.rate=t.rate||1,r.pitch=t.pitch||1,r.volume=t.volume||1,r.onstart=l,r.onpause=s,r.onresume=l,r.onend=u,window.speechSynthesis.speak(r),function(){n.current=!1}}),[]),a};const Qt=function(e){X((function(){var t=function(t){var n,r,o,a,i;!function(){var e=document.activeElement,t=document.body;if(!e)return!1;if(e===t)return!1;switch(e.tagName){case"INPUT":case"TEXTAREA":return!0}return e.hasAttribute("contenteditable")}()&&(r=(n=t).keyCode,o=n.metaKey,a=n.ctrlKey,i=n.altKey,!(o||a||i)&&(r>=48&&r<=57||r>=65&&r<=90))&&e(t)};return _(document,"keydown",t),function(){k(document,"keydown",t)}}),[])};function Yt(e,t,n){if(void 0===t&&(t=10),t<1)throw new Error("Capacity has to be greater than 1, got '"+t+"'");var o=l(),a=(0,r.useState)(e),i=a[0],s=a[1],u=(0,r.useRef)(null!=n?n:[]),c=(0,r.useRef)(0);return o&&(u.current.length?(u.current[u.current.length-1]!==e&&u.current.push(e),u.current.length>t&&(u.current=u.current.slice(u.current.length-t))):u.current.push(e),c.current=u.current.length&&u.current.length-1),[i,(0,r.useCallback)((function(e){s((function(n){return(e=V(e,n))!==n&&(c.current<u.current.length-1&&(u.current=u.current.slice(0,c.current+1)),c.current=u.current.push(e)-1,u.current.length>t&&(u.current=u.current.slice(u.current.length-t))),e}))}),[i,t]),(0,r.useMemo)((function(){return{history:u.current,position:c.current,capacity:t,back:function(e){void 0===e&&(e=1),c.current&&s((function(){return c.current-=Math.min(e,c.current),u.current[c.current]}))},forward:function(e){void 0===e&&(e=1),c.current!==u.current.length-1&&s((function(){return c.current=Math.min(c.current+e,u.current.length-1),u.current[c.current]}))},go:function(e){e!==c.current&&s((function(){return c.current=e<0?Math.max(u.current.length+e,0):Math.min(u.current.length-1,e),u.current[c.current]}))}}}),[i])]}function Xt(e){void 0===e&&(e=[]);var t=p(),n=H(),o=(0,r.useRef)(0);s((function(){e.length<=o.current&&(o.current=e.length-1,n())}),[e.length]);var a=(0,r.useMemo)((function(){return{next:function(){return a.setStateAt(o.current+1)},prev:function(){return a.setStateAt(o.current-1)},setStateAt:function(r){t()&&e.length&&r!==o.current&&(o.current=r>=0?r%e.length:e.length+r%e.length,n())},setState:function(r){if(t()){var a=e.length?e.indexOf(r):-1;if(-1===a)throw new Error("State '"+r+"' is not a valid state (does not exist in state list)");o.current=a,n()}}}}),[e]);return(0,f.__assign)({state:e[o.current],currentIndex:o.current},a)}const Kt=function(e,t){void 0===t&&(t=200);var n=(0,r.useState)(e),o=n[0],a=n[1],i=(0,r.useRef)(),l=(0,r.useRef)(null),s=(0,r.useRef)(0);return(0,r.useEffect)((function(){if(i.current)l.current=e,s.current=!0;else{a(e);var n=function(){s.current?(s.current=!1,a(l.current),i.current=setTimeout(n,t)):i.current=void 0};i.current=setTimeout(n,t)}}),[e]),ut((function(){i.current&&clearTimeout(i.current)})),o};const Jt=function(e,t,n){void 0===t&&(t=200);var o=(0,r.useState)(null),a=o[0],i=o[1],l=(0,r.useRef)(),s=(0,r.useRef)();return(0,r.useEffect)((function(){if(l.current)s.current=n;else{i(e.apply(void 0,n));var r=function(){s.current?(i(e.apply(void 0,s.current)),s.current=void 0,l.current=setTimeout(r,t)):l.current=void 0};l.current=setTimeout(r,t)}}),n),ut((function(){l.current&&clearTimeout(l.current)})),a};function en(e){return void 0===e&&(e=0),ne(H(),e)}var tn={restoreOnUnmount:!1};const nn="undefined"!=typeof document?function(e,t){void 0===t&&(t=tn);var n=(0,r.useRef)(document.title);document.title!==e&&(document.title=e),(0,r.useEffect)((function(){return t&&t.restoreOnUnmount?function(){document.title=n.current}:void 0}),[])}:function(e){};var rn=n(75534);const on=function(e,t,n){return void 0===e&&(e="inCirc"),void 0===t&&(t=200),void 0===n&&(n=0),(0,rn.U[e])(Pt(t,n))};const an=function(){var e=(0,r.useRef)(!1);return se((function(){return function(){e.current=!0}})),(0,r.useMemo)((function(){return function(t,n){return new Promise((function(r,o){t.then((function(t){e.current||r(t)}),(function(t){e.current?n?n(t):console.error("useUnmountPromise",t):o(t)}))}))}}),[])};function ln(e,t){void 0===t&&(t=[]);var n=Be(t),r=n[0],o=n[1];return[r,(0,f.__assign)((0,f.__assign)({},o),{upsert:function(t){o.upsert(e,t)}})]}const sn=S&&"vibrate"in navigator?function(e,t,n){void 0===e&&(e=!0),void 0===t&&(t=[1e3,1e3]),void 0===n&&(n=!0),(0,r.useEffect)((function(){var r;if(e&&(navigator.vibrate(t),n)){var o=t instanceof Array?t.reduce((function(e,t){return e+t})):t;r=setInterval((function(){navigator.vibrate(t)}),o)}return function(){e&&(navigator.vibrate(0),n&&clearInterval(r))}}),[e])}:x;const un=y("video");function cn(e,t,n){void 0===n&&(n=[void 0]);var o=(0,r.useRef)(t),a=(0,r.useRef)(e);o.current=t,a.current=e;var i=(0,r.useState)(n),l=i[0],s=i[1],u=(0,r.useCallback)((function(){o.current.length>=2?o.current(a.current,s):s(o.current(a.current))}),[s]);return(0,r.useEffect)((function(){u()}),[e]),[l,u]}var dn=function(e){if("undefined"==typeof document)return 0;if(document.body&&(!document.readyState||"loading"!==document.readyState)){if(!0!==e&&"number"==typeof dn.__cache)return dn.__cache;var t=document.createElement("div"),n=t.style;n.display="block",n.position="absolute",n.width="100px",n.height="100px",n.left="-999px",n.top="-999px",n.overflow="scroll",document.body.insertBefore(t,null);var r=t.clientWidth;if(0!==r)return dn.__cache=100-r,document.body.removeChild(t),dn.__cache;document.body.removeChild(t)}};function fn(){var e=(0,r.useState)(dn()),t=e[0],n=e[1];return(0,r.useEffect)((function(){if(void 0===t){var e=requestAnimationFrame((function(){n(dn())}));return function(){return cancelAnimationFrame(e)}}}),[]),t}function pn(e,t,n){if(void 0===n&&(n=[void 0]),"object"!=typeof e)throw new Error("states expected to be an object or array, got "+typeof e);var o=(0,r.useRef)(t),a=(0,r.useRef)(e);o.current=t,a.current=e;var i=(0,r.useState)(n),l=i[0],s=i[1],u=(0,r.useCallback)((function(){o.current.length>=2?o.current(a.current,s):s(o.current(a.current))}),[s]);return(0,r.useEffect)((function(){u()}),Object.values(e)),[l,u]}const hn=function(){var e=ct((function(){return{x:E?window.pageXOffset:0,y:E?window.pageYOffset:0}})),t=e[0],n=e[1];return(0,r.useEffect)((function(){var e=function(){n((function(e){var t=window.pageXOffset,n=window.pageYOffset;return e.x!==t||e.y!==n?{x:t,y:n}:e}))};return e(),_(window,"scroll",e,{capture:!1,passive:!0}),function(){k(window,"scroll",e)}}),[]),t};const mn=function(e,t){void 0===e&&(e=1/0),void 0===t&&(t=1/0);var n=ct({width:E?window.innerWidth:e,height:E?window.innerHeight:t}),o=n[0],a=n[1];return(0,r.useEffect)((function(){if(E){var e=function(){a({width:window.innerWidth,height:window.innerHeight})};return _(window,"resize",e),function(){k(window,"resize",e)}}}),[]),o};var gn={x:0,y:0,width:0,height:0,top:0,left:0,bottom:0,right:0};const vn=E&&void 0!==window.ResizeObserver?function(){var e=(0,r.useState)(null),t=e[0],n=e[1],o=(0,r.useState)(gn),a=o[0],i=o[1],l=(0,r.useMemo)((function(){return new window.ResizeObserver((function(e){if(e[0]){var t=e[0].contentRect,n=t.x,r=t.y,o=t.width,a=t.height,l=t.top,s=t.left,u=t.bottom,c=t.right;i({x:n,y:r,width:o,height:a,top:l,left:s,bottom:u,right:c})}}))}),[]);return X((function(){if(t)return l.observe(t),function(){l.disconnect()}}),[t]),[n,a]}:function(){return[x,gn]};var bn;!function(e){e.ZOOMING_IN="ZOOMING_IN",e.ZOOMING_OUT="ZOOMING_OUT"}(bn||(bn={}));const yn=function(e){var t=(0,r.useMemo)((function(){return{evCache:[],prevDiff:-1}}),[e.current]),n=(0,r.useState)(),o=n[0],a=n[1],i=function(e){for(var n=0;n<t.evCache.length;n++)if(e.pointerId==t.evCache[n].pointerId){t.evCache[n]=e;break}if(2==t.evCache.length){var r=Math.abs(t.evCache[0].clientX-t.evCache[1].clientX);t.prevDiff>0&&(r>t.prevDiff&&a([bn.ZOOMING_IN,r]),r<t.prevDiff&&a([bn.ZOOMING_OUT,r])),t.prevDiff=r}},l=function(e){t.evCache.push(e)},s=function(e){u(e),t.evCache.length<2&&(t.prevDiff=-1)},u=function(e){for(var n=0;n<t.evCache.length;n++)if(t.evCache[n].pointerId==e.pointerId){t.evCache.splice(n,1);break}};return(0,r.useEffect)((function(){(null==e?void 0:e.current)&&(e.current.onpointerdown=l,e.current.onpointermove=i,e.current.onpointerup=s,e.current.onpointercancel=s,e.current.onpointerout=s,e.current.onpointerleave=s)}),[null==e?void 0:e.current]),o?{zoomingState:o[0],pinchState:o[1]}:{zoomingState:null,pinchState:0}};function wn(){return++(0,r.useRef)(0).current}const xn=function(e){void 0===e&&(e=new Set);var t=(0,r.useState)(e),n=t[0],o=t[1],a=(0,r.useMemo)((function(){return{add:function(e){return o((function(t){return new Set((0,f.__spreadArrays)(Array.from(t),[e]))}))},remove:function(e){return o((function(t){return new Set(Array.from(t).filter((function(t){return t!==e})))}))},toggle:function(e){return o((function(t){return t.has(e)?new Set(Array.from(t).filter((function(t){return t!==e}))):new Set((0,f.__spreadArrays)(Array.from(t),[e]))}))},reset:function(){return o(e)}}}),[o]),i=(0,f.__assign)({has:(0,r.useCallback)((function(e){return n.has(e)}),[n])},a);return[n,i]};function _n(e){var t={state:e instanceof Function?e():e,setState:function(e){t.state=V(e,t.state),t.setters.forEach((function(e){return e(t.state)}))},setters:[]};return function(){var e=(0,r.useState)(t.state),n=e[0],o=e[1];return se((function(){return function(){t.setters=t.setters.filter((function(e){return e!==o}))}})),X((function(){t.setters.includes(o)||t.setters.push(o)})),[n,t.setState]}}var kn=function(){var e=(0,r.useState)((function(){return window.location.hash})),t=e[0],n=e[1],o=(0,r.useCallback)((function(){n(window.location.hash)}),[]);Fe((function(){_(window,"hashchange",o)}),(function(){k(window,"hashchange",o)}));var a=(0,r.useCallback)((function(e){e!==t&&(window.location.hash=e)}),[t]);return[t,a]}},72408:(e,t,n)=>{"use strict";var r=n(27418),o=60103,a=60106;t.Fragment=60107,t.StrictMode=60108,t.Profiler=60114;var i=60109,l=60110,s=60112;t.Suspense=60113;var u=60115,c=60116;if("function"==typeof Symbol&&Symbol.for){var d=Symbol.for;o=d("react.element"),a=d("react.portal"),t.Fragment=d("react.fragment"),t.StrictMode=d("react.strict_mode"),t.Profiler=d("react.profiler"),i=d("react.provider"),l=d("react.context"),s=d("react.forward_ref"),t.Suspense=d("react.suspense"),u=d("react.memo"),c=d("react.lazy")}var f="function"==typeof Symbol&&Symbol.iterator;function p(e){for(var t="https://reactjs.org/docs/error-decoder.html?invariant="+e,n=1;n<arguments.length;n++)t+="&args[]="+encodeURIComponent(arguments[n]);return"Minified React error #"+e+"; visit "+t+" for the full message or use the non-minified dev environment for full errors and additional helpful warnings."}var h={isMounted:function(){return!1},enqueueForceUpdate:function(){},enqueueReplaceState:function(){},enqueueSetState:function(){}},m={};function g(e,t,n){this.props=e,this.context=t,this.refs=m,this.updater=n||h}function v(){}function b(e,t,n){this.props=e,this.context=t,this.refs=m,this.updater=n||h}g.prototype.isReactComponent={},g.prototype.setState=function(e,t){if("object"!=typeof e&&"function"!=typeof e&&null!=e)throw Error(p(85));this.updater.enqueueSetState(this,e,t,"setState")},g.prototype.forceUpdate=function(e){this.updater.enqueueForceUpdate(this,e,"forceUpdate")},v.prototype=g.prototype;var y=b.prototype=new v;y.constructor=b,r(y,g.prototype),y.isPureReactComponent=!0;var w={current:null},x=Object.prototype.hasOwnProperty,_={key:!0,ref:!0,__self:!0,__source:!0};function k(e,t,n){var r,a={},i=null,l=null;if(null!=t)for(r in void 0!==t.ref&&(l=t.ref),void 0!==t.key&&(i=""+t.key),t)x.call(t,r)&&!_.hasOwnProperty(r)&&(a[r]=t[r]);var s=arguments.length-2;if(1===s)a.children=n;else if(1<s){for(var u=Array(s),c=0;c<s;c++)u[c]=arguments[c+2];a.children=u}if(e&&e.defaultProps)for(r in s=e.defaultProps)void 0===a[r]&&(a[r]=s[r]);return{$$typeof:o,type:e,key:i,ref:l,props:a,_owner:w.current}}function E(e){return"object"==typeof e&&null!==e&&e.$$typeof===o}var S=/\/+/g;function C(e,t){return"object"==typeof e&&null!==e&&null!=e.key?function(e){var t={"=":"=0",":":"=2"};return"$"+e.replace(/[=:]/g,(function(e){return t[e]}))}(""+e.key):t.toString(36)}function T(e,t,n,r,i){var l=typeof e;"undefined"!==l&&"boolean"!==l||(e=null);var s=!1;if(null===e)s=!0;else switch(l){case"string":case"number":s=!0;break;case"object":switch(e.$$typeof){case o:case a:s=!0}}if(s)return i=i(s=e),e=""===r?"."+C(s,0):r,Array.isArray(i)?(n="",null!=e&&(n=e.replace(S,"$&/")+"/"),T(i,t,n,"",(function(e){return e}))):null!=i&&(E(i)&&(i=function(e,t){return{$$typeof:o,type:e.type,key:t,ref:e.ref,props:e.props,_owner:e._owner}}(i,n+(!i.key||s&&s.key===i.key?"":(""+i.key).replace(S,"$&/")+"/")+e)),t.push(i)),1;if(s=0,r=""===r?".":r+":",Array.isArray(e))for(var u=0;u<e.length;u++){var c=r+C(l=e[u],u);s+=T(l,t,n,c,i)}else if(c=function(e){return null===e||"object"!=typeof e?null:"function"==typeof(e=f&&e[f]||e["@@iterator"])?e:null}(e),"function"==typeof c)for(e=c.call(e),u=0;!(l=e.next()).done;)s+=T(l=l.value,t,n,c=r+C(l,u++),i);else if("object"===l)throw t=""+e,Error(p(31,"[object Object]"===t?"object with keys {"+Object.keys(e).join(", ")+"}":t));return s}function O(e,t,n){if(null==e)return e;var r=[],o=0;return T(e,r,"","",(function(e){return t.call(n,e,o++)})),r}function D(e){if(-1===e._status){var t=e._result;t=t(),e._status=0,e._result=t,t.then((function(t){0===e._status&&(t=t.default,e._status=1,e._result=t)}),(function(t){0===e._status&&(e._status=2,e._result=t)}))}if(1===e._status)return e._result;throw e._result}var P={current:null};function N(){var e=P.current;if(null===e)throw Error(p(321));return e}var A={ReactCurrentDispatcher:P,ReactCurrentBatchConfig:{transition:0},ReactCurrentOwner:w,IsSomeRendererActing:{current:!1},assign:r};t.Children={map:O,forEach:function(e,t,n){O(e,(function(){t.apply(this,arguments)}),n)},count:function(e){var t=0;return O(e,(function(){t++})),t},toArray:function(e){return O(e,(function(e){return e}))||[]},only:function(e){if(!E(e))throw Error(p(143));return e}},t.Component=g,t.PureComponent=b,t.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED=A,t.cloneElement=function(e,t,n){if(null==e)throw Error(p(267,e));var a=r({},e.props),i=e.key,l=e.ref,s=e._owner;if(null!=t){if(void 0!==t.ref&&(l=t.ref,s=w.current),void 0!==t.key&&(i=""+t.key),e.type&&e.type.defaultProps)var u=e.type.defaultProps;for(c in t)x.call(t,c)&&!_.hasOwnProperty(c)&&(a[c]=void 0===t[c]&&void 0!==u?u[c]:t[c])}var c=arguments.length-2;if(1===c)a.children=n;else if(1<c){u=Array(c);for(var d=0;d<c;d++)u[d]=arguments[d+2];a.children=u}return{$$typeof:o,type:e.type,key:i,ref:l,props:a,_owner:s}},t.createContext=function(e,t){return void 0===t&&(t=null),(e={$$typeof:l,_calculateChangedBits:t,_currentValue:e,_currentValue2:e,_threadCount:0,Provider:null,Consumer:null}).Provider={$$typeof:i,_context:e},e.Consumer=e},t.createElement=k,t.createFactory=function(e){var t=k.bind(null,e);return t.type=e,t},t.createRef=function(){return{current:null}},t.forwardRef=function(e){return{$$typeof:s,render:e}},t.isValidElement=E,t.lazy=function(e){return{$$typeof:c,_payload:{_status:-1,_result:e},_init:D}},t.memo=function(e,t){return{$$typeof:u,type:e,compare:void 0===t?null:t}},t.useCallback=function(e,t){return N().useCallback(e,t)},t.useContext=function(e,t){return N().useContext(e,t)},t.useDebugValue=function(){},t.useEffect=function(e,t){return N().useEffect(e,t)},t.useImperativeHandle=function(e,t,n){return N().useImperativeHandle(e,t,n)},t.useLayoutEffect=function(e,t){return N().useLayoutEffect(e,t)},t.useMemo=function(e,t){return N().useMemo(e,t)},t.useReducer=function(e,t,n){return N().useReducer(e,t,n)},t.useRef=function(e){return N().useRef(e)},t.useState=function(e){return N().useState(e)},t.version="17.0.2"},67294:(e,t,n)=>{"use strict";e.exports=n(72408)},60053:(e,t)=>{"use strict";var n,r,o,a;if("object"==typeof performance&&"function"==typeof performance.now){var i=performance;t.unstable_now=function(){return i.now()}}else{var l=Date,s=l.now();t.unstable_now=function(){return l.now()-s}}if("undefined"==typeof window||"function"!=typeof MessageChannel){var u=null,c=null,d=function(){if(null!==u)try{var e=t.unstable_now();u(!0,e),u=null}catch(n){throw setTimeout(d,0),n}};n=function(e){null!==u?setTimeout(n,0,e):(u=e,setTimeout(d,0))},r=function(e,t){c=setTimeout(e,t)},o=function(){clearTimeout(c)},t.unstable_shouldYield=function(){return!1},a=t.unstable_forceFrameRate=function(){}}else{var f=window.setTimeout,p=window.clearTimeout;if("undefined"!=typeof console){var h=window.cancelAnimationFrame;"function"!=typeof window.requestAnimationFrame&&console.error("This browser doesn't support requestAnimationFrame. Make sure that you load a polyfill in older browsers. https://reactjs.org/link/react-polyfills"),"function"!=typeof h&&console.error("This browser doesn't support cancelAnimationFrame. Make sure that you load a polyfill in older browsers. https://reactjs.org/link/react-polyfills")}var m=!1,g=null,v=-1,b=5,y=0;t.unstable_shouldYield=function(){return t.unstable_now()>=y},a=function(){},t.unstable_forceFrameRate=function(e){0>e||125<e?console.error("forceFrameRate takes a positive int between 0 and 125, forcing frame rates higher than 125 fps is not supported"):b=0<e?Math.floor(1e3/e):5};var w=new MessageChannel,x=w.port2;w.port1.onmessage=function(){if(null!==g){var e=t.unstable_now();y=e+b;try{g(!0,e)?x.postMessage(null):(m=!1,g=null)}catch(n){throw x.postMessage(null),n}}else m=!1},n=function(e){g=e,m||(m=!0,x.postMessage(null))},r=function(e,n){v=f((function(){e(t.unstable_now())}),n)},o=function(){p(v),v=-1}}function _(e,t){var n=e.length;e.push(t);e:for(;;){var r=n-1>>>1,o=e[r];if(!(void 0!==o&&0<S(o,t)))break e;e[r]=t,e[n]=o,n=r}}function k(e){return void 0===(e=e[0])?null:e}function E(e){var t=e[0];if(void 0!==t){var n=e.pop();if(n!==t){e[0]=n;e:for(var r=0,o=e.length;r<o;){var a=2*(r+1)-1,i=e[a],l=a+1,s=e[l];if(void 0!==i&&0>S(i,n))void 0!==s&&0>S(s,i)?(e[r]=s,e[l]=n,r=l):(e[r]=i,e[a]=n,r=a);else{if(!(void 0!==s&&0>S(s,n)))break e;e[r]=s,e[l]=n,r=l}}}return t}return null}function S(e,t){var n=e.sortIndex-t.sortIndex;return 0!==n?n:e.id-t.id}var C=[],T=[],O=1,D=null,P=3,N=!1,A=!1,I=!1;function L(e){for(var t=k(T);null!==t;){if(null===t.callback)E(T);else{if(!(t.startTime<=e))break;E(T),t.sortIndex=t.expirationTime,_(C,t)}t=k(T)}}function R(e){if(I=!1,L(e),!A)if(null!==k(C))A=!0,n(j);else{var t=k(T);null!==t&&r(R,t.startTime-e)}}function j(e,n){A=!1,I&&(I=!1,o()),N=!0;var a=P;try{for(L(n),D=k(C);null!==D&&(!(D.expirationTime>n)||e&&!t.unstable_shouldYield());){var i=D.callback;if("function"==typeof i){D.callback=null,P=D.priorityLevel;var l=i(D.expirationTime<=n);n=t.unstable_now(),"function"==typeof l?D.callback=l:D===k(C)&&E(C),L(n)}else E(C);D=k(C)}if(null!==D)var s=!0;else{var u=k(T);null!==u&&r(R,u.startTime-n),s=!1}return s}finally{D=null,P=a,N=!1}}var M=a;t.unstable_IdlePriority=5,t.unstable_ImmediatePriority=1,t.unstable_LowPriority=4,t.unstable_NormalPriority=3,t.unstable_Profiling=null,t.unstable_UserBlockingPriority=2,t.unstable_cancelCallback=function(e){e.callback=null},t.unstable_continueExecution=function(){A||N||(A=!0,n(j))},t.unstable_getCurrentPriorityLevel=function(){return P},t.unstable_getFirstCallbackNode=function(){return k(C)},t.unstable_next=function(e){switch(P){case 1:case 2:case 3:var t=3;break;default:t=P}var n=P;P=t;try{return e()}finally{P=n}},t.unstable_pauseExecution=function(){},t.unstable_requestPaint=M,t.unstable_runWithPriority=function(e,t){switch(e){case 1:case 2:case 3:case 4:case 5:break;default:e=3}var n=P;P=e;try{return t()}finally{P=n}},t.unstable_scheduleCallback=function(e,a,i){var l=t.unstable_now();switch("object"==typeof i&&null!==i?i="number"==typeof(i=i.delay)&&0<i?l+i:l:i=l,e){case 1:var s=-1;break;case 2:s=250;break;case 5:s=1073741823;break;case 4:s=1e4;break;default:s=5e3}return e={id:O++,callback:a,priorityLevel:e,startTime:i,expirationTime:s=i+s,sortIndex:-1},i>l?(e.sortIndex=i,_(T,e),null===k(C)&&e===k(T)&&(I?o():I=!0,r(R,i-l))):(e.sortIndex=s,_(C,e),A||N||(A=!0,n(j))),e},t.unstable_wrapCallback=function(e){var t=P;return function(){var n=P;P=t;try{return e.apply(this,arguments)}finally{P=n}}}},63840:(e,t,n)=>{"use strict";e.exports=n(60053)},10577:e=>{!function(){"use strict";var t="undefined"!=typeof window&&void 0!==window.document?window.document:{},n=e.exports,r=function(){for(var e,n=[["requestFullscreen","exitFullscreen","fullscreenElement","fullscreenEnabled","fullscreenchange","fullscreenerror"],["webkitRequestFullscreen","webkitExitFullscreen","webkitFullscreenElement","webkitFullscreenEnabled","webkitfullscreenchange","webkitfullscreenerror"],["webkitRequestFullScreen","webkitCancelFullScreen","webkitCurrentFullScreenElement","webkitCancelFullScreen","webkitfullscreenchange","webkitfullscreenerror"],["mozRequestFullScreen","mozCancelFullScreen","mozFullScreenElement","mozFullScreenEnabled","mozfullscreenchange","mozfullscreenerror"],["msRequestFullscreen","msExitFullscreen","msFullscreenElement","msFullscreenEnabled","MSFullscreenChange","MSFullscreenError"]],r=0,o=n.length,a={};r<o;r++)if((e=n[r])&&e[1]in t){for(r=0;r<e.length;r++)a[n[0][r]]=e[r];return a}return!1}(),o={change:r.fullscreenchange,error:r.fullscreenerror},a={request:function(e,n){return new Promise(function(o,a){var i=function(){this.off("change",i),o()}.bind(this);this.on("change",i);var l=(e=e||t.documentElement)[r.requestFullscreen](n);l instanceof Promise&&l.then(i).catch(a)}.bind(this))},exit:function(){return new Promise(function(e,n){if(this.isFullscreen){var o=function(){this.off("change",o),e()}.bind(this);this.on("change",o);var a=t[r.exitFullscreen]();a instanceof Promise&&a.then(o).catch(n)}else e()}.bind(this))},toggle:function(e,t){return this.isFullscreen?this.exit():this.request(e,t)},onchange:function(e){this.on("change",e)},onerror:function(e){this.on("error",e)},on:function(e,n){var r=o[e];r&&t.addEventListener(r,n,!1)},off:function(e,n){var r=o[e];r&&t.removeEventListener(r,n,!1)},raw:r};r?(Object.defineProperties(a,{isFullscreen:{get:function(){return Boolean(t[r.fullscreenElement])}},element:{enumerable:!0,get:function(){return t[r.fullscreenElement]}},isEnabled:{enumerable:!0,get:function(){return Boolean(t[r.fullscreenEnabled])}}}),n?e.exports=a:window.screenfull=a):n?e.exports={isEnabled:!1}:window.screenfull={isEnabled:!1}}()},96774:e=>{e.exports=function(e,t,n,r){var o=n?n.call(r,e,t):void 0;if(void 0!==o)return!!o;if(e===t)return!0;if("object"!=typeof e||!e||"object"!=typeof t||!t)return!1;var a=Object.keys(e),i=Object.keys(t);if(a.length!==i.length)return!1;for(var l=Object.prototype.hasOwnProperty.bind(t),s=0;s<a.length;s++){var u=a[s];if(!l(u))return!1;var c=e[u],d=t[u];if(!1===(o=n?n.call(r,c,d,u):void 0)||void 0===o&&c!==d)return!1}return!0}},11742:e=>{e.exports=function(){var e=document.getSelection();if(!e.rangeCount)return function(){};for(var t=document.activeElement,n=[],r=0;r<e.rangeCount;r++)n.push(e.getRangeAt(r));switch(t.tagName.toUpperCase()){case"INPUT":case"TEXTAREA":t.blur();break;default:t=null}return e.removeAllRanges(),function(){"Caret"===e.type&&e.removeAllRanges(),e.rangeCount||n.forEach((function(t){e.addRange(t)})),t&&t.focus()}}},75534:(e,t)=>{"use strict";t.U={linear:function(e){return e},quadratic:function(e){return e*(-e*e*e+4*e*e-6*e+4)},cubic:function(e){return e*(4*e*e-9*e+6)},elastic:function(e){return e*(33*e*e*e*e-106*e*e*e+126*e*e-67*e+15)},inQuad:function(e){return e*e},outQuad:function(e){return e*(2-e)},inOutQuad:function(e){return e<.5?2*e*e:(4-2*e)*e-1},inCubic:function(e){return e*e*e},outCubic:function(e){return--e*e*e+1},inOutCubic:function(e){return e<.5?4*e*e*e:(e-1)*(2*e-2)*(2*e-2)+1},inQuart:function(e){return e*e*e*e},outQuart:function(e){return 1- --e*e*e*e},inOutQuart:function(e){return e<.5?8*e*e*e*e:1-8*--e*e*e*e},inQuint:function(e){return e*e*e*e*e},outQuint:function(e){return 1+--e*e*e*e*e},inOutQuint:function(e){return e<.5?16*e*e*e*e*e:1+16*--e*e*e*e*e},inSine:function(e){return 1-Math.cos(e*(Math.PI/2))},outSine:function(e){return Math.sin(e*(Math.PI/2))},inOutSine:function(e){return-(Math.cos(Math.PI*e)-1)/2},inExpo:function(e){return Math.pow(2,10*(e-1))},outExpo:function(e){return 1-Math.pow(2,-10*e)},inOutExpo:function(e){return(e/=.5)<1?Math.pow(2,10*(e-1))/2:(e--,(2-Math.pow(2,-10*e))/2)},inCirc:function(e){return 1-Math.sqrt(1-e*e)},outCirc:function(e){return Math.sqrt(1-(e-=1)*e)},inOutCirc:function(e){return(e/=.5)<1?-(Math.sqrt(1-e*e)-1)/2:(e-=2,(Math.sqrt(1-e*e)+1)/2)}}},70655:(e,t,n)=>{"use strict";n.r(t),n.d(t,{__assign:()=>a,__asyncDelegator:()=>x,__asyncGenerator:()=>w,__asyncValues:()=>_,__await:()=>y,__awaiter:()=>c,__classPrivateFieldGet:()=>T,__classPrivateFieldIn:()=>D,__classPrivateFieldSet:()=>O,__createBinding:()=>f,__decorate:()=>l,__exportStar:()=>p,__extends:()=>o,__generator:()=>d,__importDefault:()=>C,__importStar:()=>S,__makeTemplateObject:()=>k,__metadata:()=>u,__param:()=>s,__read:()=>m,__rest:()=>i,__spread:()=>g,__spreadArray:()=>b,__spreadArrays:()=>v,__values:()=>h});var r=function(e,t){return r=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(e,t){e.__proto__=t}||function(e,t){for(var n in t)Object.prototype.hasOwnProperty.call(t,n)&&(e[n]=t[n])},r(e,t)};function o(e,t){if("function"!=typeof t&&null!==t)throw new TypeError("Class extends value "+String(t)+" is not a constructor or null");function n(){this.constructor=e}r(e,t),e.prototype=null===t?Object.create(t):(n.prototype=t.prototype,new n)}var a=function(){return a=Object.assign||function(e){for(var t,n=1,r=arguments.length;n<r;n++)for(var o in t=arguments[n])Object.prototype.hasOwnProperty.call(t,o)&&(e[o]=t[o]);return e},a.apply(this,arguments)};function i(e,t){var n={};for(var r in e)Object.prototype.hasOwnProperty.call(e,r)&&t.indexOf(r)<0&&(n[r]=e[r]);if(null!=e&&"function"==typeof Object.getOwnPropertySymbols){var o=0;for(r=Object.getOwnPropertySymbols(e);o<r.length;o++)t.indexOf(r[o])<0&&Object.prototype.propertyIsEnumerable.call(e,r[o])&&(n[r[o]]=e[r[o]])}return n}function l(e,t,n,r){var o,a=arguments.length,i=a<3?t:null===r?r=Object.getOwnPropertyDescriptor(t,n):r;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)i=Reflect.decorate(e,t,n,r);else for(var l=e.length-1;l>=0;l--)(o=e[l])&&(i=(a<3?o(i):a>3?o(t,n,i):o(t,n))||i);return a>3&&i&&Object.defineProperty(t,n,i),i}function s(e,t){return function(n,r){t(n,r,e)}}function u(e,t){if("object"==typeof Reflect&&"function"==typeof Reflect.metadata)return Reflect.metadata(e,t)}function c(e,t,n,r){return new(n||(n=Promise))((function(o,a){function i(e){try{s(r.next(e))}catch(t){a(t)}}function l(e){try{s(r.throw(e))}catch(t){a(t)}}function s(e){var t;e.done?o(e.value):(t=e.value,t instanceof n?t:new n((function(e){e(t)}))).then(i,l)}s((r=r.apply(e,t||[])).next())}))}function d(e,t){var n,r,o,a,i={label:0,sent:function(){if(1&o[0])throw o[1];return o[1]},trys:[],ops:[]};return a={next:l(0),throw:l(1),return:l(2)},"function"==typeof Symbol&&(a[Symbol.iterator]=function(){return this}),a;function l(a){return function(l){return function(a){if(n)throw new TypeError("Generator is already executing.");for(;i;)try{if(n=1,r&&(o=2&a[0]?r.return:a[0]?r.throw||((o=r.return)&&o.call(r),0):r.next)&&!(o=o.call(r,a[1])).done)return o;switch(r=0,o&&(a=[2&a[0],o.value]),a[0]){case 0:case 1:o=a;break;case 4:return i.label++,{value:a[1],done:!1};case 5:i.label++,r=a[1],a=[0];continue;case 7:a=i.ops.pop(),i.trys.pop();continue;default:if(!(o=i.trys,(o=o.length>0&&o[o.length-1])||6!==a[0]&&2!==a[0])){i=0;continue}if(3===a[0]&&(!o||a[1]>o[0]&&a[1]<o[3])){i.label=a[1];break}if(6===a[0]&&i.label<o[1]){i.label=o[1],o=a;break}if(o&&i.label<o[2]){i.label=o[2],i.ops.push(a);break}o[2]&&i.ops.pop(),i.trys.pop();continue}a=t.call(e,i)}catch(l){a=[6,l],r=0}finally{n=o=0}if(5&a[0])throw a[1];return{value:a[0]?a[1]:void 0,done:!0}}([a,l])}}}var f=Object.create?function(e,t,n,r){void 0===r&&(r=n);var o=Object.getOwnPropertyDescriptor(t,n);o&&!("get"in o?!t.__esModule:o.writable||o.configurable)||(o={enumerable:!0,get:function(){return t[n]}}),Object.defineProperty(e,r,o)}:function(e,t,n,r){void 0===r&&(r=n),e[r]=t[n]};function p(e,t){for(var n in e)"default"===n||Object.prototype.hasOwnProperty.call(t,n)||f(t,e,n)}function h(e){var t="function"==typeof Symbol&&Symbol.iterator,n=t&&e[t],r=0;if(n)return n.call(e);if(e&&"number"==typeof e.length)return{next:function(){return e&&r>=e.length&&(e=void 0),{value:e&&e[r++],done:!e}}};throw new TypeError(t?"Object is not iterable.":"Symbol.iterator is not defined.")}function m(e,t){var n="function"==typeof Symbol&&e[Symbol.iterator];if(!n)return e;var r,o,a=n.call(e),i=[];try{for(;(void 0===t||t-- >0)&&!(r=a.next()).done;)i.push(r.value)}catch(l){o={error:l}}finally{try{r&&!r.done&&(n=a.return)&&n.call(a)}finally{if(o)throw o.error}}return i}function g(){for(var e=[],t=0;t<arguments.length;t++)e=e.concat(m(arguments[t]));return e}function v(){for(var e=0,t=0,n=arguments.length;t<n;t++)e+=arguments[t].length;var r=Array(e),o=0;for(t=0;t<n;t++)for(var a=arguments[t],i=0,l=a.length;i<l;i++,o++)r[o]=a[i];return r}function b(e,t,n){if(n||2===arguments.length)for(var r,o=0,a=t.length;o<a;o++)!r&&o in t||(r||(r=Array.prototype.slice.call(t,0,o)),r[o]=t[o]);return e.concat(r||Array.prototype.slice.call(t))}function y(e){return this instanceof y?(this.v=e,this):new y(e)}function w(e,t,n){if(!Symbol.asyncIterator)throw new TypeError("Symbol.asyncIterator is not defined.");var r,o=n.apply(e,t||[]),a=[];return r={},i("next"),i("throw"),i("return"),r[Symbol.asyncIterator]=function(){return this},r;function i(e){o[e]&&(r[e]=function(t){return new Promise((function(n,r){a.push([e,t,n,r])>1||l(e,t)}))})}function l(e,t){try{(n=o[e](t)).value instanceof y?Promise.resolve(n.value.v).then(s,u):c(a[0][2],n)}catch(r){c(a[0][3],r)}var n}function s(e){l("next",e)}function u(e){l("throw",e)}function c(e,t){e(t),a.shift(),a.length&&l(a[0][0],a[0][1])}}function x(e){var t,n;return t={},r("next"),r("throw",(function(e){throw e})),r("return"),t[Symbol.iterator]=function(){return this},t;function r(r,o){t[r]=e[r]?function(t){return(n=!n)?{value:y(e[r](t)),done:"return"===r}:o?o(t):t}:o}}function _(e){if(!Symbol.asyncIterator)throw new TypeError("Symbol.asyncIterator is not defined.");var t,n=e[Symbol.asyncIterator];return n?n.call(e):(e=h(e),t={},r("next"),r("throw"),r("return"),t[Symbol.asyncIterator]=function(){return this},t);function r(n){t[n]=e[n]&&function(t){return new Promise((function(r,o){(function(e,t,n,r){Promise.resolve(r).then((function(t){e({value:t,done:n})}),t)})(r,o,(t=e[n](t)).done,t.value)}))}}}function k(e,t){return Object.defineProperty?Object.defineProperty(e,"raw",{value:t}):e.raw=t,e}var E=Object.create?function(e,t){Object.defineProperty(e,"default",{enumerable:!0,value:t})}:function(e,t){e.default=t};function S(e){if(e&&e.__esModule)return e;var t={};if(null!=e)for(var n in e)"default"!==n&&Object.prototype.hasOwnProperty.call(e,n)&&f(t,e,n);return E(t,e),t}function C(e){return e&&e.__esModule?e:{default:e}}function T(e,t,n,r){if("a"===n&&!r)throw new TypeError("Private accessor was defined without a getter");if("function"==typeof t?e!==t||!r:!t.has(e))throw new TypeError("Cannot read private member from an object whose class did not declare it");return"m"===n?r:"a"===n?r.call(e):r?r.value:t.get(e)}function O(e,t,n,r,o){if("m"===r)throw new TypeError("Private method is not writable");if("a"===r&&!o)throw new TypeError("Private accessor was defined without a setter");if("function"==typeof t?e!==t||!o:!t.has(e))throw new TypeError("Cannot write private member to an object whose class did not declare it");return"a"===r?o.call(e,n):o?o.value=n:t.set(e,n),n}function D(e,t){if(null===t||"object"!=typeof t&&"function"!=typeof t)throw new TypeError("Cannot use 'in' operator on non-object");return"function"==typeof e?t===e:e.has(t)}},53250:(e,t,n)=>{"use strict";var r=n(67294);var o="function"==typeof Object.is?Object.is:function(e,t){return e===t&&(0!==e||1/e==1/t)||e!=e&&t!=t},a=r.useState,i=r.useEffect,l=r.useLayoutEffect,s=r.useDebugValue;function u(e){var t=e.getSnapshot;e=e.value;try{var n=t();return!o(e,n)}catch(r){return!0}}var c="undefined"==typeof window||void 0===window.document||void 0===window.document.createElement?function(e,t){return t()}:function(e,t){var n=t(),r=a({inst:{value:n,getSnapshot:t}}),o=r[0].inst,c=r[1];return l((function(){o.value=n,o.getSnapshot=t,u(o)&&c({inst:o})}),[e,n,t]),i((function(){return u(o)&&c({inst:o}),e((function(){u(o)&&c({inst:o})}))}),[e]),s(n),n};t.useSyncExternalStore=void 0!==r.useSyncExternalStore?r.useSyncExternalStore:c},61688:(e,t,n)=>{"use strict";e.exports=n(53250)},36809:(e,t,n)=>{"use strict";n.d(t,{Z:()=>r});const r={title:"Vac Research",url:"https://vac.dev",baseUrl:"/",markdown:{mermaid:!0},i18n:{defaultLocale:"en",locales:["en"],path:"i18n",localeConfigs:{}},presets:[["@acid-info/logos-docusaurus-preset",{businessUnit:"VacResearch",theme:{name:"default",options:{customCss:["/home/jenkins/workspace/website/vac.dev/src/css/custom.scss"]}},docs:{id:"Docs",breadcrumbs:!1,routeBasePath:"/",sidebarPath:"docs/sidebars.js",remarkPlugins:[null],rehypePlugins:[null]},og:{},generated:{jobList:{jobBoard:"vac"}}}]],plugins:[["@docusaurus/plugin-content-blog",{id:"blog",routeBasePath:"/rlog",path:"rlog",blogTitle:"Research Blog",blogSidebarCount:0,authorsMapPath:"authors.yml",remarkPlugins:[null],rehypePlugins:[null]}],["@docusaurus/plugin-client-redirects",{redirects:[{from:"/research",to:"/rlog"}]}],["@acid-info/docusaurus-og",{path:"_og",imageRenderers:{}}]],themeConfig:{docs:{sidebar:{hideable:!0,autoCollapseCategories:!1},versionPersistence:"localStorage"},metadata:[{name:"description",content:"Vac - Communication, Privacy, Etc."},{name:"image",content:"theme/image/preview-image.png"}],colorMode:{disableSwitch:!1,defaultMode:"dark",respectPrefersColorScheme:!0},navbar:{title:"",logo:{alt:"Vac Research",src:"theme/image/logo.svg",height:26},hideOnScroll:!0,items:[{type:"search",position:"left"},{label:"About Vac",to:"/",activeBaseRegex:"^/$",position:"left"},{label:"Community",to:"/community",activeBasePath:"community",position:"left"},{label:"Research Blog",to:"/rlog",activeBasePath:"rlog",position:"left"},{label:"Join Us",to:"/join-us",activeBasePath:"join-us",position:"left"}]},footer:{logo:{alt:"Vac Research",src:"theme/image/logo.svg",href:"/",width:22},links:[{items:[{label:"Twitter",href:"https://twitter.com/vacp2p"},{label:"Discord",href:"https://discord.gg/PQFdubGt6d"},{label:"Github",href:"https://github.com/vacp2p"}],title:null},{items:[{label:"Work With Us",href:"https://jobs.status.im/"},{label:"Terms & Conditions",to:"/terms"},{href:"/privacy-policy",label:"Privacy Policy"},{href:"/security",label:"Security"}],title:null},{title:"shared:Research",items:[{href:"https://vac.dev",label:"VacP2P"},{href:"https://afaik.institute",label:"AFAIK"}]},{title:"shared:Infrastructure",items:[{href:"https://waku.org/",label:"Waku"},{href:"https://nimbus.team/",label:"Nimbus"},{href:"https://codex.storage",label:"Codex"},{href:"https://nomos.tech",label:"Nomos"}]},{title:"shared:Creative Studio",items:[{href:"https://acid.info",label:"Acid.info"}]},{title:"shared:Movement",items:[{href:"https://logos.co",label:"Logos"}]},{title:"shared:User-facing products",items:[{href:"https://status.im",label:"Status"},{href:"https://keycard.tech",label:"Keycard"}]}],copyright:"Vac Research \xa9 2024<br/>All rights reserved.",style:"light"},prism:{theme:{plain:{color:"#000000",backgroundColor:"rgba(var(--lsd-surface-secondary), 0.08)"},styles:[{types:["comment"],style:{color:"rgb(0, 128, 0)"}},{types:["builtin"],style:{color:"rgb(0, 112, 193)"}},{types:["number","variable","inserted"],style:{color:"rgb(9, 134, 88)"}},{types:["operator"],style:{color:"rgb(0, 0, 0)"}},{types:["constant","char"],style:{color:"rgb(129, 31, 63)"}},{types:["tag"],style:{color:"rgb(128, 0, 0)"}},{types:["attr-name"],style:{color:"rgb(255, 0, 0)"}},{types:["deleted","string"],style:{color:"rgb(163, 21, 21)"}},{types:["changed","punctuation"],style:{color:"rgb(4, 81, 165)"}},{types:["function","keyword"],style:{color:"rgb(0, 0, 255)"}},{types:["class-name"],style:{color:"rgb(38, 127, 153)"}}]},darkTheme:{plain:{color:"#F8F8F2",backgroundColor:"rgba(var(--lsd-surface-secondary), 0.08)"},styles:[{types:["prolog","constant","builtin"],style:{color:"rgb(189, 147, 249)"}},{types:["inserted","function"],style:{color:"rgb(80, 250, 123)"}},{types:["deleted"],style:{color:"rgb(255, 85, 85)"}},{types:["changed"],style:{color:"rgb(255, 184, 108)"}},{types:["punctuation","symbol"],style:{color:"rgb(248, 248, 242)"}},{types:["string","char","tag","selector"],style:{color:"rgb(255, 121, 198)"}},{types:["keyword","variable"],style:{color:"rgb(189, 147, 249)",fontStyle:"italic"}},{types:["comment"],style:{color:"rgb(98, 114, 164)"}},{types:["attr-name"],style:{color:"rgb(241, 250, 140)"}}]},additionalLanguages:[],magicComments:[{className:"theme-code-block-highlighted-line",line:"highlight-next-line",block:{start:"highlight-start",end:"highlight-end"}}]},tableOfContents:{minHeadingLevel:2,maxHeadingLevel:3},mermaid:{theme:{dark:"dark",light:"default"},options:{}}},stylesheets:[{href:"https://cdn.jsdelivr.net/npm/katex@0.13.24/dist/katex.min.css",type:"text/css",integrity:"sha384-odtC+0UGzzFL/6PNoE8rX/SPcQDXBJ+uRepguP4QkPCm2LBxH3FA3y+fKSiJ+AmM",crossorigin:"anonymous"}],baseUrlIssueBanner:!0,onBrokenLinks:"warn",onBrokenMarkdownLinks:"warn",onDuplicateRoutes:"warn",staticDirectories:["static","/home/jenkins/workspace/website/vac.dev/node_modules/@acid-info/logos-docusaurus-preset/static/common","/home/jenkins/workspace/website/vac.dev/node_modules/@acid-info/logos-docusaurus-preset/static/VacResearch","/home/jenkins/workspace/website/vac.dev/node_modules/@acid-info/logos-docusaurus-theme/lib/client/static/"],customFields:{businessUnits:"VacResearch","logos-docusaurus-theme":{customCss:["/home/jenkins/workspace/website/vac.dev/src/css/custom.scss"],docs:{},id:"default"}},themes:[],scripts:[],headTags:[],clientModules:[],tagline:"Vac - Communication, Privacy, Etc.",titleDelimiter:"|",noIndex:!1,favicon:"theme/image/favicon.ico"}},87462:(e,t,n)=>{"use strict";function r(){return r=Object.assign?Object.assign.bind():function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e},r.apply(this,arguments)}n.d(t,{Z:()=>r})},75068:(e,t,n)=>{"use strict";function r(e,t){return r=Object.setPrototypeOf?Object.setPrototypeOf.bind():function(e,t){return e.__proto__=t,e},r(e,t)}function o(e,t){e.prototype=Object.create(t.prototype),e.prototype.constructor=e,r(e,t)}n.d(t,{Z:()=>o})},63366:(e,t,n)=>{"use strict";function r(e,t){if(null==e)return{};var n,r,o={},a=Object.keys(e);for(r=0;r<a.length;r++)n=a[r],t.indexOf(n)>=0||(o[n]=e[n]);return o}n.d(t,{Z:()=>r})},27563:(e,t,n)=>{"use strict";n.d(t,{Ab:()=>i,Fr:()=>l,G$:()=>a,JM:()=>d,K$:()=>u,MS:()=>r,h5:()=>s,lK:()=>c,uj:()=>o});var r="-ms-",o="-moz-",a="-webkit-",i="comm",l="rule",s="decl",u="@import",c="@keyframes",d="@layer"},92190:(e,t,n)=>{"use strict";n.d(t,{MY:()=>i});var r=n(27563),o=n(26686),a=n(46411);function i(e){return(0,a.cE)(l("",null,null,null,[""],e=(0,a.un)(e),0,[0],e))}function l(e,t,n,r,i,d,f,p,h){for(var m=0,g=0,v=f,b=0,y=0,w=0,x=1,_=1,k=1,E=0,S="",C=i,T=d,O=r,D=S;_;)switch(w=E,E=(0,a.lp)()){case 40:if(108!=w&&58==(0,o.uO)(D,v-1)){-1!=(0,o.Cw)(D+=(0,o.gx)((0,a.iF)(E),"&","&\f"),"&\f")&&(k=-1);break}case 34:case 39:case 91:D+=(0,a.iF)(E);break;case 9:case 10:case 13:case 32:D+=(0,a.Qb)(w);break;case 92:D+=(0,a.kq)((0,a.Ud)()-1,7);continue;case 47:switch((0,a.fj)()){case 42:case 47:(0,o.R3)(u((0,a.q6)((0,a.lp)(),(0,a.Ud)()),t,n),h);break;default:D+="/"}break;case 123*x:p[m++]=(0,o.to)(D)*k;case 125*x:case 59:case 0:switch(E){case 0:case 125:_=0;case 59+g:-1==k&&(D=(0,o.gx)(D,/\f/g,"")),y>0&&(0,o.to)(D)-v&&(0,o.R3)(y>32?c(D+";",r,n,v-1):c((0,o.gx)(D," ","")+";",r,n,v-2),h);break;case 59:D+=";";default:if((0,o.R3)(O=s(D,t,n,m,g,i,p,S,C=[],T=[],v),d),123===E)if(0===g)l(D,t,O,O,C,d,v,p,T);else switch(99===b&&110===(0,o.uO)(D,3)?100:b){case 100:case 108:case 109:case 115:l(e,O,O,r&&(0,o.R3)(s(e,O,O,0,0,i,p,S,i,C=[],v),T),i,T,v,p,r?C:T);break;default:l(D,O,O,O,[""],T,0,p,T)}}m=g=y=0,x=k=1,S=D="",v=f;break;case 58:v=1+(0,o.to)(D),y=w;default:if(x<1)if(123==E)--x;else if(125==E&&0==x++&&125==(0,a.mp)())continue;switch(D+=(0,o.Dp)(E),E*x){case 38:k=g>0?1:(D+="\f",-1);break;case 44:p[m++]=((0,o.to)(D)-1)*k,k=1;break;case 64:45===(0,a.fj)()&&(D+=(0,a.iF)((0,a.lp)())),b=(0,a.fj)(),g=v=(0,o.to)(S=D+=(0,a.QU)((0,a.Ud)())),E++;break;case 45:45===w&&2==(0,o.to)(D)&&(x=0)}}return d}function s(e,t,n,i,l,s,u,c,d,f,p){for(var h=l-1,m=0===l?s:[""],g=(0,o.Ei)(m),v=0,b=0,y=0;v<i;++v)for(var w=0,x=(0,o.tb)(e,h+1,h=(0,o.Wn)(b=u[v])),_=e;w<g;++w)(_=(0,o.fy)(b>0?m[w]+" "+x:(0,o.gx)(x,/&\f/g,m[w])))&&(d[y++]=_);return(0,a.dH)(e,t,n,0===l?r.Fr:c,d,f,p)}function u(e,t,n){return(0,a.dH)(e,t,n,r.Ab,(0,o.Dp)((0,a.Tb)()),(0,o.tb)(e,2,-2),0)}function c(e,t,n,i){return(0,a.dH)(e,t,n,r.h5,(0,o.tb)(e,0,i),(0,o.tb)(e,i+1,-1),i)}},20211:(e,t,n)=>{"use strict";n.d(t,{P:()=>i,q:()=>a});var r=n(27563),o=n(26686);function a(e,t){for(var n="",r=(0,o.Ei)(e),a=0;a<r;a++)n+=t(e[a],a,e,t)||"";return n}function i(e,t,n,i){switch(e.type){case r.JM:if(e.children.length)break;case r.K$:case r.h5:return e.return=e.return||e.value;case r.Ab:return"";case r.lK:return e.return=e.value+"{"+a(e.children,i)+"}";case r.Fr:e.value=e.props.join(",")}return(0,o.to)(n=a(e.children,i))?e.return=e.value+"{"+n+"}":""}},46411:(e,t,n)=>{"use strict";n.d(t,{FK:()=>l,JG:()=>d,QU:()=>C,Qb:()=>_,Tb:()=>f,Ud:()=>g,cE:()=>w,dH:()=>c,fj:()=>m,iF:()=>x,kq:()=>k,lp:()=>h,mp:()=>p,q6:()=>S,r:()=>b,tP:()=>v,un:()=>y});var r=n(26686),o=1,a=1,i=0,l=0,s=0,u="";function c(e,t,n,r,i,l,s){return{value:e,root:t,parent:n,type:r,props:i,children:l,line:o,column:a,length:s,return:""}}function d(e,t){return(0,r.f0)(c("",null,null,"",null,null,0),e,{length:-e.length},t)}function f(){return s}function p(){return s=l>0?(0,r.uO)(u,--l):0,a--,10===s&&(a=1,o--),s}function h(){return s=l<i?(0,r.uO)(u,l++):0,a++,10===s&&(a=1,o++),s}function m(){return(0,r.uO)(u,l)}function g(){return l}function v(e,t){return(0,r.tb)(u,e,t)}function b(e){switch(e){case 0:case 9:case 10:case 13:case 32:return 5;case 33:case 43:case 44:case 47:case 62:case 64:case 126:case 59:case 123:case 125:return 4;case 58:return 3;case 34:case 39:case 40:case 91:return 2;case 41:case 93:return 1}return 0}function y(e){return o=a=1,i=(0,r.to)(u=e),l=0,[]}function w(e){return u="",e}function x(e){return(0,r.fy)(v(l-1,E(91===e?e+2:40===e?e+1:e)))}function _(e){for(;(s=m())&&s<33;)h();return b(e)>2||b(s)>3?"":" "}function k(e,t){for(;--t&&h()&&!(s<48||s>102||s>57&&s<65||s>70&&s<97););return v(e,g()+(t<6&&32==m()&&32==h()))}function E(e){for(;h();)switch(s){case e:return l;case 34:case 39:34!==e&&39!==e&&E(s);break;case 40:41===e&&E(e);break;case 92:h()}return l}function S(e,t){for(;h()&&e+s!==57&&(e+s!==84||47!==m()););return"/*"+v(t,l-1)+"*"+(0,r.Dp)(47===e?e:h())}function C(e){for(;!b(m());)h();return v(e,l)}},26686:(e,t,n)=>{"use strict";n.d(t,{$e:()=>g,Cw:()=>c,Dp:()=>o,EQ:()=>s,Ei:()=>h,R3:()=>m,Wn:()=>r,f0:()=>a,fy:()=>l,gx:()=>u,tb:()=>f,to:()=>p,uO:()=>d,vp:()=>i});var r=Math.abs,o=String.fromCharCode,a=Object.assign;function i(e,t){return 45^d(e,0)?(((t<<2^d(e,0))<<2^d(e,1))<<2^d(e,2))<<2^d(e,3):0}function l(e){return e.trim()}function s(e,t){return(e=t.exec(e))?e[0]:e}function u(e,t,n){return e.replace(t,n)}function c(e,t){return e.indexOf(t)}function d(e,t){return 0|e.charCodeAt(t)}function f(e,t,n){return e.slice(t,n)}function p(e){return e.length}function h(e){return e.length}function m(e,t){return t.push(e),e}function g(e,t){return e.map(t).join("")}},38776:(e,t,n)=>{"use strict";n.d(t,{Z:()=>o});var r="Invariant failed";function o(e,t){if(!e)throw new Error(r)}},57529:e=>{"use strict";e.exports={}},16887:e=>{"use strict";e.exports=JSON.parse('{"/rlog-20f":{"__comp":"a6aa9e1f","__context":{"plugin":"1e4c069f"},"sidebar":"95b96bb9","items":[{"content":"d758c4b4"},{"content":"2e8c87b8"},{"content":"cbf8cf19"},{"content":"feda84cd"},{"content":"2858c6ff"},{"content":"fdd3b45a"},{"content":"382fdf29"},{"content":"39f27fb8"},{"content":"84dd0cf8"},{"content":"38dc9501"}],"metadata":"124805df"},"/rlog/archive-242":{"__comp":"9e4087bc","__context":{"plugin":"1e4c069f"},"archive":"99c49682"},"/rlog/building-privacy-protecting-infrastructure-b52":{"__comp":"ccc49370","__context":{"plugin":"1e4c069f"},"sidebar":"95b96bb9","content":"e22c7a04"},"/rlog/device-pairing-in-js-waku-and-go-waku-6e6":{"__comp":"ccc49370","__context":{"plugin":"1e4c069f"},"sidebar":"95b96bb9","content":"67b45d3c"},"/rlog/dns-based-discovery-f9b":{"__comp":"ccc49370","__context":{"plugin":"1e4c069f"},"sidebar":"95b96bb9","content":"15a93281"},"/rlog/ethics-surveillance-tech-872":{"__comp":"ccc49370","__context":{"plugin":"1e4c069f"},"sidebar":"95b96bb9","content":"7b019678"},"/rlog/feasibility-discv5-2c3":{"__comp":"ccc49370","__context":{"plugin":"1e4c069f"},"sidebar":"95b96bb9","content":"f7ba2fd8"},"/rlog/feasibility-semaphore-rate-limiting-zksnarks-cff":{"__comp":"ccc49370","__context":{"plugin":"1e4c069f"},"sidebar":"95b96bb9","content":"96524732"},"/rlog/fixing-whisper-with-waku-4ec":{"__comp":"ccc49370","__context":{"plugin":"1e4c069f"},"sidebar":"95b96bb9","content":"2056d17e"},"/rlog/future-of-waku-network-100":{"__comp":"ccc49370","__context":{"plugin":"1e4c069f"},"sidebar":"95b96bb9","content":"91ce8bda"},"/rlog/GossipSub Improvements-4fc":{"__comp":"ccc49370","__context":{"plugin":"1e4c069f"},"sidebar":"95b96bb9","content":"bd3d84fb"},"/rlog/introducing-nwaku-9eb":{"__comp":"ccc49370","__context":{"plugin":"1e4c069f"},"sidebar":"95b96bb9","content":"9e34dc04"},"/rlog/kademlia-to-discv5-2d3":{"__comp":"ccc49370","__context":{"plugin":"1e4c069f"},"sidebar":"95b96bb9","content":"f40b13b8"},"/rlog/membership-with-bloom-filters-and-cuckoo-filters-b1b":{"__comp":"ccc49370","__context":{"plugin":"1e4c069f"},"sidebar":"95b96bb9","content":"7b0e1478"},"/rlog/Nescience-A-zkVM-leveraging-hiding-properties-605":{"__comp":"ccc49370","__context":{"plugin":"1e4c069f"},"sidebar":"95b96bb9","content":"3b467599"},"/rlog/Nescience-state-separation-architecture-72d":{"__comp":"ccc49370","__context":{"plugin":"1e4c069f"},"sidebar":"95b96bb9","content":"18a94246"},"/rlog/p2p-data-sync-for-mobile-8e8":{"__comp":"ccc49370","__context":{"plugin":"1e4c069f"},"sidebar":"95b96bb9","content":"e954d700"},"/rlog/page/2-de8":{"__comp":"a6aa9e1f","__context":{"plugin":"1e4c069f"},"sidebar":"95b96bb9","items":[{"content":"544f54cc"},{"content":"6facda94"},{"content":"7d3f2fdb"},{"content":"ec8fd1ee"},{"content":"13a255f1"},{"content":"c8894de3"},{"content":"0d54ff0d"},{"content":"f643ab5d"},{"content":"18961ce6"},{"content":"9fb2a6b1"}],"metadata":"cde6c892"},"/rlog/page/3-a57":{"__comp":"a6aa9e1f","__context":{"plugin":"1e4c069f"},"sidebar":"95b96bb9","items":[{"content":"3f64d9a3"},{"content":"c2965f87"},{"content":"74c00f84"},{"content":"6f6bcf93"},{"content":"6abf00de"},{"content":"83575890"},{"content":"84f8336a"},{"content":"7af80316"},{"content":"3f082616"},{"content":"158719ed"}],"metadata":"8c1443cc"},"/rlog/page/4-917":{"__comp":"a6aa9e1f","__context":{"plugin":"1e4c069f"},"sidebar":"95b96bb9","items":[{"content":"6f1f8c5f"},{"content":"db970d56"},{"content":"4a8210e4"},{"content":"c7770090"},{"content":"2d6b2291"}],"metadata":"2ef0cd56"},"/rlog/presenting-js-waku-380":{"__comp":"ccc49370","__context":{"plugin":"1e4c069f"},"sidebar":"95b96bb9","content":"12da0170"},"/rlog/remote-log-5c3":{"__comp":"ccc49370","__context":{"plugin":"1e4c069f"},"sidebar":"95b96bb9","content":"f1787e6d"},"/rlog/rln-anonymous-dos-prevention-535":{"__comp":"ccc49370","__context":{"plugin":"1e4c069f"},"sidebar":"95b96bb9","content":"8779ed83"},"/rlog/rln-light-verifiers-657":{"__comp":"ccc49370","__context":{"plugin":"1e4c069f"},"sidebar":"95b96bb9","content":"a71c3513"},"/rlog/rln-relay-2b7":{"__comp":"ccc49370","__context":{"plugin":"1e4c069f"},"sidebar":"95b96bb9","content":"29ae586d"},"/rlog/rln-v3-f91":{"__comp":"ccc49370","__context":{"plugin":"1e4c069f"},"sidebar":"95b96bb9","content":"db40b3a8"},"/rlog/vac-overview-13b":{"__comp":"ccc49370","__context":{"plugin":"1e4c069f"},"sidebar":"95b96bb9","content":"5a7c4f09"},"/rlog/waku-for-all-8f7":{"__comp":"ccc49370","__context":{"plugin":"1e4c069f"},"sidebar":"95b96bb9","content":"191d05a9"},"/rlog/waku-update-7bc":{"__comp":"ccc49370","__context":{"plugin":"1e4c069f"},"sidebar":"95b96bb9","content":"d0c5fcac"},"/rlog/waku-v1-v2-bandwidth-comparison-a00":{"__comp":"ccc49370","__context":{"plugin":"1e4c069f"},"sidebar":"95b96bb9","content":"b0a36ee8"},"/rlog/waku-v2-ethereum-coscup-f86":{"__comp":"ccc49370","__context":{"plugin":"1e4c069f"},"sidebar":"95b96bb9","content":"f3c329e5"},"/rlog/waku-v2-ethereum-messaging-d5b":{"__comp":"ccc49370","__context":{"plugin":"1e4c069f"},"sidebar":"95b96bb9","content":"9e396004"},"/rlog/waku-v2-plan-943":{"__comp":"ccc49370","__context":{"plugin":"1e4c069f"},"sidebar":"95b96bb9","content":"3ec022cb"},"/rlog/waku-v2-update-73e":{"__comp":"ccc49370","__context":{"plugin":"1e4c069f"},"sidebar":"95b96bb9","content":"384035e2"},"/rlog/wakuv2-apd-f04":{"__comp":"ccc49370","__context":{"plugin":"1e4c069f"},"sidebar":"95b96bb9","content":"99f69f8e"},"/rlog/wakuv2-noise-6d7":{"__comp":"ccc49370","__context":{"plugin":"1e4c069f"},"sidebar":"95b96bb9","content":"1e7f5ce0"},"/rlog/wakuv2-relay-anon-dc8":{"__comp":"ccc49370","__context":{"plugin":"1e4c069f"},"sidebar":"95b96bb9","content":"b6f6cb50"},"/rlog/wechat-replacement-need-4e9":{"__comp":"ccc49370","__context":{"plugin":"1e4c069f"},"sidebar":"95b96bb9","content":"e6b418ad"},"/rlog/zkVM-explorations-337":{"__comp":"ccc49370","__context":{"plugin":"1e4c069f"},"sidebar":"95b96bb9","content":"b8fd8041"},"/rlog/zkVM-testing-dc5":{"__comp":"ccc49370","__context":{"plugin":"1e4c069f"},"sidebar":"95b96bb9","content":"93541fc5"},"/-4d6":{"__comp":"1be78505","__context":{"plugin":"bfd2a918"},"versionMetadata":"1f3523a7"},"/-d22":{"__comp":"17896441","content":"c377a04b"},"/community-051":{"__comp":"17896441","content":"2c2dd814"},"/contribute-00f":{"__comp":"17896441","content":"4ba7e5a3"},"/deepresearch-40e":{"__comp":"17896441","content":"4f94ff0f"},"/join-us-63f":{"__comp":"17896441","content":"a413eb42"},"/media-895":{"__comp":"17896441","content":"8e79cc52"},"/principles-ef3":{"__comp":"17896441","content":"f8d84f88"},"/privacy-policy-4cd":{"__comp":"17896441","content":"8c5da4da"},"/publications-be1":{"__comp":"17896441","content":"0b46e8e7"},"/rfcprocess-d12":{"__comp":"17896441","content":"8161b354"},"/security-2fb":{"__comp":"17896441","content":"db32d859"},"/terms-37d":{"__comp":"17896441","content":"500a151f"},"/vips-fef":{"__comp":"17896441","content":"3f781295"},"/vsus-e2a":{"__comp":"17896441","content":"ad3e391a"}}')}},e=>{e.O(0,[532],(()=>{return t=3364,e(e.s=t);var t}));e.O()}]); \ No newline at end of file diff --git a/assets/js/main.ffc20c94.js.LICENSE.txt b/assets/js/main.5454aec3.js.LICENSE.txt similarity index 100% rename from assets/js/main.ffc20c94.js.LICENSE.txt rename to assets/js/main.5454aec3.js.LICENSE.txt diff --git a/assets/js/main.ffc20c94.js b/assets/js/main.ffc20c94.js deleted file mode 100644 index d8126b3d..00000000 --- a/assets/js/main.ffc20c94.js +++ /dev/null @@ -1,6 +0,0 @@ -/*! For license information please see main.ffc20c94.js.LICENSE.txt */ -(self.webpackChunkvac_dev=self.webpackChunkvac_dev||[]).push([[179],{31665:(e,t,n)=>{"use strict";Object.defineProperty(t,Symbol.toStringTag,{value:"Module"});const r=n(67294),o=n(73935),a=n(70917);function i(e){const t=Object.create(null,{[Symbol.toStringTag]:{value:"Module"}});if(e)for(const n in e)if("default"!==n){const r=Object.getOwnPropertyDescriptor(e,n);Object.defineProperty(t,n,r.get?r:{enumerable:!0,get:()=>e[n]})}return t.default=e,Object.freeze(t)}const l=i(r);var s=function(){function e(e){var t=this;this._insertTag=function(e){var n;n=0===t.tags.length?t.insertionPoint?t.insertionPoint.nextSibling:t.prepend?t.container.firstChild:t.before:t.tags[t.tags.length-1].nextSibling,t.container.insertBefore(e,n),t.tags.push(e)},this.isSpeedy=void 0===e.speedy||e.speedy,this.tags=[],this.ctr=0,this.nonce=e.nonce,this.key=e.key,this.container=e.container,this.prepend=e.prepend,this.insertionPoint=e.insertionPoint,this.before=null}var t=e.prototype;return t.hydrate=function(e){e.forEach(this._insertTag)},t.insert=function(e){this.ctr%(this.isSpeedy?65e3:1)==0&&this._insertTag(function(e){var t=document.createElement("style");return t.setAttribute("data-emotion",e.key),void 0!==e.nonce&&t.setAttribute("nonce",e.nonce),t.appendChild(document.createTextNode("")),t.setAttribute("data-s",""),t}(this));var t=this.tags[this.tags.length-1];if(this.isSpeedy){var n=function(e){if(e.sheet)return e.sheet;for(var t=0;t<document.styleSheets.length;t++)if(document.styleSheets[t].ownerNode===e)return document.styleSheets[t]}(t);try{n.insertRule(e,n.cssRules.length)}catch(r){0}}else t.appendChild(document.createTextNode(e));this.ctr++},t.flush=function(){this.tags.forEach((function(e){return e.parentNode&&e.parentNode.removeChild(e)})),this.tags=[],this.ctr=0},e}(),u="-ms-",c="-moz-",d="-webkit-",f="comm",p="rule",h="decl",m="@keyframes",g=Math.abs,v=String.fromCharCode,b=Object.assign;function y(e){return e.trim()}function w(e,t,n){return e.replace(t,n)}function x(e,t){return e.indexOf(t)}function _(e,t){return 0|e.charCodeAt(t)}function k(e,t,n){return e.slice(t,n)}function E(e){return e.length}function S(e){return e.length}function C(e,t){return t.push(e),e}var T=1,O=1,D=0,P=0,N=0,A="";function I(e,t,n,r,o,a,i){return{value:e,root:t,parent:n,type:r,props:o,children:a,line:T,column:O,length:i,return:""}}function L(e,t){return b(I("",null,null,"",null,null,0),e,{length:-e.length},t)}function R(){return N=P<D?_(A,P++):0,O++,10===N&&(O=1,T++),N}function j(){return _(A,P)}function M(){return P}function F(e,t){return k(A,e,t)}function B(e){switch(e){case 0:case 9:case 10:case 13:case 32:return 5;case 33:case 43:case 44:case 47:case 62:case 64:case 126:case 59:case 123:case 125:return 4;case 58:return 3;case 34:case 39:case 40:case 91:return 2;case 41:case 93:return 1}return 0}function z(e){return T=O=1,D=E(A=e),P=0,[]}function $(e){return A="",e}function U(e){return y(F(P-1,q(91===e?e+2:40===e?e+1:e)))}function H(e){for(;(N=j())&&N<33;)R();return B(e)>2||B(N)>3?"":" "}function V(e,t){for(;--t&&R()&&!(N<48||N>102||N>57&&N<65||N>70&&N<97););return F(e,M()+(t<6&&32==j()&&32==R()))}function q(e){for(;R();)switch(N){case e:return P;case 34:case 39:34!==e&&39!==e&&q(N);break;case 40:41===e&&q(e);break;case 92:R()}return P}function G(e,t){for(;R()&&e+N!==57&&(e+N!==84||47!==j()););return"/*"+F(t,P-1)+"*"+v(47===e?e:R())}function W(e){for(;!B(j());)R();return F(e,P)}function Z(e){return $(Q("",null,null,null,[""],e=z(e),0,[0],e))}function Q(e,t,n,r,o,a,i,l,s){for(var u=0,c=0,d=i,f=0,p=0,h=0,m=1,g=1,b=1,y=0,k="",S=o,D=a,I=r,L=k;g;)switch(h=y,y=R()){case 40:if(108!=h&&58==_(L,d-1)){-1!=x(L+=w(U(y),"&","&\f"),"&\f")&&(b=-1);break}case 34:case 39:case 91:L+=U(y);break;case 9:case 10:case 13:case 32:L+=H(h);break;case 92:L+=V(M()-1,7);continue;case 47:switch(j()){case 42:case 47:C(X(G(R(),M()),t,n),s);break;default:L+="/"}break;case 123*m:l[u++]=E(L)*b;case 125*m:case 59:case 0:switch(y){case 0:case 125:g=0;case 59+c:p>0&&E(L)-d&&C(p>32?K(L+";",r,n,d-1):K(w(L," ","")+";",r,n,d-2),s);break;case 59:L+=";";default:if(C(I=Y(L,t,n,u,c,o,l,k,S=[],D=[],d),a),123===y)if(0===c)Q(L,t,I,I,S,a,d,l,D);else switch(99===f&&110===_(L,3)?100:f){case 100:case 109:case 115:Q(e,I,I,r&&C(Y(e,I,I,0,0,o,l,k,o,S=[],d),D),o,D,d,l,r?S:D);break;default:Q(L,I,I,I,[""],D,0,l,D)}}u=c=p=0,m=b=1,k=L="",d=i;break;case 58:d=1+E(L),p=h;default:if(m<1)if(123==y)--m;else if(125==y&&0==m++&&125==(N=P>0?_(A,--P):0,O--,10===N&&(O=1,T--),N))continue;switch(L+=v(y),y*m){case 38:b=c>0?1:(L+="\f",-1);break;case 44:l[u++]=(E(L)-1)*b,b=1;break;case 64:45===j()&&(L+=U(R())),f=j(),c=d=E(k=L+=W(M())),y++;break;case 45:45===h&&2==E(L)&&(m=0)}}return a}function Y(e,t,n,r,o,a,i,l,s,u,c){for(var d=o-1,f=0===o?a:[""],h=S(f),m=0,v=0,b=0;m<r;++m)for(var x=0,_=k(e,d+1,d=g(v=i[m])),E=e;x<h;++x)(E=y(v>0?f[x]+" "+_:w(_,/&\f/g,f[x])))&&(s[b++]=E);return I(e,t,n,0===o?p:l,s,u,c)}function X(e,t,n){return I(e,t,n,f,v(N),k(e,2,-2),0)}function K(e,t,n,r){return I(e,t,n,h,k(e,0,r),k(e,r+1,-1),r)}function J(e,t){for(var n="",r=S(e),o=0;o<r;o++)n+=t(e[o],o,e,t)||"";return n}function ee(e,t,n,r){switch(e.type){case"@import":case h:return e.return=e.return||e.value;case f:return"";case m:return e.return=e.value+"{"+J(e.children,r)+"}";case p:e.value=e.props.join(",")}return E(n=J(e.children,r))?e.return=e.value+"{"+n+"}":""}function te(e){var t=Object.create(null);return function(n){return void 0===t[n]&&(t[n]=e(n)),t[n]}}var ne=function(e,t,n){for(var r=0,o=0;r=o,o=j(),38===r&&12===o&&(t[n]=1),!B(o);)R();return F(e,P)},re=function(e,t){return $(function(e,t){var n=-1,r=44;do{switch(B(r)){case 0:38===r&&12===j()&&(t[n]=1),e[n]+=ne(P-1,t,n);break;case 2:e[n]+=U(r);break;case 4:if(44===r){e[++n]=58===j()?"&\f":"",t[n]=e[n].length;break}default:e[n]+=v(r)}}while(r=R());return e}(z(e),t))},oe=new WeakMap,ae=function(e){if("rule"===e.type&&e.parent&&!(e.length<1)){for(var t=e.value,n=e.parent,r=e.column===n.column&&e.line===n.line;"rule"!==n.type;)if(!(n=n.parent))return;if((1!==e.props.length||58===t.charCodeAt(0)||oe.get(n))&&!r){oe.set(e,!0);for(var o=[],a=re(t,o),i=n.props,l=0,s=0;l<a.length;l++)for(var u=0;u<i.length;u++,s++)e.props[s]=o[l]?a[l].replace(/&\f/g,i[u]):i[u]+" "+a[l]}}},ie=function(e){if("decl"===e.type){var t=e.value;108===t.charCodeAt(0)&&98===t.charCodeAt(2)&&(e.return="",e.value="")}};function le(e,t){switch(function(e,t){return 45^_(e,0)?(((t<<2^_(e,0))<<2^_(e,1))<<2^_(e,2))<<2^_(e,3):0}(e,t)){case 5103:return d+"print-"+e+e;case 5737:case 4201:case 3177:case 3433:case 1641:case 4457:case 2921:case 5572:case 6356:case 5844:case 3191:case 6645:case 3005:case 6391:case 5879:case 5623:case 6135:case 4599:case 4855:case 4215:case 6389:case 5109:case 5365:case 5621:case 3829:return d+e+e;case 5349:case 4246:case 4810:case 6968:case 2756:return d+e+c+e+u+e+e;case 6828:case 4268:return d+e+u+e+e;case 6165:return d+e+u+"flex-"+e+e;case 5187:return d+e+w(e,/(\w+).+(:[^]+)/,"-webkit-box-$1$2-ms-flex-$1$2")+e;case 5443:return d+e+u+"flex-item-"+w(e,/flex-|-self/,"")+e;case 4675:return d+e+u+"flex-line-pack"+w(e,/align-content|flex-|-self/,"")+e;case 5548:return d+e+u+w(e,"shrink","negative")+e;case 5292:return d+e+u+w(e,"basis","preferred-size")+e;case 6060:return d+"box-"+w(e,"-grow","")+d+e+u+w(e,"grow","positive")+e;case 4554:return d+w(e,/([^-])(transform)/g,"$1-webkit-$2")+e;case 6187:return w(w(w(e,/(zoom-|grab)/,d+"$1"),/(image-set)/,d+"$1"),e,"")+e;case 5495:case 3959:return w(e,/(image-set\([^]*)/,d+"$1$`$1");case 4968:return w(w(e,/(.+:)(flex-)?(.*)/,"-webkit-box-pack:$3-ms-flex-pack:$3"),/s.+-b[^;]+/,"justify")+d+e+e;case 4095:case 3583:case 4068:case 2532:return w(e,/(.+)-inline(.+)/,d+"$1$2")+e;case 8116:case 7059:case 5753:case 5535:case 5445:case 5701:case 4933:case 4677:case 5533:case 5789:case 5021:case 4765:if(E(e)-1-t>6)switch(_(e,t+1)){case 109:if(45!==_(e,t+4))break;case 102:return w(e,/(.+:)(.+)-([^]+)/,"$1-webkit-$2-$3$1"+c+(108==_(e,t+3)?"$3":"$2-$3"))+e;case 115:return~x(e,"stretch")?le(w(e,"stretch","fill-available"),t)+e:e}break;case 4949:if(115!==_(e,t+1))break;case 6444:switch(_(e,E(e)-3-(~x(e,"!important")&&10))){case 107:return w(e,":",":"+d)+e;case 101:return w(e,/(.+:)([^;!]+)(;|!.+)?/,"$1"+d+(45===_(e,14)?"inline-":"")+"box$3$1"+d+"$2$3$1"+u+"$2box$3")+e}break;case 5936:switch(_(e,t+11)){case 114:return d+e+u+w(e,/[svh]\w+-[tblr]{2}/,"tb")+e;case 108:return d+e+u+w(e,/[svh]\w+-[tblr]{2}/,"tb-rl")+e;case 45:return d+e+u+w(e,/[svh]\w+-[tblr]{2}/,"lr")+e}return d+e+u+e+e}return e}var se,ue=[function(e,t,n,r){if(e.length>-1&&!e.return)switch(e.type){case h:e.return=le(e.value,e.length);break;case m:return J([L(e,{value:w(e.value,"@","@"+d)})],r);case p:if(e.length)return function(e,t){return e.map(t).join("")}(e.props,(function(t){switch(function(e,t){return(e=t.exec(e))?e[0]:e}(t,/(::plac\w+|:read-\w+)/)){case":read-only":case":read-write":return J([L(e,{props:[w(t,/:(read-\w+)/,":-moz-$1")]})],r);case"::placeholder":return J([L(e,{props:[w(t,/:(plac\w+)/,":-webkit-input-$1")]}),L(e,{props:[w(t,/:(plac\w+)/,":-moz-$1")]}),L(e,{props:[w(t,/:(plac\w+)/,u+"input-$1")]})],r)}return""}))}}],ce=function(e){var t=e.key;if("css"===t){var n=document.querySelectorAll("style[data-emotion]:not([data-s])");Array.prototype.forEach.call(n,(function(e){-1!==e.getAttribute("data-emotion").indexOf(" ")&&(document.head.appendChild(e),e.setAttribute("data-s",""))}))}var r=e.stylisPlugins||ue;var o,a,i={},l=[];o=e.container||document.head,Array.prototype.forEach.call(document.querySelectorAll('style[data-emotion^="'+t+' "]'),(function(e){for(var t=e.getAttribute("data-emotion").split(" "),n=1;n<t.length;n++)i[t[n]]=!0;l.push(e)}));var u,c,d,f,p=[ee,(f=function(e){u.insert(e)},function(e){e.root||(e=e.return)&&f(e)})],h=(c=[ae,ie].concat(r,p),d=S(c),function(e,t,n,r){for(var o="",a=0;a<d;a++)o+=c[a](e,t,n,r)||"";return o});a=function(e,t,n,r){u=n,J(Z(e?e+"{"+t.styles+"}":t.styles),h),r&&(m.inserted[t.name]=!0)};var m={key:t,sheet:new s({key:t,container:o,nonce:e.nonce,speedy:e.speedy,prepend:e.prepend,insertionPoint:e.insertionPoint}),nonce:e.nonce,inserted:i,registered:{},insert:a};return m.sheet.hydrate(l),m},de="undefined"!=typeof globalThis?globalThis:"undefined"!=typeof window?window:void 0!==n.g?n.g:"undefined"!=typeof self?self:{},fe={},pe={};({get exports(){return fe},set exports(e){fe=e}}).exports=function(){if(se)return pe;se=1;var e="function"==typeof Symbol&&Symbol.for,t=e?Symbol.for("react.element"):60103,n=e?Symbol.for("react.portal"):60106,r=e?Symbol.for("react.fragment"):60107,o=e?Symbol.for("react.strict_mode"):60108,a=e?Symbol.for("react.profiler"):60114,i=e?Symbol.for("react.provider"):60109,l=e?Symbol.for("react.context"):60110,s=e?Symbol.for("react.async_mode"):60111,u=e?Symbol.for("react.concurrent_mode"):60111,c=e?Symbol.for("react.forward_ref"):60112,d=e?Symbol.for("react.suspense"):60113,f=e?Symbol.for("react.suspense_list"):60120,p=e?Symbol.for("react.memo"):60115,h=e?Symbol.for("react.lazy"):60116,m=e?Symbol.for("react.block"):60121,g=e?Symbol.for("react.fundamental"):60117,v=e?Symbol.for("react.responder"):60118,b=e?Symbol.for("react.scope"):60119;function y(e){if("object"==typeof e&&null!==e){var f=e.$$typeof;switch(f){case t:switch(e=e.type){case s:case u:case r:case a:case o:case d:return e;default:switch(e=e&&e.$$typeof){case l:case c:case h:case p:case i:return e;default:return f}}case n:return f}}}function w(e){return y(e)===u}return pe.AsyncMode=s,pe.ConcurrentMode=u,pe.ContextConsumer=l,pe.ContextProvider=i,pe.Element=t,pe.ForwardRef=c,pe.Fragment=r,pe.Lazy=h,pe.Memo=p,pe.Portal=n,pe.Profiler=a,pe.StrictMode=o,pe.Suspense=d,pe.isAsyncMode=function(e){return w(e)||y(e)===s},pe.isConcurrentMode=w,pe.isContextConsumer=function(e){return y(e)===l},pe.isContextProvider=function(e){return y(e)===i},pe.isElement=function(e){return"object"==typeof e&&null!==e&&e.$$typeof===t},pe.isForwardRef=function(e){return y(e)===c},pe.isFragment=function(e){return y(e)===r},pe.isLazy=function(e){return y(e)===h},pe.isMemo=function(e){return y(e)===p},pe.isPortal=function(e){return y(e)===n},pe.isProfiler=function(e){return y(e)===a},pe.isStrictMode=function(e){return y(e)===o},pe.isSuspense=function(e){return y(e)===d},pe.isValidElementType=function(e){return"string"==typeof e||"function"==typeof e||e===r||e===u||e===a||e===o||e===d||e===f||"object"==typeof e&&null!==e&&(e.$$typeof===h||e.$$typeof===p||e.$$typeof===i||e.$$typeof===l||e.$$typeof===c||e.$$typeof===g||e.$$typeof===v||e.$$typeof===b||e.$$typeof===m)},pe.typeOf=y,pe}();var he=fe,me={};me[he.ForwardRef]={$$typeof:!0,render:!0,defaultProps:!0,displayName:!0,propTypes:!0},me[he.Memo]={$$typeof:!0,compare:!0,defaultProps:!0,displayName:!0,propTypes:!0,type:!0};var ge=function(e,t,n){var r=e.key+"-"+t.name;!1===n&&void 0===e.registered[r]&&(e.registered[r]=t.styles)};var ve={animationIterationCount:1,borderImageOutset:1,borderImageSlice:1,borderImageWidth:1,boxFlex:1,boxFlexGroup:1,boxOrdinalGroup:1,columnCount:1,columns:1,flex:1,flexGrow:1,flexPositive:1,flexShrink:1,flexNegative:1,flexOrder:1,gridRow:1,gridRowEnd:1,gridRowSpan:1,gridRowStart:1,gridColumn:1,gridColumnEnd:1,gridColumnSpan:1,gridColumnStart:1,msGridRow:1,msGridRowSpan:1,msGridColumn:1,msGridColumnSpan:1,fontWeight:1,lineHeight:1,opacity:1,order:1,orphans:1,tabSize:1,widows:1,zIndex:1,zoom:1,WebkitLineClamp:1,fillOpacity:1,floodOpacity:1,stopOpacity:1,strokeDasharray:1,strokeDashoffset:1,strokeMiterlimit:1,strokeOpacity:1,strokeWidth:1},be=/[A-Z]|^ms/g,ye=/_EMO_([^_]+?)_([^]*?)_EMO_/g,we=function(e){return 45===e.charCodeAt(1)},xe=function(e){return null!=e&&"boolean"!=typeof e},_e=te((function(e){return we(e)?e:e.replace(be,"-$&").toLowerCase()})),ke=function(e,t){switch(e){case"animation":case"animationName":if("string"==typeof t)return t.replace(ye,(function(e,t,n){return Se={name:t,styles:n,next:Se},t}))}return 1===ve[e]||we(e)||"number"!=typeof t||0===t?t:t+"px"};function Ee(e,t,n){if(null==n)return"";if(void 0!==n.__emotion_styles)return n;switch(typeof n){case"boolean":return"";case"object":if(1===n.anim)return Se={name:n.name,styles:n.styles,next:Se},n.name;if(void 0!==n.styles){var r=n.next;if(void 0!==r)for(;void 0!==r;)Se={name:r.name,styles:r.styles,next:Se},r=r.next;return n.styles+";"}return function(e,t,n){var r="";if(Array.isArray(n))for(var o=0;o<n.length;o++)r+=Ee(e,t,n[o])+";";else for(var a in n){var i=n[a];if("object"!=typeof i)null!=t&&void 0!==t[i]?r+=a+"{"+t[i]+"}":xe(i)&&(r+=_e(a)+":"+ke(a,i)+";");else if(!Array.isArray(i)||"string"!=typeof i[0]||null!=t&&void 0!==t[i[0]]){var l=Ee(e,t,i);switch(a){case"animation":case"animationName":r+=_e(a)+":"+l+";";break;default:r+=a+"{"+l+"}"}}else for(var s=0;s<i.length;s++)xe(i[s])&&(r+=_e(a)+":"+ke(a,i[s])+";")}return r}(e,t,n);case"function":if(void 0!==e){var o=Se,a=n(e);return Se=o,Ee(e,t,a)}}if(null==t)return n;var i=t[n];return void 0!==i?i:n}var Se,Ce=/label:\s*([^\s;\n{]+)\s*(;|$)/g;var Te=!!l.useInsertionEffect&&l.useInsertionEffect||function(e){return e()},Oe={}.hasOwnProperty,De=r.createContext("undefined"!=typeof HTMLElement?ce({key:"css"}):null);De.Provider;var Pe=function(e){return r.forwardRef((function(t,n){var o=r.useContext(De);return e(t,o,n)}))},Ne=r.createContext({});var Ae="__EMOTION_TYPE_PLEASE_DO_NOT_USE__",Ie=function(e,t){var n={};for(var r in t)Oe.call(t,r)&&(n[r]=t[r]);return n[Ae]=e,n},Le=function(e){var t=e.cache,n=e.serialized,r=e.isStringTag;return ge(t,n,r),Te((function(){return function(e,t,n){ge(e,t,n);var r=e.key+"-"+t.name;if(void 0===e.inserted[t.name]){var o=t;do{e.insert(t===o?"."+r:"",o,e.sheet,!0),o=o.next}while(void 0!==o)}}(t,n,r)})),null},Re=Pe((function(e,t,n){var o=e.css;"string"==typeof o&&void 0!==t.registered[o]&&(o=t.registered[o]);var a=e[Ae],i=[o],l="";"string"==typeof e.className?l=function(e,t,n){var r="";return n.split(" ").forEach((function(n){void 0!==e[n]?t.push(e[n]+";"):r+=n+" "})),r}(t.registered,i,e.className):null!=e.className&&(l=e.className+" ");var s=function(e,t,n){if(1===e.length&&"object"==typeof e[0]&&null!==e[0]&&void 0!==e[0].styles)return e[0];var r=!0,o="";Se=void 0;var a=e[0];null==a||void 0===a.raw?(r=!1,o+=Ee(n,t,a)):o+=a[0];for(var i=1;i<e.length;i++)o+=Ee(n,t,e[i]),r&&(o+=a[i]);Ce.lastIndex=0;for(var l,s="";null!==(l=Ce.exec(o));)s+="-"+l[1];var u=function(e){for(var t,n=0,r=0,o=e.length;o>=4;++r,o-=4)t=1540483477*(65535&(t=255&e.charCodeAt(r)|(255&e.charCodeAt(++r))<<8|(255&e.charCodeAt(++r))<<16|(255&e.charCodeAt(++r))<<24))+(59797*(t>>>16)<<16),n=1540483477*(65535&(t^=t>>>24))+(59797*(t>>>16)<<16)^1540483477*(65535&n)+(59797*(n>>>16)<<16);switch(o){case 3:n^=(255&e.charCodeAt(r+2))<<16;case 2:n^=(255&e.charCodeAt(r+1))<<8;case 1:n=1540483477*(65535&(n^=255&e.charCodeAt(r)))+(59797*(n>>>16)<<16)}return(((n=1540483477*(65535&(n^=n>>>13))+(59797*(n>>>16)<<16))^n>>>15)>>>0).toString(36)}(o)+s;return{name:u,styles:o,next:Se}}(i,void 0,r.useContext(Ne));l+=t.key+"-"+s.name;var u={};for(var c in e)Oe.call(e,c)&&"css"!==c&&c!==Ae&&(u[c]=e[c]);return u.ref=n,u.className=l,r.createElement(r.Fragment,null,r.createElement(Le,{cache:t,serialized:s,isStringTag:"string"==typeof a}),r.createElement(a,u))}));var je,Me,Fe,Be={},ze={};function $e(){if(Fe)return ze;Fe=1,function(){if(Me)return je;Me=1;var e=Object.getOwnPropertySymbols,t=Object.prototype.hasOwnProperty,n=Object.prototype.propertyIsEnumerable;function r(e){if(null==e)throw new TypeError("Object.assign cannot be called with null or undefined");return Object(e)}je=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(o){return!1}}()?Object.assign:function(o,a){for(var i,l,s=r(o),u=1;u<arguments.length;u++){for(var c in i=Object(arguments[u]))t.call(i,c)&&(s[c]=i[c]);if(e){l=e(i);for(var d=0;d<l.length;d++)n.call(i,l[d])&&(s[l[d]]=i[l[d]])}}return s}}();var e=r,t=60103;if(ze.Fragment=60107,"function"==typeof Symbol&&Symbol.for){var n=Symbol.for;t=n("react.element"),ze.Fragment=n("react.fragment")}var o=e.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED.ReactCurrentOwner,a=Object.prototype.hasOwnProperty,i={key:!0,ref:!0,__self:!0,__source:!0};function l(e,n,r){var l,s={},u=null,c=null;for(l in void 0!==r&&(u=""+r),void 0!==n.key&&(u=""+n.key),void 0!==n.ref&&(c=n.ref),n)a.call(n,l)&&!i.hasOwnProperty(l)&&(s[l]=n[l]);if(e&&e.defaultProps)for(l in n=e.defaultProps)void 0===s[l]&&(s[l]=n[l]);return{$$typeof:t,type:e,key:u,ref:c,props:s,_owner:o.current}}return ze.jsx=l,ze.jsxs=l,ze}!function(e){e.exports=$e()}({get exports(){return Be},set exports(e){Be=e}});const Ue=Be.Fragment,He=Be.jsx,Ve=Be.jsxs;var qe=Ue;function Ge(e,t,n){return Oe.call(t,"css")?He(Re,Ie(e,t),n):He(e,t,n)}function We(e,t,n){return Oe.call(t,"css")?Ve(Re,Ie(e,t),n):Ve(e,t,n)}function Ze(e){var t,n,r="";if("string"==typeof e||"number"==typeof e)r+=e;else if("object"==typeof e)if(Array.isArray(e))for(t=0;t<e.length;t++)e[t]&&(n=Ze(e[t]))&&(r&&(r+=" "),r+=n);else for(t in e)e[t]&&(r&&(r+=" "),r+=t);return r}function Qe(){for(var e,t,n=0,r="";n<arguments.length;)(e=arguments[n++])&&(t=Ze(e))&&(r&&(r+=" "),r+=t);return r}const Ye=e=>{const[t,n]=r.useState(e.value??e.defaultValue),o=void 0===e.value,a=void 0!==t&&("string"==typeof t?t.length>0:t.toString().length>0);return r.useEffect((()=>{!o&&n(e.value)}),[o,e.value]),{value:t,filled:a,onChange:t=>{if(o){const e=t.target.type,r=t.target["checkbox"===e||"radio"===e?"checked":"value"];n(r)}e.onChange&&e.onChange(t)},setValue:t=>{var n,r,o,a;const i=(null==(n=null==e?void 0:e.ref)?void 0:n.current)??("function"==typeof e.getInput&&e.getInput());if(!i)return;const l=new Event("input",{bubbles:!0});null==(a=null==(o=null==(r=Object.getOwnPropertyDescriptor(window.HTMLInputElement.prototype,"value"))?void 0:r.set)?void 0:o.call)||a.call(o,i,t),i.dispatchEvent(l)}}};var Xe=function(e,t){for(var n=-1,r=null==e?0:e.length,o=Array(r);++n<r;)o[n]=t(e[n],n,e);return o};var Ke=function(){this.__data__=[],this.size=0};var Je=function(e,t){return e===t||e!=e&&t!=t},et=Je;var tt=function(e,t){for(var n=e.length;n--;)if(et(e[n][0],t))return n;return-1},nt=tt,rt=Array.prototype.splice;var ot=tt;var at=tt;var it=tt;var lt=Ke,st=function(e){var t=this.__data__,n=nt(t,e);return!(n<0)&&(n==t.length-1?t.pop():rt.call(t,n,1),--this.size,!0)},ut=function(e){var t=this.__data__,n=ot(t,e);return n<0?void 0:t[n][1]},ct=function(e){return at(this.__data__,e)>-1},dt=function(e,t){var n=this.__data__,r=it(n,e);return r<0?(++this.size,n.push([e,t])):n[r][1]=t,this};function ft(e){var t=-1,n=null==e?0:e.length;for(this.clear();++t<n;){var r=e[t];this.set(r[0],r[1])}}ft.prototype.clear=lt,ft.prototype.delete=st,ft.prototype.get=ut,ft.prototype.has=ct,ft.prototype.set=dt;var pt=ft,ht=pt;var mt=function(){this.__data__=new ht,this.size=0};var gt=function(e){var t=this.__data__,n=t.delete(e);return this.size=t.size,n};var vt=function(e){return this.__data__.get(e)};var bt=function(e){return this.__data__.has(e)},yt="object"==typeof de&&de&&de.Object===Object&&de,wt=yt,xt="object"==typeof self&&self&&self.Object===Object&&self,_t=wt||xt||Function("return this")(),kt=_t.Symbol,Et=kt,St=Object.prototype,Ct=St.hasOwnProperty,Tt=St.toString,Ot=Et?Et.toStringTag:void 0;var Dt=function(e){var t=Ct.call(e,Ot),n=e[Ot];try{e[Ot]=void 0;var r=!0}catch(a){}var o=Tt.call(e);return r&&(t?e[Ot]=n:delete e[Ot]),o},Pt=Object.prototype.toString;var Nt=Dt,At=function(e){return Pt.call(e)},It=kt?kt.toStringTag:void 0;var Lt=function(e){return null==e?void 0===e?"[object Undefined]":"[object Null]":It&&It in Object(e)?Nt(e):At(e)};var Rt=function(e){var t=typeof e;return null!=e&&("object"==t||"function"==t)},jt=Lt,Mt=Rt;var Ft,Bt=function(e){if(!Mt(e))return!1;var t=jt(e);return"[object Function]"==t||"[object GeneratorFunction]"==t||"[object AsyncFunction]"==t||"[object Proxy]"==t},zt=_t["__core-js_shared__"],$t=(Ft=/[^.]+$/.exec(zt&&zt.keys&&zt.keys.IE_PROTO||""))?"Symbol(src)_1."+Ft:"";var Ut=function(e){return!!$t&&$t in e},Ht=Function.prototype.toString;var Vt=function(e){if(null!=e){try{return Ht.call(e)}catch(t){}try{return e+""}catch(t){}}return""},qt=Bt,Gt=Ut,Wt=Rt,Zt=Vt,Qt=/^\[object .+?Constructor\]$/,Yt=Function.prototype,Xt=Object.prototype,Kt=Yt.toString,Jt=Xt.hasOwnProperty,en=RegExp("^"+Kt.call(Jt).replace(/[\\^$.*+?()[\]{}|]/g,"\\$&").replace(/hasOwnProperty|(function).*?(?=\\\()| for .+?(?=\\\])/g,"$1.*?")+"$");var tn=function(e){return!(!Wt(e)||Gt(e))&&(qt(e)?en:Qt).test(Zt(e))},nn=function(e,t){return null==e?void 0:e[t]};var rn=function(e,t){var n=nn(e,t);return tn(n)?n:void 0},on=rn(_t,"Map"),an=rn(Object,"create"),ln=an;var sn=function(){this.__data__=ln?ln(null):{},this.size=0};var un=function(e){var t=this.has(e)&&delete this.__data__[e];return this.size-=t?1:0,t},cn=an,dn=Object.prototype.hasOwnProperty;var fn=function(e){var t=this.__data__;if(cn){var n=t[e];return"__lodash_hash_undefined__"===n?void 0:n}return dn.call(t,e)?t[e]:void 0},pn=an,hn=Object.prototype.hasOwnProperty;var mn=an;var gn=sn,vn=un,bn=fn,yn=function(e){var t=this.__data__;return pn?void 0!==t[e]:hn.call(t,e)},wn=function(e,t){var n=this.__data__;return this.size+=this.has(e)?0:1,n[e]=mn&&void 0===t?"__lodash_hash_undefined__":t,this};function xn(e){var t=-1,n=null==e?0:e.length;for(this.clear();++t<n;){var r=e[t];this.set(r[0],r[1])}}xn.prototype.clear=gn,xn.prototype.delete=vn,xn.prototype.get=bn,xn.prototype.has=yn,xn.prototype.set=wn;var _n=xn,kn=pt,En=on;var Sn=function(e){var t=typeof e;return"string"==t||"number"==t||"symbol"==t||"boolean"==t?"__proto__"!==e:null===e};var Cn=function(e,t){var n=e.__data__;return Sn(t)?n["string"==typeof t?"string":"hash"]:n.map},Tn=Cn;var On=Cn;var Dn=Cn;var Pn=Cn;var Nn=function(){this.size=0,this.__data__={hash:new _n,map:new(En||kn),string:new _n}},An=function(e){var t=Tn(this,e).delete(e);return this.size-=t?1:0,t},In=function(e){return On(this,e).get(e)},Ln=function(e){return Dn(this,e).has(e)},Rn=function(e,t){var n=Pn(this,e),r=n.size;return n.set(e,t),this.size+=n.size==r?0:1,this};function jn(e){var t=-1,n=null==e?0:e.length;for(this.clear();++t<n;){var r=e[t];this.set(r[0],r[1])}}jn.prototype.clear=Nn,jn.prototype.delete=An,jn.prototype.get=In,jn.prototype.has=Ln,jn.prototype.set=Rn;var Mn=jn,Fn=pt,Bn=on,zn=Mn;var $n=pt,Un=mt,Hn=gt,Vn=vt,qn=bt,Gn=function(e,t){var n=this.__data__;if(n instanceof Fn){var r=n.__data__;if(!Bn||r.length<199)return r.push([e,t]),this.size=++n.size,this;n=this.__data__=new zn(r)}return n.set(e,t),this.size=n.size,this};function Wn(e){var t=this.__data__=new $n(e);this.size=t.size}Wn.prototype.clear=Un,Wn.prototype.delete=Hn,Wn.prototype.get=Vn,Wn.prototype.has=qn,Wn.prototype.set=Gn;var Zn=Wn;var Qn=function(e,t){for(var n=-1,r=null==e?0:e.length;++n<r&&!1!==t(e[n],n,e););return e},Yn=rn,Xn=function(){try{var e=Yn(Object,"defineProperty");return e({},"",{}),e}catch(t){}}(),Kn=Xn;var Jn=function(e,t,n){"__proto__"==t&&Kn?Kn(e,t,{configurable:!0,enumerable:!0,value:n,writable:!0}):e[t]=n},er=Jn,tr=Je,nr=Object.prototype.hasOwnProperty;var rr=function(e,t,n){var r=e[t];nr.call(e,t)&&tr(r,n)&&(void 0!==n||t in e)||er(e,t,n)},or=rr,ar=Jn;var ir=function(e,t,n,r){var o=!n;n||(n={});for(var a=-1,i=t.length;++a<i;){var l=t[a],s=r?r(n[l],e[l],l,n,e):void 0;void 0===s&&(s=e[l]),o?ar(n,l,s):or(n,l,s)}return n};var lr=function(e,t){for(var n=-1,r=Array(e);++n<e;)r[n]=t(n);return r};var sr=function(e){return null!=e&&"object"==typeof e},ur=Lt,cr=sr;var dr=function(e){return cr(e)&&"[object Arguments]"==ur(e)},fr=sr,pr=Object.prototype,hr=pr.hasOwnProperty,mr=pr.propertyIsEnumerable,gr=dr(function(){return arguments}())?dr:function(e){return fr(e)&&hr.call(e,"callee")&&!mr.call(e,"callee")},vr=Array.isArray,br={};var yr=function(){return!1};!function(e,t){var n=_t,r=yr,o=t&&!t.nodeType&&t,a=o&&e&&!e.nodeType&&e,i=a&&a.exports===o?n.Buffer:void 0,l=(i?i.isBuffer:void 0)||r;e.exports=l}({get exports(){return br},set exports(e){br=e}},br);var wr=/^(?:0|[1-9]\d*)$/;var xr=function(e,t){var n=typeof e;return!!(t=null==t?9007199254740991:t)&&("number"==n||"symbol"!=n&&wr.test(e))&&e>-1&&e%1==0&&e<t};var _r=function(e){return"number"==typeof e&&e>-1&&e%1==0&&e<=9007199254740991},kr=Lt,Er=_r,Sr=sr,Cr={};Cr["[object Float32Array]"]=Cr["[object Float64Array]"]=Cr["[object Int8Array]"]=Cr["[object Int16Array]"]=Cr["[object Int32Array]"]=Cr["[object Uint8Array]"]=Cr["[object Uint8ClampedArray]"]=Cr["[object Uint16Array]"]=Cr["[object Uint32Array]"]=!0,Cr["[object Arguments]"]=Cr["[object Array]"]=Cr["[object ArrayBuffer]"]=Cr["[object Boolean]"]=Cr["[object DataView]"]=Cr["[object Date]"]=Cr["[object Error]"]=Cr["[object Function]"]=Cr["[object Map]"]=Cr["[object Number]"]=Cr["[object Object]"]=Cr["[object RegExp]"]=Cr["[object Set]"]=Cr["[object String]"]=Cr["[object WeakMap]"]=!1;var Tr=function(e){return Sr(e)&&Er(e.length)&&!!Cr[kr(e)]};var Or=function(e){return function(t){return e(t)}},Dr={};!function(e,t){var n=yt,r=t&&!t.nodeType&&t,o=r&&e&&!e.nodeType&&e,a=o&&o.exports===r&&n.process,i=function(){try{var e=o&&o.require&&o.require("util").types;return e||a&&a.binding&&a.binding("util")}catch(t){}}();e.exports=i}({get exports(){return Dr},set exports(e){Dr=e}},Dr);var Pr=Tr,Nr=Or,Ar=Dr&&Dr.isTypedArray,Ir=Ar?Nr(Ar):Pr,Lr=lr,Rr=gr,jr=vr,Mr=br,Fr=xr,Br=Ir,zr=Object.prototype.hasOwnProperty;var $r=function(e,t){var n=jr(e),r=!n&&Rr(e),o=!n&&!r&&Mr(e),a=!n&&!r&&!o&&Br(e),i=n||r||o||a,l=i?Lr(e.length,String):[],s=l.length;for(var u in e)!t&&!zr.call(e,u)||i&&("length"==u||o&&("offset"==u||"parent"==u)||a&&("buffer"==u||"byteLength"==u||"byteOffset"==u)||Fr(u,s))||l.push(u);return l},Ur=Object.prototype;var Hr=function(e){var t=e&&e.constructor;return e===("function"==typeof t&&t.prototype||Ur)};var Vr=function(e,t){return function(n){return e(t(n))}},qr=Vr(Object.keys,Object),Gr=Hr,Wr=qr,Zr=Object.prototype.hasOwnProperty;var Qr=Bt,Yr=_r;var Xr=function(e){return null!=e&&Yr(e.length)&&!Qr(e)},Kr=$r,Jr=function(e){if(!Gr(e))return Wr(e);var t=[];for(var n in Object(e))Zr.call(e,n)&&"constructor"!=n&&t.push(n);return t},eo=Xr;var to=function(e){return eo(e)?Kr(e):Jr(e)},no=ir,ro=to;var oo=function(e,t){return e&&no(t,ro(t),e)};var ao=Rt,io=Hr,lo=function(e){var t=[];if(null!=e)for(var n in Object(e))t.push(n);return t},so=Object.prototype.hasOwnProperty;var uo=$r,co=function(e){if(!ao(e))return lo(e);var t=io(e),n=[];for(var r in e)("constructor"!=r||!t&&so.call(e,r))&&n.push(r);return n},fo=Xr;var po=function(e){return fo(e)?uo(e,!0):co(e)},ho=ir,mo=po;var go=function(e,t){return e&&ho(t,mo(t),e)},vo={};!function(e,t){var n=_t,r=t&&!t.nodeType&&t,o=r&&e&&!e.nodeType&&e,a=o&&o.exports===r?n.Buffer:void 0,i=a?a.allocUnsafe:void 0;e.exports=function(e,t){if(t)return e.slice();var n=e.length,r=i?i(n):new e.constructor(n);return e.copy(r),r}}({get exports(){return vo},set exports(e){vo=e}},vo);var bo=function(e,t){var n=-1,r=e.length;for(t||(t=Array(r));++n<r;)t[n]=e[n];return t};var yo=function(){return[]},wo=function(e,t){for(var n=-1,r=null==e?0:e.length,o=0,a=[];++n<r;){var i=e[n];t(i,n,e)&&(a[o++]=i)}return a},xo=yo,_o=Object.prototype.propertyIsEnumerable,ko=Object.getOwnPropertySymbols,Eo=ko?function(e){return null==e?[]:(e=Object(e),wo(ko(e),(function(t){return _o.call(e,t)})))}:xo,So=ir,Co=Eo;var To=function(e,t){return So(e,Co(e),t)};var Oo=function(e,t){for(var n=-1,r=t.length,o=e.length;++n<r;)e[o+n]=t[n];return e},Do=Vr(Object.getPrototypeOf,Object),Po=Oo,No=Do,Ao=Eo,Io=yo,Lo=Object.getOwnPropertySymbols?function(e){for(var t=[];e;)Po(t,Ao(e)),e=No(e);return t}:Io,Ro=ir,jo=Lo;var Mo=function(e,t){return Ro(e,jo(e),t)},Fo=Oo,Bo=vr;var zo=function(e,t,n){var r=t(e);return Bo(e)?r:Fo(r,n(e))},$o=zo,Uo=Eo,Ho=to;var Vo=function(e){return $o(e,Ho,Uo)},qo=zo,Go=Lo,Wo=po;var Zo=function(e){return qo(e,Wo,Go)},Qo=rn(_t,"DataView"),Yo=on,Xo=rn(_t,"Promise"),Ko=rn(_t,"Set"),Jo=rn(_t,"WeakMap"),ea=Lt,ta=Vt,na="[object Map]",ra="[object Promise]",oa="[object Set]",aa="[object WeakMap]",ia="[object DataView]",la=ta(Qo),sa=ta(Yo),ua=ta(Xo),ca=ta(Ko),da=ta(Jo),fa=ea;(Qo&&fa(new Qo(new ArrayBuffer(1)))!=ia||Yo&&fa(new Yo)!=na||Xo&&fa(Xo.resolve())!=ra||Ko&&fa(new Ko)!=oa||Jo&&fa(new Jo)!=aa)&&(fa=function(e){var t=ea(e),n="[object Object]"==t?e.constructor:void 0,r=n?ta(n):"";if(r)switch(r){case la:return ia;case sa:return na;case ua:return ra;case ca:return oa;case da:return aa}return t});var pa=fa,ha=Object.prototype.hasOwnProperty;var ma=function(e){var t=e.length,n=new e.constructor(t);return t&&"string"==typeof e[0]&&ha.call(e,"index")&&(n.index=e.index,n.input=e.input),n},ga=_t.Uint8Array;var va=function(e){var t=new e.constructor(e.byteLength);return new ga(t).set(new ga(e)),t},ba=va;var ya=function(e,t){var n=t?ba(e.buffer):e.buffer;return new e.constructor(n,e.byteOffset,e.byteLength)},wa=/\w*$/;var xa=function(e){var t=new e.constructor(e.source,wa.exec(e));return t.lastIndex=e.lastIndex,t},_a=kt?kt.prototype:void 0,ka=_a?_a.valueOf:void 0;var Ea=va;var Sa=va,Ca=ya,Ta=xa,Oa=function(e){return ka?Object(ka.call(e)):{}},Da=function(e,t){var n=t?Ea(e.buffer):e.buffer;return new e.constructor(n,e.byteOffset,e.length)};var Pa=function(e,t,n){var r=e.constructor;switch(t){case"[object ArrayBuffer]":return Sa(e);case"[object Boolean]":case"[object Date]":return new r(+e);case"[object DataView]":return Ca(e,n);case"[object Float32Array]":case"[object Float64Array]":case"[object Int8Array]":case"[object Int16Array]":case"[object Int32Array]":case"[object Uint8Array]":case"[object Uint8ClampedArray]":case"[object Uint16Array]":case"[object Uint32Array]":return Da(e,n);case"[object Map]":case"[object Set]":return new r;case"[object Number]":case"[object String]":return new r(e);case"[object RegExp]":return Ta(e);case"[object Symbol]":return Oa(e)}},Na=Rt,Aa=Object.create,Ia=function(){function e(){}return function(t){if(!Na(t))return{};if(Aa)return Aa(t);e.prototype=t;var n=new e;return e.prototype=void 0,n}}(),La=Do,Ra=Hr;var ja=function(e){return"function"!=typeof e.constructor||Ra(e)?{}:Ia(La(e))},Ma=pa,Fa=sr;var Ba=function(e){return Fa(e)&&"[object Map]"==Ma(e)},za=Or,$a=Dr&&Dr.isMap,Ua=$a?za($a):Ba,Ha=pa,Va=sr;var qa=function(e){return Va(e)&&"[object Set]"==Ha(e)},Ga=Or,Wa=Dr&&Dr.isSet,Za=Wa?Ga(Wa):qa,Qa=Zn,Ya=Qn,Xa=rr,Ka=oo,Ja=go,ei=vo,ti=bo,ni=To,ri=Mo,oi=Vo,ai=Zo,ii=pa,li=ma,si=Pa,ui=ja,ci=vr,di=br,fi=Ua,pi=Rt,hi=Za,mi=to,gi=po,vi="[object Arguments]",bi="[object Function]",yi="[object Object]",wi={};wi[vi]=wi["[object Array]"]=wi["[object ArrayBuffer]"]=wi["[object DataView]"]=wi["[object Boolean]"]=wi["[object Date]"]=wi["[object Float32Array]"]=wi["[object Float64Array]"]=wi["[object Int8Array]"]=wi["[object Int16Array]"]=wi["[object Int32Array]"]=wi["[object Map]"]=wi["[object Number]"]=wi[yi]=wi["[object RegExp]"]=wi["[object Set]"]=wi["[object String]"]=wi["[object Symbol]"]=wi["[object Uint8Array]"]=wi["[object Uint8ClampedArray]"]=wi["[object Uint16Array]"]=wi["[object Uint32Array]"]=!0,wi["[object Error]"]=wi[bi]=wi["[object WeakMap]"]=!1;var xi=function e(t,n,r,o,a,i){var l,s=1&n,u=2&n,c=4&n;if(r&&(l=a?r(t,o,a,i):r(t)),void 0!==l)return l;if(!pi(t))return t;var d=ci(t);if(d){if(l=li(t),!s)return ti(t,l)}else{var f=ii(t),p=f==bi||"[object GeneratorFunction]"==f;if(di(t))return ei(t,s);if(f==yi||f==vi||p&&!a){if(l=u||p?{}:ui(t),!s)return u?ri(t,Ja(l,t)):ni(t,Ka(l,t))}else{if(!wi[f])return a?t:{};l=si(t,f,s)}}i||(i=new Qa);var h=i.get(t);if(h)return h;i.set(t,l),hi(t)?t.forEach((function(o){l.add(e(o,n,r,o,t,i))})):fi(t)&&t.forEach((function(o,a){l.set(a,e(o,n,r,a,t,i))}));var m=d?void 0:(c?u?ai:oi:u?gi:mi)(t);return Ya(m||t,(function(o,a){m&&(o=t[a=o]),Xa(l,a,e(o,n,r,a,t,i))})),l},_i=Lt,ki=sr;var Ei=function(e){return"symbol"==typeof e||ki(e)&&"[object Symbol]"==_i(e)},Si=vr,Ci=Ei,Ti=/\.|\[(?:[^[\]]*|(["'])(?:(?!\1)[^\\]|\\.)*?\1)\]/,Oi=/^\w*$/;var Di=function(e,t){if(Si(e))return!1;var n=typeof e;return!("number"!=n&&"symbol"!=n&&"boolean"!=n&&null!=e&&!Ci(e))||(Oi.test(e)||!Ti.test(e)||null!=t&&e in Object(t))},Pi=Mn;function Ni(e,t){if("function"!=typeof e||null!=t&&"function"!=typeof t)throw new TypeError("Expected a function");var n=function(){var r=arguments,o=t?t.apply(this,r):r[0],a=n.cache;if(a.has(o))return a.get(o);var i=e.apply(this,r);return n.cache=a.set(o,i)||a,i};return n.cache=new(Ni.Cache||Pi),n}Ni.Cache=Pi;var Ai=Ni;var Ii=/[^.[\]]+|\[(?:(-?\d+(?:\.\d+)?)|(["'])((?:(?!\2)[^\\]|\\.)*?)\2)\]|(?=(?:\.|\[\])(?:\.|\[\]|$))/g,Li=/\\(\\)?/g,Ri=function(e){var t=Ai(e,(function(e){return 500===n.size&&n.clear(),e})),n=t.cache;return t}((function(e){var t=[];return 46===e.charCodeAt(0)&&t.push(""),e.replace(Ii,(function(e,n,r,o){t.push(r?o.replace(Li,"$1"):n||e)})),t})),ji=Xe,Mi=vr,Fi=Ei,Bi=kt?kt.prototype:void 0,zi=Bi?Bi.toString:void 0;var $i=function e(t){if("string"==typeof t)return t;if(Mi(t))return ji(t,e)+"";if(Fi(t))return zi?zi.call(t):"";var n=t+"";return"0"==n&&1/t==-Infinity?"-0":n},Ui=$i;var Hi=function(e){return null==e?"":Ui(e)},Vi=vr,qi=Di,Gi=Ri,Wi=Hi;var Zi=function(e,t){return Vi(e)?e:qi(e,t)?[e]:Gi(Wi(e))};var Qi=Ei;var Yi=function(e){if("string"==typeof e||Qi(e))return e;var t=e+"";return"0"==t&&1/e==-Infinity?"-0":t},Xi=Zi,Ki=Yi;var Ji=function(e,t){for(var n=0,r=(t=Xi(t,e)).length;null!=e&&n<r;)e=e[Ki(t[n++])];return n&&n==r?e:void 0};var el=Ji,tl=function(e,t,n){var r=-1,o=e.length;t<0&&(t=-t>o?0:o+t),(n=n>o?o:n)<0&&(n+=o),o=t>n?0:n-t>>>0,t>>>=0;for(var a=Array(o);++r<o;)a[r]=e[r+t];return a};var nl=Zi,rl=function(e){var t=null==e?0:e.length;return t?e[t-1]:void 0},ol=function(e,t){return t.length<2?e:el(e,tl(t,0,-1))},al=Yi;var il=function(e,t){return t=nl(t,e),null==(e=ol(e,t))||delete e[al(rl(t))]},ll=Lt,sl=Do,ul=sr,cl=Function.prototype,dl=Object.prototype,fl=cl.toString,pl=dl.hasOwnProperty,hl=fl.call(Object);var ml=function(e){if(!ul(e)||"[object Object]"!=ll(e))return!1;var t=sl(e);if(null===t)return!0;var n=pl.call(t,"constructor")&&t.constructor;return"function"==typeof n&&n instanceof n&&fl.call(n)==hl};var gl=function(e){return ml(e)?void 0:e},vl=gr,bl=vr,yl=kt?kt.isConcatSpreadable:void 0;var wl=Oo,xl=function(e){return bl(e)||vl(e)||!!(yl&&e&&e[yl])};var _l=function e(t,n,r,o,a){var i=-1,l=t.length;for(r||(r=xl),a||(a=[]);++i<l;){var s=t[i];n>0&&r(s)?n>1?e(s,n-1,r,o,a):wl(a,s):o||(a[a.length]=s)}return a},kl=_l;var El=function(e){return(null==e?0:e.length)?kl(e,1):[]};var Sl=function(e,t,n){switch(n.length){case 0:return e.call(t);case 1:return e.call(t,n[0]);case 2:return e.call(t,n[0],n[1]);case 3:return e.call(t,n[0],n[1],n[2])}return e.apply(t,n)},Cl=Math.max;var Tl=function(e,t,n){return t=Cl(void 0===t?e.length-1:t,0),function(){for(var r=arguments,o=-1,a=Cl(r.length-t,0),i=Array(a);++o<a;)i[o]=r[t+o];o=-1;for(var l=Array(t+1);++o<t;)l[o]=r[o];return l[t]=n(i),Sl(e,this,l)}};var Ol=function(e){return function(){return e}},Dl=Xn,Pl=Dl?function(e,t){return Dl(e,"toString",{configurable:!0,enumerable:!1,value:Ol(t),writable:!0})}:function(e){return e},Nl=Date.now;var Al=function(e){var t=0,n=0;return function(){var r=Nl(),o=16-(r-n);if(n=r,o>0){if(++t>=800)return arguments[0]}else t=0;return e.apply(void 0,arguments)}}(Pl),Il=El,Ll=Tl,Rl=Al;var jl=function(e){return Rl(Ll(e,void 0,Il),e+"")},Ml=Xe,Fl=xi,Bl=il,zl=Zi,$l=ir,Ul=gl,Hl=Zo,Vl=jl((function(e,t){var n={};if(null==e)return n;var r=!1;t=Ml(t,(function(t){return t=zl(t,e),r||(r=t.length>1),t})),$l(e,Hl(e),n),r&&(n=Fl(n,7,Ul));for(var o=t.length;o--;)Bl(n,t[o]);return n})),ql=rr,Gl=Zi,Wl=xr,Zl=Rt,Ql=Yi;var Yl=Ji,Xl=function(e,t,n,r){if(!Zl(e))return e;for(var o=-1,a=(t=Gl(t,e)).length,i=a-1,l=e;null!=l&&++o<a;){var s=Ql(t[o]),u=n;if("__proto__"===s||"constructor"===s||"prototype"===s)return e;if(o!=i){var c=l[s];void 0===(u=r?r(c,s,l):void 0)&&(u=Zl(c)?c:Wl(t[o+1])?[]:{})}ql(l,s,u),l=l[s]}return e},Kl=Zi;var Jl=Zi,es=gr,ts=vr,ns=xr,rs=_r,os=Yi;var as=function(e,t){return null!=e&&t in Object(e)},is=function(e,t,n){for(var r=-1,o=(t=Jl(t,e)).length,a=!1;++r<o;){var i=os(t[r]);if(!(a=null!=e&&n(e,i)))break;e=e[i]}return a||++r!=o?a:!!(o=null==e?0:e.length)&&rs(o)&&ns(i,o)&&(ts(e)||es(e))};var ls=function(e,t,n){for(var r=-1,o=t.length,a={};++r<o;){var i=t[r],l=Yl(e,i);n(l,i)&&Xl(a,Kl(i,e),l)}return a},ss=function(e,t){return null!=e&&is(e,t,as)};var us=function(e,t){return ls(e,t,(function(t,n){return ss(e,n)}))},cs=jl((function(e,t){return null==e?{}:us(e,t)}));const ds=(e,t)=>Object.fromEntries((Array.isArray(e)?e:Object.keys(e)).map(((e,n)=>[e,t(e,n)]))),fs=["xs","sm","md","lg","xl"],ps=["display1","display2","display3","display4","h1","h2","h3","h4","h5","h6","subtitle1","subtitle2","subtitle3","subtitle4","body1","body2","body3","label1","label2"],hs={h1:["h1"],h2:["h2"],h3:["h3"],h4:["h4"],h5:["h5"],h6:["h6"],body1:["body"],label1:["label"]},ms=["fontSize","fontWeight","lineHeight"],gs={...ds(ps,(e=>`lsd-typography--${e}`)),root:"lsd-typography",primary:"lsd-typography--primary",secondary:"lsd-typography--secondary",serif:"lsd-typography--serif",sansSerif:"lsd-typography--sans-serif",monospace:"lsd-typography--monospace"},vs=["genericFontFamily"],bs=({genericFontFamily:e})=>({className:Qe("serif"===e&&gs.serif,"monospace"===e&&gs.monospace,"sans-serif"===e&&gs.sansSerif)}),ys=e=>cs(e,vs),ws=e=>Vl(e,vs),xs={root:"lsd-icon",small:"lsd-icon--small",filled:"lsd-icon--filled",stroked:"lsd-icon--stroked",primary:"lsd-icon--primary",secondary:"lsd-icon--secondary"},_s=(e,t)=>{const n=({color:n,size:r="small",className:o,...a})=>{const i=bs(a);return Ge(e,{className:Qe(i.className,o,xs.root,xs[r],n&&xs[n],(null==t?void 0:t.filled)&&xs.filled,(null==t?void 0:t.stroked)&&xs.stroked),...ws(a)})};return n.displayName=e.displayName,n.classes=xs,n},ks=_s((e=>Ge("svg",{width:"14",height:"14",viewBox:"0 0 14 14",fill:"none",xmlns:"http://www.w3.org/2000/svg",...e,children:Ge("path",{d:"M11.6666 7.58334H7.58325V11.6667H6.41659V7.58334H2.33325V6.41668H6.41659V2.33334H7.58325V6.41668H11.6666V7.58334Z",fill:"black"})})),{filled:!0}),Es=_s((e=>Ge("svg",{width:"14",height:"14",viewBox:"0 0 14 14",fill:"none",xmlns:"http://www.w3.org/2000/svg",...e,children:Ge("path",{d:"M10.5 5.66125L9.6775 4.83875L7 7.51041L4.3225 4.83874L3.5 5.66125L7 9.16125L10.5 5.66125Z",fill:"black"})})),{filled:!0}),Ss=_s((e=>Ge("svg",{width:"14",height:"14",viewBox:"0 0 14 14",fill:"none",xmlns:"http://www.w3.org/2000/svg",...e,children:Ge("path",{d:"M6.99992 2.33334L6.17742 3.15584L9.43242 6.41668H2.33325V7.58334H9.43242L6.17742 10.8442L6.99992 11.6667L11.6666 7.00001L6.99992 2.33334Z",fill:"black"})})),{filled:!0}),Cs=_s((e=>Ge("svg",{width:"14",height:"14",viewBox:"0 0 14 14",fill:"none",xmlns:"http://www.w3.org/2000/svg",...e,children:Ge("path",{d:"M3.5 8.33875L4.3225 9.16125L7 6.48959L9.6775 9.16125L10.5 8.33875L7 4.83875L3.5 8.33875Z",fill:"black"})})),{filled:!0}),Ts=_s((e=>Ge("svg",{width:"14",height:"14",viewBox:"0 0 14 14",fill:"none",xmlns:"http://www.w3.org/2000/svg",...e,children:Ge("path",{fillRule:"evenodd",clipRule:"evenodd",d:"M2.91667 1.75H11.0833C11.725 1.75 12.25 2.275 12.25 2.91667V11.0833C12.25 11.725 11.725 12.25 11.0833 12.25H2.91667C2.275 12.25 1.75 11.725 1.75 11.0833V2.91667C1.75 2.275 2.275 1.75 2.91667 1.75ZM9.68333 4.43333L10.5 5.25L5.83333 9.91667L3.5 7.58333L4.31667 6.76667L5.83333 8.28333L9.68333 4.43333Z",fill:"black"})})),{filled:!0}),Os=_s((e=>Ge("svg",{width:"14",height:"14",viewBox:"0 0 14 14",fill:"none",xmlns:"http://www.w3.org/2000/svg",...e,children:Ge("path",{d:"M11.0833 2.91667V11.0833H2.91667V2.91667H11.0833ZM11.0833 1.75H2.91667C2.275 1.75 1.75 2.275 1.75 2.91667V11.0833C1.75 11.725 2.275 12.25 2.91667 12.25H11.0833C11.725 12.25 12.25 11.725 12.25 11.0833V2.91667C12.25 2.275 11.725 1.75 11.0833 1.75Z",fill:"black"})})),{filled:!0}),Ds=_s((e=>Ge("svg",{width:"14",height:"14",viewBox:"0 0 14 14",fill:"none",xmlns:"http://www.w3.org/2000/svg",...e,children:Ge("path",{d:"M5.25009 9.43247L2.81759 6.99997L1.98926 7.82247L5.25009 11.0833L12.2501 4.0833L11.4276 3.2608L5.25009 9.43247Z",fill:"black"})})),{filled:!0}),Ps=_s((e=>Ge("svg",{width:"14",height:"14",viewBox:"0 0 14 14",fill:"none",xmlns:"http://www.w3.org/2000/svg",...e,children:Ge("path",{d:"M11.0834 3.73916L10.2609 2.91666L7.00008 6.17749L3.73925 2.91666L2.91675 3.73916L6.17758 6.99999L2.91675 10.2608L3.73925 11.0833L7.00008 7.82249L10.2609 11.0833L11.0834 10.2608L7.82258 6.99999L11.0834 3.73916Z",fill:"black"})})),{filled:!0}),Ns=_s((e=>Ge("svg",{width:"14",height:"14",viewBox:"0 0 14 14",fill:"none",xmlns:"http://www.w3.org/2000/svg",...e,children:Ge("path",{fillRule:"evenodd",clipRule:"evenodd",d:"M7.00008 1.16666C3.78008 1.16666 1.16675 3.77999 1.16675 6.99999C1.16675 10.22 3.78008 12.8333 7.00008 12.8333C10.2201 12.8333 12.8334 10.22 12.8334 6.99999C12.8334 3.77999 10.2201 1.16666 7.00008 1.16666ZM6.41675 9.91666V8.74999H7.58342V9.91666H6.41675ZM6.41675 4.08332V7.58332H7.58342V4.08332H6.41675Z",fill:"black"})})),{filled:!0}),As=_s((e=>Ge("svg",{width:"14",height:"14",viewBox:"0 0 14 14",fill:"none",xmlns:"http://www.w3.org/2000/svg",...e,children:Ge("path",{d:"M5.34925 3.50001L6.51591 4.66668H11.6667V10.5H2.33341V3.50001H5.34925ZM5.83341 2.33334H2.33341C1.69175 2.33334 1.17258 2.85834 1.17258 3.50001L1.16675 10.5C1.16675 11.1417 1.69175 11.6667 2.33341 11.6667H11.6667C12.3084 11.6667 12.8334 11.1417 12.8334 10.5V4.66668C12.8334 4.02501 12.3084 3.50001 11.6667 3.50001H7.00008L5.83341 2.33334Z",fill:"black"})})),{filled:!0}),Is=_s((e=>Ge("svg",{width:"14",height:"14",viewBox:"0 0 14 14",fill:"none",xmlns:"http://www.w3.org/2000/svg",...e,children:Ge("path",{d:"M11.0833 4.08333V6.41667H3.98417L6.0725 4.3225L5.25 3.5L1.75 7L5.25 10.5L6.0725 9.6775L3.98417 7.58333H12.25V4.08333H11.0833Z",fill:"black"})})),{filled:!0}),Ls=_s((e=>Ge("svg",{width:"14",height:"14",viewBox:"0 0 14 14",fill:"none",xmlns:"http://www.w3.org/2000/svg",...e,children:Ge("path",{fillRule:"evenodd",clipRule:"evenodd",d:"M1.75 4.66667V3.5H12.25V4.66667H1.75ZM1.75 7.58333H12.25V6.41667H1.75V7.58333ZM1.75 10.5H12.25V9.33333H1.75V10.5Z",fill:"black"})})),{filled:!0}),Rs=_s((e=>Ge("svg",{width:"14",height:"14",viewBox:"0 0 14 14",fill:"none",xmlns:"http://www.w3.org/2000/svg",...e,children:Ge("path",{fillRule:"evenodd",clipRule:"evenodd",d:"M3.49992 5.83334C2.85825 5.83334 2.33325 6.35834 2.33325 7.00001C2.33325 7.64168 2.85825 8.16668 3.49992 8.16668C4.14159 8.16668 4.66659 7.64168 4.66659 7.00001C4.66659 6.35834 4.14159 5.83334 3.49992 5.83334ZM10.4999 5.83334C9.85825 5.83334 9.33325 6.35834 9.33325 7.00001C9.33325 7.64168 9.85825 8.16668 10.4999 8.16668C11.1416 8.16668 11.6666 7.64168 11.6666 7.00001C11.6666 6.35834 11.1416 5.83334 10.4999 5.83334ZM5.83325 7.00001C5.83325 6.35834 6.35825 5.83334 6.99992 5.83334C7.64159 5.83334 8.16659 6.35834 8.16659 7.00001C8.16659 7.64168 7.64159 8.16668 6.99992 8.16668C6.35825 8.16668 5.83325 7.64168 5.83325 7.00001Z",fill:"black"})})),{filled:!0}),js=_s((e=>Ge("svg",{width:"14",height:"14",viewBox:"0 0 14 14",fill:"none",xmlns:"http://www.w3.org/2000/svg",...e,children:Ge("path",{d:"M9.16137 4.3225L8.33887 3.5L4.83887 7L8.33887 10.5L9.16137 9.6775L6.4897 7L9.16137 4.3225Z",fill:"black"})})),{filled:!0}),Ms=_s((e=>Ge("svg",{width:"14",height:"14",viewBox:"0 0 14 14",fill:"none",xmlns:"http://www.w3.org/2000/svg",...e,children:Ge("path",{d:"M5.66137 3.5L4.83887 4.3225L7.51053 7L4.83887 9.6775L5.66137 10.5L9.16137 7L5.66137 3.5Z",fill:"black"})})),{filled:!0}),Fs=_s((e=>Ge("svg",{width:"14",height:"14",viewBox:"0 0 14 14",fill:"none",xmlns:"http://www.w3.org/2000/svg",...e,children:Ge("path",{fillRule:"evenodd",clipRule:"evenodd",d:"M8.61 7.74083L11.9525 11.0833L11.0833 11.9525L7.74083 8.61C7.11667 9.05917 6.36417 9.33333 5.54167 9.33333C3.4475 9.33333 1.75 7.63583 1.75 5.54167C1.75 3.4475 3.4475 1.75 5.54167 1.75C7.63583 1.75 9.33333 3.4475 9.33333 5.54167C9.33333 6.36417 9.05917 7.11667 8.61 7.74083ZM5.54167 2.91667C4.08917 2.91667 2.91667 4.08917 2.91667 5.54167C2.91667 6.99417 4.08917 8.16667 5.54167 8.16667C6.99417 8.16667 8.16667 6.99417 8.16667 5.54167C8.16667 4.08917 6.99417 2.91667 5.54167 2.91667Z",fill:"black"})})),{filled:!0}),Bs=_s((e=>Ge("svg",{width:"14",height:"14",viewBox:"0 0 14 14",fill:"none",xmlns:"http://www.w3.org/2000/svg",...e,children:Ge("path",{fillRule:"evenodd",clipRule:"evenodd",d:"M9.79287 3.5H2.99998V2.5H11.5V11H10.5V4.20711L3.35353 11.3536L2.64642 10.6464L9.79287 3.5Z",fill:"black"})})),{filled:!0}),zs=_s((e=>Ge("svg",{width:"14",height:"14",viewBox:"0 0 14 14",fill:"none",xmlns:"http://www.w3.org/2000/svg",...e,children:Ge("path",{d:"M7.0013 1.16669C3.7813 1.16669 1.16797 3.78002 1.16797 7.00002C1.16797 10.22 3.7813 12.8334 7.0013 12.8334C10.2213 12.8334 12.8346 10.22 12.8346 7.00002C12.8346 3.78002 10.2213 1.16669 7.0013 1.16669ZM7.0013 11.6667C4.42297 11.6667 2.33464 9.57835 2.33464 7.00002C2.33464 4.42169 4.42297 2.33335 7.0013 2.33335C9.57964 2.33335 11.668 4.42169 11.668 7.00002C11.668 9.57835 9.57964 11.6667 7.0013 11.6667Z",fill:"black"})})),{filled:!0}),$s=_s((e=>We("svg",{width:"14",height:"14",viewBox:"0 0 14 14",fill:"none",xmlns:"http://www.w3.org/2000/svg",...e,children:[Ge("path",{d:"M7.0013 1.16669C3.7813 1.16669 1.16797 3.78002 1.16797 7.00002C1.16797 10.22 3.7813 12.8334 7.0013 12.8334C10.2213 12.8334 12.8346 10.22 12.8346 7.00002C12.8346 3.78002 10.2213 1.16669 7.0013 1.16669ZM7.0013 11.6667C4.42297 11.6667 2.33464 9.57835 2.33464 7.00002C2.33464 4.42169 4.42297 2.33335 7.0013 2.33335C9.57964 2.33335 11.668 4.42169 11.668 7.00002C11.668 9.57835 9.57964 11.6667 7.0013 11.6667Z",fill:"black"}),Ge("path",{d:"M7.0013 9.91669C8.61213 9.91669 9.91797 8.61085 9.91797 7.00002C9.91797 5.38919 8.61213 4.08335 7.0013 4.08335C5.39047 4.08335 4.08464 5.38919 4.08464 7.00002C4.08464 8.61085 5.39047 9.91669 7.0013 9.91669Z",fill:"black"})]})),{filled:!0}),Us=_s((e=>Ge("svg",{width:"14",height:"14",viewBox:"0 0 14 14",fill:"none",xmlns:"http://www.w3.org/2000/svg",...e,children:Ge("path",{"fill-rule":"evenodd","clip-rule":"evenodd",d:"M11.0833 2.33332H10.5V1.16666H9.33333V2.33332H4.66667V1.16666H3.5V2.33332H2.91667C2.26917 2.33332 1.75 2.85832 1.75 3.49999V11.6667C1.75 12.3083 2.26917 12.8333 2.91667 12.8333H11.0833C11.725 12.8333 12.25 12.3083 12.25 11.6667V3.49999C12.25 2.85832 11.725 2.33332 11.0833 2.33332ZM11.0833 11.6667H2.91667V5.24999H11.0833V11.6667ZM3.79167 7.58332C3.79167 6.77832 4.445 6.12499 5.25 6.12499C6.055 6.12499 6.70833 6.77832 6.70833 7.58332C6.70833 8.38832 6.055 9.04166 5.25 9.04166C4.445 9.04166 3.79167 8.38832 3.79167 7.58332Z",fill:"black"})})),{filled:!0}),Hs=_s((e=>Ge("svg",{width:"14",height:"14",viewBox:"0 0 14 14",fill:"none",xmlns:"http://www.w3.org/2000/svg",...e,children:Ge("path",{d:"M2.32812 7.58329V6.41663H11.6581V7.58329H2.32812Z",fill:"black"})})),{filled:!0}),Vs=({color:e,variant:t="body1",component:n,className:r,children:o,...a})=>{const i=bs(a);return Ge(n??{h1:"h1",h2:"h2",h3:"h3",h4:"h4",h5:"h5",h6:"h6",label1:"label",label2:"label"}[t]??"span",{className:Qe(i.className,gs.root,gs[t],e&&gs[e],r),...ws(a),children:o})};Vs.classes=gs;const qs={root:"lsd-dropdown-item",icon:"lsd-dropdown-item__icon",label:"lsd-dropdown-item__label",error:"lsd-dropdown-item--error",disabled:"lsd-dropdown-item--disabled",selected:"lsd-dropdown-item--selected",withIcon:"lsd-dropdown-item--with-icon",small:"lsd-dropdown-item--small",medium:"lsd-dropdown-item--medium",large:"lsd-dropdown-item--large"},Gs=({label:e,size:t="large",withIcon:n,selected:r,disabled:o,className:a,...i})=>{const l=bs(i),s={color:"primary",className:qs.icon};return We("div",{role:"option","aria-selected":r?"true":"false",...ws(i),className:Qe(l.className,a,qs.root,qs[t],n&&qs.withIcon,o&&qs.disabled),children:[n&&Ge(r?Ts:Os,{...s}),Ge(Vs,{variant:"large"===t?"label1":"label2",component:"span",className:qs.label,children:e})]})};function Ws(e){for(var t=[],n=1;n<arguments.length;n++)t[n-1]=arguments[n];e&&e.addEventListener&&e.addEventListener.apply(e,t)}function Zs(e){for(var t=[],n=1;n<arguments.length;n++)t[n-1]=arguments[n];e&&e.removeEventListener&&e.removeEventListener.apply(e,t)}Gs.classes=qs;var Qs=["mousedown","touchstart"];const Ys=function(e,t,n){void 0===n&&(n=Qs);var o=r.useRef(t);r.useEffect((function(){o.current=t}),[t]),r.useEffect((function(){for(var t=function(t){var n=e.current;n&&!n.contains(t.target)&&o.current(t)},r=0,a=n;r<a.length;r++){var i=a[r];Ws(document,i,t)}return function(){for(var e=0,r=n;e<r.length;e++){var o=r[e];Zs(document,o,t)}}}),[n,e])};const Xs=function(e){r.useEffect(e,[])};const Ks=function(e){var t=r.useRef(e);t.current=e,Xs((function(){return function(){return t.current()}}))};const Js=function(e){var t=r.useRef(0),n=r.useState(e),o=n[0],a=n[1],i=r.useCallback((function(e){cancelAnimationFrame(t.current),t.current=requestAnimationFrame((function(){a(e)}))}),[]);return Ks((function(){cancelAnimationFrame(t.current)})),[o,i]};const eu=function(e){var t=Js({x:0,y:0}),n=t[0],o=t[1];return r.useEffect((function(){var t=function(){e.current&&o({x:e.current.scrollLeft,y:e.current.scrollTop})};return e.current&&Ws(e.current,"scroll",t,{capture:!1,passive:!0}),function(){e.current&&Zs(e.current,"scroll",t)}}),[e]),n},tu={root:"lsd-dropdown-menu",open:"lsd-dropdown-menu--open",large:"lsd-dropdown-menu--large",medium:"lsd-dropdown-menu--medium",small:"lsd-dropdown-menu--small"},nu=(e,t)=>{const[n,o]=r.useState({});return r.useEffect((()=>{const{width:t,height:n,top:r,left:a}=e.current.getBoundingClientRect();o({left:a+window.scrollX,width:t,top:r+n+window.scrollY})}),[t]),n},ru=({size:e="large",open:t,label:n,handleRef:o,onClose:a,children:i,...l})=>{const s=bs(l),u=r.useRef(null);Ys(u,(e=>{t&&!e.composedPath().includes(o.current)&&a&&a()}));const c=nu(o,t);return Ge("ul",{...ws(l),ref:u,role:"listbox","aria-label":n,style:{...c,...l.style??{}},className:Qe(s.className,l.className,tu.root,tu[e],t&&tu.open),children:i})};ru.classes=tu;const ou=r.createContext({initialized:!1}),au=({id:e,children:t})=>{var n;return(null==(n=r.useContext(ou))?void 0:n.initialized)??!1?Ge(iu,{id:e,children:t}):Ge(qe,{})},iu=({id:e,children:t})=>{const n=(({parentId:e})=>{const t=r.useRef();return"undefined"==typeof window||t.current||(t.current=document.createElement("div")),r.useEffect((()=>{var n;if("undefined"==typeof window||!t.current)return;const r=document.querySelectorAll(`#${e}`);return null==(n=r[r.length-1])||n.appendChild(t.current),()=>{var n;try{null==(n=document.getElementById(e))||n.removeChild(t.current)}catch(r){}}}),[e,t.current]),t.current})({parentId:"lsd-presentation"});return n?o.createPortal(t,n,e):Ge(qe,{})},lu={root:"lsd-autocomplete",label:"lsd-autocomplete__label",inputContainer:"lsd-autocomplete__input-container",input:"lsd-autocomplete__input",icon:"lsd-autocomplete__icon",dropdownItemPlaceholder:"lsd-autocomplete__dropdown-item-placeholder",disabled:"lsd-autocomplete--disabled",error:"lsd-autocomplete--error",large:"lsd-autocomplete--large",medium:"lsd-autocomplete--medium",small:"lsd-autocomplete--small",withIcon:"lsd-autocomplete--with-icon",outlined:"lsd-autocomplete--outlined",underlined:"lsd-autocomplete--underlined"},su=({label:e,size:t="large",withIcon:n=!1,error:o=!1,disabled:a=!1,children:i,value:l,defaultValue:s,placeholder:u,onChange:c,options:d=[],inputProps:f={},variant:p="outlined",...h})=>{const m=bs(h),g=r.useRef(null),v=r.useRef(null),b=Ye({defaultValue:s,value:l,onChange:c,ref:g}),y=b.value,[w,x]=r.useState(!1),[_,k]=r.useState(),E=e=>{x(!1),k(e),b.setValue(e)},S=r.useMemo((()=>b.filled?d.filter((e=>new RegExp(`^${b.value}.+`,"i").test(e))).map((e=>[e,e.slice(0,y.length),e.slice(y.length)])):d),[b.value,d]);r.useEffect((()=>{!_&&b.filled&&!w&&x(!0)}),[b.value,_,w]);const C=!a&&w&&S.length>0&&b.filled,T=(null==f?void 0:f.id)??(h.id||"autocomplete")+"-input";return We("div",{ref:v,...ws(h),className:Qe(h.className,m.className,lu.root,lu[t],a&&lu.disabled,n&&lu.withIcon,"outlined"===p?lu.outlined:lu.underlined),children:[e&&Ge(Vs,{htmlFor:T,className:lu.label,variant:"label2",component:"label",children:e}),We("div",{className:lu.inputContainer,children:[Ge("input",{id:T,ref:g,value:b.value,placeholder:u,onChange:b.onChange,disabled:a,onFocus:()=>x(!0),...f,className:Qe(f.className,lu.input,o&&lu.error)}),n&&b.value?Ge("span",{className:lu.icon,onClick:()=>b.setValue(""),children:Ge(Ps,{color:"primary"})}):n&&!b.value?Ge("span",{className:lu.icon,children:Ge(Fs,{color:"primary"})}):null]}),Ge(au,{id:"autocomplete",children:Ge(ru,{handleRef:v,open:C,onClose:()=>x(!1),size:t,...ys(h),children:S.map(((e,n)=>Ge(Gs,{size:t,tabIndex:0,label:We(qe,{children:[e[1],Ge("span",{className:lu.dropdownItemPlaceholder,children:e[2]})]}),onClick:()=>E(e[0]),onKeyDown:t=>"Enter"===t.key&&E(e[0])},n)))})})]})};su.classes=lu;const uu={root:"lsd-badge",label:"lsd-badge__label",outlined:"lsd-badge--outlined",filled:"lsd-badge--filled",disabled:"lsd-badge--disabled",small:"lsd-badge--small",large:"lsd-badge--large"},cu=({variant:e="outlined",disabled:t,size:n="large",icon:r,iconDirection:o="left",children:a,...i})=>{const l=bs(i);return We("div",{"aria-label":a,...ws(i),className:Qe(i.className,l.className,uu.root,uu[e],t&&uu.disabled,uu[n]),children:["left"===o&&r,Ge(Vs,{component:"span",variant:"small"===n?"label2":"label1",className:uu.label,children:a}),"right"===o&&r]})};cu.classes=uu;const du={root:"lsd-breadcrumb-item",outlined:"lsd-breadcrumb-item--outlined",itemLink:"lsd-breadcrumb-item__link",large:"lsd-breadcrumb-item--large",small:"lsd-breadcrumb-item--small"},fu=({size:e="large",label:t,link:n,linkComponent:r=(e=>Ge("a",{...e,children:e.children})),outlined:o,selected:a,ellipsisRef:i,onClick:l,className:s,...u})=>{const c=bs(u);return Ge("li",{...ws(u),className:Qe(c.className,du.root,du[e],s),"aria-selected":a?"true":"false",onClick:l,ref:i,children:Ge(r,{href:n,className:Qe(du.itemLink,o&&du.outlined),children:Ge(Vs,{color:"primary",component:"span",variant:"large"===e?"label1":"label2",children:t})})})};fu.classes=du;const pu={root:"lsd-breadcrumb",list:"lsd-breadcrumb__list",listBox:"lsd-breadcrumb__dropdown-menu",open:"lsd-breadcrumb--open",disabled:"lsd-breadcrumb--disabled"},hu=({size:e="large",disabled:t=!1,ellipsis:n=!1,maxItems:o,value:a=[],onChange:i,options:l=[],...s})=>{const u=bs(s),c=r.useRef(null),[d,f]=r.useState(!1);o=Math.max(2,Math.min(o||2,l.length));const[p,...h]=l,[m,g]=n?[h.slice(0,h.length-o+1),h.slice(h.length-o+1)]:[[],h],v=t=>t.map(((t,n)=>Ge(fu,{outlined:n===g.length-1&&t!==p,label:t.value,link:t.link,linkComponent:null==t?void 0:t.linkComponent,size:e},n)));return r.useEffect((()=>{t&&d&&f(!1)}),[d,t]),We("div",{...ws(s),className:Qe(s.className,u.className,pu.root,t&&pu.disabled,d&&pu.open),children:[We("ul",{className:pu.list,children:[p&&v([p]),m.length>0&&Ge(fu,{ellipsisRef:c,label:"...",onClick:()=>{!t&&f((e=>!e))},size:e,...ys(s)}),v(g)]}),null!=(null==c?void 0:c.current)&&n&&o&&Ge(au,{id:"breadcrumb",children:Ge(ru,{handleRef:c,open:d,onClose:()=>f(!1),className:Qe(pu.listBox),size:e,genericFontFamily:s.genericFontFamily,...ys(s),children:m.map(((e,t)=>Ge(fu,{label:e.value,link:e.link,className:du.itemLink,linkComponent:null==e?void 0:e.linkComponent},t)))})})]})};hu.classes=pu;const mu=r.createContext(null),gu={root:"lsd-button",disabled:"lsd-button--disabled",large:"lsd-button--large",medium:"lsd-button--medium",small:"lsd-button--small",withIcon:"lsd-button--with-icon",outlined:"lsd-button--outlined",filled:"lsd-button--filled",text:"lsd-button__text",icon:"lsd-button__icon"},vu=({size:e,variant:t,disabled:n,icon:o,children:a,...i})=>{const l=r.useContext(mu),s=bs(i),u=bs(l||{}),c=s.className||u.className,d=e??(null==l?void 0:l.size)??"medium",f=t??(null==l?void 0:l.variant)??"outlined",p=n??(null==l?void 0:l.disabled)??!1;return Ge(qe,{children:We("button",{...ws(i),className:Qe(c,i.className,gu.root,gu[d],gu[f],p&&gu.disabled,o&&gu.withIcon),children:[Ge(Vs,{component:"span",className:gu.text,variant:"small"===d?"label2":"label1",children:a}),o&&Ge("span",{className:gu.icon,children:o})]})})};vu.classes=gu;const bu={root:"lsd-card",small:"lsd-card--small",medium:"lsd-card--medium",large:"lsd-card--large"},yu=r.createContext(null),wu=({size:e="large",children:t,...n})=>{const r=bs(n);return Ge(yu.Provider,{value:{size:e},children:Ge("div",{...ws(n),className:Qe(r.className,bu.root,bu[e]),children:t})})};wu.classes=bu;const xu={root:"lsd-card-body"},_u=({children:e,...t})=>{const n=bs(t);return Ge("div",{...ws(t),className:Qe(n.className,t.className,xu.root),children:e})};_u.classes=xu;const ku={root:"lsd-card-header",title:"lsd-card-header__title",small:"lsd-card-header--small",medium:"lsd-card-header--medium",large:"lsd-card-header--large"},Eu=({size:e="large",children:t,...n})=>{const o=bs(n),a=r.useContext(yu),i=(null==a?void 0:a.size)??e;return Ge("div",{...ws(n),className:Qe(o.className,n.className,ku.root,ku[i]),children:Ge(Vs,{className:ku.title,component:"div",variant:"large"===i?"label1":"label2",children:t})})};Eu.classes=ku;const Su=r.createContext(null),Cu=_s((e=>Ge("svg",{width:"14",height:"14",viewBox:"0 0 14 14",fill:"none",xmlns:"http://www.w3.org/2000/svg",...e,children:Ge("path",{fillRule:"evenodd",clipRule:"evenodd",d:"M2.91667 1.75C2.27233 1.75 1.75 2.27233 1.75 2.91667V11.0833C1.75 11.7277 2.27233 12.25 2.91667 12.25H11.0833C11.7277 12.25 12.25 11.7277 12.25 11.0833V2.91667C12.25 2.27233 11.7277 1.75 11.0833 1.75H2.91667ZM9.91667 6.41667H4.08333V7.58333H9.91667V6.41667Z",fill:"black"})})),{filled:!0}),Tu={root:"lsd-checkbox",input:"lsd-checkbox__input",icon:"lsd-checkbox__icon",label:"lsd-checkbox__label",focused:"lsd-checkbox--focused",disabled:"lsd-checkbox--disabled",indeterminate:"lsd-checkbox--indeterminate",large:"lsd-checkbox--large",medium:"lsd-checkbox--medium",small:"lsd-checkbox--small"},Ou=({name:e,size:t="large",onChange:n,checked:o,defaultChecked:a,disabled:i=!1,indeterminate:l=!1,inputProps:s={},children:u,...c})=>{const d=bs(c),f=r.useRef(null),[p,h]=r.useState(!1),m=Ye({value:o,defaultValue:a??!1,onChange:n,ref:f}),g=r.useContext(Su),v=(null==g?void 0:g.size)??t;return r.useEffect((()=>{if(!f.current)return;const e=()=>h(!0),t=()=>h(!1);return f.current.addEventListener("focus",e),f.current.addEventListener("blur",t),()=>{var n,r;null==(n=f.current)||n.removeEventListener("focus",e),null==(r=f.current)||r.removeEventListener("blur",t)}}),[f.current]),We(Vs,{color:"primary",variant:"large"===v?"label1":"label2",component:"label","aria-disabled":i?"true":"false",...ws(c),className:Qe(d.className,c.className,Tu.root,Tu[v],p&&Tu.focused,i&&Tu.disabled,l&&Tu.indeterminate),children:[Ge("input",{ref:f,name:e,type:"checkbox",disabled:i,checked:m.value,onChange:m.onChange,defaultChecked:a,className:Qe(s.className,Tu.input),...s}),l?Ge(Cu,{color:"primary",focusable:!1}):m.value?Ge(Ts,{color:"primary",focusable:!1}):Ge(Os,{color:"primary",focusable:!1}),Ge("span",{className:Tu.label,children:u})]})};Ou.classes=Tu;const Du={root:"lsd-checkbox-group",label:"lsd-checkbox-group__label"},Pu=({size:e="large",label:t,children:n,...r})=>{const o=bs(r);return Ge(Su.Provider,{value:{size:e},children:We("div",{...ws(r),className:Qe(o.className,r.className,Du.root),children:[Ge(Vs,{component:"span",variant:"small"===e?"label2":"label1",className:Du.label,...ys(r),children:t}),n]})})};Pu.classes=Du;const Nu={root:"lsd-collapse-header",trigger:"lsd-collapse-header__trigger",label:"lsd-collapse-header__label",icons:"lsd-collapse-header__icons",icon:"lsd-collapse-header__icon",menuIcon:"lsd-collapse-header__menu-icon",open:"lsd-collapse-header--open",disabled:"lsd-collapse-header--disabled",small:"lsd-collapse-header--small",medium:"lsd-collapse-header--medium",large:"lsd-collapse-header--large"},Au=({label:e,disabled:t=!1,open:n,setOpen:r,size:o="large",onTrigger:a,...i})=>{const l=bs(i);return Ge("div",{...ws(i),className:Qe(l.className,i.className,Nu.root,Nu[o],t&&Nu.disabled,n&&Nu.open),children:We("button",{className:Qe(Nu.trigger),onClick:a,children:[Ge(Vs,{color:"primary",component:"label",variant:"small"===o?"label2":"label1",className:Nu.label,children:e}),Ge("div",{className:Nu.icons,children:Ge(n?Cs:Es,{color:"primary",className:Nu.menuIcon})})]})})};Au.classes=Nu;const Iu={root:"lsd-collapse",content:"lsd-collapse__content",open:"lsd-collapse--open",disabled:"lsd-collapse--disabled"},Lu=({label:e,disabled:t=!1,size:n="large",open:o,children:a,...i})=>{const l=bs(i),s=r.useRef(null),[u,c]=r.useState(o??!1),d=e=>{if(void 0===o)return c(e);i.onChange&&i.onChange(e)};return r.useEffect((()=>{t&&u&&d(!1)}),[t,u,d]),r.useEffect((()=>{void 0!==o&&c(o)}),[o]),We("div",{...ws(i),ref:s,className:Qe(l.className,i.className,Iu.root,t&&Iu.disabled,u&&Iu.open),children:[Ge(Au,{label:e,open:u,setOpen:c,size:n,onTrigger:()=>!t&&d(!u),disabled:t,...ys(i)}),u&&Ge("div",{className:Iu.content,children:a})]})};Lu.classes=Iu;const Ru={root:"lsd-dropdown",label:"lsd-dropdown__label",buttonContainer:"lsd-dropdown__button-container",trigger:"lsd-dropdown__trigger",optionLabel:"lsd-dropdown__option-label",icons:"lsd-dropdown__icons",icon:"lsd-dropdown__icon",menuIcon:"lsd-dropdown__menu-icon",supportingText:"lsd-dropdown__supporting-text",open:"lsd-dropdown--open",error:"lsd-dropdown--error",disabled:"lsd-dropdown--disabled",small:"lsd-dropdown--small",medium:"lsd-dropdown--medium",large:"lsd-dropdown--large",outlined:"lsd-dropdown--outlined",underlined:"lsd-dropdown--underlined"},ju=({label:e,size:t="large",error:n=!1,disabled:o=!1,supportingText:a,triggerLabel:i,value:l=[],onChange:s,options:u=[],multi:c=!1,variant:d="outlined",isOpen:f,onToggle:p,menuProps:h={},...m})=>{const g=bs(m),v=r.useRef(null),b=void 0!==f,[y,w]=r.useState(!1);b&&f!==y&&w(f);const{select:x,isSelected:_,selected:k}=((e,t,{onDone:n,onChange:o,multi:a=!1}={})=>{const i=r.useMemo((()=>Object.fromEntries(e.map((e=>[e.value,e])))),[e]),[l,s]=r.useState(Array.isArray(t)?t:t?[t]:[]),u=r.useMemo((()=>ds(l,(()=>!0))),[l]),c=r.useMemo((()=>l.map((e=>i[e]))),[l,i]);r.useEffect((()=>{o&&s(Array.isArray(t)?t:t?[t]:[])}),[t,o]);const d=e=>"string"==typeof e?e:e.value;return{selected:c,isSelected:e=>!!u[d(e)],select:e=>{const t=d(e),r=a?u[t]?l.filter((e=>e!==t)):[...l,t]:[t];o?o(a?r:r[0]):s(r),!a&&n&&n(a?r:r[0])}}})(u,l,{multi:c,onChange:s,onDone:()=>{w(!1)}}),E=e=>{b?p&&p(e):w(e)};r.useEffect((()=>{o&&y&&!b&&w(!1)}),[y,o,b]);const S=(null==m?void 0:m.id)??(m.id||"dropdown")+"-input";return We("div",{ref:v,...ws(m),className:Qe(g.className,m.className,Ru.root,Ru[t],n&&Ru.error,o&&Ru.disabled,y&&Ru.open,"outlined"===d?Ru.outlined:Ru.underlined),children:[e&&Ge(Vs,{htmlFor:S,className:Ru.label,variant:"label2",component:"label",children:e}),Ge("div",{className:Ru.buttonContainer,children:We("button",{id:S,className:Qe(Ru.trigger),onClick:()=>{o||E(!y)},children:[Ge(Vs,{color:"primary",component:"label",variant:"large"===t?"label1":"label2",className:Ru.optionLabel,children:k.length>0?k.map((e=>e.name)).join(", "):i}),We("div",{className:Ru.icons,children:[n&&Ge(Ns,{color:"primary",className:Ru.icon}),Ge(y?Cs:Es,{color:"primary",className:Ru.menuIcon})]})]})}),a&&Ge(Vs,{variant:"large"===t?"label1":"label2",component:"p",className:Ru.supportingText,children:a}),Ge(au,{id:"dropdown",children:Ge(ru,{handleRef:v,open:y,onClose:()=>E(!1),size:t,genericFontFamily:m.genericFontFamily,...h,children:u.map((e=>Ge(Gs,{size:t,tabIndex:0,onClick:x.bind(null,e),withIcon:c,label:e.name,selected:_(e),onKeyDown:t=>"Enter"===t.key&&x(e)},e.value)))})})]})};ju.classes=Ru;const Mu=r.createContext(null),Fu={root:"lsd-icon-button",outlined:"lsd-icon-button--outlined",filled:"lsd-icon-button--filled",disabled:"lsd-icon-button--disabled",small:"lsd-icon-button--small",medium:"lsd-icon-button--medium",large:"lsd-icon-button--large"},Bu=({size:e,disabled:t,variant:n,children:o,...a})=>{const i=bs(a),l=r.useContext(Mu),s=e??(null==l?void 0:l.size)??"large",u=n??(null==l?void 0:l.variant)??"outlined",c=t??(null==l?void 0:l.disabled)??!1;return Ge("button",{...ws(a),className:Qe(i.className,a.className,Fu.root,Fu[s],Fu[u],c&&Fu.disabled),children:o})};Bu.classes=Fu;const zu={root:"lsd-icon-button-group",outlined:"lsd-icon-button-group--outlined",filled:"lsd-icon-button-group--filled",disabled:"lsd-icon-button-group--disabled",small:"lsd-icon-button-group--small",medium:"lsd-icon-button-group--medium",large:"lsd-icon-button-group--large"},$u=({size:e="large",disabled:t,variant:n="outlined",children:r,...o})=>{const a=bs(o);return Ge("div",{...ws(o),className:Qe(a.className,o.className,zu.root,zu[e],zu[n],t&&zu.disabled),children:Ge(Mu.Provider,{value:{size:e,variant:n,disabled:t},children:r})})};$u.classes=zu;const Uu={root:"lsd-quote",indentedInline:"lsd-quote--indented-inline",parentheses:"lsd-quote--parentheses",text:"lsd-quote__text"},Hu=({mode:e="indented-line",children:t,...n})=>{const r=bs(n);return Ge(qe,{children:Ge("div",{...ws(n),className:Qe(r.className,n.className,Uu.root,e&&"parentheses"===e?Uu.parentheses:Uu.indentedInline),children:Ge(Vs,{color:"primary",component:"label",variant:"label1",children:t})})})};Hu.classes=Uu;const Vu=r.createContext(null),qu={root:"lsd-radio-button",input:"lsd-radio-button__input",label:"lsd-radio-button__label",disabled:"lsd-radio-button--disabled",large:"lsd-radio-button--large",medium:"lsd-radio-button--medium",small:"lsd-radio-button--small"},Gu=({size:e="large",onChange:t,checked:n,defaultChecked:o,disabled:a=!1,value:i,name:l,inputProps:s={},children:u,...c})=>{const d=bs(c),f=r.useRef(null),p=r.useContext(Vu),h=(null==p?void 0:p.size)??e,m=(null==p?void 0:p.name)??l??"",g=p?p.value===i:n,v=Ye({value:g,defaultValue:o??!1,onChange:t,ref:f});return We(Vs,{color:"primary",variant:"large"===h?"label1":"label2",component:"label","aria-disabled":a?"true":"false",...ws(c),className:Qe(d.className,c.className,qu.root,qu[h],a&&qu.disabled),children:[Ge("input",{ref:f,name:m,value:i,type:"radio",checked:v.value,onChange:e=>{p?p.setActiveRadioButton(e.target.value):v.onChange(e)},defaultChecked:o,className:Qe(s.className,qu.input),...s}),v.value?Ge($s,{color:"primary",focusable:!1}):Ge(zs,{color:"primary",focusable:!1}),Ge("span",{className:qu.label,children:u})]})};Gu.classes=qu;const Wu={root:"lsd-radio-button-group",label:"lsd-radio-button-group__label"},Zu=({size:e="large",label:t,value:n,name:o,onChange:a,children:i,...l})=>{const s=bs(l),u=r.useRef(null),[c,d]=r.useState(n);return r.useEffect((()=>d(n)),[n]),Ge(Vu.Provider,{value:{value:c,setActiveRadioButton:e=>{a?a(e):d(e)},name:o,size:e},children:We("div",{ref:u,...ws(l),className:Qe(s.className,l.className,Wu.root),children:[Ge(Vs,{component:"span",variant:"small"===e?"label2":"label1",className:Wu.label,children:t&&t}),i]})})};Zu.classes=Wu;const Qu=r.createContext(null),Yu={root:"lsd-tab-item",text:"lsd-tab-item--text",icon:"lsd-tab-item--icon",disabled:"lsd-tab-item--disabled",selected:"lsd-tab-item--selected",small:"lsd-tab-item--small",medium:"lsd-tab-item--medium",large:"lsd-tab-item--large",withIcon:"lsd-tab-item--with-icon"},Xu=({name:e,size:t="large",selected:n=!1,inactive:o=!1,icon:a,children:i,...l})=>{const s=bs(l),u=r.useContext(Qu),c=(null==u?void 0:u.size)??t,d=u?u.activeTab===e:n;return We("button",{...ws(l),className:Qe(s.className,l.className,Yu.root,Yu[c],d&&Yu.selected,l.disabled&&Yu.disabled,!!a&&Yu.withIcon),onClick:t=>{l.onClick&&l.onClick(t),o||(null==u?void 0:u.setActiveTab)&&u.setActiveTab(e)},children:[Ge(Vs,{component:"span",className:Yu.text,variant:"small"===c?"label2":"label1",children:i}),a&&Ge("span",{className:Yu.icon,children:a})]})};Xu.classes=Yu;const Ku={root:"lsd-table-body",toolbar:"lsd-table-body__toolbar",row:"lsd-table-body__row"},Ju=({options:e=[],size:t="large",buttonLabel:n="Button",toolbar:r,children:o,...a})=>{const i=bs(a);return We("div",{...ws(a),className:Qe(i.className,a.className,Ku.root),children:[r&&Ge("div",{className:Qe(Ku.toolbar),children:r}),Ge("table",{children:o})]})};Ju.classes=Ku;const ec={root:"lsd-table-header"},tc=({size:e="large",children:t,...n})=>{const r=bs(n);return Ge("div",{...ws(n),className:Qe(r.className,n.className,ec.root),children:t})};tc.classes=ec;const nc={root:"lsd-table",small:"lsd-table--small",medium:"lsd-table--medium",large:"lsd-table--large"},rc=r.createContext(null),oc=()=>r.useContext(rc),ac=({size:e="large",type:t="default",headerOptions:n,header:r,toolbar:o,children:a,...i})=>{const l=bs(i);return Ge(rc.Provider,{value:{size:e,type:t,headerOptions:n},children:We("div",{...ws(i),className:Qe(l.className,nc.root,nc[e]),children:[Ge(tc,{children:r}),Ge(Ju,{toolbar:o,options:n,children:a})]})})};ac.classes=nc;const ic={root:"lsd-table-item",large:"lsd-table-item--large",medium:"lsd-table-item--medium",small:"lsd-table-item--small"},lc=({size:e="large",children:t,...n})=>{const r=bs(n),o=oc(),a=(null==o?void 0:o.size)??e;return Ge("td",{...ws(n),className:Qe(r.className,n.className,ic.root,ic[a]),children:t})};lc.classes=ic;const sc={root:"lsd-table-row"},uc=({size:e="large",type:t="default",children:n,...r})=>{const o=bs(r),a=oc(),i=(null==a?void 0:a.type)??t;return We("tr",{...ws(r),className:Qe(o.className,r.className,sc.root),children:["checkbox"===i&&Ge("td",{className:ic.root,children:Ge(Ou,{})}),"radio"===i&&Ge("td",{className:ic.root,children:Ge(Gu,{value:"1"})}),n]})};uc.classes=sc;const cc=r.createContext(null),dc=(e=0)=>{let t=e-1;return()=>(t++,t)},fc="undefined"==typeof DOMRectReadOnly?null:new DOMRectReadOnly(0,0,0,0),pc=dc(),hc=(e,t)=>{const n=(()=>{const{observe:e,unobserve:t,ready:n}=r.useContext(cc)??{};return r.useMemo((()=>({observe:e,unobserve:t,ready:n})),[e,t,n])})(),o=r.useMemo((()=>t??pc().toString()),[t]),a=((e,t)=>{var n;const o=r.useContext(cc);return(null==(n=null==o?void 0:o.rect)?void 0:n[e])??t})(o)??fc;return r.useEffect((()=>{if(n&&n.ready)return e.current&&n.observe(o,e),()=>{n.unobserve(o)}}),[n.ready,e.current]),a},mc=(e,t,n,r)=>-1===e?t:n-(r+t),gc=(e,t)=>{var n;const o=hc(e),[a,i]=r.useState((null==(n=null==e?void 0:e.current)?void 0:n.scrollLeft)??0),[l,s]=r.useState(0),[u,c]=r.useState(0),d=r.useRef(null);((e,t,n,o,a)=>{const i=r.useMemo((()=>"string"==typeof e?e:e()),[]),l=r.useMemo((()=>"function"==typeof t?t():t),[t]);r.useEffect((()=>{if((null==l?void 0:l.addEventListener)&&(null==l?void 0:l.removeEventListener))return l.addEventListener(i,n,o),()=>{l.removeEventListener(i,n,o)}}),[i,l])})("scroll",e.current,(e=>{i(e.target.scrollLeft)}),{passive:!0});r.useEffect((()=>{if(d.current&&clearTimeout(d.current),!e.current)return;const{scrollLeft:t,scrollWidth:n,clientWidth:r}=e.current;c(mc(1,t,n,r)),s(mc(-1,t,n,r))}),[o,a,null==t?void 0:t.deps]);const f=(n,r)=>{const{clientWidth:o,scrollLeft:a}=e.current,i=Array.from(e.current.childNodes).find((e=>e.getBoundingClientRect().x>=0)),l=Math.max(r??o/3,i?i.clientWidth:0);e.current.scrollTo({behavior:(null==t?void 0:t.scrollBehavior)??"smooth",left:a+l*n})};return r.useMemo((()=>({right:u,left:l,toRight:f.bind(null,1),toLeft:f.bind(null,-1)})),[u,l])},vc={root:"lsd-tabs",fullWidth:"lsd-tabs--full-width",withScrollControls:"lsd-tabs--with-scroll-controls",leftScrollControl:"lsd-tabs__left-scroll-control",rightScrollControl:"lsd-tabs__right-scroll-control"},bc=({size:e="large",fullWidth:t=!1,scrollControls:n=!1,onChange:o,activeTab:a,children:i,...l})=>{const s=bs(l),u=r.useRef(null),[c,d]=r.useState(a);r.useEffect((()=>d(a)),[a]);const f=gc(u,{scrollBehavior:"smooth",deps:[i]}),p=0!==f.left||0!==f.right;return Ge(Qu.Provider,{value:{activeTab:c,setActiveTab:e=>{o?o(e):d(e)},size:e},children:We("div",{ref:u,...ws(l),className:Qe(s.className,l.className,vc.root,t&&vc.fullWidth,n&&p&&vc.withScrollControls),children:[n&&p&&Ge(Xu,{inactive:!0,name:"Prev",disabled:0===f.left,onClick:()=>f.toLeft(),className:vc.leftScrollControl,children:Ge(js,{color:"primary"})}),i,n&&p&&Ge(Xu,{inactive:!0,name:"Next",disabled:0===f.right,onClick:()=>f.toRight(),className:vc.rightScrollControl,children:Ge(Ms,{color:"primary"})})]})})};bc.classes=vc;const yc={root:"lsd-tag",label:"lsd-tag__label",outlined:"lsd-tag--outlined",filled:"lsd-tag--filled",disabled:"lsd-tag--disabled",small:"lsd-badge--small",large:"lsd-badge--large"},wc=({variant:e="outlined",disabled:t,icon:n,iconDirection:r="left",children:o,size:a="large",...i})=>{const l=bs(i);return We("div",{"aria-label":o,...ws(i),className:Qe(l.className,i.className,yc.root,yc[e],t&&yc.disabled,yc[a]),children:["left"===r&&n,Ge(Vs,{variant:"small"===a?"label2":"label1",className:yc.label,component:"span",children:o}),"right"===r&&n]})};wc.classes=yc;var xc=Hi,_c=0;var kc=function(e){var t=++_c;return xc(e)+t};const Ec={root:"lsd-text-field",inputContainer:"lsd-text-field__input-container",label:"lsd-text-field__label",input:"lsd-text-field__input",icon:"lsd-text-field__icon",clearButton:"lsd-text-field__clear-button",supportingText:"lsd-text-field__supporting-text",disabled:"lsd-text-field--disabled",error:"lsd-text-field--error",large:"lsd-text-field--large",medium:"lsd-text-field--medium",small:"lsd-text-field--small",outlined:"lsd-text-field--outlined",underlined:"lsd-text-field--underlined"},Sc=({size:e="large",label:t,icon:n,error:o=!1,errorIcon:a=!1,clearButton:i,supportingText:l,children:s,value:u,placeholder:c,defaultValue:d,disabled:f,onChange:p,inputProps:h={},labelProps:m={},variant:g="underlined",...v})=>{const b=bs(v),y=r.useRef(null),w=Ye({defaultValue:d,value:u,onChange:p,ref:y}),x=h.id||kc("TextField-");return We("div",{"aria-disabled":f?"true":"false",...ws(v),className:Qe(b.className,v.className,Ec.root,Ec[e],f&&Ec.disabled,o&&Ec.error,"outlined"===g?Ec.outlined:Ec.underlined),children:[t&&Ge(Vs,{variant:"label2",component:"label",htmlFor:x,...m,className:Qe(Ec.label,m.className),children:t}),We("div",{className:Ec.inputContainer,children:[Ge("input",{id:x,placeholder:c,ref:y,value:w.value,onChange:w.onChange,...h,className:Qe(h.className,Ec.input)}),o&&a?Ge(Ns,{color:"primary",className:Ec.icon}):i&&w.filled?Ge(Bu,{disabled:f,onClick:()=>!f&&w.setValue(""),"aria-label":"clear",className:Ec.clearButton,children:Ge(Ps,{color:"primary",className:Ec.icon})}):n]}),l&&Ge("div",{className:Qe(Ec.supportingText),children:Ge(Vs,{variant:"large"===e?"label1":"label2",component:"p",children:l})})]})};Sc.classes=Ec;const Cc={vars:{lsd:(...e)=>`--${["lsd",...e].join("-")}`,typography:(e,t)=>Cc.vars.lsd(e,t),color:(e,t)=>Cc.vars.lsd(e,t),wrap:e=>`var(${e})`},define:(e,t)=>`${e}: ${t};`},Tc=(()=>{const e={};return t=>{const n=t.name;return e[n]&&"undefined"!=typeof window||(e[n]=(e=>{const t=[],n=[],r=fs.map((()=>[])),o=fs.map((()=>[]));ps.forEach((n=>{ms.forEach((r=>{var o;const a=(null==(o=e.typography[n][r])?void 0:o.toString())??"unset";t.push(Cc.define(Cc.vars.typography(n,r),a))}))})),t.push(Cc.define(Cc.vars.lsd("typography","generic-font-family"),e.typographyGlobal.genericFontFamily)),fs.forEach(((t,n)=>{ps.forEach((r=>{ms.forEach((a=>{var i,l,s,u;const c=e.breakpoints[t].typography[r][a],d=n>0?null==(u=null==(s=null==(l=null==(i=e.breakpoints)?void 0:i[fs[n-1]])?void 0:l.typography)?void 0:s[r])?void 0:u[a]:e.typography[r][a];c&&c!==d&&o[n].push(Cc.define(Cc.vars.typography(r,a),c.toString()))}))}))}));{const{primary:n,secondary:r,...o}=e.palette,a=o;t.push(Cc.define(Cc.vars.color("theme","primary"),n),Cc.define(Cc.vars.color("theme","secondary"),r),...Object.keys(a).flatMap((e=>Object.keys(a[e]).map((t=>Cc.define(Cc.vars.color(e,t),a[e][t]))))))}e.spacing.map((e=>{const n=Cc.vars.lsd("spacing",e.toString());t.push(Cc.define(n,`${e}px`))})),fs.map(((t,a)=>{n.push(`@media (min-width: ${e.breakpoints[t].width}px) {\n :root {\n ${o[a].join("\n")}\n }\n\n ${r[a]}\n }`)}));const i=`\n ${t.join("\n")} \n\n ${n.join("\n")}\n `;return{cssVars:i,globalStyles:a.css(":root{",i,";}","")}})(t)),e[n]}})(),Oc={name:"LSD",breakpoints:{xs:{width:0,typography:{display1:{},display2:{},display3:{},display4:{},h1:{},h2:{},h3:{},h4:{},h5:{},h6:{},body1:{},body2:{},body3:{},label1:{},label2:{},subtitle1:{},subtitle2:{},subtitle3:{},subtitle4:{}}},sm:{width:400,typography:{display1:{},display2:{},display3:{},display4:{},h1:{},h2:{},h3:{},h4:{},h5:{},h6:{},body1:{},body2:{},body3:{},label1:{},subtitle4:{},subtitle3:{},label2:{},subtitle1:{},subtitle2:{}}},md:{width:768,typography:{display1:{},display2:{},display3:{},display4:{},h1:{},h2:{},h3:{},h4:{},h5:{},h6:{},body1:{},body2:{},body3:{},label1:{},subtitle4:{},subtitle3:{},label2:{},subtitle1:{},subtitle2:{}}},lg:{width:1024,typography:{display1:{},display2:{},display3:{},display4:{},h1:{},h2:{},h3:{},h4:{},h5:{},h6:{},body1:{},body2:{},body3:{},label1:{},subtitle4:{},subtitle3:{},label2:{},subtitle1:{},subtitle2:{}}},xl:{width:1205,typography:{display1:{},display2:{},display3:{},display4:{},h1:{},h2:{},h3:{},h4:{},h5:{},h6:{},body1:{},body2:{},body3:{},label1:{},subtitle4:{},subtitle3:{},label2:{},subtitle1:{},subtitle2:{}}}},typography:{display1:{fontSize:"5.5rem",fontWeight:"normal",lineHeight:"6rem"},display2:{fontSize:"4rem",fontWeight:"normal",lineHeight:"4.5rem"},display3:{fontSize:"3.5rem",fontWeight:"normal",lineHeight:"4rem"},display4:{fontSize:"3rem",fontWeight:"normal",lineHeight:"3.5rem"},h1:{fontSize:"2.5rem",fontWeight:"normal",lineHeight:"3rem"},h2:{fontSize:"2rem",fontWeight:"normal",lineHeight:"2.5rem"},h3:{fontSize:"1.75rem",fontWeight:"normal",lineHeight:"2.25rem"},h4:{fontSize:"1.5rem",fontWeight:"normal",lineHeight:"2rem"},h5:{fontSize:"1.25rem",fontWeight:"normal",lineHeight:"1.75rem"},h6:{fontSize:"1rem",fontWeight:"normal",lineHeight:"1.5rem"},subtitle1:{fontSize:"1.125rem",fontWeight:"normal",lineHeight:"1.5rem"},subtitle2:{fontSize:"1rem",fontWeight:"normal",lineHeight:"1.5rem"},subtitle3:{fontSize:"0.875rem",fontWeight:"normal",lineHeight:"1.25rem"},subtitle4:{fontSize:"0.75rem",fontWeight:"normal",lineHeight:"1rem"},body1:{fontSize:"1rem",fontWeight:"normal",lineHeight:"1.5rem"},body2:{fontSize:"0.875rem",fontWeight:"normal",lineHeight:"1.25rem"},body3:{fontSize:"0.75rem",fontWeight:"normal",lineHeight:"1rem"},label1:{fontSize:"0.875rem",fontWeight:"normal",lineHeight:"1.25rem"},label2:{fontSize:"0.75rem",fontWeight:"normal",lineHeight:"1rem"}},typographyGlobal:{genericFontFamily:"sans-serif"},palette:{primary:"0, 0, 0",secondary:"255, 255, 255",surface:{primary:"255, 255, 255",secondary:"0, 0, 0"},text:{primary:"0, 0, 0",secondary:"255, 255, 255",tertiary:"0, 0, 0, 0.34"},border:{primary:"0, 0, 0",secondary:"255, 255, 255"},icon:{primary:"0, 0, 0",secondary:"255, 255, 255"}},spacing:[4,8,16,24,32,40,64,80,96,120],globalStyles:a.css("",""),cssVars:""},{cssVars:Dc,globalStyles:Pc}=Tc(Oc);Oc.cssVars=Dc,Oc.globalStyles=Pc;const Nc=dc(),Ac=(e,t)=>ds(ps,(n=>({...t.typography[n],...e.typography[n]??{}}))),Ic=(e,t)=>({...t.typographyGlobal,...e.typographyGlobal}),Lc=(e,t)=>{const n=new Map;return Object.fromEntries(fs.reduce(((r,o,a)=>[...r,{...t.breakpoints[o],...e.breakpoints[o],...ds(["typography"],(o=>((e,t,n,r,o,a)=>"typography"===e?ds(o[e],(i=>{var l,s,u,c,d,f,p,h,m,g,v;const b=`${e}.${i}`,y=!0===a.get(b);return Object.keys((null==(u=null==(s=null==(l=r.breakpoints)?void 0:l[fs[n]])?void 0:s[e])?void 0:u[i])??{}).length>0&&a.set(b,!0),{...o[e][i],...r[e][i],...y?(null==(d=null==(c=null==t?void 0:t[n-1])?void 0:c[e])?void 0:d[i])??{}:null==(h=null==(p=null==(f=o.breakpoints)?void 0:f[fs[n]])?void 0:p[e])?void 0:h[i],...(null==(v=null==(g=null==(m=r.breakpoints)?void 0:m[fs[n]])?void 0:g[e])?void 0:v[i])??{}}})):{})(o,r,a,e,t,n)))}]),[]).map(((e,t)=>[fs[t],e])))},Rc=(e,t)=>{var n,r,o,a,i,l,s,u,c;const d=e.palette.primary??t.palette.primary,f=e.palette.secondary??t.palette.secondary;return{primary:d,secondary:f,surface:{primary:(null==(n=e.palette.surface)?void 0:n.primary)??f,secondary:(null==(r=e.palette.surface)?void 0:r.secondary)??d},border:{primary:(null==(o=e.palette.border)?void 0:o.primary)??d,secondary:(null==(a=e.palette.border)?void 0:a.secondary)??f},icon:{primary:(null==(i=e.palette.icon)?void 0:i.primary)??d,secondary:(null==(l=e.palette.icon)?void 0:l.secondary)??f},text:{primary:(null==(s=e.palette.text)?void 0:s.primary)??d,secondary:(null==(u=e.palette.text)?void 0:u.secondary)??f,tertiary:(null==(c=e.palette.text)?void 0:c.tertiary)??`${d}, 0.34`}}},jc=(e,t=Oc)=>{const n={name:e.name??(r=t.name,`${r}-${Nc()}`),typography:Ac(e,t),typographyGlobal:Ic(e,t),breakpoints:Lc(e,t),palette:Rc(e,t),globalStyles:a.css("",""),cssVars:"",spacing:e.spacing.length?e.spacing:t.spacing};var r;const{cssVars:o,globalStyles:i}=Tc(n);return n.cssVars=o,n.globalStyles=i,n},Mc=jc({name:"Light",breakpoints:{},typography:{},typographyGlobal:{},palette:{},spacing:[]},Oc),Fc={light:Mc,dark:jc({name:"Dark",breakpoints:{},typography:{},typographyGlobal:{},palette:{primary:"255, 255, 255",secondary:"0, 0, 0"},spacing:[]},Mc)},Bc=a.css(".",lu.root,"{box-sizing:border-box;}.",lu.label,"{display:block;}.",lu.inputContainer,"{display:flex;justify-content:space-between;}.",lu.disabled,"{opacity:0.34;}.",lu.input,"{border:none;outline:none;font-size:14px;color:rgb(var(--lsd-text-primary));background:none;width:100%;}.",lu.input,":hover{outline:none;}.",lu.input,"::placeholder{color:rgb(var(--lsd-text-primary));opacity:0.3;}.",lu.icon,"{cursor:pointer;display:flex;align-items:center;}.",lu.error,"{text-decoration:line-through;}.",lu.large,"{width:208px;.",lu.label,"{margin:0 0 6px 18px;}.",lu.inputContainer,"{height:40px;}.",lu.input,"{padding:9px 17px;}.",lu.icon,"{padding:12px 13px;}}.",lu.medium,"{width:188px;.",lu.label,"{margin:0 0 6px 14px;}.",lu.inputContainer,"{height:32px;}.",lu.input,"{padding:5px 13px;}.",lu.icon,"{padding:8px 11px;}}.",lu.small,"{width:164px;.",lu.label,"{margin:0 0 6px 12px;}.",lu.inputContainer,"{height:28px;}.",lu.input,"{padding:5px 11px;}.",lu.icon,"{padding:6px 9px;}}.",lu.withIcon,"{}.",lu.outlined," .",lu.inputContainer,"{border:1px solid rgb(var(--lsd-border-primary));}.",lu.underlined," .",lu.inputContainer,"{border:1px solid transparent;border-bottom:1px solid rgb(var(--lsd-border-primary));}.",lu.dropdownItemPlaceholder,"{opacity:0.5;white-space:pre;}",""),zc=a.css(".",uu.root,"{width:fit-content;box-sizing:border-box;display:flex;flex-direction:row;align-items:center;justify-content:center;border:1px solid rgb(var(--lsd-icon-primary));border-radius:20px;&:hover,&:focus{text-decoration:underline;cursor:pointer;}}.",uu.large,"{padding:3px 11px;gap:12px;height:28px;}.",uu.small,"{padding:3px 7px;gap:8px;height:24px;}.",uu.filled,"{background-color:rgb(var(--lsd-icon-primary));.",uu.label,"{color:rgb(var(--lsd-text-secondary));}svg{--lsd-icon-primary:var(--lsd-icon-secondary);}}.",uu.outlined,"{color:rgb(var(--lsd-text-primary));}.",uu.disabled,"{opacity:0.3;cursor:initial;pointer-events:none;}",""),$c=a.css(".",pu.root,"{}.",pu.list,"{display:flex;flex-direction:row;align-items:center;list-style-type:none;margin:0;padding:0;}.",pu.disabled,"{.",pu.list,"{opacity:0.34;cursor:initial;pointer-events:none;}}.",pu.listBox,"{display:flex;flex-direction:column;overflow:auto;border:1px solid rgb(var(--lsd-border-primary));margin-top:10px;position:absolute;width:auto!important;}.",pu.listBox,">li{cursor:pointer;&:not(:last-child){border-bottom:1px solid rgb(var(--lsd-border-primary));}&:hover,&:focus{text-decoration:underline;text-decoration-color:rgb(var(--lsd-border-primary));}}.",pu.listBox," li>a{width:164px;padding:5px 11px;}",""),Uc=a.css(".",du.root,"{list-style-type:none;display:flex;align-items:center;}.",pu.list,">li:not(:last-child)::after{display:inline-block;margin-inline:12px;content:'/';}.",du.itemLink,"{text-decoration:none;cursor:pointer;}.",du.outlined,"{padding:3px 11px;border:1px solid rgb(var(--lsd-border-primary));}",du.large,"{}",du.small,"{}.",pu.root,":not(.",pu.disabled,"){.",du.itemLink,"{&:hover,&:focus{text-decoration:underline;text-decoration-color:rgb(var(--lsd-border-primary));}}}",""),Hc=a.css(".",gu.root,"{width:auto;cursor:pointer;padding:6px 24px;}.",gu.disabled,"{cursor:default;opacity:0.34;}.",gu.large,"{padding:10px 40px;}.",gu.medium,"{padding:6px 24px;}.",gu.small,"{padding:6px 12px;}.",gu.root,":hover{&:not(.",gu.disabled,"){.",gu.text,"{text-decoration:underline;}}}.",gu.withIcon,"{display:flex;align-items:center;}.",gu.icon,"{display:flex;justify-content:center;align-items:center;height:100%;}.",gu.large,".",gu.withIcon,"{padding:10px 0px 10px 18px;.",gu.icon,"{width:42px;}}.",gu.medium,".",gu.withIcon,"{padding:6px 0px 6px 14px;.",gu.icon,"{width:38px;}}.",gu.small,".",gu.withIcon,"{padding:6px 0px 6px 12px;.",gu.icon,"{width:34px;}}.",gu.outlined,"{background:none;border:1px solid rgb(var(--lsd-border-primary));.",gu.text,"{color:rgb(var(--lsd-text-primary));}}.",gu.filled,"{background:rgb(var(--lsd-surface-secondary));border:1px solid rgb(var(--lsd-border-primary));.",gu.text,"{color:rgb(var(--lsd-text-secondary));}}",""),Vc={root:"lsd-calendar",container:"lsd-calendar-container",small:"lsd-calendar--small",medium:"lsd-calendar--medium",large:"lsd-calendar--large",open:"lsd-calendar--open",disabled:"lsd-calendar--disabled",header:"lsd-calendar-header",weekDay:"lsd-calendar__week_day",button:"lsd-calendar__button",changeYear:"lsd-calendar__change-year",changeYearActive:"lsd-calendar__change-year--active",changeYearIconContainer:"lsd-calendar__change-year-icon-container",year:"lsd-calendar-year",month:"lsd-calendar-month",day:"lsd-calendar-day",yearAndIcon:"lsd-calendar__year-and-icon",monthAndYear:"lsd-calendar__month-and-year",dayContainer:"lsd-calendar-day__container",dayRange:"lsd-calendar-day--range",daySelected:"lsd-calendar-day--selected",dayDisabled:"lsd-calendar-day--disabled",dayIsToday:"lsd-calendar-day--today",dayBorderLeft:"lsd-calendar-day--border-left",dayBorderRight:"lsd-calendar-day--border-right",dayBorderLeftAndRight:"lsd-calendar-day--border-left-and-right",dayBorderTopAndBottom:"lsd-calendar-day--border-top-and-bottom",todayIndicator:"lsd-calendar-day__today_indicator",monthTable:"lsd-calendar__month-table",nextMonthButton:"lsd-calendar__next-month-button",previousMonthButton:"lsd-calendar__previous-month-button",yearDropdown:"lsd-calendar__year-dropdown",yearDropdownHidden:"lsd-calendar__year-dropdown--hidden"},qc=a.css(".",Vc.root,"{border:1px solid rgb(var(--lsd-border-primary));visibility:hidden;position:absolute!important;top:0;left:0;opacity:0;visibility:hidden;margin:0;padding:0;box-sizing:border-box;background:rgb(var(--lsd-surface-primary));user-select:none;}.",Vc.container,"{display:flex;flex-direction:column;padding:8px;}.",Vc.open,"{opacity:1;visibility:visible;}.",Vc.header,"{display:flex;justify-content:center;align-items:center;height:32px;margin-bottom:8px;}.",Vc.weekDay,"{display:flex;justify-content:center;align-items:center;aspect-ratio:1/1;margin-bottom:4px;}.",Vc.changeYear,"{position:relative;display:flex;justify-content:center;align-items:center;padding:2px 0xp 2px 8px;gap:6px;border:1px solid transparent;}.",Vc.changeYearActive,"{.",Vc.yearAndIcon,"{border:1px solid rgb(var(--lsd-border-primary));}}.",Vc.changeYearIconContainer,"{display:flex;justify-content:center;align-items:center;cursor:pointer;border:none;}.",Vc.month,"{margin-right:8px;}.",Vc.monthAndYear,"{display:flex;align-items:center;justify-content:center;}.",Vc.dayContainer,"{cursor:pointer;background:transparent;position:relative;box-sizing:border-box;border:1px solid transparent;}.",Vc.day,"{aspect-ratio:1/1;display:flex;justify-content:center;align-items:center;}.",Vc.day,":hover{cursor:pointer;text-decoration:underline;text-decoration-color:rgb(var(--lsd-border-primary));}.",Vc.day," label:hover{cursor:pointer;}.",Vc.daySelected,"{border:1px solid rgb(var(--lsd-border-primary));}.",Vc.dayDisabled,"{opacity:0.3;cursor:default;}.",Vc.todayIndicator,"{position:absolute;left:50%;transform:translateX(-50%);bottom:2px;}.",Vc.disabled,"{pointer-events:none;border:1px solid rgba(var(--lsd-border-primary), 0.3);label{opacity:0.3;}.",Vc.button,"{opacity:0.3;}.",Vc.daySelected,"{opacity:0.3;}}.",Vc.button,"{border:1px solid rgb(var(--lsd-border-primary));cursor:pointer;background:transparent;width:32px;height:32px;display:flex;align-items:center;justify-content:center;position:absolute;}.",Vc.nextMonthButton,"{top:8px;right:8px;}.",Vc.previousMonthButton,"{top:8px;left:8px;}.",Vc.dayBorderLeft,"{border-left:1px double rgb(var(--lsd-border-primary));}.",Vc.dayBorderRight,"{border-right:1px double rgb(var(--lsd-border-primary));}.",Vc.dayBorderLeftAndRight,"{border-left:1px double rgb(var(--lsd-border-primary));border-right:1px double rgb(var(--lsd-border-primary));}.",Vc.dayBorderTopAndBottom,"{border-top:1px double rgb(var(--lsd-border-primary));border-bottom:1px double rgb(var(--lsd-border-primary));}.",Vc.monthTable,"{border-collapse:collapse;}.",Vc.yearDropdown,"{box-sizing:border-box;position:absolute;top:100%;left:0;max-height:200px;overflow-y:auto;width:100%;border:1px solid rgb(var(--lsd-border-primary));border-top:none;z-index:1;.",Vc.year,"{border-bottom:1px solid rgb(var(--lsd-border-primary));}}.",Vc.yearDropdownHidden,"{visibility:hidden;}.",Vc.year,"{display:flex;cursor:pointer;transition:background-color 0.2s;align-items:center;background:rgb(var(--lsd-surface-primary));:hover{text-decoration:underline;}}.",Vc.yearAndIcon,"{border:1px solid rgb(var(--lsd-border-primary));}.",Vc.large,"{.",Vc.year,"{padding:6px 0px 6px 14px;}.",Vc.changeYearIconContainer,"{width:32px;}}.",Vc.medium,"{.",Vc.year,"{padding:6px 0px 6px 12px;}.",Vc.changeYearIconContainer,"{width:28px;}}.",Vc.small,"{.",Vc.year,"{padding:6px 0px 6px 12px;}.",Vc.changeYearIconContainer,"{width:28px;}}",""),Gc=a.css(".",bu.root,"{box-sizing:border-box;display:flex;flex-direction:column;}.",bu.root,">.",ku.root,"{margin-bottom:-1px;}.",bu.large,"{}.",bu.medium,"{}.",bu.small,"{}",""),Wc=a.css(".",xu.root,"{box-sizing:border-box;padding:14px 22px;border:1px solid rgb(var(--lsd-border-primary));}",""),Zc=a.css(".",ku.root,"{box-sizing:border-box;padding:10px 18px;text-align:center;border:1px solid rgb(var(--lsd-border-primary));}.",ku.title,"{overflow:hidden;word-break:break-all;}.",ku.large,"{padding:10px 18px;}.",ku.medium,"{padding:6px 14px;}.",ku.small,"{padding:6px 12px;}",""),Qc=a.css(".",Tu.root,"{position:relative;display:flex;flex-direction:row;align-items:center;}.",Tu.input,"{opacity:0;position:absolute;left:0;top:0;padding:0;margin:0;width:100%;height:100%;}.",Tu.root,":not(.",Tu.disabled,"){&:hover,&.",Tu.focused,"{text-decoration:underline;}.",Tu.input,"{cursor:pointer;}}.",Tu.disabled,"{opacity:0.34;}.",Tu.label,"{margin-left:18px;}.",Tu.large,"{.",Tu.label,"{margin-left:18px;}}.",Tu.medium,"{.",Tu.label,"{margin-left:14px;}}.",Tu.small,"{.",Tu.label,"{margin-left:12px;}}",""),Yc=a.css(".",Du.root,"{display:flex;flex-direction:column;gap:6px;width:fit-content;}.",Du.label,"{margin-bottom:6px;}",""),Xc=a.css(".",Iu.root,"{box-sizing:border-box;display:flex;flex-direction:column;}.",Iu.open,"{.",Iu.content,"{border-top:1px solid transparent;}}.",Iu.content,"{border:1px solid rgb(var(--lsd-border-primary));}",""),Kc=a.css(".",Nu.root,"{box-sizing:border-box;}.",Nu.root,":not(.",Nu.disabled,"){.",Nu.trigger,"{&:hover{.",Nu.label,"{text-decoration:underline;}}}}.",Nu.trigger,"{width:100%;display:flex;flex-direction:row;align-items:center;justify-content:space-between;cursor:pointer;background:none;border:1px solid rgb(var(--lsd-border-primary));&:focus{outline:none;}}.",Nu.label,"{cursor:inherit;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;margin:auto;}.",Nu.icons,"{display:flex;flex-direction:row;align-items:center;justify-content:flex-end;}.",Nu.icon,"{margin-right:8px;}.",Nu.menuIcon,"{}.",Nu.disabled,"{.",Nu.trigger,"{opacity:0.34;cursor:initial;}}.",Nu.large,"{.",Nu.trigger,"{width:299px;height:40px;padding:9px 17px;}}.",Nu.medium,"{.",Nu.trigger,"{width:270px;height:32px;padding:5px 13px;}}.",Nu.small,"{.",Nu.trigger,"{width:235px;height:28px;padding:5px 11px;}}",""),Jc={root:"lsd-date-field",label:"lsd-date-field__label",inputContainer:"lsd-date-field__input-container",input:"lsd-date-field__input-container__input",inputFilled:"lsd-date-field__input-container__input--filled",icon:"lsd-date-field__input-container__icon",noIcon:"lsd-date-field__input-container__no-icon",iconButton:"lsd-date-field__input-container__icon-button",supportingText:"lsd-date-field__supporting-text",disabled:"lsd-date-field--disabled",error:"lsd-date-field--error",large:"lsd-date-field--large",medium:"lsd-date-field--medium",small:"lsd-date-field--small",outlined:"lsd-date-field--outlined",underlined:"lsd-date-field--underlined"},ed=a.css(".",Jc.root,"{width:auto;box-sizing:border-box;}.",Jc.label,"{display:block;}.",Jc.icon,"{position:absolute;right:0;cursor:pointer;display:flex;align-items:center;background-color:rgb(var(--lsd-surface-primary));}.",Jc.icon,":focus{background:blue;background-color:pink;border:1px solid rgb(var(--lsd-border-primary));}.",Jc.noIcon,"{position:absolute;right:0;background-color:rgb(var(--lsd-surface-primary));padding:12px;}.",Jc.outlined,"{border:1px solid rgb(var(--lsd-border-primary));}.",Jc.underlined,"{border-bottom:1px solid rgb(var(--lsd-border-primary));}.",Jc.inputContainer,"{position:relative;display:flex;align-items:center;justify-content:space-between;}.",Jc.disabled,"{opacity:0.34;}.",Jc.input,"{border:none;outline:none;font-size:14px;color:rgb(var(--lsd-text-primary));background:none;width:100%;opacity:0.4;transition:opacity 0.2s ease-in-out;}.",Jc.input,"::-webkit-inner-spin-button,.",Jc.input,"::-webkit-calendar-picker-indicator{display:none;-webkit-appearance:none;}.",Jc.input,":hover{outline:none;}.",Jc.supportingText,"{position:absolute;}.",Jc.large,"{width:208px;.",Jc.label,"{margin:0 0 6px 18px;}.",Jc.inputContainer,"{height:40px;}.",Jc.input,"{padding:9px 0px 9px 17px;}.",Jc.icon,"{padding:12px 13px;}.",Jc.supportingText,"{margin:6px 18px 0 18px;}}.",Jc.medium,"{width:188px;.",Jc.label,"{margin:0 0 6px 14px;}.",Jc.inputContainer,"{height:32px;}.",Jc.input,"{padding:5px 11px 5px 13px;}.",Jc.icon,"{padding:8px 11px;}.",Jc.supportingText,"{margin:6px 14px 0 14px;}}.",Jc.small,"{width:164px;.",Jc.label,"{margin:0 0 6px 12px;}.",Jc.inputContainer,"{height:28px;}.",Jc.input,"{padding:5px 9px 5px 11px;font-size:12px;}.",Jc.icon,"{padding:6px 9px;}.",Jc.supportingText,"{margin:6px 12px 0 12px;}}.",Jc.input,":invalid,.",Jc.inputFilled,"{color:rgb(var(--lsd-border-primary));opacity:1;}.",Jc.error," .",Jc.input,"::-webkit-datetime-edit-year-field,.",Jc.error," .",Jc.input,"::-webkit-datetime-edit-month-field,.",Jc.error," .",Jc.input,"::-webkit-datetime-edit-day-field{text-decoration:line-through;}@supports not selector(::-webkit-datetime-edit-day-field){.",Jc.error," .",Jc.input,"{text-decoration:line-through;}}",""),td={root:"lsd-date-picker",calendar:"lsd-date-picker__calendar",large:"lsd-date-picker--large",medium:"lsd-date-picker--medium",small:"lsd-date-picker--small"},nd=a.css(".",td.root,"{width:fit-content;}.",td.calendar,"{border-top:none!important;}.",td.large,"{.",Jc.large,"{width:318px;}}.",td.medium,"{.",Jc.medium,"{width:290px;}}.",td.small,"{.",Jc.small,"{width:262px;}}",""),rd=a.css(".",Ru.root,"{}.",Ru.root,":not(.",Ru.disabled,"):not(\n .",Ru.error,"\n ){.",Ru.trigger,"{&:hover,&:focus{.",Ru.optionLabel,"{text-decoration:underline;}}}}.",Ru.label,"{display:block;}.",Ru.buttonContainer,"{display:flex;justify-content:space-between;}.",Ru.trigger,"{width:100%;display:flex;flex-direction:row;align-items:center;justify-content:space-between;border:none;cursor:pointer;background:none;&:focus{outline:none;}}.",Ru.optionLabel,"{cursor:inherit;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;}.",Ru.icons,"{display:flex;flex-direction:row;align-items:center;justify-content:center;gap:8px;}.",Ru.icon,"{display:flex;align-items:center;}.",Ru.menuIcon,"{}.",Ru.supportingText,"{margin:6px 14px;}.",Ru.error,"{.",Ru.optionLabel,"{text-decoration:line-through;}}.",Ru.disabled,"{opacity:0.34;cursor:initial;}.",Ru.large,"{width:208px;&.",Ru.error,"{width:230px;}.",Ru.label,"{margin:0 0 6px 18px;}.",Ru.buttonContainer,"{height:40px;}.",Ru.trigger,"{padding:10px 0px 10px 18px;}.",Ru.icons,"{padding:0px 14px;}}.",Ru.medium,"{width:188px;&.",Ru.error,"{width:210px;}.",Ru.label,"{margin:0 0 6px 14px;}.",Ru.buttonContainer,"{height:32px;}.",Ru.trigger,"{padding:6px 0px 6px 14px;}.",Ru.icons,"{padding:0px 12px;}}.",Ru.small,"{width:164px;&.",Ru.error,"{width:186px;}.",Ru.label,"{margin:0 0 6px 12px;}.",Ru.buttonContainer,"{height:28px;}.",Ru.trigger,"{padding:6px 0px 6px 12px;}.",Ru.icons,"{padding:0px 10px;}}.",Ru.outlined,"{.",Ru.buttonContainer,"{border:1px solid rgb(var(--lsd-border-primary));}}.",Ru.underlined,"{.",Ru.buttonContainer,"{border:1px solid transparent;border-bottom:1px solid rgb(var(--lsd-border-primary));}}",""),od=a.css(".",qs.root,"{width:100%;box-sizing:border-box;display:flex;flex-direction:row;align-items:center;border:1px solid rgb(var(--lsd-border-primary));:not(.",qs.disabled,"){cursor:pointer;&:hover,&:focus{outline:none;.",qs.label,"{text-decoration:underline;}}}}.",qs.label,"{display:block;overflow:hidden;white-space:nowrap;text-overflow:ellipsis;}.",qs.disabled,"{opacity:0.34;}.",qs.icon,"{margin-right:18px;flex-shrink:0;}.",qs.small,"{padding:5px 9px;height:28px;}.",qs.medium,"{padding:5px 11px;height:32px;}.",qs.large,"{padding:5px 13px;height:40px;}",""),ad=a.css(".",Fu.root,"{display:flex;flex-direction:row;align-items:center;justify-content:center;cursor:pointer;background:none;padding:0;border:1px solid rgb(var(--lsd-border-primary));}.",Fu.filled,"{background-color:rgb(var(--lsd-icon-primary));svg{--lsd-icon-primary:var(--lsd-icon-secondary);}}.",Fu.outlined,"{}.",Fu.disabled,"{opacity:0.34;cursor:default;}.",Fu.large,"{width:40px;height:40px;}.",Fu.medium,"{width:32px;height:32px;}.",Fu.small,"{width:28px;height:28px;}",""),id=a.css(".",zu.root,"{display:flex;flex-direction:row;}.",zu.outlined," .",Fu.root,":not(:last-child){border-right:none;}",""),ld=a.css(".",xs.root,"{}.",xs.primary,"{&.",xs.filled,"{&,*{fill:rgb(var(--lsd-icon-primary));}}$.",xs.stroked,"{&,*{fill:rgb(var(--lsd-icon-primary));}}}.",xs.secondary,"{&.",xs.filled,"{&,*{fill:rgb(var(--lsd-icon-secondary));}}$.",xs.stroked,"{&,*{fill:rgb(var(--lsd-icon-secondary));}}}",""),sd=a.css(".",tu.root,"{position:absolute;top:0;left:0;opacity:0;visibility:hidden;margin:0;padding:0;box-sizing:border-box;background:rgb(var(--lsd-surface-primary));overflow:auto;border:1px solid rgb(var(--lsd-border-primary));border-top:0;}.",tu.root,">div{border:0;&:not(:last-child){border-bottom:1px solid rgb(var(--lsd-border-primary));}}.",tu.open,"{opacity:1;visibility:visible;}.",tu.large,"{max-height:220px;}.",tu.medium,"{max-height:176px;}.",tu.small,"{max-height:154px;}",""),ud=a.css(".",Uu.root,"{color:rgb(var(--lsd-text-primary));white-space:pre-wrap;}.",Uu.indentedInline,"{border-left:1px solid rgb(var(--lsd-border-primary));padding:4px 8px 4px 28px;}.",Uu.parentheses,"{padding:0px;text-align:center;}.",Uu.parentheses,"::before{content:'***';}.",Uu.parentheses,"::after{content:'***';}",""),cd=a.css(".",qu.root,"{position:relative;display:flex;flex-direction:row;align-items:center;}.",qu.input,"{opacity:0;position:absolute;left:0;top:0;padding:0;margin:0;width:100%;height:100%;}.",qu.root,":not(.",qu.disabled,"){&:hover{text-decoration:underline;}.",qu.input,"{cursor:pointer;}}.",qu.disabled,"{opacity:0.34;}.",qu.label,"{margin-left:18px;}.",qu.large,"{.",qu.label,"{margin-left:18px;}}.",qu.medium,"{.",qu.label,"{margin-left:14px;}}.",qu.small,"{.",qu.label,"{margin-left:12px;}}",""),dd=a.css(".",Wu.root,"{display:flex;flex-direction:column;gap:6px;width:fit-content;}.",Wu.label,"{margin-bottom:6px;}",""),fd=a.css(".",Yu.root,"{background:rgb(var(--lsd-surface-primary));border:1px solid transparent;cursor:pointer;display:flex;flex-direction:row;align-items:center;justify-content:center;box-sizing:border-box;&:hover{text-decoration:underline;}&:not(",Yu.selected,"){border-bottom:1px solid rgb(var(--lsd-border-primary));}}.",Yu.text,"{overflow:hidden;white-space:nowrap;text-overflow:ellipsis;}.",Yu.icon,"{margin-left:14px;}.",Yu.selected,"{border:1px solid rgb(var(--lsd-border-primary));&:hover{text-decoration:none;}}.",Yu.withIcon,"{justify-content:space-between;}.",Yu.disabled,"{cursor:default;opacity:0.34;&:hover{text-decoration:none;}}.",Yu.small,"{padding:6px 12px;.",Yu.icon,"{margin-left:10px;}}.",Yu.medium,"{padding:6px 14px;.",Yu.icon,"{margin-left:12px;}}.",Yu.large,"{padding:10px 18px;.",Yu.icon,"{margin-left:14px;}}",""),pd=a.css(".",nc.root,"{box-sizing:border-box;display:flex;flex-direction:column;}.",nc.root,">.",ec.root,"{margin-bottom:-1px;}.",nc.large,"{}.",nc.medium,"{}.",nc.small,"{}",""),hd=a.css(".",Ku.root,"{table{border-collapse:collapse;text-align:center;table-layout:fixed;width:100%;height:auto;}table tr:first-of-type td label:has(input[type='radio']){display:none;}}.",Ku.toolbar,"{box-sizing:border-box;padding:10px;border:1px solid rgb(var(--lsd-border-primary));border-bottom:none;display:flex;justify-content:space-between;}",""),md=a.css(".",ec.root,"{box-sizing:border-box;border:1px solid rgb(var(--lsd-border-primary));}",""),gd=a.css(".",ic.root,"{border:1px solid rgb(var(--lsd-border-primary));}.",ic.root,":has(> label){width:40px;input{position:relative;width:14px;height:14px;margin:auto;}span{margin-left:14px!important;}}.",ic.large,"{padding:10px;}.",ic.medium,"{padding:6px 8px;}.",ic.small,"{padding:6px;}",""),vd=a.css(".",sc.root,"{align-items:center;}",""),bd=a.css(".",vc.root,"{display:flex;flex-direction:row;overflow:auto;width:fit-content;max-width:100%;border-bottom:1px solid rgb(var(--lsd-border-primary));&>*{flex-shrink:0;}.",Yu.root,"{border-bottom:none;}}.",vc.fullWidth,"{width:100%;justify-content:stretch;&>*{width:100%;flex:1 0;}}.",vc.root,"{-ms-overflow-style:none;scrollbar-width:none;&::-webkit-scrollbar{display:none;}}.",vc.leftScrollControl,"{left:0;}.",vc.rightScrollControl,"{right:0;}.",vc.rightScrollControl,",.",vc.leftScrollControl,"{top:0;flex:0 1;position:sticky;}",""),yd=a.css(".",yc.root,"{width:fit-content;display:flex;flex-direction:row;align-items:center;justify-content:center;box-sizing:border-box;border:1px solid rgb(var(--lsd-icon-primary));&:hover,&:focus{text-decoration:underline;cursor:pointer;}}.",yc.large,"{padding:3px 11px;gap:12px;height:28px;}.",yc.small,"{padding:3px 7px;gap:8px;height:24px;}.",yc.filled,"{background-color:rgb(var(--lsd-icon-primary));.",yc.label,"{color:rgb(var(--lsd-text-secondary));}svg{--lsd-icon-primary:var(--lsd-icon-secondary);}}.",yc.outlined,"{color:rgb(var(--lsd-text-primary));}.",yc.disabled,"{opacity:0.3;cursor:initial;pointer-events:none;}",""),wd=a.css(".",Ec.root,"{box-sizing:border-box;display:flex;flex-direction:column;}.",Ec.inputContainer,"{display:flex;align-items:center;justify-content:space-between;}.",Ec.disabled,"{opacity:0.34;}.",Ec.input,"{border:none;outline:none;font-size:14px;color:rgb(var(--lsd-text-primary));background:none;width:100%;}.",Ec.input,":hover{outline:none;}.",Ec.input,"::placeholder{color:rgb(var(--lsd-text-primary));opacity:0.3;}.",Ec.error," .",Ec.input,"{text-decoration:line-through;}.",Ec.supportingText,"{width:fit-content;}.",Ec.large,"{width:208px;&>*{padding:10px 14px 10px 18px;}}.",Ec.medium,"{width:188px;&>*{padding:6px 12px 6px 14px;}}.",Ec.small,"{width:164px;&>*{padding:6px 10px 6px 12px;}}.",Ec.label,"{padding-top:0;padding-bottom:6px;}.",Ec.supportingText,"{padding-bottom:0;padding-top:6px;}.",Ec.outlined," .",Ec.inputContainer,"{border:1px solid rgb(var(--lsd-border-primary));}.",Ec.underlined," .",Ec.inputContainer,"{border:1px solid transparent;border-bottom:1px solid rgb(var(--lsd-border-primary));}.",Ec.clearButton,"{padding:0;width:auto;height:auto;margin:0;border:0;}.",Ec.icon,"{}",""),xd=a.css("body *{font-family:var(--lsd-typography-generic-font-family);}.",gs.root,"{color:rgb(var(--lsd-text-primary));}.",gs.sansSerif,"{&,*{font-family:sans-serif;}}.",gs.serif,"{&,*{font-family:serif;}}.",gs.monospace,"{&,*{font-family:monospace;}}",ps.map((e=>a.css((e=>[...hs[e]??[],`.${gs[e]}`].join(", "))(e),"{color:rgb(var(--lsd-text-primary));font-weight:var(--lsd-",e,"-fontWeight);font-size:var(--lsd-",e,"-fontSize);line-height:var(--lsd-",e,"-lineHeight);}","")))," .",gs.primary,"{color:rgb(var(--lsd-text-primary));}.",gs.secondary,"{color:rgb(var(--lsd-text-secondary));}input{color:rgb(var(--lsd-text-primary));font-size:var(--lsd-body1-fontSize);font-weight:var(--lsd-body1-fontWeight);}h1,h2,h3,h4,h5,h6,p,span{margin:0;}",""),_d={root:"lsd-number-input",label:"lsd-number-input__label",mainContainer:"lsd-number-input__main-container",inputContainer:"lsd-number-input__input-container",input:"lsd-number-input__input",errorIcon:"lsd-number-input__error-icon",plusMinusIcons:"lsd-number-input__plus-minus-icons",supportingText:"lsd-number-input__supporting-text",disabled:"lsd-number-input--disabled",error:"lsd-number-input--error",large:"lsd-number-input--large",medium:"lsd-number-input--medium",small:"lsd-number-input--small"},kd={root:"lsd-modal",small:"lsd-modal--small",medium:"lsd-modal--medium",large:"lsd-modal--large",xsmall:"lsd-modal--extra-small",modalContainer:"lsd-modal__container",header:"lsd-modal__header",title:"lsd-modal__title",subtitle:"lsd-modal__subtitle",titleAndSubtitleContainer:"lsd-modal__title-and-subtitle-container",closeIcon:"lsd-modal__close-icon"},Ed={root:"lsd-modal-footer"},Sd={root:"lsd-modal-body"},Cd={root:"lsd-toast",inlineContainer:"lsd-toast__inline-container",columnContainer:"lsd-toast__column-container",large:"lsd-toast--large",medium:"lsd-toast--medium",small:"lsd-toast--small",icon:"lsd-toast__icon",textContainer:"lsd-toast__text-container",columnIconContainer:"lsd-toast__column-icon-container",inlineIconContainer:"lsd-toast__inline-icon-container",title:"lsd-toast__title",information:"lsd-toast__information",inlineButtonContainer:"lsd-toast__inline-button-container",columnButtonContainer:"lsd-toast__column-button-container",buttonContainer:"lsd-toast__button-container",closeButton:"lsd-toast__close-button"},Td={toastContainer:"lsd-toast-provider__toast-container",topLeft:"lsd-toast-provider__toast--top-left",topCenter:"lsd-toast-provider__toast--top-center",topRight:"lsd-toast-provider__toast--top-right",bottomLeft:"lsd-toast-provider__toast--bottom-left",bottomCenter:"lsd-toast-provider__toast--bottom-center",bottomRight:"lsd-toast-provider__toast--bottom-right"},Od={root:"lsd-button-group",outlined:"lsd-button-group--outlined",filled:"lsd-button-group--filled",disabled:"lsd-button-group--disabled",small:"lsd-button-group--small",medium:"lsd-button-group--medium",large:"lsd-button-group--large"},Dd={root:"lsd-date-range-picker",calendar:"lsd-date-picker__calendar",withCalendar:"lsd-date-range-picker--with-calendar",openCalendar:"lsd-date-range-picker--calendar-open",disabled:"lsd-date-range-picker--disabled",inputContainer:"lsd-date-range-picker__input-container",icon:"lsd-date-range-picker__icon",large:"lsd-date-range-picker--large",medium:"lsd-date-range-picker--medium",small:"lsd-date-range-picker--small",label:"lsd-date-range-picker__label",supportingText:"lsd-date-range-picker__supporting-text",outlined:"lsd-date-range-picker--outlined",separator:"lsd-date-range-picker__separator"},Pd={root:"lsd-tooltip-base",arrowTip:"lsd-tooltip-base__arrow-tip",content:"lsd-tooltip-base__content"},Nd=[Hc,ad,id,xd,ld,fd,bd,sd,rd,od,$c,Uc,Gc,Zc,Wc,yd,wd,Qc,Bc,ud,Xc,Kc,Yc,zc,cd,dd,pd,md,hd,gd,vd,a.css(".",_d.root,"{width:auto;box-sizing:border-box;}.",_d.mainContainer,":hover{text-decoration:underline;}.",_d.error,"{.",_d.mainContainer,"{text-decoration:line-through;}}.",_d.label,"{display:block;}.",_d.plusMinusIcons,"{display:flex;flex-shrink:0;}.",_d.inputContainer,"{box-sizing:border-box;border:1px solid rgb(var(--lsd-border-primary));border-left:0px;border-right:0px;}.",_d.errorIcon,"{cursor:pointer;display:flex;align-items:center;padding:10px 8px;}.",_d.inputContainer,"{display:flex;align-items:center;justify-content:space-between;}.",_d.disabled,"{opacity:0.34;}.",_d.mainContainer,"{display:flex;align-items:center;}.",_d.input,"{border:none;outline:none;font-size:14px;color:rgb(var(--lsd-text-primary));background:none;text-align:center;padding:0 4px;}.",_d.input,"::-webkit-inner-spin-button{display:none;-webkit-appearance:none;}.",_d.input,":hover{outline:none;}.",_d.supportingText,"{position:absolute;}.",_d.large,"{.",_d.label,"{margin:0 0 6px 18px;}.",_d.inputContainer,"{height:40px;}.",_d.input,"{width:62px;}.",_d.plusMinusIcons,"{height:40px;width:40px;}.",_d.supportingText,"{margin:6px 18px 0 18px;}}.",_d.medium,"{.",_d.label,"{margin:0 0 6px 14px;}.",_d.inputContainer,"{height:32px;}.",_d.input,"{width:58px;}.",_d.plusMinusIcons,"{height:32px;width:32px;}.",_d.supportingText,"{margin:6px 14px 0 14px;}}.",_d.small,"{.",_d.label,"{margin:0 0 6px 12px;}.",_d.inputContainer,"{height:28px;}.",_d.input,"{width:50px;}.",_d.plusMinusIcons,"{height:28px;width:28px;}.",_d.supportingText,"{margin:6px 12px 0 12px;}}",""),a.css(".",kd.root,"{box-sizing:border-box;display:flex;flex-direction:column;position:fixed;top:0;left:0;right:0;bottom:0;background-color:rgba(0, 0, 0, 0.5);display:flex;justify-content:center;align-items:center;z-index:9999;}.",kd.modalContainer,"{position:relative;background:rgb(var(--lsd-surface-primary));padding:20px;max-width:90%;box-sizing:border-box;border:1px solid rgb(var(--lsd-border-primary));}.",kd.header,"{display:flex;justify-content:space-between;align-items:center;}.",kd.title,"{}.",kd.subtitle,"{}.",kd.closeIcon,"{position:absolute;top:8px;right:8px;cursor:pointer;}.",kd.titleAndSubtitleContainer,"{display:flex;flex-direction:column;}.",kd.large,"{.",kd.modalContainer,"{min-width:960px;}}.",kd.medium,"{.",kd.modalContainer,"{min-width:768px;}}.",kd.small,"{.",kd.modalContainer,"{min-width:614px;}}.",kd.xsmall,"{.",kd.modalContainer,"{min-width:490px;}}",""),a.css(".",Ed.root,"{display:flex;}",""),a.css(".",Sd.root,"{margin:18px 0;}",""),nd,ed,qc,a.css(".",Cd.root,"{box-sizing:border-box;display:inline-flex;align-items:center;background:rgb(var(--lsd-surface-primary));border:1px solid rgb(var(--lsd-border-primary));padding:8px;height:fit-content;}.",Cd.inlineButtonContainer,"{flex-shrink:0;}.",Cd.columnButtonContainer,"{margin-top:18px;margin-bottom:6px;}.",Cd.inlineContainer,"{display:flex;align-items:center;justify-content:space-between;flex-grow:1;}.",Cd.columnContainer,"{display:flex;flex-direction:column;justify-content:space-between;}.",Cd.textContainer,"{display:flex;flex-direction:column;color:rgb(var(--lsd-text-secondary));padding-left:12px;}.",Cd.title,"{position:relative;}.",Cd.information,"{margin-top:4px;}.",Cd.buttonContainer,"{min-height:28px;min-width:60px;width:fit-content;padding:0px 12px;}.",Cd.closeButton,"{margin-bottom:auto;flex-shrink:0;height:28px;width:28px;margin-left:auto;}.",Cd.columnIconContainer,"{display:flex;justify-content:center;margin-bottom:auto;position:relative;top:4px;padding-left:4px;}.",Cd.inlineIconContainer,"{display:flex;align-items:center;justify-content:center;padding-left:4px;}.",Cd.icon,"{position:relative;}.",Cd.large,"{width:364px;}.",Cd.medium,"{width:336px;}.",Cd.small,"{width:296px;.",Cd.icon,"{top:0px;}}",""),a.css(".",Td.toastContainer,"{position:fixed;transition:all 230ms cubic-bezier(0.21, 1.02, 0.73, 1);z-index:9999;}.",Td.topLeft,",.",Td.topCenter,",.",Td.topRight,"{top:0;}.",Td.bottomLeft,",.",Td.bottomCenter,",.",Td.bottomRight,"{bottom:0;}.",Td.topCenter,",.",Td.bottomCenter,"{left:50%;}.",Td.topRight,",.",Td.bottomRight,"{right:0;}",""),a.css(".",Od.root,"{display:flex;flex-direction:row;>*:not(:last-child){&.",gu.outlined,",.",gu.outlined,"{border-right:none;}}}",""),a.css(".",Dd.root,"{box-sizing:border-box;.",Jc.outlined,"{border:none;}.",Jc.icon,"{padding:8px;}}.",Dd.label,"{display:block;}.",Dd.inputContainer,"{box-sizing:border-box;display:flex;align-items:center;border:1px solid transparent;}.",Dd.calendar,"{border-top:none!important;.",Pd.arrowTip,"{transition:left 0.2s ease-in-out;}}.",Dd.openCalendar,"{.",Dd.inputContainer,"{border-bottom:1px solid rgb(var(--lsd-border-primary));}}.",Dd.icon,"{cursor:pointer;display:flex;align-items:center;justify-content:center;flex-grow:1;padding:0 10px;}.",Dd.disabled,"{opacity:0.3;}.",Dd.supportingText,"{position:absolute;}.",Dd.large,"{width:318px;.",Jc.large,"{width:156px;}.",Jc.input,"{padding-right:0;}.",Jc.icon,"{padding:11px 12px;}.",Dd.label,"{margin:0 0 6px 18px;}.",Dd.inputContainer,"{height:40px;}.",Dd.supportingText,"{margin:6px 18px 0 18px;}}.",Dd.medium,"{width:290px;.",Jc.medium,"{width:142px;}.",Jc.input,"{padding-right:0;}.",Jc.icon,"{padding:7px 8px;}.",Dd.label,"{margin:0 0 6px 14px;}.",Dd.inputContainer,"{height:32px;}.",Dd.supportingText,"{margin:6px 14px 0 14px;}}.",Dd.small,"{width:262px;.",Jc.small,"{width:128px;}.",Jc.input,"{padding-right:0;}.",Jc.icon,"{padding:5px 7px;}.",Dd.label,"{margin:0 0 6px 12px;}.",Dd.inputContainer,"{height:28px;}.",Dd.supportingText,"{margin:6px 12px 0 12px;}}.",Dd.separator,"{margin-left:3px;width:1px;height:100%;}.",Dd.separator,"{border-left:1px solid transparent;}.",Dd.outlined,"{border:1px solid rgb(var(--lsd-border-primary));.",Dd.separator,"{border-left:1px solid rgb(var(--lsd-border-primary));}}",""),a.css(".",Pd.root,"{border:1px solid rgb(var(--lsd-border-primary));position:relative;}.",Pd.arrowTip,"{border:1px solid rgb(var(--lsd-border-primary));position:absolute;background:rgb(var(--lsd-surface-primary));}.",Pd.content,"{background:rgb(var(--lsd-surface-primary));width:100%;height:100%;position:relative;z-index:1;}","")],Ad=({theme:e=Fc.light})=>{const t=r.useMemo((()=>Nd.map((t=>"function"==typeof t?t(e):t)).map((e=>Ge(a.Global,{styles:e},e.name)))),[e]);return Ge(qe,{children:t})},Id=e=>{try{return[e(),void 0]}catch(t){return[void 0,t]}},Ld=({children:e})=>{const[t,n]=r.useState(!1);return r.useEffect((()=>{if("undefined"==typeof window)return;const e=document.querySelector("body");let t=e.querySelector("#lsd-presentation");return t||(t=document.createElement("div"),t.id="lsd-presentation"),e.appendChild(t),n(!0),()=>{Id((()=>e.removeChild(t)))}}),[]),Ge(ou.Provider,{value:{initialized:t},children:e})},Rd=({children:e})=>{const t=r.useRef(),n=r.useRef({}),[o,a]=r.useState({}),[i,l]=r.useState(!1),s=e=>{const t=n.current[e];t&&t.current&&Id((()=>{a((n=>({...n,[e]:t.current.getBoundingClientRect()})))}))};r.useEffect((()=>{if("undefined"!=typeof window&&"undefined"!=typeof ResizeObserver)return t.current=new ResizeObserver((e=>{Id((()=>{const t=Object.entries(n.current);e.map((e=>t.find((([t,n])=>n.current===e.target)))).forEach((e=>{if(e&&2===e.length){const[t]=e;s(t)}}))}))})),l(!0),()=>{var e;null==(e=t.current)||e.disconnect()}}),[]);return Ge(cc.Provider,{value:{observe:(e,r)=>{t.current&&(n.current[e]=r,s(e),r.current instanceof Element&&t.current.observe(r.current))},unobserve:e=>{if(!t.current)return;const r=n.current[e];r&&(r.current instanceof Element&&t.current.unobserve(r.current),delete n.current[e],a((t=>Vl(t,e))))},rect:o,ready:i},children:e})},jd=r.createContext({theme:null}),Md=({label:e,size:t="large",error:n=!1,errorIcon:o=!1,supportingText:a,value:i,placeholder:l,defaultValue:s,disabled:u,onChange:c,icon:d,inputProps:f={},id:p="number-input",min:h=Number.MIN_SAFE_INTEGER,max:m=Number.MAX_SAFE_INTEGER,step:g=1,...v})=>{const b=r.useRef(null),y=bs(v),w=Ye({defaultValue:s,value:i,onChange:c,ref:b});return We("div",{"aria-disabled":u?"true":"false",...ws(v),className:Qe(v.className,y.className,_d.root,_d[t],u&&_d.disabled,n&&_d.error),children:[e&&Ge(Vs,{htmlFor:p,className:_d.label,variant:"label2",component:"label",children:e}),We("div",{className:_d.mainContainer,children:[Ge(Bu,{onClick:()=>{if(u)return;const e=Math.max(h,Number(w.value||"0")-g);w.setValue(e.toString())},className:_d.plusMinusIcons,children:Ge(Hs,{color:"primary"})}),We("div",{className:_d.inputContainer,children:[Ge("input",{id:p,type:"number",placeholder:l,ref:b,className:Qe(f.className,_d.input),value:w.value||"",onChange:w.onChange,min:h,max:m,step:g,disabled:u,...f}),n&&!!o&&Ge("span",{className:_d.errorIcon,children:Ge(Ns,{color:"primary"})})]}),Ge(Bu,{onClick:()=>{if(u)return;const e=Math.min(m,Number(w.value||"0")+g);w.setValue(e.toString())},className:_d.plusMinusIcons,children:Ge(ks,{color:"primary"})})]}),a&&Ge("div",{className:Qe(_d.supportingText),children:Ge(Vs,{variant:"label2",component:"p",children:a})})]})};Md.classes=_d;const Fd=({isOpen:e,size:t="large",title:n,subtitle:r,onClose:o,children:a,...i})=>{const l=bs(i);return e?Ge("div",{...ws(i),className:Qe(l.className,kd.root,kd[t]),onClick:e=>{e.target===e.currentTarget&&o&&o()},children:We("div",{className:Qe(kd.modalContainer),children:[We("div",{className:kd.header,children:[We("div",{className:kd.titleAndSubtitleContainer,children:[!!n&&Ge(Vs,{className:kd.title,component:"div",variant:"small"===t?"h6":"h5",children:n}),!!r&&Ge(Vs,{className:kd.subtitle,variant:"small"===t?"label2":"label1",component:"div",children:r})]}),Ge(Bu,{onClick:o,className:kd.closeIcon,size:"medium",children:Ge(Ps,{color:"primary"})})]}),a]})}):null};Fd.classes=kd;const Bd=({children:e,...t})=>{const n=bs(t);return Ge("div",{...ws(t),className:Qe(n.className,Sd.root),children:e})};Bd.classes=Sd;const zd=({children:e,...t})=>{const n=bs(t);return Ge("div",{...ws(t),className:Qe(n.className,Ed.root),children:e})};zd.classes=Ed;const $d=({label:e,size:t="large",error:n=!1,errorIcon:o=!1,clearButton:a,supportingText:i,children:l,value:s,placeholder:u,defaultValue:c,disabled:d,onChange:f,icon:p,onIconClick:h,inputProps:m={},calendarIconRef:g,variant:v="underlined",...b})=>{const y=bs(b),w=r.useRef(null),x=Ye({defaultValue:c,value:s,onChange:f,ref:w}),_=(null==m?void 0:m.id)??(b.id||"date-field")+"-input";return We("div",{"aria-disabled":d?"true":"false",...b,className:Qe({...ws(b)},b.className,y.className,Jc.root,Jc[t],d&&Jc.disabled,n&&Jc.error),children:[e&&Ge(Vs,{htmlFor:_,className:Jc.label,variant:"label2",component:"label",children:e}),We("div",{className:Qe(Jc.inputContainer,"outlined"===v?Jc.outlined:Jc.underlined),children:[Ge("input",{id:_,type:"date",placeholder:u,...m,ref:w,value:x.value||"",onChange:x.onChange,className:Qe(m.className,Jc.input,x.filled&&Jc.inputFilled),max:m.max||"9999-12-31"}),p?Ge("span",{className:Jc.icon,onClick:()=>!d&&h&&h(),ref:g,children:p}):n&&o?Ge("span",{className:Jc.icon,children:Ge(Ns,{color:"primary"})}):a&&x.filled?Ge("span",{onClick:()=>!d&&x.setValue(""),className:Jc.icon,children:Ge(Ps,{color:"primary"})}):Ge("span",{className:Jc.noIcon})]}),i&&Ge("div",{className:Qe(Jc.supportingText),children:Ge(Vs,{variant:"label2",component:"p",children:i})}),l]})};$d.classes=Jc;const Ud=(e,t,n)=>{if(!e)return{isValid:!1,date:null};const r=new Date(e+"T00:00:00");return{isValid:!Number.isNaN(+r)&&r>=t&&r<=n,date:r}},Hd=e=>new Date(e.getTime()-6e4*e.getTimezoneOffset()).toISOString().split("T")[0],Vd=e=>e.setHours(0,0,0,0),qd=(e,t,n)=>!!(e&&t&&n)&&(Vd(t)<=Vd(e)&&Vd(n)>=Vd(e)),Gd=(e,t)=>{if(!e||!t)return!1;return Hd(e)===Hd(t)},Wd=e=>{const t=(e=>{const t=e.find((e=>"number"!=typeof e));return t?new Date(t.date):new Date})(e),n=new Date(t);n.setDate(n.getDate()-t.getDay());const r=[];for(let o=0;o<42;o++){const e=new Date(n);e.setDate(e.getDate()+o),r.push(e)}return r},Zd=(e,t)=>e&&e===t?null:t;function Qd(e,t){if(!e||!t)return!0;let n=new Date(Hd(new Date(e)));return new Date(Hd(new Date(t)))>n}const Yd=(e,t)=>"large"===t?"startDate"===e?130:291:"medium"===t?"startDate"===e?120:267:"small"===t?"startDate"===e?107:239:0;var Xd={lessThanXSeconds:{one:"less than a second",other:"less than {{count}} seconds"},xSeconds:{one:"1 second",other:"{{count}} seconds"},halfAMinute:"half a minute",lessThanXMinutes:{one:"less than a minute",other:"less than {{count}} minutes"},xMinutes:{one:"1 minute",other:"{{count}} minutes"},aboutXHours:{one:"about 1 hour",other:"about {{count}} hours"},xHours:{one:"1 hour",other:"{{count}} hours"},xDays:{one:"1 day",other:"{{count}} days"},aboutXWeeks:{one:"about 1 week",other:"about {{count}} weeks"},xWeeks:{one:"1 week",other:"{{count}} weeks"},aboutXMonths:{one:"about 1 month",other:"about {{count}} months"},xMonths:{one:"1 month",other:"{{count}} months"},aboutXYears:{one:"about 1 year",other:"about {{count}} years"},xYears:{one:"1 year",other:"{{count}} years"},overXYears:{one:"over 1 year",other:"over {{count}} years"},almostXYears:{one:"almost 1 year",other:"almost {{count}} years"}};function Kd(e){return function(t){var n=t||{},r=n.width?String(n.width):e.defaultWidth;return e.formats[r]||e.formats[e.defaultWidth]}}var Jd={date:Kd({formats:{full:"EEEE, MMMM do, y",long:"MMMM do, y",medium:"MMM d, y",short:"MM/dd/yyyy"},defaultWidth:"full"}),time:Kd({formats:{full:"h:mm:ss a zzzz",long:"h:mm:ss a z",medium:"h:mm:ss a",short:"h:mm a"},defaultWidth:"full"}),dateTime:Kd({formats:{full:"{{date}} 'at' {{time}}",long:"{{date}} 'at' {{time}}",medium:"{{date}}, {{time}}",short:"{{date}}, {{time}}"},defaultWidth:"full"})},ef={lastWeek:"'last' eeee 'at' p",yesterday:"'yesterday at' p",today:"'today at' p",tomorrow:"'tomorrow at' p",nextWeek:"eeee 'at' p",other:"P"};function tf(e){return function(t,n){var r,o=n||{};if("formatting"===(o.context?String(o.context):"standalone")&&e.formattingValues){var a=e.defaultFormattingWidth||e.defaultWidth,i=o.width?String(o.width):a;r=e.formattingValues[i]||e.formattingValues[a]}else{var l=e.defaultWidth,s=o.width?String(o.width):e.defaultWidth;r=e.values[s]||e.values[l]}return r[e.argumentCallback?e.argumentCallback(t):t]}}function nf(e){return function(t,n){var r=String(t),o=n||{},a=o.width,i=a&&e.matchPatterns[a]||e.matchPatterns[e.defaultMatchWidth],l=r.match(i);if(!l)return null;var s,u=l[0],c=a&&e.parsePatterns[a]||e.parsePatterns[e.defaultParseWidth];return s="[object Array]"===Object.prototype.toString.call(c)?function(e,t){for(var n=0;n<e.length;n++)if(t(e[n]))return n}(c,(function(e){return e.test(u)})):function(e,t){for(var n in e)if(e.hasOwnProperty(n)&&t(e[n]))return n}(c,(function(e){return e.test(u)})),s=e.valueCallback?e.valueCallback(s):s,{value:s=o.valueCallback?o.valueCallback(s):s,rest:r.slice(u.length)}}}var rf,of={code:"en-US",formatDistance:function(e,t,n){var r;return n=n||{},r="string"==typeof Xd[e]?Xd[e]:1===t?Xd[e].one:Xd[e].other.replace("{{count}}",t),n.addSuffix?n.comparison>0?"in "+r:r+" ago":r},formatLong:Jd,formatRelative:function(e,t,n,r){return ef[e]},localize:{ordinalNumber:function(e,t){var n=Number(e),r=n%100;if(r>20||r<10)switch(r%10){case 1:return n+"st";case 2:return n+"nd";case 3:return n+"rd"}return n+"th"},era:tf({values:{narrow:["B","A"],abbreviated:["BC","AD"],wide:["Before Christ","Anno Domini"]},defaultWidth:"wide"}),quarter:tf({values:{narrow:["1","2","3","4"],abbreviated:["Q1","Q2","Q3","Q4"],wide:["1st quarter","2nd quarter","3rd quarter","4th quarter"]},defaultWidth:"wide",argumentCallback:function(e){return Number(e)-1}}),month:tf({values:{narrow:["J","F","M","A","M","J","J","A","S","O","N","D"],abbreviated:["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"],wide:["January","February","March","April","May","June","July","August","September","October","November","December"]},defaultWidth:"wide"}),day:tf({values:{narrow:["S","M","T","W","T","F","S"],short:["Su","Mo","Tu","We","Th","Fr","Sa"],abbreviated:["Sun","Mon","Tue","Wed","Thu","Fri","Sat"],wide:["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"]},defaultWidth:"wide"}),dayPeriod:tf({values:{narrow:{am:"a",pm:"p",midnight:"mi",noon:"n",morning:"morning",afternoon:"afternoon",evening:"evening",night:"night"},abbreviated:{am:"AM",pm:"PM",midnight:"midnight",noon:"noon",morning:"morning",afternoon:"afternoon",evening:"evening",night:"night"},wide:{am:"a.m.",pm:"p.m.",midnight:"midnight",noon:"noon",morning:"morning",afternoon:"afternoon",evening:"evening",night:"night"}},defaultWidth:"wide",formattingValues:{narrow:{am:"a",pm:"p",midnight:"mi",noon:"n",morning:"in the morning",afternoon:"in the afternoon",evening:"in the evening",night:"at night"},abbreviated:{am:"AM",pm:"PM",midnight:"midnight",noon:"noon",morning:"in the morning",afternoon:"in the afternoon",evening:"in the evening",night:"at night"},wide:{am:"a.m.",pm:"p.m.",midnight:"midnight",noon:"noon",morning:"in the morning",afternoon:"in the afternoon",evening:"in the evening",night:"at night"}},defaultFormattingWidth:"wide"})},match:{ordinalNumber:(rf={matchPattern:/^(\d+)(th|st|nd|rd)?/i,parsePattern:/\d+/i,valueCallback:function(e){return parseInt(e,10)}},function(e,t){var n=String(e),r=t||{},o=n.match(rf.matchPattern);if(!o)return null;var a=o[0],i=n.match(rf.parsePattern);if(!i)return null;var l=rf.valueCallback?rf.valueCallback(i[0]):i[0];return{value:l=r.valueCallback?r.valueCallback(l):l,rest:n.slice(a.length)}}),era:nf({matchPatterns:{narrow:/^(b|a)/i,abbreviated:/^(b\.?\s?c\.?|b\.?\s?c\.?\s?e\.?|a\.?\s?d\.?|c\.?\s?e\.?)/i,wide:/^(before christ|before common era|anno domini|common era)/i},defaultMatchWidth:"wide",parsePatterns:{any:[/^b/i,/^(a|c)/i]},defaultParseWidth:"any"}),quarter:nf({matchPatterns:{narrow:/^[1234]/i,abbreviated:/^q[1234]/i,wide:/^[1234](th|st|nd|rd)? quarter/i},defaultMatchWidth:"wide",parsePatterns:{any:[/1/i,/2/i,/3/i,/4/i]},defaultParseWidth:"any",valueCallback:function(e){return e+1}}),month:nf({matchPatterns:{narrow:/^[jfmasond]/i,abbreviated:/^(jan|feb|mar|apr|may|jun|jul|aug|sep|oct|nov|dec)/i,wide:/^(january|february|march|april|may|june|july|august|september|october|november|december)/i},defaultMatchWidth:"wide",parsePatterns:{narrow:[/^j/i,/^f/i,/^m/i,/^a/i,/^m/i,/^j/i,/^j/i,/^a/i,/^s/i,/^o/i,/^n/i,/^d/i],any:[/^ja/i,/^f/i,/^mar/i,/^ap/i,/^may/i,/^jun/i,/^jul/i,/^au/i,/^s/i,/^o/i,/^n/i,/^d/i]},defaultParseWidth:"any"}),day:nf({matchPatterns:{narrow:/^[smtwf]/i,short:/^(su|mo|tu|we|th|fr|sa)/i,abbreviated:/^(sun|mon|tue|wed|thu|fri|sat)/i,wide:/^(sunday|monday|tuesday|wednesday|thursday|friday|saturday)/i},defaultMatchWidth:"wide",parsePatterns:{narrow:[/^s/i,/^m/i,/^t/i,/^w/i,/^t/i,/^f/i,/^s/i],any:[/^su/i,/^m/i,/^tu/i,/^w/i,/^th/i,/^f/i,/^sa/i]},defaultParseWidth:"any"}),dayPeriod:nf({matchPatterns:{narrow:/^(a|p|mi|n|(in the|at) (morning|afternoon|evening|night))/i,any:/^([ap]\.?\s?m\.?|midnight|noon|(in the|at) (morning|afternoon|evening|night))/i},defaultMatchWidth:"any",parsePatterns:{any:{am:/^a/i,pm:/^p/i,midnight:/^mi/i,noon:/^no/i,morning:/morning/i,afternoon:/afternoon/i,evening:/evening/i,night:/night/i}},defaultParseWidth:"any"})},options:{weekStartsOn:0,firstWeekContainsDate:1}};function af(e){if(null===e||!0===e||!1===e)return NaN;var t=Number(e);return isNaN(t)?t:t<0?Math.ceil(t):Math.floor(t)}function lf(e,t){if(t.length<e)throw new TypeError(e+" argument"+(e>1?"s":"")+" required, but only "+t.length+" present")}function sf(e){lf(1,arguments);var t=Object.prototype.toString.call(e);return e instanceof Date||"object"==typeof e&&"[object Date]"===t?new Date(e.getTime()):"number"==typeof e||"[object Number]"===t?new Date(e):("string"!=typeof e&&"[object String]"!==t||"undefined"==typeof console||(console.warn("Starting with v2.0.0-beta.1 date-fns doesn't accept strings as arguments. Please use `parseISO` to parse strings. See: https://git.io/fjule"),console.warn((new Error).stack)),new Date(NaN))}function uf(e,t){lf(2,arguments);var n=sf(e).getTime(),r=af(t);return new Date(n+r)}function cf(e,t){lf(2,arguments);var n=af(t);return uf(e,-n)}function df(e,t){switch(e){case"P":return t.date({width:"short"});case"PP":return t.date({width:"medium"});case"PPP":return t.date({width:"long"});default:return t.date({width:"full"})}}function ff(e,t){switch(e){case"p":return t.time({width:"short"});case"pp":return t.time({width:"medium"});case"ppp":return t.time({width:"long"});default:return t.time({width:"full"})}}var pf={p:ff,P:function(e,t){var n,r=e.match(/(P+)(p+)?/),o=r[1],a=r[2];if(!a)return df(e,t);switch(o){case"P":n=t.dateTime({width:"short"});break;case"PP":n=t.dateTime({width:"medium"});break;case"PPP":n=t.dateTime({width:"long"});break;default:n=t.dateTime({width:"full"})}return n.replace("{{date}}",df(o,t)).replace("{{time}}",ff(a,t))}};function hf(e){return e.getTime()%6e4}function mf(e){var t=new Date(e.getTime()),n=Math.ceil(t.getTimezoneOffset());return t.setSeconds(0,0),6e4*n+(n>0?(6e4+hf(t))%6e4:hf(t))}var gf=["D","DD"],vf=["YY","YYYY"];function bf(e){return-1!==gf.indexOf(e)}function yf(e){return-1!==vf.indexOf(e)}function wf(e){if("YYYY"===e)throw new RangeError("Use `yyyy` instead of `YYYY` for formatting years; see: https://git.io/fxCyr");if("YY"===e)throw new RangeError("Use `yy` instead of `YY` for formatting years; see: https://git.io/fxCyr");if("D"===e)throw new RangeError("Use `d` instead of `D` for formatting days of the month; see: https://git.io/fxCyr");if("DD"===e)throw new RangeError("Use `dd` instead of `DD` for formatting days of the month; see: https://git.io/fxCyr")}function xf(e,t){lf(1,arguments);var n=t||{},r=n.locale,o=r&&r.options&&r.options.weekStartsOn,a=null==o?0:af(o),i=null==n.weekStartsOn?a:af(n.weekStartsOn);if(!(i>=0&&i<=6))throw new RangeError("weekStartsOn must be between 0 and 6 inclusively");var l=sf(e),s=l.getUTCDay(),u=(s<i?7:0)+s-i;return l.setUTCDate(l.getUTCDate()-u),l.setUTCHours(0,0,0,0),l}function _f(e,t){lf(1,arguments);var n=sf(e,t),r=n.getUTCFullYear(),o=t||{},a=o.locale,i=a&&a.options&&a.options.firstWeekContainsDate,l=null==i?1:af(i),s=null==o.firstWeekContainsDate?l:af(o.firstWeekContainsDate);if(!(s>=1&&s<=7))throw new RangeError("firstWeekContainsDate must be between 1 and 7 inclusively");var u=new Date(0);u.setUTCFullYear(r+1,0,s),u.setUTCHours(0,0,0,0);var c=xf(u,t),d=new Date(0);d.setUTCFullYear(r,0,s),d.setUTCHours(0,0,0,0);var f=xf(d,t);return n.getTime()>=c.getTime()?r+1:n.getTime()>=f.getTime()?r:r-1}function kf(e){lf(1,arguments);var t=1,n=sf(e),r=n.getUTCDay(),o=(r<t?7:0)+r-t;return n.setUTCDate(n.getUTCDate()-o),n.setUTCHours(0,0,0,0),n}function Ef(e){lf(1,arguments);var t=sf(e),n=t.getUTCFullYear(),r=new Date(0);r.setUTCFullYear(n+1,0,4),r.setUTCHours(0,0,0,0);var o=kf(r),a=new Date(0);a.setUTCFullYear(n,0,4),a.setUTCHours(0,0,0,0);var i=kf(a);return t.getTime()>=o.getTime()?n+1:t.getTime()>=i.getTime()?n:n-1}function Sf(e){lf(1,arguments);var t=Ef(e),n=new Date(0);n.setUTCFullYear(t,0,4),n.setUTCHours(0,0,0,0);var r=kf(n);return r}function Cf(e,t){lf(1,arguments);var n=t||{},r=n.locale,o=r&&r.options&&r.options.firstWeekContainsDate,a=null==o?1:af(o),i=null==n.firstWeekContainsDate?a:af(n.firstWeekContainsDate),l=_f(e,t),s=new Date(0);s.setUTCFullYear(l,0,i),s.setUTCHours(0,0,0,0);var u=xf(s,t);return u}function Tf(e){lf(1,arguments);var t=sf(e);return!isNaN(t)}function Of(e,t){for(var n=e<0?"-":"",r=Math.abs(e).toString();r.length<t;)r="0"+r;return n+r}var Df={G:function(e,t,n){var r=e.getUTCFullYear()>0?1:0;switch(t){case"G":case"GG":case"GGG":return n.era(r,{width:"abbreviated"});case"GGGGG":return n.era(r,{width:"narrow"});default:return n.era(r,{width:"wide"})}},y:function(e,t,n){if("yo"===t){var r=e.getUTCFullYear(),o=r>0?r:1-r;return n.ordinalNumber(o,{unit:"year"})}return function(e,t){var n=e.getUTCFullYear(),r=n>0?n:1-n;return Of("yy"===t?r%100:r,t.length)}(e,t)},Y:function(e,t,n,r){var o=_f(e,r),a=o>0?o:1-o;return"YY"===t?Of(a%100,2):"Yo"===t?n.ordinalNumber(a,{unit:"year"}):Of(a,t.length)},R:function(e,t){return Of(Ef(e),t.length)},u:function(e,t){return Of(e.getUTCFullYear(),t.length)},Q:function(e,t,n){var r=Math.ceil((e.getUTCMonth()+1)/3);switch(t){case"Q":return String(r);case"QQ":return Of(r,2);case"Qo":return n.ordinalNumber(r,{unit:"quarter"});case"QQQ":return n.quarter(r,{width:"abbreviated",context:"formatting"});case"QQQQQ":return n.quarter(r,{width:"narrow",context:"formatting"});default:return n.quarter(r,{width:"wide",context:"formatting"})}},q:function(e,t,n){var r=Math.ceil((e.getUTCMonth()+1)/3);switch(t){case"q":return String(r);case"qq":return Of(r,2);case"qo":return n.ordinalNumber(r,{unit:"quarter"});case"qqq":return n.quarter(r,{width:"abbreviated",context:"standalone"});case"qqqqq":return n.quarter(r,{width:"narrow",context:"standalone"});default:return n.quarter(r,{width:"wide",context:"standalone"})}},M:function(e,t,n){var r=e.getUTCMonth();switch(t){case"M":case"MM":return function(e,t){var n=e.getUTCMonth();return"M"===t?String(n+1):Of(n+1,2)}(e,t);case"Mo":return n.ordinalNumber(r+1,{unit:"month"});case"MMM":return n.month(r,{width:"abbreviated",context:"formatting"});case"MMMMM":return n.month(r,{width:"narrow",context:"formatting"});default:return n.month(r,{width:"wide",context:"formatting"})}},L:function(e,t,n){var r=e.getUTCMonth();switch(t){case"L":return String(r+1);case"LL":return Of(r+1,2);case"Lo":return n.ordinalNumber(r+1,{unit:"month"});case"LLL":return n.month(r,{width:"abbreviated",context:"standalone"});case"LLLLL":return n.month(r,{width:"narrow",context:"standalone"});default:return n.month(r,{width:"wide",context:"standalone"})}},w:function(e,t,n,r){var o=function(e,t){lf(1,arguments);var n=sf(e),r=xf(n,t).getTime()-Cf(n,t).getTime();return Math.round(r/6048e5)+1}(e,r);return"wo"===t?n.ordinalNumber(o,{unit:"week"}):Of(o,t.length)},I:function(e,t,n){var r=function(e){lf(1,arguments);var t=sf(e),n=kf(t).getTime()-Sf(t).getTime();return Math.round(n/6048e5)+1}(e);return"Io"===t?n.ordinalNumber(r,{unit:"week"}):Of(r,t.length)},d:function(e,t,n){return"do"===t?n.ordinalNumber(e.getUTCDate(),{unit:"date"}):function(e,t){return Of(e.getUTCDate(),t.length)}(e,t)},D:function(e,t,n){var r=function(e){lf(1,arguments);var t=sf(e),n=t.getTime();t.setUTCMonth(0,1),t.setUTCHours(0,0,0,0);var r=t.getTime(),o=n-r;return Math.floor(o/864e5)+1}(e);return"Do"===t?n.ordinalNumber(r,{unit:"dayOfYear"}):Of(r,t.length)},E:function(e,t,n){var r=e.getUTCDay();switch(t){case"E":case"EE":case"EEE":return n.day(r,{width:"abbreviated",context:"formatting"});case"EEEEE":return n.day(r,{width:"narrow",context:"formatting"});case"EEEEEE":return n.day(r,{width:"short",context:"formatting"});default:return n.day(r,{width:"wide",context:"formatting"})}},e:function(e,t,n,r){var o=e.getUTCDay(),a=(o-r.weekStartsOn+8)%7||7;switch(t){case"e":return String(a);case"ee":return Of(a,2);case"eo":return n.ordinalNumber(a,{unit:"day"});case"eee":return n.day(o,{width:"abbreviated",context:"formatting"});case"eeeee":return n.day(o,{width:"narrow",context:"formatting"});case"eeeeee":return n.day(o,{width:"short",context:"formatting"});default:return n.day(o,{width:"wide",context:"formatting"})}},c:function(e,t,n,r){var o=e.getUTCDay(),a=(o-r.weekStartsOn+8)%7||7;switch(t){case"c":return String(a);case"cc":return Of(a,t.length);case"co":return n.ordinalNumber(a,{unit:"day"});case"ccc":return n.day(o,{width:"abbreviated",context:"standalone"});case"ccccc":return n.day(o,{width:"narrow",context:"standalone"});case"cccccc":return n.day(o,{width:"short",context:"standalone"});default:return n.day(o,{width:"wide",context:"standalone"})}},i:function(e,t,n){var r=e.getUTCDay(),o=0===r?7:r;switch(t){case"i":return String(o);case"ii":return Of(o,t.length);case"io":return n.ordinalNumber(o,{unit:"day"});case"iii":return n.day(r,{width:"abbreviated",context:"formatting"});case"iiiii":return n.day(r,{width:"narrow",context:"formatting"});case"iiiiii":return n.day(r,{width:"short",context:"formatting"});default:return n.day(r,{width:"wide",context:"formatting"})}},a:function(e,t,n){var r=e.getUTCHours()/12>=1?"pm":"am";switch(t){case"a":case"aa":case"aaa":return n.dayPeriod(r,{width:"abbreviated",context:"formatting"});case"aaaaa":return n.dayPeriod(r,{width:"narrow",context:"formatting"});default:return n.dayPeriod(r,{width:"wide",context:"formatting"})}},b:function(e,t,n){var r,o=e.getUTCHours();switch(r=12===o?"noon":0===o?"midnight":o/12>=1?"pm":"am",t){case"b":case"bb":case"bbb":return n.dayPeriod(r,{width:"abbreviated",context:"formatting"});case"bbbbb":return n.dayPeriod(r,{width:"narrow",context:"formatting"});default:return n.dayPeriod(r,{width:"wide",context:"formatting"})}},B:function(e,t,n){var r,o=e.getUTCHours();switch(r=o>=17?"evening":o>=12?"afternoon":o>=4?"morning":"night",t){case"B":case"BB":case"BBB":return n.dayPeriod(r,{width:"abbreviated",context:"formatting"});case"BBBBB":return n.dayPeriod(r,{width:"narrow",context:"formatting"});default:return n.dayPeriod(r,{width:"wide",context:"formatting"})}},h:function(e,t,n){if("ho"===t){var r=e.getUTCHours()%12;return 0===r&&(r=12),n.ordinalNumber(r,{unit:"hour"})}return function(e,t){return Of(e.getUTCHours()%12||12,t.length)}(e,t)},H:function(e,t,n){return"Ho"===t?n.ordinalNumber(e.getUTCHours(),{unit:"hour"}):function(e,t){return Of(e.getUTCHours(),t.length)}(e,t)},K:function(e,t,n){var r=e.getUTCHours()%12;return"Ko"===t?n.ordinalNumber(r,{unit:"hour"}):Of(r,t.length)},k:function(e,t,n){var r=e.getUTCHours();return 0===r&&(r=24),"ko"===t?n.ordinalNumber(r,{unit:"hour"}):Of(r,t.length)},m:function(e,t,n){return"mo"===t?n.ordinalNumber(e.getUTCMinutes(),{unit:"minute"}):function(e,t){return Of(e.getUTCMinutes(),t.length)}(e,t)},s:function(e,t,n){return"so"===t?n.ordinalNumber(e.getUTCSeconds(),{unit:"second"}):function(e,t){return Of(e.getUTCSeconds(),t.length)}(e,t)},S:function(e,t){return function(e,t){var n=t.length,r=e.getUTCMilliseconds();return Of(Math.floor(r*Math.pow(10,n-3)),t.length)}(e,t)},X:function(e,t,n,r){var o=(r._originalDate||e).getTimezoneOffset();if(0===o)return"Z";switch(t){case"X":return Nf(o);case"XXXX":case"XX":return Af(o);default:return Af(o,":")}},x:function(e,t,n,r){var o=(r._originalDate||e).getTimezoneOffset();switch(t){case"x":return Nf(o);case"xxxx":case"xx":return Af(o);default:return Af(o,":")}},O:function(e,t,n,r){var o=(r._originalDate||e).getTimezoneOffset();switch(t){case"O":case"OO":case"OOO":return"GMT"+Pf(o,":");default:return"GMT"+Af(o,":")}},z:function(e,t,n,r){var o=(r._originalDate||e).getTimezoneOffset();switch(t){case"z":case"zz":case"zzz":return"GMT"+Pf(o,":");default:return"GMT"+Af(o,":")}},t:function(e,t,n,r){var o=r._originalDate||e;return Of(Math.floor(o.getTime()/1e3),t.length)},T:function(e,t,n,r){return Of((r._originalDate||e).getTime(),t.length)}};function Pf(e,t){var n=e>0?"-":"+",r=Math.abs(e),o=Math.floor(r/60),a=r%60;if(0===a)return n+String(o);var i=t||"";return n+String(o)+i+Of(a,2)}function Nf(e,t){return e%60==0?(e>0?"-":"+")+Of(Math.abs(e)/60,2):Af(e,t)}function Af(e,t){var n=t||"",r=e>0?"-":"+",o=Math.abs(e);return r+Of(Math.floor(o/60),2)+n+Of(o%60,2)}var If=/[yYQqMLwIdDecihHKkms]o|(\w)\1*|''|'(''|[^'])+('|$)|./g,Lf=/P+p+|P+|p+|''|'(''|[^'])+('|$)|./g,Rf=/^'([^]*?)'?$/,jf=/''/g,Mf=/[a-zA-Z]/;function Ff(e,t,n){lf(2,arguments);var r=String(t),o=n||{},a=o.locale||of,i=a.options&&a.options.firstWeekContainsDate,l=null==i?1:af(i),s=null==o.firstWeekContainsDate?l:af(o.firstWeekContainsDate);if(!(s>=1&&s<=7))throw new RangeError("firstWeekContainsDate must be between 1 and 7 inclusively");var u=a.options&&a.options.weekStartsOn,c=null==u?0:af(u),d=null==o.weekStartsOn?c:af(o.weekStartsOn);if(!(d>=0&&d<=6))throw new RangeError("weekStartsOn must be between 0 and 6 inclusively");if(!a.localize)throw new RangeError("locale must contain localize property");if(!a.formatLong)throw new RangeError("locale must contain formatLong property");var f=sf(e);if(!Tf(f))throw new RangeError("Invalid time value");var p=mf(f),h=cf(f,p),m={firstWeekContainsDate:s,weekStartsOn:d,locale:a,_originalDate:f},g=r.match(Lf).map((function(e){var t=e[0];return"p"===t||"P"===t?(0,pf[t])(e,a.formatLong,m):e})).join("").match(If).map((function(e){if("''"===e)return"'";var t=e[0];if("'"===t)return Bf(e);var n=Df[t];if(n)return!o.useAdditionalWeekYearTokens&&yf(e)&&wf(e),!o.useAdditionalDayOfYearTokens&&bf(e)&&wf(e),n(h,e,a.localize,m);if(t.match(Mf))throw new RangeError("Format string contains an unescaped latin alphabet character `"+t+"`");return e})).join("");return g}function Bf(e){return e.match(Rf)[1].replace(jf,"'")}function zf(e,t){lf(2,arguments);var n=sf(e),r=af(t);return isNaN(r)?new Date(NaN):r?(n.setDate(n.getDate()+r),n):n}function $f(e,t){lf(1,arguments);var n=e||{},r=sf(n.start),o=sf(n.end),a=o.getTime();if(!(r.getTime()<=a))throw new RangeError("Invalid interval");var i=[],l=r;l.setHours(0,0,0,0);var s=t&&"step"in t?Number(t.step):1;if(s<1||isNaN(s))throw new RangeError("`options.step` must be a number greater than 1");for(;l.getTime()<=a;)i.push(sf(l)),l.setDate(l.getDate()+s),l.setHours(0,0,0,0);return i}function Uf(e,t){lf(1,arguments);var n=t||{},r=n.locale,o=r&&r.options&&r.options.weekStartsOn,a=null==o?0:af(o),i=null==n.weekStartsOn?a:af(n.weekStartsOn);if(!(i>=0&&i<=6))throw new RangeError("weekStartsOn must be between 0 and 6 inclusively");var l=sf(e),s=l.getDay(),u=6+(s<i?-7:0)-(s-i);return l.setDate(l.getDate()+u),l.setHours(23,59,59,999),l}function Hf(e){lf(1,arguments);var t=sf(e);return t.setDate(1),t.setHours(0,0,0,0),t}function Vf(e,t){lf(1,arguments);var n=t||{},r=n.locale,o=r&&r.options&&r.options.weekStartsOn,a=null==o?0:af(o),i=null==n.weekStartsOn?a:af(n.weekStartsOn);if(!(i>=0&&i<=6))throw new RangeError("weekStartsOn must be between 0 and 6 inclusively");var l=sf(e),s=l.getDay(),u=(s<i?7:0)+s-i;return l.setDate(l.getDate()-u),l.setHours(0,0,0,0),l}var qf=function(e){return Ff(e,"dd")},Gf=function(e){return Ff(e,"eeeeee")},Wf=function(e){return Ff(e,"MMMM yyyy")};function Zf(e){var t=e.year,n=e.month,o=e.firstDayOfWeek,a=void 0===o?1:o,i=e.dayLabelFormat,l=void 0===i?qf:i,s=e.weekdayLabelFormat,u=void 0===s?Gf:s,c=e.monthLabelFormat,d=void 0===c?Wf:c;return{days:r.useMemo((function(){return function(e){var t=e.year,n=e.month,r=e.firstDayOfWeek,o=void 0===r?1:r,a=e.dayLabelFormat,i=void 0===a?function(e){return Ff(e,"dd")}:a,l=new Date(t,n),s=Hf(l),u=function(e){return lf(1,arguments),sf(e).getDay()}(s),c=function(e){lf(1,arguments);var t=sf(e),n=t.getMonth();return t.setFullYear(t.getFullYear(),n+1,0),t.setHours(23,59,59,999),t}(l);return function(){for(var e=0,t=0,n=arguments.length;t<n;t++)e+=arguments[t].length;var r=Array(e),o=0;for(t=0;t<n;t++)for(var a=arguments[t],i=0,l=a.length;i<l;i++,o++)r[o]=a[i];return r}(Array.from(Array(u>=o?u-o:6-o+u+1).keys()).fill(0),$f({start:s,end:c}).map((function(e){return{date:e,dayLabel:i(e)}})))}({year:t,month:n,firstDayOfWeek:a,dayLabelFormat:l})}),[t,n,a,l]),weekdayLabels:r.useMemo((function(){return function(e){var t=void 0===e?{}:e,n=t.firstDayOfWeek,r=void 0===n?1:n,o=t.weekdayLabelFormat,a=void 0===o?function(e){return Ff(e,"iiiiii")}:o,i=new Date;return $f({start:zf(Vf(i),r),end:zf(Uf(i),r)}).reduce((function(e,t){return e.push(a(t)),e}),[])}({firstDayOfWeek:a,weekdayLabelFormat:u})}),[a,u]),monthLabel:d(new Date(t,n))}}function Qf(e,t){lf(2,arguments);var n=sf(e),r=sf(t);return n.getTime()<r.getTime()}function Yf(e,t){lf(2,arguments);var n=sf(e),r=sf(t);return n.getTime()>r.getTime()}function Xf(e,t){lf(2,arguments);var n=t||{},r=sf(e).getTime(),o=sf(n.start).getTime(),a=sf(n.end).getTime();if(!(o<=a))throw new RangeError("Invalid interval");return r>=o&&r<=a}function Kf(e){lf(1,arguments);var t=sf(e);return t.setHours(0,0,0,0),t}function Jf(e,t){lf(2,arguments);var n=Kf(e),r=Kf(t);return n.getTime()===r.getTime()}function ep(e,t){lf(2,arguments);var n=sf(e),r=af(t);if(isNaN(r))return new Date(NaN);if(!r)return n;var o=n.getDate(),a=new Date(n.getTime());a.setMonth(n.getMonth()+r+1,0);var i=a.getDate();return o>=i?a:(n.setFullYear(a.getFullYear(),a.getMonth(),o),n)}var tp=function(e,t){return void 0===e&&(e=[]),e.some((function(e){return Jf(t,e)}))};function np(e){var t=Hf(e);return{year:function(e){lf(1,arguments);var t=sf(e),n=t.getFullYear();return n}(t),month:function(e){lf(1,arguments);var t=sf(e),n=t.getMonth();return n}(t),date:t}}function rp(e,t){var n=np(t||Kf(Date.now())),r=n.date,o=[n];return e>1&&(o=Array.from(Array(e-1).keys()).reduce((function(e){return r=ep(e[e.length-1].date,1),e.concat([np(r)])}),o)),o}function op(e,t,n,r){var o=e[r?n>0?0:e.length-r:n>0?e.length-1:0].date;return Array.from(Array(t).keys()).reduce((function(e){return o=0===e.length?ep(o,n):ep(o,n>=0?1:-1),n>0?e.concat([np(o)]):[np(o)].concat(e)}),[])}function ap(e){var t=e.startDate,n=e.endDate,r=e.isDateBlocked,o=e.minBookingDays,a=e.exactMinBookingDays,i=e.minBookingDate,l=e.maxBookingDate,s=!i||!Qf(t,zf(i,-1)),u=!l||!Yf(zf(t,o-1),l);return!((!t||1!==o||n||r(t))&&(t&&o>1&&!n&&!a||t&&o>0&&a&&s&&u||t&&o>0&&a&&!i&&!l?$f({start:t,end:zf(t,o-1)}).some((function(e){return r(e)})):!t||!n||a||Qf(n,zf(t,o-1))||$f({start:t,end:n}).some((function(e){return r(e)}))))}function ip(e){var t=e.startDate,n=e.endDate,o=e.focusedInput,a=e.minBookingDate,i=e.maxBookingDate,l=e.onDatesChange,s=e.initialVisibleMonth,u=e.exactMinBookingDays,c=void 0!==u&&u,d=e.minBookingDays,f=void 0===d?1:d,p=e.numberOfMonths,h=void 0===p?2:p,m=e.firstDayOfWeek,g=void 0===m?1:m,v=e.isDateBlocked,b=void 0===v?function(){return!1}:v,y=e.unavailableDates,w=void 0===y?[]:y,x=e.changeActiveMonthOnSelect,_=void 0===x||x,k=r.useState((function(){return rp(h,t||s||null)})),E=k[0],S=k[1],C=r.useState(null),T=C[0],O=C[1],D=r.useState(t),P=D[0],N=D[1];r.useEffect((function(){return"undefined"!=typeof window&&window.addEventListener&&window.addEventListener("keydown",R),function(){window.removeEventListener&&window.removeEventListener("keydown",R)}}));var A=function(e){return tp(w,e)||b(e)},I=function(e){N(e),(!P||P&&!Jf(e,P))&&S(rp(h,e))},L=function(e){return function(e){var t=e.date,n=e.minBookingDate,r=e.maxBookingDate,o=e.isDateBlockedFn,a=e.startDate,i=e.endDate,l=e.minBookingDays,s=void 0===l?1:l,u=e.unavailableDates,c=void 0===u?[]:u,d=n?new Date(n.getFullYear(),n.getMonth(),n.getDate(),0,0,0):n,f=r?new Date(r.getFullYear(),r.getMonth(),r.getDate(),0,0,0):r;return!!(tp(c,t)||d&&Qf(t,d)||f&&Yf(t,f)||a&&!i&&s>1&&Xf(t,{start:a,end:zf(a,s-2)})||o&&o(t))}({date:e,minBookingDate:a,maxBookingDate:i,startDate:t,endDate:n,minBookingDays:f,isDateBlockedFn:A})};function R(e){if(("ArrowRight"===e.key||"ArrowLeft"===e.key||"ArrowDown"===e.key||"ArrowUp"===e.key)&&!P){var t=E[0];I(t.date),S(rp(h,t.date))}}var j=r.useCallback((function(){S(op(E,h,-1)),N(null)}),[E,h]),M=r.useCallback((function(){S(op(E,h,-1,1)),N(null)}),[E,h]),F=r.useCallback((function(){S(op(E,h,1)),N(null)}),[E,h]),B=r.useCallback((function(){S(op(E,h,1,1)),N(null)}),[E,h]),z=r.useCallback((function(e){S(rp(h,e)),N(null)}),[h]),$=r.useCallback((function(e){void 0===e&&(e=1),S(op(E,h,-(12*e-h+1))),N(null)}),[E,h]),U=r.useCallback((function(e){void 0===e&&(e=1),S(op(E,h,12*e-h+1)),N(null)}),[E,h]);return{firstDayOfWeek:g,activeMonths:E,isDateSelected:function(e){return function(e,t,n){return!(!t||!n)&&Xf(e,{start:t,end:n})}(e,t,n)},isDateHovered:function(e){return o=(r={date:e,hoveredDate:T,startDate:t,endDate:n,minBookingDays:f,exactMinBookingDays:c,isDateBlocked:A}).date,a=r.startDate,i=r.endDate,l=r.isDateBlocked,u=r.minBookingDays,(s=r.hoveredDate)&&u>1&&r.exactMinBookingDays&&Xf(o,{start:s,end:zf(s,u-1)})?!$f({start:s,end:zf(s,u-1)}).some((function(e){return l(e)})):a&&!i&&s&&Xf(o,{start:a,end:zf(a,u-1)})&&Jf(a,s)&&u>1?!$f({start:a,end:zf(a,u-1)}).some((function(e){return l(e)})):!(!a||i||!s||Qf(s,a)||!Xf(o,{start:a,end:s})||$f({start:a,end:s}).some((function(e){return l(e)})));var r,o,a,i,l,s,u},isFirstOrLastSelectedDate:function(e){return function(e,t,n){return!!(t&&Jf(e,t)||n&&Jf(e,n))}(e,t,n)},isStartDate:function(e){return function(e,t){return!(!t||!Jf(e,t))}(e,t)},isEndDate:function(e){return function(e,t){return!(!t||!Jf(e,t))}(e,n)},isDateBlocked:L,numberOfMonths:h,isDateFocused:function(e){return!!P&&Jf(e,P)},focusedDate:P,hoveredDate:T,onResetDates:function(){l({startDate:null,endDate:null,focusedInput:"startDate"})},onDateHover:function(e){if(e){if(e){var r=!L(e)||t&&Jf(e,t),o=!a||!Qf(e,zf(a,-1)),l=!i||!Yf(e,i),s=zf(e,f-1),u=!a||!Qf(s,a),d=!i||!Yf(s,i),p=c&&f>1&&o&&l&&u&&d,h=t&&!n&&!c&&o&&l,m=!(f>1&&t)||Xf(e,{start:t,end:zf(t,f-2)}),g=t&&Jf(e,t)&&m;r&&(p||h||g)?O(e):null!==T&&O(null)}}else O(null)},onDateSelect:function(e){("endDate"===o||"startDate"===o)&&f>0&&c&&ap({minBookingDays:f,exactMinBookingDays:c,minBookingDate:a,maxBookingDate:i,isDateBlocked:A,startDate:e,endDate:null})?l({startDate:e,endDate:zf(e,f-1),focusedInput:null}):("endDate"===o&&t&&Qf(e,t)||"startDate"===o&&n&&Yf(e,n))&&!c&&ap({minBookingDays:f,isDateBlocked:A,startDate:e,endDate:null})?l({endDate:null,startDate:e,focusedInput:"endDate"}):"startDate"===o&&!c&&ap({minBookingDays:f,isDateBlocked:A,endDate:n,startDate:e})?l({endDate:n,startDate:e,focusedInput:"endDate"}):"startDate"===o&&!c&&ap({minBookingDays:f,isDateBlocked:A,endDate:null,startDate:e})?l({endDate:null,startDate:e,focusedInput:"endDate"}):"endDate"===o&&t&&!Qf(e,t)&&!c&&ap({minBookingDays:f,isDateBlocked:A,startDate:t,endDate:e})&&l({startDate:t,endDate:e,focusedInput:null}),"endDate"!==o&&(!P||P&&!Jf(e,P))&&_&&S(rp(h,e))},onDateFocus:I,goToPreviousMonths:j,goToPreviousMonthsByOneMonth:M,goToNextMonths:F,goToNextMonthsByOneMonth:B,goToDate:z,goToPreviousYear:$,goToNextYear:U}}const lp=r.createContext(null),sp=()=>r.useContext(lp),up=({day:e,index:t,fullMonthDays:n,disabled:o=!1})=>{const a=n[t],{mode:i,startDate:l,endDate:s,onDateSelect:u}=sp(),c=r.useRef(null),d=Vd(a)===Vd(new Date),f="range"===i&&qd(a,l,s),p=r.useCallback((()=>u(a)),[a,u]),h=Gd(a,l),m="range"===i&&Gd(a,s),g=h||m||f;if(!e)return null;const v=((e,t,n,r,o)=>{if(!n)return"";if(!r||!o)return Vc.dayBorderLeftAndRight;const{prevIndex:a,nextIndex:i}=((e,t)=>{const n=e-1,r=e+1;return{prevIndex:n>=0?n:null,nextIndex:r<t.length?r:null}})(e,t),l=null!==a&&qd(t[a],r,o),s=null!==i&&qd(t[i],r,o),u=null!==a&&Gd(t[a],r)||l,c=null!==i&&Gd(t[i],r)||s;let d="";return n&&(d=e%7==0?c?Vc.dayBorderLeft:Vc.dayBorderLeftAndRight:e%7==6?u?Vc.dayBorderRight:Vc.dayBorderLeftAndRight:u&&c?"":u?Vc.dayBorderRight:c?Vc.dayBorderLeft:Vc.dayBorderLeftAndRight),d})(t,n,g,l,s);return Ge("td",{onClick:p,ref:c,className:Qe(Vc.dayContainer,g&&Vc.dayBorderTopAndBottom,o&&Vc.dayDisabled,d&&Vc.dayIsToday,v),children:We("div",{className:Vc.day,children:[Ge(Vs,{variant:"label2",children:parseInt(e,10)}),d&&Ge(Vs,{variant:"label2",className:Vc.todayIndicator,children:"\u25ac"})]})})},cp=({year:e,monthNumber:t,size:n,yearStep:o=10})=>{const a=r.useRef(null),i=r.useRef(null),{goToDate:l,changeYearMode:s,setChangeYearMode:u}=sp(),c=r.useRef(null),{y:d}=eu(c),[f,p]=r.useState((()=>parseInt(e)-o)),[h,m]=r.useState((()=>parseInt(e)+o)),g=Array.from({length:h-f+1},((e,t)=>f+t));Ys(a,(()=>{u(!1)}));return r.useEffect((()=>{if(s&&i.current&&c.current){const e=i.current.offsetTop,t=i.current.offsetHeight,n=e-c.current.clientHeight/2+t/2;c.current.scrollTop=n}}),[s]),r.useEffect((()=>{var e,t;const n=null==(e=null==c?void 0:c.current)?void 0:e.scrollHeight,r=null==(t=null==c?void 0:c.current)?void 0:t.clientHeight;if(!n||!r)return;const a=d/(n-r)*100;a>90&&m((e=>Math.min(e+o,bp))),a<10&&p((e=>Math.max(e-o,vp)))}),[d,o]),We("div",{ref:a,className:Qe(Vc.changeYear,s&&Vc.changeYearActive),onClick:()=>{u(!s)},children:[We("div",{className:Qe(Vc.year,Vc.yearAndIcon),children:[Ge(Vs,{component:"span",variant:"large"===n?"label1":"label2",children:e}),Ge("div",{className:Vc.changeYearIconContainer,children:Ge(s?Cs:Es,{color:"primary"})})]}),Ge("div",{className:Qe(Vc.yearDropdown,!s&&Vc.yearDropdownHidden),ref:c,children:g.map((r=>Ge("div",{className:Vc.year,onClick:()=>(e=>{const n=new Date(e,t,1);l(n),u(!1)})(r),ref:r===parseInt(e)?i:null,children:Ge(Vs,{component:"span",variant:"large"===n?"label1":"label2",children:r})},r)))})]})},dp=({direction:e,onClick:t,className:n})=>{const r="previous"===e?js:Ms;return Ge("button",{className:Qe(Vc.button,n),type:"button",onClick:t,children:Ge(r,{color:"primary"})})},fp=({monthLabel:e,monthNumber:t,size:n})=>{const{goToPreviousMonths:r,goToNextMonths:o}=sp(),[a,i]=e.split(" ");return We("div",{className:Vc.header,children:[Ge(dp,{direction:"previous",onClick:r,className:Vc.previousMonthButton}),We("div",{className:Vc.monthAndYear,children:[Ge(Vs,{className:Vc.month,component:"span",variant:"large"===n?"label1":"label2",children:a}),Ge(cp,{year:i,monthNumber:t,size:n})]}),Ge(dp,{direction:"next",onClick:o,className:Vc.nextMonthButton})]})},pp=({weekdayLabels:e})=>Ge("tr",{children:e.map(((e,t)=>Ge("th",{children:Ge("div",{className:Vc.weekDay,children:Ge(Vs,{variant:"label2",children:e[0]})})},t)))}),hp=({days:e})=>{const t=Wd(e),n=new Date(t[15]).getMonth();return Ge(qe,{children:Array.from({length:6}).map(((e,r)=>Ge("tr",{children:Array.from({length:7}).map(((e,o)=>{const a=7*r+o,i=t[a];return Ge(up,{index:a,day:i.getDate().toString(),fullMonthDays:t,disabled:i.getMonth()!==n},`day-${a}`)}))},`week-${r}`)))})},mp=({size:e="large",year:t,month:n,firstDayOfWeek:r})=>{const o=sp(),a=(null==o?void 0:o.size)??e,{days:i,weekdayLabels:l,monthLabel:s}=Zf({year:t,month:n,firstDayOfWeek:r});return We(qe,{children:[Ge(fp,{monthLabel:s,monthNumber:n,size:a}),We("table",{className:Vc.monthTable,children:[Ge("thead",{children:Ge(pp,{weekdayLabels:l})}),Ge("tbody",{children:Ge(hp,{days:i})})]})]})},gp=({children:e,arrowOffset:t,arrowPosition:n="top",arrowSize:r=10,rootRef:o,...a})=>{const i=bs(a),l={width:`${r}px`,height:`${r}px`,transform:"rotate(45deg)"};return["top","bottom"].includes(n)?(l.left=`${t}px`,l[n]=`-${r/2}px`):(l.top=`${t}px`,l[n]=`-${r/2}px`),Ge("div",{ref:o,...ws(a),className:Qe(i.className,a.className,Pd.root),children:t?We(qe,{children:[Ge("div",{className:Pd.arrowTip,style:l}),Ge("div",{className:Pd.content,children:e})]}):e})};gp.classes=Pd;const vp=1850,bp=2100,yp=({open:e,handleRef:t,size:n="large",mode:o="date",disabled:a=!1,onStartDateChange:i,onEndDateChange:l,onClose:s,onCalendarClickaway:u,startDate:c,endDate:d,calendarType:f="startDate",minDate:p=new Date(vp,0,1),maxDate:h=new Date(bp,0,1),tooltipArrowOffset:m,...g})=>{const v=bs(g),b=r.useRef(null),[y,w]=r.useState(c?Ud(c,p,h).date:null),[x,_]=r.useState(d?Ud(d,p,h).date:null),[k,E]=r.useState(!1);Ys(b,(t=>{e&&(u&&u(t),void 0===e&&s&&s())}));const{activeMonths:S,onDateFocus:C,onDateSelect:T,goToPreviousMonths:O,goToNextMonths:D,goToDate:P}=ip({startDate:y,endDate:x,focusedInput:"startDate",onDatesChange:e=>{const t=((e,t,n,r)=>{let o=t,a=n;const i=r.startDate;return i?("startDate"===e?(!a||a&&i.getTime()<=a.getTime())&&(o=i):"endDate"===e&&(!o||o&&i.getTime()>=o.getTime())&&(a=i),{newStartDate:o,newEndDate:a}):{newStartDate:o,newEndDate:a}})(f,y,x,e),{newStartDate:n,newEndDate:r}=t;n!==y&&(null==i||i(n??new Date),w(n)),r!==x&&"range"===o&&(null==l||l(r??new Date),_(r))},numberOfMonths:1});r.useEffect((()=>{const e=Ud(c,p,h);if(Gd(e.date,y)||w(e.isValid?e.date:null),"range"===o){const e=Ud(d,p,h);Gd(e.date,x)||_(e.isValid?e.date:null)}}),[c,d,o,p,h,y,x]),r.useEffect((()=>{y&&C(y)}),[y]),r.useEffect((()=>{x&&C(x)}),[x]);const N=nu(t,e);return Ge(lp.Provider,{value:{size:n,mode:o,startDate:y,endDate:x,onDateFocus:C,onDateSelect:T,goToPreviousMonths:O,goToNextMonths:D,goToDate:P,changeYearMode:k,setChangeYearMode:E},children:Ge(gp,{...g,className:Qe({...ws(g)},v.className,g.className,Vc.root,Vc[n],e&&Vc.open,a&&Vc.disabled),rootRef:b,style:{...N,...g.style??{}},arrowOffset:m,children:Ge("div",{className:Qe(Vc.container),children:S.map(((e,t)=>Ge(mp,{year:e.year,month:e.month,firstDayOfWeek:0,size:n},`${e.year}-${e.month}-${t}`)))})})})};yp.classes=Vc;const wp=(e,t)=>t&&(null==e?void 0:e.composedPath().includes(t))||!1,xp=({label:e,size:t="large",value:n,onChange:o,withCalendar:a=!0,variant:i="underlined",...l})=>{const s=bs(l),u=r.useRef(null),c=r.useRef(null),[d,f]=r.useState(!1),p=void 0!==n,h=Ye({value:n,defaultValue:"",onChange:o,getInput:()=>{var e;return null==(e=u.current)?void 0:e.querySelector(`input.${$d.classes.input}`)}});return Ge("div",{id:(l.id||"date-picker")+"-input",ref:u,className:Qe({...ws(l)},l.className,s.className,td.root,td[t]),children:Ge($d,{label:e,size:t,variant:i,icon:a&&Ge(Us,{color:"primary"}),onIconClick:()=>f((e=>!e)),value:p||d?h.value:void 0,onChange:h.onChange,calendarIconRef:c,...l,children:Ge(au,{id:"calendar",children:a&&Ge(yp,{...ys(l),onStartDateChange:e=>(e=>h.setValue(Hd(e)))(e),open:d,onCalendarClickaway:e=>{wp(e,c.current)||f(!1)},handleRef:u,startDate:h.value,disabled:l.disabled,className:td.calendar})})})})};xp.classes=td;const _p=({title:e,information:t,onClose:n,size:r="large",toastRef:o,children:a,icon:i,actions:l,...s})=>{const u=bs(s),c=!t,d=void 0===i?Ns:i;return We("div",{ref:o,...ws(s),className:Qe(s.className,u.className,Cd.root,Cd[r]),children:[Ge("div",{className:Qe(c?Cd.inlineIconContainer:Cd.columnIconContainer),children:d&&Ge(d,{color:"primary",className:Cd.icon})}),We("div",{className:c?Cd.inlineContainer:Cd.columnContainer,children:[We("div",{className:Qe(Cd.textContainer),children:[!!e&&Ge(Vs,{className:Cd.title,component:"div",variant:"small"===r?"label2":"label1",children:e}),!!t&&Ge(Vs,{className:Cd.information,component:"div",variant:"small"===r?"label2":"label1",children:t})]}),!!l&&Ge("div",{className:Qe(Cd.buttonContainer,c?Cd.inlineButtonContainer:Cd.columnButtonContainer),children:l})]}),Ge(Bu,{onClick:n,className:Cd.closeButton,size:"medium",children:Ge(Ps,{color:"primary"})})]})};_p.classes=Cd;var kp=(e,t)=>(e=>"function"==typeof e)(e)?e(t):e,Ep=(()=>{let e=0;return()=>(++e).toString()})(),Sp=new Map,Cp=e=>{if(Sp.has(e))return;let t=setTimeout((()=>{Sp.delete(e),Pp({type:4,toastId:e})}),1e3);Sp.set(e,t)},Tp=(e,t)=>{switch(t.type){case 0:return{...e,toasts:[t.toast,...e.toasts].slice(0,20)};case 1:return t.toast.id&&(e=>{let t=Sp.get(e);t&&clearTimeout(t)})(t.toast.id),{...e,toasts:e.toasts.map((e=>e.id===t.toast.id?{...e,...t.toast}:e))};case 2:let{toast:n}=t;return e.toasts.find((e=>e.id===n.id))?Tp(e,{type:1,toast:n}):Tp(e,{type:0,toast:n});case 3:let{toastId:r}=t;return r?Cp(r):e.toasts.forEach((e=>{Cp(e.id)})),{...e,toasts:e.toasts.map((e=>e.id===r||void 0===r?{...e,visible:!1}:e))};case 4:return void 0===t.toastId?{...e,toasts:[]}:{...e,toasts:e.toasts.filter((e=>e.id!==t.toastId))};case 5:return{...e,pausedAt:t.time};case 6:let o=t.time-(e.pausedAt||0);return{...e,pausedAt:void 0,toasts:e.toasts.map((e=>({...e,pauseDuration:e.pauseDuration+o})))}}},Op=[],Dp={toasts:[],pausedAt:void 0},Pp=e=>{Dp=Tp(Dp,e),Op.forEach((e=>{e(Dp)}))},Np={blank:4e3,error:4e3,success:2e3,loading:1/0,custom:4e3},Ap=e=>(t,n)=>{let r=((e,t="blank",n)=>({createdAt:Date.now(),visible:!0,type:t,ariaProps:{role:"status","aria-live":"polite"},message:e,pauseDuration:0,...n,id:(null==n?void 0:n.id)||Ep()}))(t,e,n);return Pp({type:2,toast:r}),r.id},Ip=(e,t)=>Ap("blank")(e,t);Ip.error=Ap("error"),Ip.success=Ap("success"),Ip.loading=Ap("loading"),Ip.custom=Ap("custom"),Ip.dismiss=e=>{Pp({type:3,toastId:e})},Ip.remove=e=>Pp({type:4,toastId:e}),Ip.promise=(e,t,n)=>{let r=Ip.loading(t.loading,{...n,...null==n?void 0:n.loading});return e.then((e=>(Ip.success(kp(t.success,e),{id:r,...n,...null==n?void 0:n.success}),e))).catch((e=>{Ip.error(kp(t.error,e),{id:r,...n,...null==n?void 0:n.error})})),e};var Lp=(e,t)=>{Pp({type:1,toast:{id:e,height:t}})},Rp=()=>{Pp({type:5,time:Date.now()})},jp=e=>{let{toasts:t,pausedAt:n}=((e={})=>{let[t,n]=r.useState(Dp);r.useEffect((()=>(Op.push(n),()=>{let e=Op.indexOf(n);e>-1&&Op.splice(e,1)})),[t]);let o=t.toasts.map((t=>{var n,r;return{...e,...e[t.type],...t,duration:t.duration||(null==(n=e[t.type])?void 0:n.duration)||(null==e?void 0:e.duration)||Np[t.type],style:{...e.style,...null==(r=e[t.type])?void 0:r.style,...t.style}}}));return{...t,toasts:o}})(e);r.useEffect((()=>{if(n)return;let e=Date.now(),r=t.map((t=>{if(t.duration===1/0)return;let n=(t.duration||0)+t.pauseDuration-(e-t.createdAt);if(!(n<0))return setTimeout((()=>Ip.dismiss(t.id)),n);t.visible&&Ip.dismiss(t.id)}));return()=>{r.forEach((e=>e&&clearTimeout(e)))}}),[t,n]);let o=r.useCallback((()=>{n&&Pp({type:6,time:Date.now()})}),[n]),a=r.useCallback(((e,n)=>{let{reverseOrder:r=!1,gutter:o=8,defaultPosition:a}=n||{},i=t.filter((t=>(t.position||a)===(e.position||a)&&t.height)),l=i.findIndex((t=>t.id===e.id)),s=i.filter(((e,t)=>t<l&&e.visible)).length;return i.filter((e=>e.visible)).slice(...r?[s+1]:[0,s]).reduce(((e,t)=>e+(t.height||0)+o),0)}),[t]);return{toasts:t,handlers:{updateHeight:Lp,startPause:Rp,endPause:o,calculateOffset:a}}};const Mp=r.createContext(null),Fp=({toastsPropsMap:e,className:t,...n})=>{const{toasts:r,handlers:o}=jp(),{startPause:a,endPause:i,calculateOffset:l,updateHeight:s}=o;return Ge(au,{id:"toast",children:r.map((r=>{const o=e.get(r.id);if(!o)return console.warn("Could not find toast with id",r.id),null;const{position:u,duration:c,...d}=o,f=l(r,{reverseOrder:!1,gutter:8,defaultPosition:u}),{transform:p,positionClassName:h}=((e,t)=>{if(!e)return{positionClassName:"",transform:`translateY(${t}px)`};let n="";const r=e.includes("center"),o=e.includes("bottom");return"top-left"===e?n=Td.topLeft:"top-center"===e?n=Td.topCenter:"top-right"===e?n=Td.topRight:"bottom-left"===e?n=Td.bottomLeft:"bottom-center"===e?n=Td.bottomCenter:"bottom-right"===e&&(n=Td.bottomRight),{positionClassName:n,transform:`translateY(${o?-t:t}px) translateX(${r?"-50%":"0"})`}})(u,f);return Ge("div",{onMouseEnter:a,onMouseLeave:i,...n,className:Qe(Td.toastContainer,h,t),style:{transform:p,...n.style},children:Ge(_p,{className:Qe(d.className),toastRef:e=>{if(e&&"number"!=typeof r.height){const t=e.getBoundingClientRect().height;s(r.id,t)}},...d,style:{opacity:r.visible?1:0,...d.style},onClose:()=>{var e;Ip.dismiss(r.id),null==(e=d.onClose)||e.call(d)}},r.id)},`container-${r.id}`)}))})};const Bp=({size:e="large",disabled:t,variant:n="outlined",children:r,...o})=>{const a=bs(o);return Ge("div",{...ws(o),className:Qe(a.className,o.className,Od.root,Od[e],Od[n],t&&Od.disabled),children:Ge(mu.Provider,{value:{size:e,variant:n,disabled:t},children:r})})};Bp.classes=Od;const zp=({startValue:e,endValue:t,onStartDateChange:n,onEndDateChange:o,size:a="large",variant:i="underlined",withCalendar:l=!0,label:s,supportingText:u,disabled:c,...d})=>{const f=bs(d),p=r.useRef(null),h=r.useRef(null),m=r.useRef(null),[g,v]=r.useState(null),b=void 0!==e,y=void 0!==t,w=Ye({value:e,defaultValue:"",onChange:n,getInput:()=>{var e;return null==(e=p.current)?void 0:e.querySelectorAll(`input.${$d.classes.input}`)[0]}}),x=Ye({value:t,defaultValue:"",onChange:o,getInput:()=>{var e;return null==(e=p.current)?void 0:e.querySelectorAll(`input.${$d.classes.input}`)[1]}}),_={...d,size:a,label:void 0,supportingText:void 0},k="startDate"===g||"endDate"===g;return We("div",{ref:p,className:Qe({...ws(d)},f.className,d.className,Dd.root,Dd[a],l&&Dd.withCalendar,k&&Dd.openCalendar,c&&Dd.disabled),children:[s&&Ge(Vs,{className:Dd.label,variant:"label2",component:"label",children:s}),We("div",{className:Qe(d.className,Dd.inputContainer,"outlined"===i&&Dd.outlined),children:[Ge($d,{variant:i,calendarIconRef:m,icon:l&&Ge(Us,{color:"primary"}),value:b||k?w.value:void 0,onIconClick:()=>v((e=>Zd(e,"startDate"))),onChange:e=>{x.value&&!Qd(e.target.value,x.value)||w.onChange(e)},..._}),Ge("div",{className:Dd.separator}),Ge($d,{variant:i,calendarIconRef:h,icon:l&&Ge(Us,{color:"primary"}),value:y||k?x.value:void 0,onIconClick:()=>v((e=>Zd(e,"endDate"))),onChange:e=>{w.value&&!Qd(w.value,e.target.value)||x.onChange(e)},..._})]}),u&&Ge("div",{className:Qe(Dd.supportingText),children:Ge(Vs,{variant:"label2",component:"p",children:u})}),l&&Ge(au,{id:"calendar",children:Ge(yp,{...ys(d),onStartDateChange:e=>{w.setValue(Hd(e)),v("endDate")},onEndDateChange:e=>x.setValue(Hd(e)),onCalendarClickaway:e=>{wp(e,h.current)||wp(e,m.current)||v(null)},calendarType:g,open:k,onClose:()=>v(null),handleRef:p,mode:"range",disabled:c,startDate:w.value,endDate:x.value,className:Dd.calendar,tooltipArrowOffset:Yd(g,a),size:a})})]})};zp.classes=Dd,t.AddIcon=ks,t.ArrowForwardIcon=Ss,t.Autocomplete=su,t.Badge=cu,t.Breadcrumb=hu,t.BreadcrumbItem=fu,t.Button=vu,t.ButtonGroup=Bp,t.CALENDAR_MAX_YEAR=bp,t.CALENDAR_MIN_YEAR=vp,t.Calendar=yp,t.CalendarIcon=Us,t.Card=wu,t.CardBody=_u,t.CardHeader=Eu,t.CheckIcon=Ds,t.Checkbox=Ou,t.CheckboxGroup=Pu,t.CheckboxIcon=Ts,t.CheckboxOutlineBlankIcon=Os,t.ChevronDownIcon=Es,t.ChevronLeftIcon=js,t.ChevronRightIcon=Ms,t.ChevronUpIcon=Cs,t.CloseIcon=Ps,t.Collapse=Lu,t.CollapseHeader=Au,t.DateField=$d,t.DatePicker=xp,t.DateRangePicker=zp,t.Dropdown=ju,t.DropdownItem=Gs,t.DropdownMenu=ru,t.ErrorIcon=Ns,t.FolderIcon=As,t.IconButton=Bu,t.IconButtonGroup=$u,t.KeyboardReturnIcon=Is,t.LSD_NAMESPACE="lsd",t.LsdIcon=_s,t.MenuIcon=Ls,t.Modal=Fd,t.ModalBody=Bd,t.ModalFooter=zd,t.MoreIcon=Rs,t.NumberInput=Md,t.PickIcon=Bs,t.Quote=Hu,t.RadioButton=Gu,t.RadioButtonCheckedIcon=$s,t.RadioButtonGroup=Zu,t.RadioButtonIcon=zs,t.RemoveIcon=Hs,t.SearchIcon=Fs,t.THEME_BREAKPOINTS=fs,t.THEME_TYPOGRAPHY_PROPERTIES=ms,t.THEME_TYPOGRAPHY_VARIANTS=ps,t.THEME_VARIANT_PROPERTIES=["typography"],t.TabItem=Xu,t.Table=ac,t.TableBody=Ju,t.TableHeader=tc,t.TableItem=lc,t.TableRow=uc,t.Tabs=bc,t.Tag=wc,t.TextField=Sc,t.ThemeProvider=({theme:e,children:t,injectCssVars:n=!0})=>Ge(Rd,{children:Ge(Ld,{children:We(jd.Provider,{value:{theme:e},children:[Ge(Ad,{theme:e}),n&&Ge(a.Global,{styles:e.globalStyles}),Ge(a.ThemeProvider,{theme:e,children:t})]})})}),t.Toast=_p,t.ToastContext=Mp,t.ToastProvider=({providerToastOptions:e,children:t,...n})=>{const[o,a]=r.useState(new Map);return We(Mp.Provider,{value:(t,n)=>{const r={...e,...n},o=Ip("",{duration:null==r?void 0:r.duration});t&&a((e=>{const n=new Map(e);return n.set(o,{...t,...r}),n}))},children:[t,Ge(Fp,{toastsPropsMap:o,...n})]})},t.TooltipBase=gp,t.Typography=Vs,t.createTheme=jc,t.createThemeGlobalStyles=Tc,t.defaultThemes=Fc,t.useTheme=()=>r.useContext(jd).theme??Fc.light,t.useToast=function(){const e=r.useContext(Mp);if(!e)throw new Error("useToast must be used within a ToastProvider");return e},t.withTheme=e=>t=>e(t)},21204:(e,t,n)=>{"use strict";n.d(t,{Z:()=>p});var r=n(67294),o=n(87462),a=n(68356),i=n.n(a),l=n(16887);const s={"0b46e8e7":[()=>n.e(5387).then(n.bind(n,94644)),"@site/docs/publications.md",94644],"0d54ff0d":[()=>n.e(4248).then(n.bind(n,36733)),"@site/rlog/2022-04-12-introducing-nwaku.mdx?truncated=true",36733],"124805df":[()=>n.e(2206).then(n.t.bind(n,9935,19)),"~blog/blog/rlog-12b.json",9935],"12da0170":[()=>n.e(8056).then(n.bind(n,16486)),"@site/rlog/2021-06-04-presenting-js-waku.mdx",16486],"13a255f1":[()=>n.e(3415).then(n.bind(n,94866)),"@site/rlog/2022-05-17-noise.mdx?truncated=true",94866],"158719ed":[()=>n.e(4763).then(n.bind(n,53590)),"@site/rlog/2020-02-7-dns-based-discovery.mdx?truncated=true",53590],"15a93281":[()=>n.e(2594).then(n.bind(n,32788)),"@site/rlog/2020-02-7-dns-based-discovery.mdx",32788],17896441:[()=>Promise.all([n.e(532),n.e(219),n.e(7918)]).then(n.bind(n,59047)),"@theme/DocItem",59047],"18961ce6":[()=>n.e(7975).then(n.bind(n,63941)),"@site/rlog/2021-10-25-waku-v1-vs-waku-v2.mdx?truncated=true",63941],"18a94246":[()=>n.e(5543).then(n.bind(n,37553)),"@site/rlog/2024-08-23-state-separation.mdx",37553],"191d05a9":[()=>n.e(14).then(n.bind(n,89670)),"@site/rlog/2022-11-08-waku-for-all-decentralize-applications.mdx",89670],"1be78505":[()=>Promise.all([n.e(532),n.e(9514)]).then(n.bind(n,93687)),"@theme/DocPage",93687],"1e4c069f":[()=>n.e(6424).then(n.t.bind(n,85804,19)),"/home/jenkins/workspace/website/vac.dev/.docusaurus/docusaurus-plugin-content-blog/blog/plugin-route-context-module-100.json",85804],"1e7f5ce0":[()=>n.e(6297).then(n.bind(n,91652)),"@site/rlog/2022-05-17-noise.mdx",91652],"1f3523a7":[()=>n.e(8648).then(n.t.bind(n,79749,19)),"~docs/Docs/version-current-metadata-prop-751.json",79749],"2056d17e":[()=>n.e(819).then(n.bind(n,30780)),"@site/rlog/2019-12-03-fixing-whisper-with-waku.mdx",30780],"2858c6ff":[()=>n.e(7604).then(n.bind(n,87233)),"@site/rlog/2024-05-13-rln-v3.mdx?truncated=true",87233],"29ae586d":[()=>n.e(1158).then(n.bind(n,99327)),"@site/rlog/2021-03-03-rln-relay.mdx",99327],"2c2dd814":[()=>Promise.all([n.e(532),n.e(1755),n.e(5035)]).then(n.bind(n,58693)),"@site/docs/community.mdx",58693],"2d6b2291":[()=>n.e(5524).then(n.bind(n,37818)),"@site/rlog/2019-07-19-p2p-data-sync-for-mobile.mdx?truncated=true",37818],"2e8c87b8":[()=>n.e(2585).then(n.bind(n,93605)),"@site/rlog/2024-08-27-Zkvm.mdx?truncated=true",93605],"2ef0cd56":[()=>n.e(7972).then(n.t.bind(n,54910,19)),"~blog/blog/rlog-page-4-205.json",54910],"382fdf29":[()=>n.e(5077).then(n.bind(n,37497)),"@site/rlog/2023-11-07-rln-relay.mdx?truncated=true",37497],"384035e2":[()=>n.e(305).then(n.bind(n,66729)),"@site/rlog/2020-09-28-waku-v2-update.mdx",66729],"38dc9501":[()=>n.e(4441).then(n.bind(n,58510)),"@site/rlog/2023-04-24-device-pairing-in-js-waku-and-go-waku.mdx?truncated=true",58510],"39f27fb8":[()=>n.e(3171).then(n.bind(n,98488)),"@site/rlog/2023-09-27-gossipimprovements.mdx?truncated=true",98488],"3b467599":[()=>n.e(5601).then(n.bind(n,4956)),"@site/rlog/2023-08-28-Nescience.mdx",4956],"3ec022cb":[()=>n.e(3607).then(n.bind(n,41412)),"@site/rlog/2020-07-01-waku-v2-pitch.mdx",41412],"3f082616":[()=>n.e(2819).then(n.bind(n,97507)),"@site/rlog/2020-02-14-waku-update.mdx?truncated=true",97507],"3f64d9a3":[()=>n.e(2282).then(n.bind(n,81283)),"@site/rlog/2021-06-04-presenting-js-waku.mdx?truncated=true",81283],"3f781295":[()=>n.e(1599).then(n.bind(n,67691)),"@site/docs/vips.md",67691],"4a8210e4":[()=>n.e(959).then(n.bind(n,76926)),"@site/rlog/2019-10-04-remote-log.mdx?truncated=true",76926],"4ba7e5a3":[()=>n.e(9735).then(n.bind(n,10238)),"@site/docs/contribute.md",10238],"4f94ff0f":[()=>n.e(1569).then(n.bind(n,80724)),"@site/docs/deepresearch.md",80724],"500a151f":[()=>n.e(4545).then(n.bind(n,40536)),"@site/docs/terms.md",40536],"544f54cc":[()=>n.e(5705).then(n.bind(n,33879)),"@site/rlog/2023-04-03-waku-as-a-network.mdx?truncated=true",33879],"5a7c4f09":[()=>n.e(5417).then(n.bind(n,33861)),"@site/rlog/2019-08-02-vac-overview.mdx",33861],"67b45d3c":[()=>n.e(8161).then(n.bind(n,40100)),"@site/rlog/2023-04-24-device-pairing-in-js-waku-and-go-waku.mdx",40100],"6abf00de":[()=>n.e(5025).then(n.bind(n,95643)),"@site/rlog/2020-07-01-waku-v2-pitch.mdx?truncated=true",95643],"6f1f8c5f":[()=>n.e(7495).then(n.bind(n,2358)),"@site/rlog/2019-12-03-fixing-whisper-with-waku.mdx?truncated=true",2358],"6f6bcf93":[()=>n.e(242).then(n.bind(n,81470)),"@site/rlog/2020-09-28-waku-v2-update.mdx?truncated=true",81470],"6facda94":[()=>n.e(6125).then(n.bind(n,27500)),"@site/rlog/2022-11-08-waku-for-all-decentralize-applications.mdx?truncated=true",27500],"74c00f84":[()=>n.e(6676).then(n.bind(n,12008)),"@site/rlog/2020-11-10-waku-v2-ethereum-messaging.mdx?truncated=true",12008],"7af80316":[()=>n.e(8761).then(n.bind(n,60129)),"@site/rlog/2020-04-9-kademlia-to-discv5.mdx?truncated=true",60129],"7b019678":[()=>n.e(3854).then(n.bind(n,51694)),"@site/rlog/2021-12-03-ethics-surveillance-tech.mdx",51694],"7b0e1478":[()=>n.e(3877).then(n.bind(n,73475)),"@site/rlog/2024-07-19-bloomfilter.mdx",73475],"7d3f2fdb":[()=>n.e(7969).then(n.bind(n,98190)),"@site/rlog/2022-11-04-building-privacy-protecting-infrastructure.mdx?truncated=true",98190],"8161b354":[()=>n.e(8398).then(n.bind(n,2978)),"@site/docs/rfcprocess.md",2978],83575890:[()=>n.e(1525).then(n.bind(n,93938)),"@site/rlog/2020-04-27-feasibility-discv5.mdx?truncated=true",93938],"84dd0cf8":[()=>n.e(6149).then(n.bind(n,63282)),"@site/rlog/2023-08-28-Nescience.mdx?truncated=true",63282],"84f8336a":[()=>n.e(1742).then(n.bind(n,6411)),"@site/rlog/2020-04-16-wechat-replacement-need.mdx?truncated=true",6411],"8779ed83":[()=>n.e(7562).then(n.bind(n,87481)),"@site/rlog/2023-11-07-rln-relay.mdx",87481],"8c1443cc":[()=>n.e(5302).then(n.t.bind(n,47407,19)),"~blog/blog/rlog-page-3-95d.json",47407],"8c5da4da":[()=>n.e(1923).then(n.bind(n,65641)),"@site/docs/privacy-policy.md",65641],"8e79cc52":[()=>n.e(3274).then(n.bind(n,68350)),"@site/docs/media.md",68350],"91ce8bda":[()=>n.e(7467).then(n.bind(n,52051)),"@site/rlog/2023-04-03-waku-as-a-network.mdx",52051],"95b96bb9":[()=>n.e(3561).then(n.t.bind(n,24577,19)),"~blog/blog/blog-post-list-prop-blog.json",24577],96524732:[()=>n.e(2982).then(n.bind(n,23877)),"@site/rlog/2019-11-08-feasibility-semaphore-rate-limiting-zksnarks.mdx",23877],"99c49682":[()=>n.e(6807).then(n.t.bind(n,10319,19)),"~blog/blog/rlog-archive-cb2.json",10319],"99f69f8e":[()=>n.e(865).then(n.bind(n,96058)),"@site/rlog/2022-05-09-ambient-peer-discovery.mdx",96058],"9e34dc04":[()=>n.e(9924).then(n.bind(n,26810)),"@site/rlog/2022-04-12-introducing-nwaku.mdx",26810],"9e396004":[()=>n.e(5328).then(n.bind(n,12134)),"@site/rlog/2020-11-10-waku-v2-ethereum-messaging.mdx",12134],"9e4087bc":[()=>n.e(3608).then(n.bind(n,8387)),"@theme/BlogArchivePage",8387],"9fb2a6b1":[()=>n.e(8381).then(n.bind(n,84428)),"@site/rlog/2021-08-06-coscup-waku-ethereum.mdx?truncated=true",84428],a413eb42:[()=>Promise.all([n.e(532),n.e(1755),n.e(9834)]).then(n.bind(n,73673)),"@site/docs/join-us.mdx",73673],a6aa9e1f:[()=>Promise.all([n.e(532),n.e(219),n.e(5253),n.e(3089)]).then(n.bind(n,68854)),"@theme/BlogListPage",68854],a71c3513:[()=>n.e(7791).then(n.bind(n,18966)),"@site/rlog/2024-05-03-rln-light-verifiers.mdx",18966],ad3e391a:[()=>n.e(2276).then(n.bind(n,27221)),"@site/docs/vsus.md",27221],b0a36ee8:[()=>n.e(1618).then(n.bind(n,46643)),"@site/rlog/2021-10-25-waku-v1-vs-waku-v2.mdx",46643],b6f6cb50:[()=>n.e(1327).then(n.bind(n,72932)),"@site/rlog/2022-07-22-relay-anonymity.mdx",72932],b8fd8041:[()=>n.e(4588).then(n.bind(n,61357)),"@site/rlog/2024-08-27-Zkvm.mdx",61357],bd3d84fb:[()=>n.e(7746).then(n.bind(n,58968)),"@site/rlog/2023-09-27-gossipimprovements.mdx",58968],bfd2a918:[()=>n.e(689).then(n.t.bind(n,12342,19)),"/home/jenkins/workspace/website/vac.dev/.docusaurus/docusaurus-plugin-content-docs/Docs/plugin-route-context-module-100.json",12342],c2965f87:[()=>n.e(4991).then(n.bind(n,61356)),"@site/rlog/2021-03-03-rln-relay.mdx?truncated=true",61356],c377a04b:[()=>n.e(6971).then(n.bind(n,42206)),"@site/docs/index.md",42206],c7770090:[()=>n.e(2702).then(n.bind(n,4304)),"@site/rlog/2019-08-02-vac-overview.mdx?truncated=true",4304],c8894de3:[()=>n.e(1869).then(n.bind(n,87608)),"@site/rlog/2022-05-09-ambient-peer-discovery.mdx?truncated=true",87608],cbf8cf19:[()=>n.e(3231).then(n.bind(n,22584)),"@site/rlog/2024-08-23-state-separation.mdx?truncated=true",22584],ccc49370:[()=>Promise.all([n.e(532),n.e(219),n.e(5253),n.e(6103)]).then(n.bind(n,4297)),"@theme/BlogPostPage",4297],cde6c892:[()=>n.e(1969).then(n.t.bind(n,44041,19)),"~blog/blog/rlog-page-2-639.json",44041],d0c5fcac:[()=>n.e(9313).then(n.bind(n,37148)),"@site/rlog/2020-02-14-waku-update.mdx",37148],db32d859:[()=>n.e(6653).then(n.bind(n,79307)),"@site/docs/security.md",79307],db40b3a8:[()=>n.e(5089).then(n.bind(n,50170)),"@site/rlog/2024-05-13-rln-v3.mdx",50170],db970d56:[()=>n.e(1221).then(n.bind(n,55941)),"@site/rlog/2019-11-08-feasibility-semaphore-rate-limiting-zksnarks.mdx?truncated=true",55941],e22c7a04:[()=>n.e(1750).then(n.bind(n,98071)),"@site/rlog/2022-11-04-building-privacy-protecting-infrastructure.mdx",98071],e6b418ad:[()=>n.e(2614).then(n.bind(n,5923)),"@site/rlog/2020-04-16-wechat-replacement-need.mdx",5923],e954d700:[()=>n.e(7120).then(n.bind(n,85498)),"@site/rlog/2019-07-19-p2p-data-sync-for-mobile.mdx",85498],ec8fd1ee:[()=>n.e(7070).then(n.bind(n,91723)),"@site/rlog/2022-07-22-relay-anonymity.mdx?truncated=true",91723],f1787e6d:[()=>n.e(2223).then(n.bind(n,85790)),"@site/rlog/2019-10-04-remote-log.mdx",85790],f3c329e5:[()=>n.e(4633).then(n.bind(n,72897)),"@site/rlog/2021-08-06-coscup-waku-ethereum.mdx",72897],f40b13b8:[()=>n.e(7846).then(n.bind(n,16732)),"@site/rlog/2020-04-9-kademlia-to-discv5.mdx",16732],f643ab5d:[()=>n.e(4046).then(n.bind(n,86269)),"@site/rlog/2021-12-03-ethics-surveillance-tech.mdx?truncated=true",86269],f7ba2fd8:[()=>n.e(3228).then(n.bind(n,94433)),"@site/rlog/2020-04-27-feasibility-discv5.mdx",94433],f8d84f88:[()=>n.e(4733).then(n.bind(n,74826)),"@site/docs/principles.md",74826],fdd3b45a:[()=>n.e(8581).then(n.bind(n,67486)),"@site/rlog/2024-05-03-rln-light-verifiers.mdx?truncated=true",67486],feda84cd:[()=>n.e(1016).then(n.bind(n,45751)),"@site/rlog/2024-07-19-bloomfilter.mdx?truncated=true",45751]};function u(e){let{error:t,retry:n,pastDelay:o}=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"))):o?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 c=n(66916),d=n(66041);function f(e,t){if("*"===e)return i()({loading:u,loader:()=>Promise.all([n.e(532),n.e(9481)]).then(n.bind(n,89481)),modules:["@theme/NotFound"],webpack:()=>[89481],render(e,t){const n=e.default;return r.createElement(d.z,{value:{plugin:{name:"native",id:"default"}}},r.createElement(n,t))}});const a=l[`${e}-${t}`],f={},p=[],h=[],m=(0,c.Z)(a);return Object.entries(m).forEach((e=>{let[t,n]=e;const r=s[n];r&&(f[t]=r[0],p.push(r[1]),h.push(r[2]))})),i().Map({loading:u,loader:f,modules:p,webpack:()=>h,render(t,n){const i=JSON.parse(JSON.stringify(a));Object.entries(t).forEach((t=>{let[n,r]=t;const o=r.default;if(!o)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 o&&"function"!=typeof o||Object.keys(r).filter((e=>"default"!==e)).forEach((e=>{o[e]=r[e]}));let a=i;const l=n.split(".");l.slice(0,-1).forEach((e=>{a=a[e]})),a[l[l.length-1]]=o}));const l=i.__comp;delete i.__comp;const s=i.__context;return delete i.__context,r.createElement(d.z,{value:s},r.createElement(l,(0,o.Z)({},i,n)))}})}const p=[{path:"/rlog",component:f("/rlog","a65"),exact:!0},{path:"/rlog/archive",component:f("/rlog/archive","242"),exact:!0},{path:"/rlog/building-privacy-protecting-infrastructure",component:f("/rlog/building-privacy-protecting-infrastructure","b52"),exact:!0},{path:"/rlog/device-pairing-in-js-waku-and-go-waku",component:f("/rlog/device-pairing-in-js-waku-and-go-waku","6e6"),exact:!0},{path:"/rlog/dns-based-discovery",component:f("/rlog/dns-based-discovery","f9b"),exact:!0},{path:"/rlog/ethics-surveillance-tech",component:f("/rlog/ethics-surveillance-tech","872"),exact:!0},{path:"/rlog/feasibility-discv5",component:f("/rlog/feasibility-discv5","2c3"),exact:!0},{path:"/rlog/feasibility-semaphore-rate-limiting-zksnarks",component:f("/rlog/feasibility-semaphore-rate-limiting-zksnarks","cff"),exact:!0},{path:"/rlog/fixing-whisper-with-waku",component:f("/rlog/fixing-whisper-with-waku","4ec"),exact:!0},{path:"/rlog/future-of-waku-network",component:f("/rlog/future-of-waku-network","100"),exact:!0},{path:"/rlog/GossipSub Improvements",component:f("/rlog/GossipSub Improvements","4fc"),exact:!0},{path:"/rlog/introducing-nwaku",component:f("/rlog/introducing-nwaku","9eb"),exact:!0},{path:"/rlog/kademlia-to-discv5",component:f("/rlog/kademlia-to-discv5","2d3"),exact:!0},{path:"/rlog/membership-with-bloom-filters-and-cuckoo-filters",component:f("/rlog/membership-with-bloom-filters-and-cuckoo-filters","b1b"),exact:!0},{path:"/rlog/Nescience-A-zkVM-leveraging-hiding-properties",component:f("/rlog/Nescience-A-zkVM-leveraging-hiding-properties","605"),exact:!0},{path:"/rlog/Nescience-state-separation-architecture",component:f("/rlog/Nescience-state-separation-architecture","72d"),exact:!0},{path:"/rlog/p2p-data-sync-for-mobile",component:f("/rlog/p2p-data-sync-for-mobile","8e8"),exact:!0},{path:"/rlog/page/2",component:f("/rlog/page/2","9df"),exact:!0},{path:"/rlog/page/3",component:f("/rlog/page/3","dbe"),exact:!0},{path:"/rlog/page/4",component:f("/rlog/page/4","7f7"),exact:!0},{path:"/rlog/presenting-js-waku",component:f("/rlog/presenting-js-waku","380"),exact:!0},{path:"/rlog/remote-log",component:f("/rlog/remote-log","5c3"),exact:!0},{path:"/rlog/rln-anonymous-dos-prevention",component:f("/rlog/rln-anonymous-dos-prevention","535"),exact:!0},{path:"/rlog/rln-light-verifiers",component:f("/rlog/rln-light-verifiers","657"),exact:!0},{path:"/rlog/rln-relay",component:f("/rlog/rln-relay","2b7"),exact:!0},{path:"/rlog/rln-v3",component:f("/rlog/rln-v3","f91"),exact:!0},{path:"/rlog/vac-overview",component:f("/rlog/vac-overview","13b"),exact:!0},{path:"/rlog/waku-for-all",component:f("/rlog/waku-for-all","8f7"),exact:!0},{path:"/rlog/waku-update",component:f("/rlog/waku-update","7bc"),exact:!0},{path:"/rlog/waku-v1-v2-bandwidth-comparison",component:f("/rlog/waku-v1-v2-bandwidth-comparison","a00"),exact:!0},{path:"/rlog/waku-v2-ethereum-coscup",component:f("/rlog/waku-v2-ethereum-coscup","f86"),exact:!0},{path:"/rlog/waku-v2-ethereum-messaging",component:f("/rlog/waku-v2-ethereum-messaging","d5b"),exact:!0},{path:"/rlog/waku-v2-plan",component:f("/rlog/waku-v2-plan","943"),exact:!0},{path:"/rlog/waku-v2-update",component:f("/rlog/waku-v2-update","73e"),exact:!0},{path:"/rlog/wakuv2-apd",component:f("/rlog/wakuv2-apd","f04"),exact:!0},{path:"/rlog/wakuv2-noise",component:f("/rlog/wakuv2-noise","6d7"),exact:!0},{path:"/rlog/wakuv2-relay-anon",component:f("/rlog/wakuv2-relay-anon","dc8"),exact:!0},{path:"/rlog/wechat-replacement-need",component:f("/rlog/wechat-replacement-need","4e9"),exact:!0},{path:"/rlog/zkVM-explorations",component:f("/rlog/zkVM-explorations","337"),exact:!0},{path:"/",component:f("/","4d6"),routes:[{path:"/",component:f("/","d22"),exact:!0,sidebar:"main"},{path:"/community",component:f("/community","051"),exact:!0},{path:"/contribute",component:f("/contribute","00f"),exact:!0,sidebar:"main"},{path:"/deepresearch",component:f("/deepresearch","40e"),exact:!0,sidebar:"main"},{path:"/join-us",component:f("/join-us","63f"),exact:!0},{path:"/media",component:f("/media","895"),exact:!0},{path:"/principles",component:f("/principles","ef3"),exact:!0,sidebar:"main"},{path:"/privacy-policy",component:f("/privacy-policy","4cd"),exact:!0},{path:"/publications",component:f("/publications","be1"),exact:!0},{path:"/rfcprocess",component:f("/rfcprocess","d12"),exact:!0},{path:"/security",component:f("/security","2fb"),exact:!0},{path:"/terms",component:f("/terms","37d"),exact:!0},{path:"/vips",component:f("/vips","fef"),exact:!0,sidebar:"main"},{path:"/vsus",component:f("/vsus","e2a"),exact:!0,sidebar:"main"}]},{path:"*",component:f("*")}]},79578:(e,t,n)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.createPromise=t.ResultType=void 0;const r=n(70655),o=n(78007),a=n(84647),i=n(32438),l=n(58263),s=r.__importStar(n(96059)),u=e=>{let{versionUrl:t,searchContextByPaths:n}=e,r=window.location.pathname;if(r=r.endsWith("/")?r:r+"/",!Array.isArray(n)||!r.startsWith(t))return"";const o=r.substring(t.length);return n.find((e=>o===e||o.startsWith(`${e}/`)))??""};class c{constructor(e){this.config=e,this.loading=!1,this.source=null,this.init=async()=>{this.loading=!0;const{wrappedIndexes:e,zhDictionary:t}=await(async e=>{const{wrappedIndexes:t,zhDictionary:n}=await(0,o.fetchIndexes)(e.versionUrl,e.searchContext);return{wrappedIndexes:t,zhDictionary:n}})({versionUrl:this.baseUrl,searchContext:u({versionUrl:this.baseUrl,searchContextByPaths:this.searchContextByPaths})});this.source=(0,l.SearchSourceFactory)(e,t,this.config.resultsLimit)},this.query=async e=>{if(!this.source)throw new Error("Not initialized");const{promise:n,callback:r}=(0,t.createPromise)();return this.source&&this.source(e,r),{results:(await n).map((e=>this.formatResult(e)))}},this.formatResult=e=>({...e,type:this.resultTypeToString(e.type),page:e.page?this.formatDocument(e.page):null,document:e.document?this.formatDocument(e.document):null,highlighted:(0,i.highlightStemmed)(e.document.t,(0,a.getStemmedPositions)(e.metadata,"t"),e.tokens)}),this.resultTypeToString=e=>({0:d.Title,1:d.Heading,2:d.Paragraph}[e]),this.formatDocument=e=>({id:e.i,title:e.t,url:e.u,hash:e.h,parentId:e.p,breadcrumb:e.b,sectionTitle:e.s}),this.baseUrl=e.preferredVersionPath,this.searchContextByPaths=e.searchContextByPaths??""}}var d;!function(e){e.Title="title",e.Heading="heading",e.Paragraph="paragraph"}(d=t.ResultType||(t.ResultType={}));t.createPromise=()=>{let e,t;const n=new Promise(((n,r)=>{e=n,t=r}));return{reject:t,resolve:e,promise:n,callback:(n,r)=>{r?t(r):e(n)}}};(async()=>{if("undefined"==typeof window)return;const e=window;e.getProxiedGeneratedData=()=>s,e.createSearchInstance=async e=>new c(e)})()},22197:(e,t,n)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.IconRemove=t.IconAdd=t.IconDownload=t.IconAvatar=t.IconX=t.IconTelegramWhite=t.IconDiscordWhite=t.IconExternalLink=t.IconFullscreenExit=t.IconFullscreen=t.IconEdit=t.IconClose=t.IconHistory=t.IconCopy=t.IconGScholar=t.IconDropdown=t.IconSearch=t.IconFolderFilled=t.IconDot=t.IconLinkedin=t.IconDiscourse=t.IconTelegram=t.IconTwitter=t.IconStatus=t.IconDiscord=t.IconGithub=t.IconFolder=t.IconArrowLeft=t.IconArrowRight=t.IconArrowLeftCircle=t.IconArrowRightCircle=t.Icon=void 0;const r=n(70655),o=n(86010),a=r.__importDefault(n(67294)),i=r.__importDefault(n(27861)),l=r.__importDefault(n(19044)),s=r.__importDefault(n(80255)),u=r.__importDefault(n(67146)),c=r.__importDefault(n(68425)),d=r.__importDefault(n(88121)),f=r.__importDefault(n(62082)),p=r.__importDefault(n(80469)),h=r.__importDefault(n(94793)),m=r.__importDefault(n(14607)),g=r.__importDefault(n(50437)),v=r.__importDefault(n(23179)),b=r.__importDefault(n(19818)),y=r.__importDefault(n(38981)),w=r.__importDefault(n(28487)),x=r.__importDefault(n(94177)),_=r.__importDefault(n(58611)),k=r.__importDefault(n(13042)),E=r.__importDefault(n(96367)),S=r.__importDefault(n(6907)),C=r.__importDefault(n(59570)),T=r.__importDefault(n(26890)),O=r.__importDefault(n(74297)),D=r.__importDefault(n(33336)),P=r.__importDefault(n(78951)),N=r.__importDefault(n(84629)),A=r.__importDefault(n(23816)),I=r.__importDefault(n(35245)),L=r.__importDefault(n(68902)),R=r.__importDefault(n(86089)),j=r.__importDefault(n(92358));t.Icon=e=>{const{children:t,size:n="m"}=e;return a.default.createElement("div",{className:(0,o.clsx)(i.default.icon,i.default[n],e.stroke&&i.default.stroke,e.fill&&i.default.fill,e.className&&e.className)},t)};t.IconArrowRightCircle=e=>a.default.createElement(t.Icon,{...e},a.default.createElement(c.default,null));t.IconArrowLeftCircle=e=>a.default.createElement(t.Icon,null,a.default.createElement(s.default,null));t.IconArrowRight=e=>a.default.createElement(t.Icon,{...e},a.default.createElement(d.default,null));t.IconArrowLeft=e=>a.default.createElement(t.Icon,null,a.default.createElement(u.default,null));t.IconFolder=e=>a.default.createElement(t.Icon,{...e},a.default.createElement(k.default,null));t.IconGithub=e=>a.default.createElement(t.Icon,{...e},a.default.createElement(C.default,null));t.IconDiscord=e=>a.default.createElement(t.Icon,{...e},a.default.createElement(g.default,null));t.IconStatus=e=>a.default.createElement(t.Icon,{...e},a.default.createElement(A.default,null));t.IconTwitter=e=>a.default.createElement(t.Icon,{...e},a.default.createElement(R.default,null));t.IconTelegram=e=>a.default.createElement(t.Icon,{...e},a.default.createElement(L.default,null));t.IconDiscourse=e=>a.default.createElement(t.Icon,{...e},a.default.createElement(v.default,null));t.IconLinkedin=e=>a.default.createElement(t.Icon,{...e},a.default.createElement(D.default,null));t.IconDot=e=>a.default.createElement(t.Icon,{...e},a.default.createElement(b.default,null));t.IconFolderFilled=e=>a.default.createElement(t.Icon,{...e},a.default.createElement(k.default,null));t.IconSearch=e=>a.default.createElement(t.Icon,{...e},a.default.createElement(N.default,null));t.IconDropdown=e=>a.default.createElement(t.Icon,{...e},a.default.createElement(w.default,null));t.IconGScholar=e=>a.default.createElement(t.Icon,{...e},a.default.createElement(T.default,null));t.IconCopy=e=>a.default.createElement(t.Icon,{...e},a.default.createElement(h.default,null));t.IconHistory=e=>a.default.createElement(t.Icon,{...e},a.default.createElement(O.default,null));t.IconClose=e=>a.default.createElement(t.Icon,{...e},a.default.createElement(p.default,null));t.IconEdit=e=>a.default.createElement(t.Icon,{...e},a.default.createElement(x.default,null));t.IconFullscreen=e=>a.default.createElement(t.Icon,{...e},a.default.createElement(S.default,null));t.IconFullscreenExit=e=>a.default.createElement(t.Icon,{...e},a.default.createElement(E.default,null));t.IconExternalLink=e=>a.default.createElement(t.Icon,{...e},a.default.createElement(_.default,null));t.IconDiscordWhite=e=>a.default.createElement(t.Icon,{...e},a.default.createElement(m.default,null));t.IconTelegramWhite=e=>a.default.createElement(t.Icon,{...e},a.default.createElement(I.default,null));t.IconX=e=>a.default.createElement(t.Icon,{...e},a.default.createElement(j.default,null));t.IconAvatar=e=>a.default.createElement(t.Icon,{...e},a.default.createElement(f.default,null));t.IconDownload=e=>a.default.createElement(t.Icon,{...e},a.default.createElement(y.default,null));t.IconAdd=e=>a.default.createElement(t.Icon,{...e,stroke:!0},a.default.createElement(l.default,null));t.IconRemove=e=>a.default.createElement(t.Icon,{...e,stroke:!0},a.default.createElement(P.default,null))},6980:(e,t,n)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0});n(70655).__exportStar(n(22197),t)},81575:(e,t,n)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.Modal=void 0;const r=n(70655),o=r.__importDefault(n(86010)),a=r.__importDefault(n(67294)),i=n(89164),l=n(67713),s=n(54920);n(22473);t.Modal=e=>{let{open:t=!1,onClose:n,keepMounted:r=!1,className:u,children:c,...d}=e;const f=(0,l.useHydrated)(),p=()=>{n&&n()};return(0,i.useKeyPressEvent)((e=>"Escape"===e.code),(e=>{p()})),f&&(t||r)?a.default.createElement(s.Portal,{containerId:"lsd-presentation",id:d.id},a.default.createElement("div",{className:(0,o.default)(u,"l-modal",t&&"l-modal--open"),...d},a.default.createElement("div",{className:"l-modal__container"},a.default.createElement("div",{className:"l-modal__content"},c),a.default.createElement("div",{className:"l-modal__backdrop",onClick:p})))):a.default.createElement(a.default.Fragment,null)}},54920:(e,t,n)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.Portal=void 0;const r=n(70655).__importDefault(n(67294)),o=n(73935),a=n(72777);t.Portal=e=>{let{children:t,containerId:n,id:i}=e;if("undefined"==typeof window)return r.default.createElement(r.default.Fragment,null);const l=(0,a.usePortal)({parentId:n});return(0,o.createPortal)(t,l,i)}},72777:(e,t,n)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.usePortal=void 0;const r=n(67294),o=n(32833);t.usePortal=e=>{let{parentId:t}=e;const n=(0,r.useRef)();return n.current||(n.current=document.createElement("div")),(0,r.useEffect)((()=>{var e;if(n.current)return null==(e=document.getElementById(t))||e.appendChild(n.current),()=>{const e=n.current;e&&(0,o.settleSync)((()=>{var n;return null==(n=document.getElementById(t))?void 0:n.removeChild(e)}))}}),[t,n.current]),n.current}},91866:(e,t,n)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.LightBoxWrapper=t.useLightBox=t.LightBoxContext=t.LightBoxProvider=void 0;const r=n(70655),o=n(31665),a=r.__importDefault(n(56306)),i=r.__importDefault(n(86010)),l=r.__importStar(n(67294)),s=r.__importStar(n(33199)),u=n(89164),c=n(22197),d=n(54920),f=n(67713),p=n(52606),h=r.__importDefault(n(10153));t.LightBoxProvider=e=>{let{children:n}=e;const r=(0,f.useHydrated)(),s=(0,u.useWindowScroll)(),[m,g]=(0,l.useState)(null),[v,b]=(0,l.useState)({opacity:"0.5"}),y=(0,p.useIsMobile)(),w=(0,l.useMemo)((()=>({opacity:1,transform:"scale(1) translate(0px, 0px)",transition:"0.3s"})),[m]),x=e=>{g(e);const t=document.body.clientWidth,n=window.innerHeight,r=window.innerWidth>768?.9375*t:t-32,o=n-128,a=e.getBoundingClientRect(),i=Math.min(o/a.height,r/a.width),l=[a.left+a.width/2,a.top+a.height/2],s=[t/2,n/2].map(((e,t)=>(e-l[t])/i));b({zIndex:202,transform:`scale(${i}) translate(${s[0]}px, ${s[1]}px)`,position:"relative"})},_=()=>{g(null)};return(0,l.useEffect)((()=>{m&&window.innerWidth>768&&_()}),[s]),(0,l.useEffect)((()=>{if(y&&m){document.querySelector("html").style.overflow="hidden"}else{document.querySelector("html").style.overflow="initial"}}),[y,m]),l.default.createElement(t.LightBoxContext.Provider,{value:{active:m,style:w,activeStyle:v,display:x,close:_,toggle:e=>{const t=m;_(),t!==e&&x(e)}}},n,r&&l.default.createElement(d.Portal,{containerId:"lsd-presentation"},l.default.createElement(l.default.Fragment,null,l.default.createElement("div",{className:(0,i.default)(h.default.backdrop,m&&h.default.visible)}),l.default.createElement("div",{className:(0,i.default)(h.default.navWrapper,m&&h.default.visible)},l.default.createElement("nav",{className:(0,i.default)(h.default.nav,"navbar",m&&h.default.visible)},l.default.createElement(a.default,null),l.default.createElement(o.IconButton,{size:"medium",onClick:_},l.default.createElement(c.IconFullscreenExit,null)))))))},t.LightBoxContext=l.default.createContext({style:{},activeStyle:{},active:null,close:null,toggle:null,display:null});t.useLightBox=()=>{const e=(0,l.useContext)(t.LightBoxContext);return{getStyle:t=>({...e.style,...t===e.active?e.activeStyle:{}}),style:e.style,activeStyle:e.activeStyle,active:e.active,isActive:!!e.active,close:e.close,toggle:e.toggle,display:e.display,isActiveElement:t=>e.active===t}};t.LightBoxWrapper=e=>{let{children:n}=e;const r=(0,l.useRef)(null),a=(0,l.useRef)(null),{getStyle:u,display:d,isActiveElement:f}=(0,t.useLightBox)(),m=(0,p.useIsMobile)(),g=(0,l.useCallback)((e=>{let{x:t,y:n,scale:r}=e;const{current:o}=a;if(o){const e=(0,s.make3dTransformValue)({x:t,y:n,scale:r});o.style.setProperty("transform",e)}}),[]),v=m&&r.current&&f(r.current)?l.default.createElement(s.default,{onUpdate:g,doubleTapZoomOutOnMaxScale:!0,maxZoom:3},l.default.createElement("div",{ref:a},n)):l.default.createElement(l.default.Fragment,null,n,l.default.createElement(o.IconButton,{className:h.default.fullscreenButton,size:"medium",onClick:()=>r.current&&d(r.current)},l.default.createElement(c.IconFullscreen,null)));return l.default.createElement(l.default.Fragment,null,l.default.createElement("div",{className:(0,i.default)(h.default.wrapper,f(r.current)&&h.default.active),ref:r,style:r.current?u(r.current):{}},v))}},30091:(e,t,n)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.ThemeProvider=void 0;const r=n(70655),o=n(31665),a=n(70917),i=r.__importDefault(n(67294)),l=n(51509);t.ThemeProvider=e=>{let{children:t}=e;const n=(0,l.useTheme)();return i.default.createElement(o.ThemeProvider,{theme:n.current,injectCssVars:!1},i.default.createElement(a.Global,{styles:n.darkCssVars}),i.default.createElement(a.Global,{styles:n.lightCssVars}),t)}},84138:(e,t,n)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0});n(70655).__exportStar(n(30091),t)},32833:(e,t)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.settleSync=t.settle=void 0;t.settle=async e=>{try{return["function"==typeof e?await e():await e,void 0]}catch(t){return[void 0,t]}};t.settleSync=e=>{try{return[e(),void 0]}catch(t){return[void 0,t]}}},68347:(e,t)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.ensureTrailingSlash=t.ensureTrailingString=void 0;t.ensureTrailingString=(e,t)=>e.endsWith(t)?e:e+t;t.ensureTrailingSlash=e=>(0,t.ensureTrailingString)(e,"/")},51509:(e,t,n)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.useTheme=void 0;const r=n(31665),o=n(93945),a=n(70917),i=n(67294),l=n(38840),s=(e,t)=>(0,i.useMemo)((()=>a.css` - [data-theme=${t}] { - ${e.cssVars} - } - `),[e]);t.useTheme=()=>{const e=(0,o.useColorMode)(),{typography:t}=(0,l.useThemeOptions)(),n=(null==t?void 0:t.genericFontFamily)??"sans-serif",a=r.defaultThemes,u=(0,i.useMemo)((()=>{const e={breakpoints:{},palette:{},typography:{},typographyGlobal:{genericFontFamily:n},spacing:[]};return{light:(0,r.createTheme)(e,a.light),dark:(0,r.createTheme)(e,a.dark)}}),[a,n]);return{dark:u.dark,light:u.light,current:u[e.colorMode],colorMode:e.colorMode,lightCssVars:s(u.light,"light"),darkCssVars:s(u.dark,"dark")}}},17648:(e,t,n)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.useEventListener=void 0;const r=n(67294);t.useEventListener=(e,t,n,o,a)=>{const i=(0,r.useMemo)((()=>"string"==typeof e?e:e()),[]),l=(0,r.useMemo)((()=>"function"==typeof t?t():t),[t]);(0,r.useEffect)((()=>{if(null!=l&&l.addEventListener&&null!=l&&l.removeEventListener)return l.addEventListener(i,n,o),()=>{l.removeEventListener(i,n,o)}}),[i,l])}},67713:(e,t,n)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.useHydrated=void 0;const r=n(67294);t.useHydrated=()=>{const[e,t]=(0,r.useState)(!1);return(0,r.useEffect)((()=>{t(!0)}),[]),e}},52606:(e,t,n)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.useIsMobile=void 0;const r=n(89164);t.useIsMobile=()=>(0,r.useMedia)("(max-width: 1199px)")},59213:(e,t,n)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.usePersistedHistory=void 0;const r=n(89164);t.usePersistedHistory=(e,t)=>{const n=(null==t?void 0:t.unique)??!1,o=(null==t?void 0:t.equals)??((e,t)=>e===t),a=(null==t?void 0:t.maxItems)??null,[i,l]=(0,r.useLocalStorage)("logos-docusaurus-theme-"+e,[]),s=e=>{l((i??[]).filter(((t,n)=>!e(t,n))))};return{add:e=>{const t=i??[],r=[e,...n?t.filter((t=>!o(t,e))):t];l(a?r.slice(0,a):r)},clear:()=>{l([])},remove:s,removeByIndex:e=>{s(((t,n)=>n===e))},list:i}}},38840:(e,t,n)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.useDocThemeOptions=t.useThemeOptions=void 0;const r=n(70655),o=n(4452),a=r.__importDefault(n(6832));t.useThemeOptions=()=>{const{siteConfig:{customFields:e={}}}=(0,a.default)();return e["logos-docusaurus-theme"]??{}};t.useDocThemeOptions=()=>{var e;const n=(0,o.useActivePlugin)(),r=(0,t.useThemeOptions)();return n?(null==r||null==(e=r.docs)?void 0:e[null==n?void 0:n.pluginId])??{}:{}}},21457:(e,t,n)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.useWindowEventListener=void 0;const r=n(17648);t.useWindowEventListener=function(e,t,n,o){void 0===o&&(o=[]),(0,r.useEventListener)(e,(()=>"undefined"!=typeof window&&window),t,n,o)}},61818:(e,t,n)=>{"use strict";const r=n(70655),o=n(31665),a=n(11614),i=r.__importDefault(n(5730)),l=r.__importDefault(n(5574)),s=r.__importDefault(n(60388)),u=r.__importDefault(n(86010)),c=r.__importDefault(n(67294)),d=r.__importDefault(n(8633));t.Z=c.default.memo((function(e){let{className:t,buttonClassName:n,value:r,onChange:f}=e;const p=(0,i.default)(),h=(0,a.translate)({message:"Switch between dark and light mode (currently {mode})",id:"theme.colorToggle.ariaLabel",description:"The ARIA label for the navbar color mode toggle"},{mode:"dark"===r?(0,a.translate)({message:"dark mode",id:"theme.colorToggle.ariaLabel.mode.dark",description:"The name for the dark color mode"}):(0,a.translate)({message:"light mode",id:"theme.colorToggle.ariaLabel.mode.light",description:"The name for the light color mode"})});return c.default.createElement(o.IconButton,{className:(0,u.default)("clean-btn",d.default.toggle,t,!p&&d.default.toggleButtonDisabled,n),type:"button",onClick:()=>f("dark"===r?"light":"dark"),disabled:!p,title:h,"aria-label":h,"aria-live":"polite"},c.default.createElement(s.default,{className:(0,u.default)(d.default.toggleIcon,d.default.lightToggleIcon)}),c.default.createElement(l.default,{className:(0,u.default)(d.default.toggleIcon,d.default.darkToggleIcon)}))}))},72726:(e,t,n)=>{"use strict";const r=n(70655),o=n(31665),a=r.__importDefault(n(86010)),i=r.__importDefault(n(67294)),l=r.__importDefault(n(79762));t.Z=function(e){let{style:t,links:n,logo:r,copyright:s}=e;const[u,c]=(e=>{const t=[],n=[];for(const r of e)"title"in r&&"string"==typeof r.title&&r.title.startsWith("shared:")?n.push({...r,title:r.title.slice(7)}):t.push(r);return[t,n]})(n.props.links);return i.default.createElement("footer",{className:(0,a.default)("footer",{"footer--dark":"dark"===t})},i.default.createElement("div",{className:(0,a.default)("container","container-fluid",l.default.firstRow)},(r||s)&&i.default.createElement(i.default.Fragment,null,i.default.createElement("div",{className:"footer__bottom text--center"},r&&i.default.createElement("div",{className:"margin-bottom--sm"},r),s)),i.default.cloneElement(n,{links:u})),i.default.createElement("div",{className:l.default.secondRow},i.default.createElement("div",{className:"footer__bottom text--center"},"Logos Collective"),i.default.cloneElement(n,{links:c})),i.default.createElement(o.Button,{className:l.default.backToTop,size:"small",onClick:()=>{window.scrollTo({top:0,behavior:"smooth"})}},"Back to top \u2191"))}},10211:(e,t,n)=>{"use strict";const r=n(70655).__importDefault(n(67294)),o=n(93945),a=n(13616),i=(0,o.composeProviders)([a.AnnouncementBarProvider,a.ScrollControllerProvider,a.DocsPreferredVersionContextProvider,a.PluginHtmlClassNameProvider,a.NavbarProvider]);t.Z=function(e){let{children:t}=e;return r.default.createElement(i,null,t)}},60969:(e,t,n)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0});const r=n(70655),o=r.__importDefault(n(67294)),a=r.__importDefault(n(88746)),i=r.__importDefault(n(51402)),l=r.__importDefault(n(6832)),s=n(93945),u=r.__importDefault(n(47002));function c(e){let{logo:t,alt:n,imageClassName:r}=e;const a={light:(0,i.default)(t.src),dark:(0,i.default)(t.srcDark||t.src)},l=o.default.createElement(u.default,{className:t.className,sources:a,height:t.height,width:t.width,alt:n,style:t.style});return r?o.default.createElement("div",{className:r},l):l}t.default=function(e){const{siteConfig:{title:t}}=(0,l.default)(),{navbar:{title:n,logo:r}}=(0,s.useThemeConfig)(),{imageClassName:u,titleClassName:d,...f}=e,p=(0,i.default)((null==r?void 0:r.href)||"/"),h=n?"":t,m=(null==r?void 0:r.alt)??h;return o.default.createElement(a.default,{to:p,...f,...(null==r?void 0:r.target)&&{target:r.target}},r&&o.default.createElement(c,{logo:r,alt:m,imageClassName:u}),null!=n&&o.default.createElement("b",{className:d},n))}},27882:(e,t,n)=>{"use strict";const r=n(70655),o=n(31665),a=n(93945),i=n(13616),l=r.__importDefault(n(17662)),s=r.__importDefault(n(56306)),u=r.__importDefault(n(60543)),c=r.__importDefault(n(93496)),d=r.__importDefault(n(20130)),f=r.__importDefault(n(86010)),p=r.__importDefault(n(67294)),h=n(67713),m=r.__importDefault(n(90826));function g(e){let{items:t}=e;return p.default.createElement(p.default.Fragment,null,t.map(((e,t)=>p.default.createElement(a.ErrorCauseBoundary,{key:t,onError:t=>new Error(`A theme navbar item failed to render.\nPlease double-check the following navbar item (themeConfig.navbar.items) of your Docusaurus config:\n${JSON.stringify(e,null,2)}`,{cause:t})},p.default.createElement(c.default,{...e})))))}t.Z=function(){const e=(0,h.useHydrated)(),t=(0,i.useNavbarMobileSidebar)(),n=(0,a.useThemeConfig)().navbar.items,[r,c]=(0,i.splitNavbarItems)(n.filter((e=>!["search"].includes(e.type??"")))),v=n.find((e=>"search"===e.type));return p.default.createElement("div",{className:"navbar__inner"},p.default.createElement("div",{className:"navbar__left"},p.default.createElement(s.default,null)),p.default.createElement("div",{className:"navbar__left-items"},p.default.createElement(g,{items:r})),p.default.createElement("div",{className:"navbar__right-items"},p.default.createElement(g,{items:c}),p.default.createElement(o.IconButtonGroup,{className:m.default.iconButtonGroup,size:"medium"},p.default.createElement(l.default,{key:"color-toggle",className:(0,f.default)(m.default.colorModeToggle,"navbar__color-mode-toggle")}),e&&p.default.createElement(p.default.Fragment,{key:"search"},v&&p.default.createElement(d.default,null)),p.default.createElement(p.default.Fragment,{key:"mobile-sidebar-toggle"},!t.disabled&&p.default.createElement(u.default,null)))))}},26558:(e,t,n)=>{"use strict";const r=n(70655),o=r.__importDefault(n(67294)),a=r.__importDefault(n(86010)),i=n(93945),l=n(13616),s=n(11614),u=r.__importDefault(n(44488)),c=r.__importDefault(n(97087));function d(e){return o.default.createElement("div",{role:"presentation",...e,className:(0,a.default)("navbar-sidebar__backdrop",e.className)})}t.Z=function(e){let{children:t}=e;const{navbar:{hideOnScroll:n,style:r}}=(0,i.useThemeConfig)(),f=(0,l.useNavbarMobileSidebar)(),{navbarRef:p,isNavbarVisible:h}=(0,l.useHideableNavbar)(n);return o.default.createElement("nav",{ref:p,"aria-label":(0,s.translate)({id:"theme.NavBar.navAriaLabel",message:"Main",description:"The ARIA label for the main navigation"}),className:(0,a.default)("navbar","navbar--fixed-top",n&&[c.default.navbarHideable,!h&&c.default.navbarHidden],{"navbar--dark":"dark"===r,"navbar--primary":"primary"===r,"navbar-sidebar--show":f.shown})},t,o.default.createElement(d,{onClick:f.toggle}),o.default.createElement(u.default,null))}},56306:(e,t,n)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0});const r=n(70655),o=r.__importDefault(n(67294)),a=r.__importDefault(n(60969));t.default=function(){return o.default.createElement(a.default,{className:"navbar__brand",imageClassName:"navbar__logo",titleClassName:"navbar__title text--truncate"})}},20080:(e,t,n)=>{"use strict";const r=n(70655),o=r.__importDefault(n(67294)),a=n(13616),i=n(11614),l=r.__importDefault(n(17662)),s=r.__importDefault(n(56306)),u=n(31665),c=r.__importDefault(n(20130));function d(){const e=(0,a.useNavbarMobileSidebar)();return o.default.createElement("button",{type:"button","aria-label":(0,i.translate)({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()},o.default.createElement(u.CloseIcon,null))}t.Z=function(){return o.default.createElement("div",{className:"navbar-sidebar__brand"},o.default.createElement(s.default,null),o.default.createElement(l.default,{className:"margin-right--md"}),o.default.createElement(c.default,null),o.default.createElement(d,null))}},64644:(e,t,n)=>{"use strict";const r=n(70655),o=r.__importDefault(n(67294)),a=r.__importDefault(n(86010)),i=n(13616),l=r.__importDefault(n(10510));t.Z=function(e){let{header:t,primaryMenu:n,secondaryMenu:r}=e;const{shown:s}=(0,i.useNavbarSecondaryMenu)();return o.default.createElement("div",{className:(0,a.default)("navbar-sidebar",s&&"navbar-sidebar--show-secondary")},t,o.default.createElement("div",{className:(0,a.default)("navbar-sidebar__items",{"navbar-sidebar__items--show-secondary":s})},o.default.createElement("div",{className:"navbar-sidebar__item menu"},n,!s&&o.default.createElement(l.default,null)),o.default.createElement("div",{className:"navbar-sidebar__item menu"},r)))}},29843:(e,t,n)=>{"use strict";const r=n(70655),o=n(31665),a=n(93945),i=n(13616),l=r.__importDefault(n(11614)),s=n(6980),u=r.__importDefault(n(67294));function c(e){return u.default.createElement("button",{...e,type:"button",className:"clean-btn navbar-sidebar__back"},u.default.createElement(s.IconArrowLeft,null),u.default.createElement(o.Typography,null,u.default.createElement(l.default,{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)"},"Back to main menu")))}t.Z=function(){const e=0===(0,a.useThemeConfig)().navbar.items.length,t=(0,i.useNavbarSecondaryMenu)();return u.default.createElement(u.default.Fragment,null,!e&&u.default.createElement(c,{onClick:()=>t.hide()}),t.content)}},71003:(e,t,n)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0});const r=n(70655),o=n(31665),a=n(93945),i=n(13616),l=r.__importDefault(n(93496)),s=r.__importDefault(n(83112)),u=r.__importDefault(n(86010)),c=r.__importStar(n(67294)),d=r.__importDefault(n(83244));function f(e,t){return e.some((e=>function(e,t){return!!(0,i.isSamePath)(e.to,t)||!!(0,a.isRegexpStringMatch)(e.activeBaseRegex,t)||!(!e.activeBasePath||!t.startsWith(e.activeBasePath))}(e,t)))}function p(e){let{items:t,position:n,className:r,onClick:a,...i}=e;const f=(0,c.useRef)(null),[p,h]=(0,c.useState)(!1);return(0,c.useEffect)((()=>{const e=e=>{f.current&&!f.current.contains(e.target)&&h(!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)}}),[f]),c.default.createElement("div",{ref:f,className:(0,u.default)("navbar__item",d.default.dropdownNavbarItem,"dropdown","dropdown--hoverable",{"dropdown--right":"right"===n,"dropdown--show":p})},c.default.createElement(s.default,{"aria-haspopup":"true","aria-expanded":p,role:"button",href:i.to?void 0:"#",className:(0,u.default)("navbar__link",r),...i,onClick:i.to?void 0:e=>e.preventDefault(),onKeyDown:e=>{"Enter"===e.key&&(e.preventDefault(),h(!p))}},i.children??i.label),c.default.createElement(o.ChevronDownIcon,{className:(0,u.default)("margin-left-8","cursor-pointer")}),c.default.createElement("ul",{className:"dropdown__menu"},t.map(((e,t)=>c.default.createElement(l.default,{isDropdownItem:!0,activeClassName:"dropdown__link--active",...e,key:t})))))}function h(e){let{items:t,className:n,position:r,onClick:d,...p}=e;const h=(0,i.useLocalPathname)(),m=f(t,h),{collapsed:g,toggleCollapsed:v,setCollapsed:b}=(0,a.useCollapsible)({initialState:()=>!m});return(0,c.useEffect)((()=>{m&&b(!m)}),[h,m,b]),c.default.createElement("li",{className:(0,u.default)("menu__list-item",{"menu__list-item--collapsed":g})},c.default.createElement(s.default,{role:"button",className:(0,u.default)("menu__link menu__link--sublist menu__link--sublist-caret",n),...p,onClick:e=>{e.preventDefault(),v()}},c.default.createElement(o.Typography,{variant:"body1"},p.children??p.label)),c.default.createElement(a.Collapsible,{lazy:!0,as:"ul",className:"menu__list",collapsed:g},t.map(((e,t)=>c.default.createElement(l.default,{mobile:!0,isDropdownItem:!0,onClick:d,activeClassName:"menu__link--active",...e,key:t})))))}t.default=function(e){let{mobile:t=!1,...n}=e;const r=t?h:p;return c.default.createElement(r,{...n})}},23247:(e,t,n)=>{"use strict";const r=n(70655),o=r.__importDefault(n(67294)),a=r.__importDefault(n(6832)),i=n(13616),l=n(11614),s=n(7154),u=r.__importDefault(n(71003));t.Z=function(e){var t;let{mobile:n,dropdownItemsBefore:r,dropdownItemsAfter:c,...d}=e;const{i18n:{currentLocale:f,locales:p,localeConfigs:h}}=(0,a.default)(),m=(0,i.useAlternatePageUtils)(),{search:g,hash:v}=(0,s.useLocation)(),b=[...r,...p.map((e=>{var t,r;const o=`${`pathname://${m.createUrl({locale:e,fullyQualified:!1})}`}${g}${v}`;return{label:null==(t=h[e])?void 0:t.label,lang:null==(r=h[e])?void 0:r.htmlLang,to:o,target:"_self",autoAddBaseUrl:!1,className:e===f?n?"menu__link--active":"dropdown__link--active":""}})),...c],y=n?(0,l.translate)({message:"Languages",id:"theme.navbar.mobileLanguageDropdown.label",description:"The label for the mobile language switcher dropdown"}):null==(t=h[f])?void 0:t.label.substring(0,2).toUpperCase();return o.default.createElement(u.default,{...d,mobile:n,label:o.default.createElement(o.default.Fragment,null,y),items:b})}},83112:(e,t,n)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0});const r=n(70655),o=n(31665),a=r.__importDefault(n(71699)),i=r.__importDefault(n(88746)),l=n(93945),s=r.__importDefault(n(51402)),u=r.__importDefault(n(67294)),c=n(22197),d=r.__importDefault(n(88822));t.default=function(e){let{activeBasePath:t,activeBaseRegex:n,to:r,href:f,label:p,html:h,isDropdownLink:m,prependBaseUrlToHref:g,...v}=e;const b=(0,s.default)(r),y=(0,s.default)(t),w=(0,s.default)(f,{forcePrependBaseUrl:!0}),x=p&&f&&!(0,a.default)(f),_=h?{dangerouslySetInnerHTML:{__html:h}}:{children:u.default.createElement(o.Typography,{component:"div",variant:"body2",className:d.default.linkContent},p,x&&u.default.createElement(c.IconExternalLink,{className:d.default.externalLinkIcon}))};return f?u.default.createElement(i.default,{href:g?w:f,...v,..._}):u.default.createElement(i.default,{to:b,isNavLink:!0,...(t||n)&&{isActive:(e,t)=>n?(0,l.isRegexpStringMatch)(n,t.pathname):t.pathname.startsWith(y)},...v,..._})}},28511:(e,t,n)=>{"use strict";const r=n(70655),o=n(13616),a=r.__importDefault(n(67294)),i=n(91866),l=n(84138),s=n(38840),u=r.__importDefault(n(36459));t.Z=function(e){var t;let{children:n}=e;const r=(0,s.useDocThemeOptions)(),c=null==r||null==(t=r.sidebar)?void 0:t.hide;return a.default.createElement(o.ColorModeProvider,null,a.default.createElement(l.ThemeProvider,null,a.default.createElement(i.LightBoxProvider,null,a.default.createElement("div",{className:u.default.root,"data-hidden-doc-sidebar":c},n))))}},56051:(e,t,n)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.SearchBar=void 0;const r=n(70655),o=n(31665),a=r.__importStar(n(67294)),i=n(81575),l=n(59213),s=n(21457),u=n(41310),c=r.__importDefault(n(31259)),d=n(55634),f=n(16991),p=n(44334);t.SearchBar=e=>{let{}=e;const t=(0,l.usePersistedHistory)("search",{unique:!0,equals:(e,t)=>e.title===t.title&&e.href===t.href,maxItems:10}),n=(0,u.useSearch)(),r=(0,a.useRef)(null),[h,m]=(0,a.useState)(""),[g,v]=(0,a.useState)([]),[b,y]=(0,a.useState)(!1);(0,a.useEffect)((()=>{h.length>0?(async e=>{const{results:t}=await n.query(e);v(t)})(h):v([])}),[h]),(0,a.useEffect)((()=>{b?(()=>{const e=r.current;if(!e)return;const t=e.querySelector("input");t&&setTimeout((()=>{t.focus()}),50)})():m("")}),[b]);return(0,s.useWindowEventListener)("keydown",(e=>{(e.ctrlKey||e.metaKey)&&"KeyK"===e.code&&(e.preventDefault(),y(!0))}),{},[]),a.default.createElement(a.default.Fragment,null,a.default.createElement(o.IconButton,{onClick:()=>y(!0),size:"medium"},a.default.createElement(o.SearchIcon,null)),a.default.createElement(i.Modal,{keepMounted:!0,id:"search-modal",open:b,onClose:()=>y(!1),className:c.default.modal},a.default.createElement("div",{className:c.default.header},a.default.createElement(f.SearchInput,{containerRef:r,onClear:()=>{m("")},value:h,onChange:e=>{m(e.target.value)}}),a.default.createElement(o.IconButton,{className:c.default.closeButton,size:"medium",onClick:()=>y(!1)},a.default.createElement(o.CloseIcon,{color:"primary"}))),h.length>0&&a.default.createElement(p.SearchResults,{results:g,onNavigate:(e,n)=>{e.preventDefault(),y(!1),t.add(n),window.location.href=n.href}}),0===h.length&&a.default.createElement(d.SearchHistory,{history:t.list??[],onRemove:t.removeByIndex,onClose:()=>y(!1)})))}},55634:(e,t,n)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.SearchHistory=void 0;const r=n(70655),o=n(31665),a=r.__importDefault(n(86010)),i=r.__importDefault(n(67294)),l=n(22197),s=n(42130),u=r.__importDefault(n(61699));t.SearchHistory=e=>{let{history:t=[],onRemove:n,onClose:r,className:c,children:d,...f}=e;return i.default.createElement("div",{className:(0,a.default)(c,u.default.root,0===t.length&&u.default.empty),...f},0===t.length?i.default.createElement(s.SearchResultMessage,null,"No recent searches"):i.default.createElement(i.default.Fragment,null,i.default.createElement(o.Typography,{className:u.default.title,variant:"subtitle2",component:"div"},"Recent"),t.map(((e,t)=>i.default.createElement("div",{key:t,className:u.default.item},i.default.createElement(l.IconHistory,null),i.default.createElement(o.Typography,{variant:"subtitle2",component:"a",href:e.href,className:u.default.itemTitle,dangerouslySetInnerHTML:{__html:e.title},onClick:()=>r&&r()}),i.default.createElement("button",{className:"clean-btn",onClick:()=>n(t)},i.default.createElement(l.IconClose,null)))))))}},16991:(e,t,n)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.SearchInput=void 0;const r=n(70655),o=n(31665),a=r.__importDefault(n(86010)),i=r.__importDefault(n(67294)),l=n(89164),s=r.__importDefault(n(9592));t.SearchInput=e=>{let{value:t="",active:n,onChange:r,onClear:u,onFocus:c,onCancel:d,className:f,inputProps:{ref:p,...h}={placeholder:""},containerRef:m,...g}=e;const v=(0,l.useMedia)("(max-width: 996px)"),b=n||(null==t?void 0:t.length)>0;return i.default.createElement("div",{ref:m,className:(0,a.default)(s.default.root,b&&s.default.expanded,f),onKeyDown:e=>{"Escape"===e.code&&t.length>0&&(e.stopPropagation(),u&&u())},...g},i.default.createElement(o.TextField,{className:s.default.textField,value:t,placeholder:b||v?h.placeholder:"",onChange:r,onFocus:e=>{c&&c()},clearButton:!0,icon:i.default.createElement(o.SearchIcon,{color:"primary"}),...h}))}},537:(e,t,n)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.SearchResultGroup=void 0;const r=n(70655),o=n(31665),a=r.__importDefault(n(86010)),i=r.__importDefault(n(67294)),l=r.__importDefault(n(1443));t.SearchResultGroup=e=>{let{className:t,title:n="",children:r,...s}=e;return i.default.createElement("div",{className:(0,a.default)(l.default.root,t),...s},i.default.createElement("div",null,i.default.createElement(o.Typography,{variant:"subtitle2"},n)),i.default.createElement("ul",null,r))}},16183:(e,t,n)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0});n(70655).__exportStar(n(537),t)},78447:(e,t,n)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.SearchResultItem=void 0;const r=n(70655),o=r.__importDefault(n(88746)),a=r.__importDefault(n(86010)),i=r.__importDefault(n(67294)),l=r.__importDefault(n(7744)),s=r.__importDefault(n(42924)),u=n(55459),c=n(79587),d=r.__importDefault(n(18589)),f={[c.SearchDocumentType.Title]:i.default.createElement(l.default,{className:(0,a.default)(d.default.icon,d.default.fill)}),[c.SearchDocumentType.Heading]:i.default.createElement(s.default,{className:(0,a.default)(d.default.icon,d.default.fill)}),[c.SearchDocumentType.Paragraph]:i.default.createElement(s.default,{className:(0,a.default)(d.default.icon,d.default.fill)})};t.SearchResultItem=e=>{let{type:t,level:n=0,href:r,title:l,content:s,className:c,linkProps:{className:p,...h}={},...m}=e;const g=f[t];return i.default.createElement(o.default,{href:r,className:(0,a.default)(d.default.root,d.default[`level${n}`],p),...h},i.default.createElement(u.SearchResultItemBase,{title:l,content:s,icon:g,...m}))}},98028:(e,t,n)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0});n(70655).__exportStar(n(78447),t)},8655:(e,t,n)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.SearchResultItemBase=void 0;const r=n(70655),o=n(31665),a=r.__importDefault(n(86010)),i=r.__importDefault(n(67294)),l=r.__importDefault(n(86620));t.SearchResultItemBase=e=>{let{icon:t,title:n,content:r,className:s,...u}=e;return i.default.createElement("li",{className:(0,a.default)(l.default.root,s),...u},i.default.createElement("span",null,t),i.default.createElement("div",null,n&&i.default.createElement(o.Typography,{variant:"subtitle2",component:"span",dangerouslySetInnerHTML:{__html:n}})))}},55459:(e,t,n)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0});n(70655).__exportStar(n(8655),t)},42130:(e,t,n)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.SearchResultMessage=void 0;const r=n(70655),o=n(31665),a=r.__importDefault(n(86010)),i=r.__importDefault(n(67294)),l=r.__importDefault(n(38076));t.SearchResultMessage=e=>{let{className:t,children:n,...r}=e;return i.default.createElement(o.Typography,{className:(0,a.default)(t,l.default.root),variant:"subtitle2",component:"div",...r},i.default.createElement("span",null,n))}},44334:(e,t,n)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.SearchResults=void 0;const r=n(70655),o=r.__importDefault(n(86010)),a=r.__importStar(n(67294)),i=n(16183),l=n(98028),s=n(42130),u=n(36570),c=r.__importDefault(n(20550));t.SearchResults=e=>{let{results:t,className:n,onNavigate:r,...d}=e;const f=t.length,p=(0,a.useMemo)((()=>(0,u.groupSearchResult)(t)),[t]);return a.default.createElement("div",{className:(0,o.default)(c.default.root,0===f&&c.default.noResults)},0===f&&a.default.createElement(s.SearchResultMessage,null,"No result."),a.default.createElement("div",{className:(0,o.default)(c.default.groups)},p.map(((e,t)=>{let[n,o]=e;return a.default.createElement(a.default.Fragment,{key:t},a.default.createElement(i.SearchResultGroup,{className:c.default.group,title:n},o.map(((e,t)=>a.default.createElement(l.SearchResultItem,{key:t,type:e.type,level:e.level,href:e.href,title:e.title,content:e.content,linkProps:r?{onClick:t=>r(t,e)}:{}})))))}))))}},41310:(e,t,n)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.useSearch=void 0;const r=n(67294),o=n(8675);t.useSearch=()=>{const{createSearchInstance:e}=window,t=(0,o.useSearchContextPath)(),[n,a]=(0,r.useState)(!1),i=(0,r.useRef)(null);return(0,r.useEffect)((()=>{a(!1),(async()=>{i.current=await e({resultsLimit:50,preferredVersionPath:t[0],searchContextByPaths:t[1]}),await i.current.init(),a(!0)})()}),[t[0],t[1]]),{loaded:n,query:async e=>await i.current.query(e)}}},8675:(e,t,n)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.useSearchContextPath=void 0;const r=n(4452),o=n(68347),a=()=>window.getProxiedGeneratedData().searchContextByPaths;t.useSearchContextPath=()=>{const e=a(),t=(0,r.useActivePluginAndVersion)();if(!t)return["/",""];const{activePlugin:{pluginData:{path:n}},activeVersion:i}=t;return i?[n!==i.path?(0,o.ensureTrailingSlash)(i.path):"/",e]:["/",""]}},20130:(e,t,n)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0});const r=n(70655),o=r.__importDefault(n(24649)),a=r.__importDefault(n(67294)),i=n(56051);t.default=()=>"undefined"==typeof window?a.default.createElement(a.default.Fragment,null):a.default.createElement(o.default,{fallback:()=>a.default.createElement(a.default.Fragment,null)},a.default.createElement(i.SearchBar,null))},79587:(e,t)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.SearchDocumentType=void 0,function(e){e.Title="title",e.Heading="heading",e.Paragraph="paragraph"}(t.SearchDocumentType||(t.SearchDocumentType={}))},36570:(e,t,n)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.groupSearchResult=void 0;const r=n(70655),o=r.__importDefault(n(7739)),a=r.__importDefault(n(57557)),i=n(79587);t.groupSearchResult=e=>Object.entries((0,o.default)(e.map((e=>(e=>{const{type:t,document:n,page:r,highlighted:o,score:a}=e,{url:l,hash:s=""}=n,u=l+s;switch(t){case i.SearchDocumentType.Title:var c;return{type:t,level:0,url:l,hash:s,href:u,score:a,title:o,content:"",category:(null==(c=n.breadcrumb)?void 0:c[1])??n.title};case i.SearchDocumentType.Heading:{var d;const e=r;return{type:t,level:1,url:l,hash:s,href:u,score:a,title:o,content:"",category:(null==e||null==(d=e.breadcrumb)?void 0:d[1])??(null==e?void 0:e.title)??""}}case i.SearchDocumentType.Paragraph:{var f;const e=r;return{type:t,level:2,url:l,hash:s,href:u,score:a,title:n.sectionTitle||n.title||"",content:o,category:(null==e||null==(f=e.breadcrumb)?void 0:f[1])??(null==e?void 0:e.title)??""}}}})(e))),"category")).map((e=>{let[t,n]=e;return[t,n.map((e=>(0,a.default)(e,"category"))).sort(((e,t)=>e.score>t.score?-1:1))]})).sort(((e,t)=>{var n,r;return((null==(n=e[1][0])?void 0:n.score)??0)>((null==(r=t[1][0])?void 0:r.score)??0)?-1:1})).map((e=>{let[t,n]=e;return[t,Object.entries((0,o.default)(n,"url")).map((e=>{var t;let[n,r]=e,o=[...r].sort(((e,t)=>e.type===i.SearchDocumentType.Title||e.score>t.score?-1:1));const a=(null==(t=o[0])?void 0:t.type)===i.SearchDocumentType.Title;return o=a?o.filter((e=>!(e.type===i.SearchDocumentType.Heading&&""===e.hash))):o,o=o.map(((e,t)=>({...e,level:a?0===t?0:1:0}))),[n,o]})).sort(((e,t)=>{var n,r;return((null==(n=e[1][0])?void 0:n.score)??0)>((null==(r=t[1][0])?void 0:r.score)??0)?-1:1})).flatMap((e=>{let[t,n]=e;return n}))]}))},74058:(e,t,n)=>{"use strict";n.d(t,{_:()=>o,t:()=>a});var r=n(67294);const o=r.createContext(!1);function a(e){let{children:t}=e;const[n,a]=(0,r.useState)(!1);return(0,r.useEffect)((()=>{a(!0)}),[]),r.createElement(o.Provider,{value:n},t)}},3364:(e,t,n)=>{"use strict";var r=n(67294),o=n(73935),a=n(73727),i=n(70405),l=n(19901);const s=[n(79578),n(32497),n(25529),n(26126),n(11057),n(93878)];var u=n(21204),c=n(16550),d=n(18790),f=n(28511),p=n(87462),h=n(32411),m=n(6832),g=n(51402),v=n(96793),b=n(44873),y=n(13156),w=n(22768),x=n(39105),_=n(26145);function k(){const{i18n:{defaultLocale:e,localeConfigs:t}}=(0,m.default)(),n=(0,y.l)();return r.createElement(h.Z,null,Object.entries(t).map((e=>{let[t,{htmlLang:o}]=e;return r.createElement("link",{key:t,rel:"alternate",href:n.createUrl({locale:t,fullyQualified:!0}),hrefLang:o})})),r.createElement("link",{rel:"alternate",href:n.createUrl({locale:e,fullyQualified:!0}),hrefLang:"x-default"}))}function E(e){let{permalink:t}=e;const{siteConfig:{url:n}}=(0,m.default)(),o=function(){const{siteConfig:{url:e}}=(0,m.default)(),{pathname:t}=(0,c.TH)();return e+(0,g.default)(t)}(),a=t?`${n}${t}`:o;return r.createElement(h.Z,null,r.createElement("meta",{property:"og:url",content:a}),r.createElement("link",{rel:"canonical",href:a}))}function S(){const{i18n:{currentLocale:e}}=(0,m.default)(),{metadata:t,image:n}=(0,v.L)();return r.createElement(r.Fragment,null,r.createElement(h.Z,null,r.createElement("meta",{name:"twitter:card",content:"summary_large_image"}),r.createElement("body",{className:w.h})),n&&r.createElement(b.d,{image:n}),r.createElement(E,null),r.createElement(k,null),r.createElement(_.Z,{tag:x.HX,locale:e}),r.createElement(h.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)(u.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 O=n(74058),D=n(56725);function P(e){for(var t=arguments.length,n=new Array(t>1?t-1:0),r=1;r<t;r++)n[r-1]=arguments[r];const o=s.map((t=>{var r;const o=(null==(r=t.default)?void 0:r[e])??t[e];return null==o?void 0:o(...n)}));return()=>o.forEach((e=>null==e?void 0:e()))}const N=function(e){let{children:t,location:n,previousLocation:o}=e;return(0,r.useLayoutEffect)((()=>{o!==n&&(!function(e){let{location:t,previousLocation:n}=e;if(!n)return;const r=t.pathname===n.pathname,o=t.hash===n.hash,a=t.search===n.search;if(r&&o&&!a)return;const{hash:i}=t;if(i){const e=decodeURIComponent(i.substring(1)),t=document.getElementById(e);null==t||t.scrollIntoView()}else window.scrollTo(0,0)}({location:n,previousLocation:o}),P("onRouteDidUpdate",{previousLocation:o,location:n}))}),[o,n]),t};function A(e){const t=Array.from(new Set([e,decodeURI(e)])).map((e=>(0,d.f)(u.Z,e))).flat();return Promise.all(t.map((e=>null==e.route.component.preload?void 0:e.route.component.preload())))}class I extends r.Component{constructor(e){super(e),this.previousLocation=void 0,this.routeUpdateCleanupCb=void 0,this.previousLocation=null,this.routeUpdateCleanupCb=l.Z.canUseDOM?P("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=P("onRouteUpdate",{previousLocation:this.previousLocation,location:n}),A(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(N,{previousLocation:this.previousLocation,location:t},r.createElement(c.AW,{location:t,render:()=>e}))}}const L=I,R="__docusaurus-base-url-issue-banner-container",j="__docusaurus-base-url-issue-banner-suggestion-container",M="__DOCUSAURUS_INSERT_BASEURL_BANNER";function F(e){return`\nwindow['${M}'] = true;\n\ndocument.addEventListener('DOMContentLoaded', maybeInsertBanner);\n\nfunction maybeInsertBanner() {\n var shouldInsert = window['${M}'];\n shouldInsert && insertBanner();\n}\n\nfunction insertBanner() {\n var bannerContainer = document.getElementById('${R}');\n if (!bannerContainer) {\n return;\n }\n var bannerHtml = ${JSON.stringify(function(e){return`\n<div id="__docusaurus-base-url-issue-banner" style="border: thick solid red; background-color: rgb(255, 230, 179); margin: 20px; padding: 20px; font-size: 20px;">\n <p style="font-weight: bold; font-size: 30px;">Your Docusaurus site did not load properly.</p>\n <p>A very common reason is a wrong site <a href="https://docusaurus.io/docs/docusaurus.config.js/#baseUrl" style="font-weight: bold;">baseUrl configuration</a>.</p>\n <p>Current configured baseUrl = <span style="font-weight: bold; color: red;">${e}</span> ${"/"===e?" (default value)":""}</p>\n <p>We suggest trying baseUrl = <span id="${j}" style="font-weight: bold; color: green;"></span></p>\n</div>\n`}(e)).replace(/</g,"\\<")};\n bannerContainer.innerHTML = bannerHtml;\n var suggestionContainer = document.getElementById('${j}');\n var actualHomePagePath = window.location.pathname;\n var suggestedBaseUrl = actualHomePagePath.substr(-1) === '/'\n ? actualHomePagePath\n : actualHomePagePath + '/';\n suggestionContainer.innerHTML = suggestedBaseUrl;\n}\n`}function B(){const{siteConfig:{baseUrl:e}}=(0,m.default)();return(0,r.useLayoutEffect)((()=>{window[M]=!1}),[]),r.createElement(r.Fragment,null,!l.Z.canUseDOM&&r.createElement(h.Z,null,r.createElement("script",null,F(e))),r.createElement("div",{id:R}))}function z(){const{siteConfig:{baseUrl:e,baseUrlIssueBanner:t}}=(0,m.default)(),{pathname:n}=(0,c.TH)();return t&&n===e?r.createElement(B,null):null}function $(){const{siteConfig:{favicon:e,title:t,noIndex:n},i18n:{currentLocale:o,localeConfigs:a}}=(0,m.default)(),i=(0,g.default)(e),{htmlLang:l,direction:s}=a[o];return r.createElement(h.Z,null,r.createElement("html",{lang:l,dir:s}),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 U=n(24649);function H(){const e=(0,d.H)(u.Z),t=(0,c.TH)();return r.createElement(U.default,null,r.createElement(D.M,null,r.createElement(O.t,null,r.createElement(f.Z,null,r.createElement($,null),r.createElement(S,null),r.createElement(z,null),r.createElement(L,{location:T(t)},e)))))}var V=n(16887);const q=function(e){try{return document.createElement("link").relList.supports(e)}catch{return!1}}("prefetch")?function(e){return new Promise(((t,n)=>{var r;if("undefined"==typeof document)return void n();const o=document.createElement("link");o.setAttribute("rel","prefetch"),o.setAttribute("href",e),o.onload=()=>t(),o.onerror=()=>n();const a=document.getElementsByTagName("head")[0]??(null==(r=document.getElementsByName("script")[0])?void 0:r.parentNode);null==a||a.appendChild(o)}))}: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 G=n(66916);const W=new Set,Z=new Set,Q=()=>{var e,t;return(null==(e=navigator.connection)?void 0:e.effectiveType.includes("2g"))||(null==(t=navigator.connection)?void 0:t.saveData)},Y={prefetch(e){if(!(e=>!Q()&&!Z.has(e)&&!W.has(e))(e))return!1;W.add(e);const t=(0,d.f)(u.Z,e).flatMap((e=>{return t=e.route.path,Object.entries(V).filter((e=>{let[n]=e;return n.replace(/-[^-]+$/,"")===t})).flatMap((e=>{let[,t]=e;return Object.values((0,G.Z)(t))}));var t}));return Promise.all(t.map((e=>{const t=n.gca(e);return t&&!t.includes("undefined")?q(t).catch((()=>{})):Promise.resolve()})))},preload:e=>!!(e=>!Q()&&!Z.has(e))(e)&&(Z.add(e),A(e))},X=Object.freeze(Y);if(l.Z.canUseDOM){window.docusaurus=X;const e=o.hydrate;A(window.location.pathname).then((()=>{e(r.createElement(i.B6,null,r.createElement(a.VK,null,r.createElement(H,null))),document.getElementById("__docusaurus"))}))}},56725:(e,t,n)=>{"use strict";n.d(t,{_:()=>c,M:()=>d});var r=n(67294),o=n(36809);const a=JSON.parse('{"docusaurus-plugin-content-docs":{"Docs":{"path":"/","versions":[{"name":"current","label":"Next","isLast":true,"path":"/","mainDocId":"index","docs":[{"id":"community","path":"/community"},{"id":"contribute","path":"/contribute","sidebar":"main"},{"id":"deepresearch","path":"/deepresearch","sidebar":"main"},{"id":"index","path":"/","sidebar":"main"},{"id":"join-us","path":"/join-us"},{"id":"media","path":"/media"},{"id":"principles","path":"/principles","sidebar":"main"},{"id":"privacy-policy","path":"/privacy-policy"},{"id":"publications","path":"/publications"},{"id":"rfcprocess","path":"/rfcprocess"},{"id":"security","path":"/security"},{"id":"terms","path":"/terms"},{"id":"vips","path":"/vips","sidebar":"main"},{"id":"vsus","path":"/vsus","sidebar":"main"}],"draftIds":[],"sidebars":{"main":{"link":{"path":"/","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 l=n(57529);const s=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-plugin-sass":{"type":"package","name":"docusaurus-plugin-sass","version":"0.2.3"},"logos-docusaurus-search-local":{"type":"package","name":"@acid-info/logos-docusaurus-search-local","version":"1.0.0-alpha.111"},"logos-data-plugin":{"type":"local"},"docusaurus-theme-classic":{"type":"package","name":"@docusaurus/theme-classic","version":"2.4.1"},"docusaurus-theme-mermaid":{"type":"package","name":"@docusaurus/theme-mermaid","version":"2.4.1"},"logos-docusaurus-theme":{"type":"package","name":"@acid-info/logos-docusaurus-theme","version":"1.0.0-alpha.133"},"docusaurus-plugin-client-redirects":{"type":"package","name":"@docusaurus/plugin-client-redirects","version":"2.4.1"},"docusaurus-og":{"type":"package","name":"@acid-info/docusaurus-og","version":"1.0.0-alpha.131"}}}'),u={siteConfig:o.Z,siteMetadata:s,globalData:a,i18n:i,codeTranslations:l},c=r.createContext(u);function d(e){let{children:t}=e;return r.createElement(c.Provider,{value:u},t)}},24649:(e,t,n)=>{"use strict";n.r(t),n.d(t,{default:()=>f});var r=n(67294),o=n(19901),a=n(32411),i=n(79861),l=n(66867);function s(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(u,{error:t}))}function u(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 c(e){let{error:t,tryAgain:n}=e;return r.createElement(f,{fallback:()=>r.createElement(s,{error:t,tryAgain:n})},r.createElement(a.Z,null,r.createElement("title",null,"Page Error")),r.createElement(l.default,null,r.createElement(s,{error:t,tryAgain:n})))}const d=e=>r.createElement(c,e);class f extends r.Component{constructor(e){super(e),this.state={error:null}}componentDidCatch(e){o.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}}},19901:(e,t,n)=>{"use strict";n.d(t,{Z:()=>o});const r="undefined"!=typeof window&&"document"in window&&"createElement"in window.document,o={canUseDOM:r,canUseEventListeners:r&&("addEventListener"in window||"attachEvent"in window),canUseIntersectionObserver:r&&"IntersectionObserver"in window,canUseViewport:r&&"screen"in window}},32411:(e,t,n)=>{"use strict";n.d(t,{Z:()=>a});var r=n(67294),o=n(70405);function a(e){return r.createElement(o.ql,e)}},88746:(e,t,n)=>{"use strict";n.r(t),n.d(t,{default:()=>p});var r=n(87462),o=n(67294),a=n(73727),i=n(79861),l=n(6832),s=n(71699),u=n(19901);const c=o.createContext({collectLink:()=>{}});var d=n(51402);function f(e,t){var n;let{isNavLink:f,to:p,href:h,activeClassName:m,isActive:g,"data-noBrokenLinkCheck":v,autoAddBaseUrl:b=!0,...y}=e;const{siteConfig:{trailingSlash:w,baseUrl:x}}=(0,l.default)(),{withBaseUrl:_}=(0,d.useBaseUrlUtils)(),k=(0,o.useContext)(c),E=(0,o.useRef)(null);(0,o.useImperativeHandle)(t,(()=>E.current));const S=p||h;const C=(0,s.default)(S),T=null==S?void 0:S.replace("pathname://","");let O=void 0!==T?(D=T,b&&(e=>e.startsWith("/"))(D)?_(D):D):void 0;var D;O&&C&&(O=(0,i.applyTrailingSlash)(O,{trailingSlash:w,baseUrl:x}));const P=(0,o.useRef)(!1),N=f?a.OL:a.rU,A=u.Z.canUseIntersectionObserver,I=(0,o.useRef)(),L=()=>{P.current||null==O||(window.docusaurus.preload(O),P.current=!0)};(0,o.useEffect)((()=>(!A&&C&&null!=O&&window.docusaurus.prefetch(O),()=>{A&&I.current&&I.current.disconnect()})),[I,O,A,C]);const R=(null==(n=O)?void 0:n.startsWith("#"))??!1,j=!O||!C||R;return j||v||k.collectLink(O),j?o.createElement("a",(0,r.Z)({ref:E,href:O},S&&!C&&{target:"_blank",rel:"noopener noreferrer"},y)):o.createElement(N,(0,r.Z)({},y,{onMouseEnter:L,onTouchStart:L,innerRef:e=>{E.current=e,A&&e&&C&&(I.current=new window.IntersectionObserver((t=>{t.forEach((t=>{e===t.target&&(t.isIntersecting||t.intersectionRatio>0)&&(I.current.unobserve(e),I.current.disconnect(),null!=O&&window.docusaurus.prefetch(O))}))})),I.current.observe(e))},to:O},f&&{isActive:g,activeClassName:m}))}const p=o.forwardRef(f)},11614:(e,t,n)=>{"use strict";n.r(t),n.d(t,{default:()=>s,translate:()=>l});var r=n(67294);function o(e,t){const n=e.split(/(\{\w+\})/).map(((e,n)=>{if(n%2==1){const n=null==t?void 0: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 a=n(57529);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 a[t??n]??n??t}function l(e,t){let{message:n,id:r}=e;return o(i({message:n,id:r}),t)}function s(e){let{children:t,id:n,values:a}=e;if(t&&"string"!=typeof t)throw console.warn("Illegal <Translate> children",t),new Error("The Docusaurus <Translate> component only accept simple string values");const l=i({message:t,id:n});return r.createElement(r.Fragment,null,o(l,a))}},12497:(e,t,n)=>{"use strict";n.d(t,{m:()=>r});const r="default"},71699:(e,t,n)=>{"use strict";function r(e){return/^(?:\w*:|\/\/)/.test(e)}function o(e){return void 0!==e&&!r(e)}n.r(t),n.d(t,{default:()=>o,hasProtocol:()=>r})},7154:(e,t,n)=>{"use strict";n.r(t),n.d(t,{Redirect:()=>r.l_,matchPath:()=>r.LX,useHistory:()=>r.k6,useLocation:()=>r.TH});var r=n(16550)},51402:(e,t,n)=>{"use strict";n.r(t),n.d(t,{default:()=>l,useBaseUrlUtils:()=>i});var r=n(67294),o=n(6832),a=n(71699);function i(){const{siteConfig:{baseUrl:e,url:t}}=(0,o.default)(),n=(0,r.useCallback)(((n,r)=>function(e,t,n,r){let{forcePrependBaseUrl:o=!1,absolute:i=!1}=void 0===r?{}:r;if(!n||n.startsWith("#")||(0,a.hasProtocol)(n))return n;if(o)return t+n.replace(/^\//,"");if(n===t.replace(/\/$/,""))return t;const l=n.startsWith(t)?n:t+n.replace(/^\//,"");return i?e+l:l}(t,e,n,r)),[t,e]);return{withBaseUrl:n}}function l(e,t){void 0===t&&(t={});const{withBaseUrl:n}=i();return n(e,t)}},6832:(e,t,n)=>{"use strict";n.r(t),n.d(t,{default:()=>a});var r=n(67294),o=n(56725);function a(){return(0,r.useContext)(o._)}},5730:(e,t,n)=>{"use strict";n.r(t),n.d(t,{default:()=>a});var r=n(67294),o=n(74058);function a(){return(0,r.useContext)(o._)}},66916:(e,t,n)=>{"use strict";n.d(t,{Z:()=>r});function r(e){const t={};return function e(n,r){Object.entries(n).forEach((n=>{let[o,a]=n;const i=r?`${r}.${o}`:o;var l;"object"==typeof(l=a)&&l&&Object.keys(l).length>0?e(a,i):t[i]=a}))}(e),t}},66041:(e,t,n)=>{"use strict";n.d(t,{_:()=>o,z:()=>a});var r=n(67294);const o=r.createContext(null);function a(e){let{children:t,value:n}=e;const a=r.useContext(o),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,...null==n?void 0:n.data};return{plugin:t.plugin,data:r}}({parent:a,value:n})),[a,n]);return r.createElement(o.Provider,{value:i},t)}},4452:(e,t,n)=>{"use strict";n.r(t),n.d(t,{useActiveDocContext:()=>b,useActivePlugin:()=>p,useActivePluginAndVersion:()=>h,useActiveVersion:()=>v,useAllDocsData:()=>d,useDocVersionSuggestions:()=>y,useDocsData:()=>f,useLatestVersion:()=>g,useVersions:()=>m});var r=n(16550),o=n(6832),a=n(12497);function i(e,t){void 0===t&&(t={});const n=function(){const{globalData:e}=(0,o.default)();return e}()[e];if(!n&&t.failfast)throw new Error(`Docusaurus plugin global data not found for "${e}" plugin.`);return n}const l=e=>e.versions.find((e=>e.isLast));function s(e,t){const n=l(e);return[...e.versions.filter((e=>e!==n)),n].find((e=>!!(0,r.LX)(t,{path:e.path,exact:!1,strict:!1})))}function u(e,t){const n=s(e,t),o=null==n?void 0:n.docs.find((e=>!!(0,r.LX)(t,{path:e.path,exact:!0,strict:!1})));return{activeVersion:n,activeDoc:o,alternateDocVersions:o?function(t){const n={};return e.versions.forEach((e=>{e.docs.forEach((r=>{r.id===t&&(n[e.name]=r)}))})),n}(o.id):{}}}const c={},d=()=>i("docusaurus-plugin-content-docs")??c,f=e=>function(e,t,n){void 0===t&&(t=a.m),void 0===n&&(n={});const r=i(e),o=null==r?void 0:r[t];if(!o&&n.failfast)throw new Error(`Docusaurus plugin global data not found for "${e}" plugin with id "${t}".`);return o}("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 o=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})})),a=o?{pluginId:o[0],pluginData:o[1]}:void 0;if(!a&&n.failfast)throw new Error(`Can't find active docs plugin for "${t}" pathname, while it was expected to be found. Maybe you tried to use a docs feature that can only be used on a docs-related page? Existing docs plugin paths are: ${Object.values(e).map((e=>e.path)).join(", ")}`);return a}(t,n,e)}function h(e){void 0===e&&(e={});const t=p(e),{pathname:n}=(0,r.TH)();if(!t)return;return{activePlugin:t,activeVersion:s(t.pluginData,n)}}function m(e){return f(e).versions}function g(e){const t=f(e);return l(t)}function v(e){const t=f(e),{pathname:n}=(0,r.TH)();return s(t,n)}function b(e){const t=f(e),{pathname:n}=(0,r.TH)();return u(t,n)}function y(e){const t=f(e),{pathname:n}=(0,r.TH)();return function(e,t){const n=l(e);return{latestDocSuggestion:u(e,t).alternateDocVersions[n.name],latestVersionSuggestion:n}}(t,n)}},26126:(e,t,n)=>{"use strict";n.r(t),n.d(t,{default:()=>a});var r=n(74865),o=n.n(r);o().configure({showSpinner:!1});const a={onRouteUpdate(e){let{location:t,previousLocation:n}=e;if(n&&t.pathname!==n.pathname){const e=window.setTimeout((()=>{o().start()}),200);return()=>window.clearTimeout(e)}},onRouteDidUpdate(){o().done()}}},25529:(e,t,n)=>{"use strict";n.r(t);var r=n(87410),o=n(36809);!function(e){const{themeConfig:{prism:t}}=o.Z,{additionalLanguages:r}=t;globalThis.Prism=e,r.forEach((e=>{n(6726)(`./prism-${e}`)})),delete globalThis.Prism}(r.Z)},10510:(e,t,n)=>{"use strict";n.r(t),n.d(t,{default:()=>T});var r=n(67294),o=n(96793),a=n(68211),i=n(87462),l=n(88746),s=n(51402),u=n(71699),c=n(43399);function d(e){let{item:t}=e;const{to:n,href:o,label:a,prependBaseUrlToHref:d,...f}=t,p=(0,s.default)(n),h=(0,s.default)(o,{forcePrependBaseUrl:!0});return r.createElement(l.default,(0,i.Z)({className:"footer__link-item"},o?{href:d?h:o}:{to:p},f),a,o&&!(0,u.default)(o)&&r.createElement(c.Z,null))}function f(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(d,{item:t}))}function p(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(f,{key:t,item:e})))))}function h(e){let{columns:t}=e;return r.createElement("div",{className:"row footer__links"},t.map(((e,t)=>r.createElement(p,{key:t,column:e}))))}function m(){return r.createElement("span",{className:"footer__link-separator"},"\xb7")}function g(e){let{item:t}=e;return t.html?r.createElement("span",{className:"footer__link-item",dangerouslySetInnerHTML:{__html:t.html}}):r.createElement(d,{item:t})}function v(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(g,{item:e}),t.length!==n+1&&r.createElement(m,null))))))}function b(e){let{links:t}=e;return(0,a.a)(t)?r.createElement(h,{columns:t}):r.createElement(v,{links:t})}var y=n(86010),w=n(47002);const x="footerLogoLink_BH7S";function _(e){let{logo:t}=e;const{withBaseUrl:n}=(0,s.useBaseUrlUtils)(),o={light:n(t.src),dark:n(t.srcDark??t.src)};return r.createElement(w.default,{className:(0,y.default)("footer__logo",t.className),alt:t.alt,sources:o,width:t.width,height:t.height,style:t.style})}function k(e){let{logo:t}=e;return t.href?r.createElement(l.default,{href:t.href,className:x,target:t.target},r.createElement(_,{logo:t})):r.createElement(_,{logo:t})}function E(e){let{copyright:t}=e;return r.createElement("div",{className:"footer__copyright",dangerouslySetInnerHTML:{__html:t}})}var S=n(72726);function C(){const{footer:e}=(0,o.L)();if(!e)return null;const{copyright:t,links:n,logo:a,style:i}=e;return r.createElement(S.Z,{style:i,links:n&&n.length>0&&r.createElement(b,{links:n}),logo:a&&r.createElement(k,{logo:a}),copyright:t&&r.createElement(E,{copyright:t})})}const T=r.memo(C)},5574:(e,t,n)=>{"use strict";n.r(t),n.d(t,{default:()=>a});var r=n(87462),o=n(67294);function a(e){return o.createElement("svg",(0,r.Z)({viewBox:"0 0 24 24",width:24,height:24},e),o.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"}))}},43399:(e,t,n)=>{"use strict";n.d(t,{Z:()=>a});var r=n(67294);const o="iconExternalLink_nPIU";function a(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:o},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"}))}},60388:(e,t,n)=>{"use strict";n.r(t),n.d(t,{default:()=>a});var r=n(87462),o=n(67294);function a(e){return o.createElement("svg",(0,r.Z)({viewBox:"0 0 24 24",width:24,height:24},e),o.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"}))}},66867:(e,t,n)=>{"use strict";n.r(t),n.d(t,{default:()=>L});var r=n(67294),o=n(86010),a=n(24649),i=n(44873),l=n(66470),s=n(18015),u=n(22768);const c="skipToContent_fXgn";function d(){return r.createElement(l.l,{className:c})}var f=n(96793),p=n(69061),h=n(87462),m=n(11614);function g(e){let{width:t=21,height:n=21,color:o="currentColor",strokeWidth:a=1.2,className:i,...l}=e;return r.createElement("svg",(0,h.Z)({viewBox:"0 0 15 15",width:t,height:n},l),r.createElement("g",{stroke:o,strokeWidth:a},r.createElement("path",{d:"M.75.75l13.5 13.5M14.25.75L.75 14.25"})))}const v="closeButton_CVFx";function b(e){return r.createElement("button",(0,h.Z)({type:"button","aria-label":(0,m.translate)({id:"theme.AnnouncementBar.closeButtonAriaLabel",message:"Close",description:"The ARIA label for close button of announcement bar"})},e,{className:(0,o.default)("clean-btn close",v,e.className)}),r.createElement(g,{width:14,height:14,strokeWidth:3.1}))}const y="content_knG7";function w(e){const{announcementBar:t}=(0,f.L)(),{content:n}=t;return r.createElement("div",(0,h.Z)({},e,{className:(0,o.default)(y,e.className),dangerouslySetInnerHTML:{__html:n}}))}const x="announcementBar_mb4j",_="announcementBarPlaceholder_vyr4",k="announcementBarClose_gvF7",E="announcementBarContent_xLdY";function S(){const{announcementBar:e}=(0,f.L)(),{isActive:t,close:n}=(0,p.nT)();if(!t)return null;const{backgroundColor:o,textColor:a,isCloseable:i}=e;return r.createElement("div",{className:x,style:{backgroundColor:o,color:a},role:"banner"},i&&r.createElement("div",{className:_}),r.createElement(w,{className:E}),i&&r.createElement(b,{onClick:n,className:k}))}var C=n(26558),T=n(27882);function O(){return r.createElement(C.Z,null,r.createElement(T.Z,null))}var D=n(10510),P=n(10211),N=n(48348);function A(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(m.default,{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(N.Cw,{onClick:n,className:"button button--primary shadow--lw"})),r.createElement("hr",null),r.createElement("div",{className:"margin-vert--md"},r.createElement(N.aG,{error:t})))))}const I="mainWrapper_z2l0";function L(e){const{children:t,noFooter:n,wrapperClassName:c,title:f,description:p}=e;return(0,u.t)(),r.createElement(P.Z,null,r.createElement(i.d,{title:f,description:p}),r.createElement(d,null),r.createElement(S,null),r.createElement(O,null),r.createElement("div",{id:l.u,className:(0,o.default)(s.k.wrapper.main,I,c)},r.createElement(a.default,{fallback:e=>r.createElement(A,e)},t)),!n&&r.createElement(D.default,null))}},17662:(e,t,n)=>{"use strict";n.r(t),n.d(t,{default:()=>s});var r=n(67294),o=n(96793),a=n(70524),i=n(61818);const l="darkNavbarColorModeToggle_X3D1";function s(e){let{className:t}=e;const n=(0,o.L)().navbar.style,s=(0,o.L)().colorMode.disableSwitch,{colorMode:u,setColorMode:c}=(0,a.I)();return s?null:r.createElement(i.Z,{className:t,buttonClassName:"dark"===n?l:void 0,value:u,onChange:c})}},60543:(e,t,n)=>{"use strict";n.r(t),n.d(t,{default:()=>s});var r=n(67294),o=n(35022),a=n(11614),i=n(87462);function l(e){let{width:t=30,height:n=30,className:o,...a}=e;return r.createElement("svg",(0,i.Z)({className:o,width:t,height:n,viewBox:"0 0 30 30","aria-hidden":"true"},a),r.createElement("path",{stroke:"currentColor",strokeLinecap:"round",strokeMiterlimit:"10",strokeWidth:"2",d:"M4 7h22M4 15h22M4 23h22"}))}function s(){const{toggle:e,shown:t}=(0,o.e)();return r.createElement("button",{onClick:e,"aria-label":(0,a.translate)({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(l,null))}},44488:(e,t,n)=>{"use strict";n.r(t),n.d(t,{default:()=>p});var r=n(67294),o=n(35022),a=n(69322),i=n(64644),l=n(20080),s=n(87462),u=n(96793),c=n(93496);function d(){const e=(0,o.e)(),t=(0,u.L)().navbar.items;return r.createElement("ul",{className:"menu__list"},t.map(((t,n)=>r.createElement(c.default,(0,s.Z)({mobile:!0},t,{onClick:()=>e.toggle(),key:n})))))}var f=n(29843);function p(){const e=(0,o.e)();return(0,a.N)(e.shown),e.shouldRender?r.createElement(i.Z,{header:r.createElement(l.Z,null),primaryMenu:r.createElement(d,null),secondaryMenu:r.createElement(f.Z,null)}):null}},93496:(e,t,n)=>{"use strict";n.r(t),n.d(t,{default:()=>_});var r=n(67294),o=n(87462),a=n(86010),i=n(83112);function l(e){let{className:t,isDropdownItem:n=!1,...l}=e;const s=r.createElement(i.default,(0,o.Z)({className:(0,a.default)(n?"dropdown__link":"navbar__item navbar__link",t),isDropdownLink:n},l));return n?r.createElement("li",null,s):s}function s(e){let{className:t,isDropdownItem:n,...l}=e;return r.createElement("li",{className:"menu__list-item"},r.createElement(i.default,(0,o.Z)({className:(0,a.default)("menu__link",t)},l)))}function u(e){let{mobile:t=!1,position:n,...a}=e;const i=t?s:l;return r.createElement(i,(0,o.Z)({},a,{activeClassName:a.activeClassName??(t?"menu__link--active":"navbar__link--active")}))}var c=n(71003),d=n(23247),f=n(20130);const p="searchBox_ZlJk";function h(e){let{children:t,className:n}=e;return r.createElement("div",{className:(0,a.default)(n,p)},t)}var m=n(4452),g=n(85919);var v=n(4049),b=n(11614),y=n(16550);const w=e=>e.docs.find((t=>t.id===e.mainDocId));const x={default:u,localeDropdown:d.Z,search:function(e){let{mobile:t,className:n}=e;return t?null:r.createElement(h,{className:n},r.createElement(f.default,null))},dropdown:c.default,html:function(e){let{value:t,className:n,mobile:o=!1,isDropdownItem:i=!1}=e;const l=i?"li":"div";return r.createElement(l,{className:(0,a.default)({navbar__item:!o&&!i,"menu__list-item":o},n),dangerouslySetInnerHTML:{__html:t}})},doc:function(e){let{docId:t,label:n,docsPluginId:a,...i}=e;const{activeDoc:l}=(0,m.useActiveDocContext)(a),s=(0,g.vY)(t,a);return null===s?null:r.createElement(u,(0,o.Z)({exact:!0},i,{isActive:()=>(null==l?void 0:l.path)===s.path||!(null==l||!l.sidebar)&&l.sidebar===s.sidebar,label:n??s.id,to:s.path}))},docSidebar:function(e){let{sidebarId:t,label:n,docsPluginId:a,...i}=e;const{activeDoc:l}=(0,m.useActiveDocContext)(a),s=(0,g.oz)(t,a).link;if(!s)throw new Error(`DocSidebarNavbarItem: Sidebar with ID "${t}" doesn't have anything to be linked to.`);return r.createElement(u,(0,o.Z)({exact:!0},i,{isActive:()=>(null==l?void 0:l.sidebar)===t,label:n??s.label,to:s.path}))},docsVersion:function(e){let{label:t,to:n,docsPluginId:a,...i}=e;const l=(0,g.lO)(a)[0],s=t??l.label,c=n??(e=>e.docs.find((t=>t.id===e.mainDocId)))(l).path;return r.createElement(u,(0,o.Z)({},i,{label:s,to:c}))},docsVersionDropdown:function(e){let{mobile:t,docsPluginId:n,dropdownActiveClassDisabled:a,dropdownItemsBefore:i,dropdownItemsAfter:l,...s}=e;const{search:d,hash:f}=(0,y.TH)(),p=(0,m.useActiveDocContext)(n),h=(0,m.useVersions)(n),{savePreferredVersionName:x}=(0,v.J)(n),_=[...i,...h.map((e=>{const t=p.alternateDocVersions[e.name]??w(e);return{label:e.label,to:`${t.path}${d}${f}`,isActive:()=>e===p.activeVersion,onClick:()=>x(e.name)}})),...l],k=(0,g.lO)(n)[0],E=t&&_.length>1?(0,b.translate)({id:"theme.navbar.mobileVersionsDropdown.label",message:"Versions",description:"The label for the navbar versions dropdown on mobile view"}):k.label,S=t&&_.length>1?void 0:w(k).path;return _.length<=1?r.createElement(u,(0,o.Z)({},s,{mobile:t,label:E,to:S,isActive:a?()=>!1:void 0})):r.createElement(c.default,(0,o.Z)({},s,{mobile:t,label:E,to:S,items:_,isActive:a?()=>!1:void 0}))}};function _(e){let{type:t,...n}=e;const o=function(e,t){return e&&"default"!==e?e:"items"in t?"dropdown":"default"}(t,n),a=x[o];if(!a)throw new Error(`No NavbarItem component found for type "${t}".`);return r.createElement(a,n)}},26145:(e,t,n)=>{"use strict";n.d(t,{Z:()=>a});var r=n(67294),o=n(32411);function a(e){let{locale:t,version:n,tag:a}=e;const i=t;return r.createElement(o.Z,null,t&&r.createElement("meta",{name:"docusaurus_locale",content:t}),n&&r.createElement("meta",{name:"docusaurus_version",content:n}),a&&r.createElement("meta",{name:"docusaurus_tag",content:a}),i&&r.createElement("meta",{name:"docsearch:language",content:i}),n&&r.createElement("meta",{name:"docsearch:version",content:n}),a&&r.createElement("meta",{name:"docsearch:docusaurus_tag",content:a}))}},47002:(e,t,n)=>{"use strict";n.r(t),n.d(t,{default:()=>u});var r=n(87462),o=n(67294),a=n(86010),i=n(5730),l=n(70524);const s={themedImage:"themedImage_ToTc","themedImage--light":"themedImage--light_HNdA","themedImage--dark":"themedImage--dark_i4oU"};function u(e){const t=(0,i.default)(),{colorMode:n}=(0,l.I)(),{sources:u,className:c,alt:d,...f}=e,p=t?"dark"===n?["dark"]:["light"]:["light","dark"];return o.createElement(o.Fragment,null,p.map((e=>o.createElement("img",(0,r.Z)({key:e,src:u[e],alt:d,className:(0,a.default)(s.themedImage,s[`themedImage--${e}`],c)},f)))))}},69061:(e,t,n)=>{"use strict";n.d(t,{nT:()=>h,pl:()=>p});var r=n(67294),o=n(5730),a=n(99200),i=n(93478),l=n(96793);const s=(0,a.WA)("docusaurus.announcement.dismiss"),u=(0,a.WA)("docusaurus.announcement.id"),c=()=>"true"===s.get(),d=e=>s.set(String(e)),f=r.createContext(null);function p(e){let{children:t}=e;const n=function(){const{announcementBar:e}=(0,l.L)(),t=(0,o.default)(),[n,a]=(0,r.useState)((()=>!!t&&c()));(0,r.useEffect)((()=>{a(c())}),[]);const i=(0,r.useCallback)((()=>{d(!0),a(!0)}),[]);return(0,r.useEffect)((()=>{if(!e)return;const{id:t}=e;let n=u.get();"annoucement-bar"===n&&(n="announcement-bar");const r=t!==n;u.set(t),r&&d(!1),!r&&c()||a(!1)}),[e]),(0,r.useMemo)((()=>({isActive:!!e&&!n,close:i})),[e,n,i])}();return r.createElement(f.Provider,{value:n},t)}function h(){const e=(0,r.useContext)(f);if(!e)throw new i.i6("AnnouncementBarProvider");return e}},17762:(e,t,n)=>{"use strict";n.d(t,{C:()=>l,n:()=>i});var r=n(67294),o=n(93478);const a=r.createContext(null);function i(e){let{children:t,content:n,isBlogPostPage:o=!1}=e;const i=function(e){let{content:t,isBlogPostPage:n}=e;return(0,r.useMemo)((()=>({metadata:t.metadata,frontMatter:t.frontMatter,assets:t.assets,toc:t.toc,isBlogPostPage:n})),[t,n])}({content:n,isBlogPostPage:o});return r.createElement(a.Provider,{value:i},t)}function l(){const e=(0,r.useContext)(a);if(null===e)throw new o.i6("BlogPostProvider");return e}},70524:(e,t,n)=>{"use strict";n.d(t,{I:()=>g,S:()=>m});var r=n(67294),o=n(19901),a=n(93478),i=n(99200),l=n(96793);const s=r.createContext(void 0),u="theme",c=(0,i.WA)(u),d="light",f="dark",p=e=>e===f?f:d;function h(){const{colorMode:{defaultMode:e,disableSwitch:t,respectPrefersColorScheme:n}}=(0,l.L)(),[a,i]=(0,r.useState)((e=>o.Z.canUseDOM?p(document.documentElement.getAttribute("data-theme")):p(e))(e));(0,r.useEffect)((()=>{t&&c.del()}),[t]);const s=(0,r.useCallback)((function(t,r){void 0===r&&(r={});const{persist:o=!0}=r;t?(i(t),o&&(e=>{c.set(p(e))})(t)):(i(n?window.matchMedia("(prefers-color-scheme: dark)").matches?f:d:e),c.del())}),[n,e]);(0,r.useEffect)((()=>{document.documentElement.setAttribute("data-theme",p(a))}),[a]),(0,r.useEffect)((()=>{if(t)return;const e=e=>{if(e.key!==u)return;const t=c.get();null!==t&&s(p(t))};return window.addEventListener("storage",e),()=>window.removeEventListener("storage",e)}),[t,s]);const h=(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||h.current?h.current=window.matchMedia("print").matches:s(null)};return e.addListener(r),()=>e.removeListener(r)}),[s,t,n]),(0,r.useMemo)((()=>({colorMode:a,setColorMode:s,get isDarkTheme(){return a===f},setLightTheme(){s(d)},setDarkTheme(){s(f)}})),[a,s])}function m(e){let{children:t}=e;const n=h();return r.createElement(s.Provider,{value:n},t)}function g(){const e=(0,r.useContext)(s);if(null==e)throw new a.i6("ColorModeProvider","Please see https://docusaurus.io/docs/api/themes/configuration#use-color-mode.");return e}},2791:(e,t,n)=>{"use strict";n.d(t,{b:()=>i,k:()=>l});var r=n(67294),o=n(93478);const a=r.createContext(null);function i(e){let{children:t,content:n}=e;const o=function(e){return(0,r.useMemo)((()=>({metadata:e.metadata,frontMatter:e.frontMatter,assets:e.assets,contentTitle:e.contentTitle,toc:e.toc})),[e])}(n);return r.createElement(a.Provider,{value:o},t)}function l(){const e=(0,r.useContext)(a);if(null===e)throw new o.i6("DocProvider");return e}},55132:(e,t,n)=>{"use strict";n.d(t,{D:()=>l,f:()=>s});var r=n(67294),o=n(93478);const a=Symbol("EmptyContext"),i=r.createContext(a);function l(e){let{children:t}=e;const[n,o]=(0,r.useState)(null),a=(0,r.useMemo)((()=>({expandedItem:n,setExpandedItem:o})),[n]);return r.createElement(i.Provider,{value:a},t)}function s(){const e=(0,r.useContext)(i);if(e===a)throw new o.i6("DocSidebarItemsExpandedStateProvider");return e}},4049:(e,t,n)=>{"use strict";n.d(t,{J:()=>y,L5:()=>v,Oh:()=>w});var r=n(67294),o=n(4452),a=n(12497),i=n(96793),l=n(85919),s=n(93478),u=n(99200);const c=e=>`docs-preferred-version-${e}`,d=(e,t,n)=>{(0,u.WA)(c(e),{persistence:t}).set(n)},f=(e,t)=>(0,u.WA)(c(e),{persistence:t}).get(),p=(e,t)=>{(0,u.WA)(c(e),{persistence:t}).del()};const h=r.createContext(null);function m(){const e=(0,o.useAllDocsData)(),t=(0,i.L)().docs.versionPersistence,n=(0,r.useMemo)((()=>Object.keys(e)),[e]),[a,l]=(0,r.useState)((()=>(e=>Object.fromEntries(e.map((e=>[e,{preferredVersionName:null}]))))(n)));(0,r.useEffect)((()=>{l(function(e){let{pluginIds:t,versionPersistence:n,allDocsData:r}=e;function o(e){const t=f(e,n);return r[e].versions.some((e=>e.name===t))?{preferredVersionName:t}:(p(e,n),{preferredVersionName:null})}return Object.fromEntries(t.map((e=>[e,o(e)])))}({allDocsData:e,versionPersistence:t,pluginIds:n}))}),[e,t,n]);return[a,(0,r.useMemo)((()=>({savePreferredVersion:function(e,n){d(e,t,n),l((t=>({...t,[e]:{preferredVersionName:n}})))}})),[t])]}function g(e){let{children:t}=e;const n=m();return r.createElement(h.Provider,{value:n},t)}function v(e){let{children:t}=e;return l.cE?r.createElement(g,null,t):r.createElement(r.Fragment,null,t)}function b(){const e=(0,r.useContext)(h);if(!e)throw new s.i6("DocsPreferredVersionContextProvider");return e}function y(e){void 0===e&&(e=a.m);const t=(0,o.useDocsData)(e),[n,i]=b(),{preferredVersionName:l}=n[e];return{preferredVersion:t.versions.find((e=>e.name===l))??null,savePreferredVersionName:(0,r.useCallback)((t=>{i.savePreferredVersion(e,t)}),[i,e])}}function w(){const e=(0,o.useAllDocsData)(),[t]=b();function n(n){const r=e[n],{preferredVersionName:o}=t[n];return r.versions.find((e=>e.name===o))??null}const r=Object.keys(e);return Object.fromEntries(r.map((e=>[e,n(e)])))}},50003:(e,t,n)=>{"use strict";n.d(t,{V:()=>s,b:()=>l});var r=n(67294),o=n(93478);const a=Symbol("EmptyContext"),i=r.createContext(a);function l(e){let{children:t,name:n,items:o}=e;const a=(0,r.useMemo)((()=>n&&o?{name:n,items:o}:null),[n,o]);return r.createElement(i.Provider,{value:a},t)}function s(){const e=(0,r.useContext)(i);if(e===a)throw new o.i6("DocsSidebarProvider");return e}},6141:(e,t,n)=>{"use strict";n.d(t,{E:()=>l,q:()=>i});var r=n(67294),o=n(93478);const a=r.createContext(null);function i(e){let{children:t,version:n}=e;return r.createElement(a.Provider,{value:n},t)}function l(){const e=(0,r.useContext)(a);if(null===e)throw new o.i6("DocsVersionProvider");return e}},35022:(e,t,n)=>{"use strict";n.d(t,{M:()=>d,e:()=>f});var r=n(67294),o=n(82306),a=n(94980),i=n(34423),l=n(96793),s=n(93478);const u=r.createContext(void 0);function c(){const e=function(){const e=(0,o.HY)(),{items:t}=(0,l.L)().navbar;return 0===t.length&&!e.component}(),t=(0,a.i)(),n=!e&&"mobile"===t,[s,u]=(0,r.useState)(!1);(0,i.Rb)((()=>{if(s)return u(!1),!1}));const c=(0,r.useCallback)((()=>{u((e=>!e))}),[]);return(0,r.useEffect)((()=>{"desktop"===t&&u(!1)}),[t]),(0,r.useMemo)((()=>({disabled:e,shouldRender:n,toggle:c,shown:s})),[e,n,c,s])}function d(e){let{children:t}=e;const n=c();return r.createElement(u.Provider,{value:n},t)}function f(){const e=r.useContext(u);if(void 0===e)throw new s.i6("NavbarMobileSidebarProvider");return e}},82306:(e,t,n)=>{"use strict";n.d(t,{HY:()=>l,Zo:()=>s,n2:()=>i});var r=n(67294),o=n(93478);const a=r.createContext(null);function i(e){let{children:t}=e;const n=(0,r.useState)({component:null,props:null});return r.createElement(a.Provider,{value:n},t)}function l(){const e=(0,r.useContext)(a);if(!e)throw new o.i6("NavbarSecondaryMenuContentProvider");return e[0]}function s(e){let{component:t,props:n}=e;const i=(0,r.useContext)(a);if(!i)throw new o.i6("NavbarSecondaryMenuContentProvider");const[,l]=i,s=(0,o.Ql)(n);return(0,r.useEffect)((()=>{l({component:t,props:s})}),[l,t,s]),(0,r.useEffect)((()=>()=>l({component:null,props:null})),[l]),null}},20883:(e,t,n)=>{"use strict";n.d(t,{a:()=>i});var r=n(67294),o=n(63735),a=n(68265);function i(e){let{threshold:t}=e;const[n,i]=(0,r.useState)(!1),l=(0,r.useRef)(!1),{startScroll:s,cancelScroll:u}=(0,o.Ct)();return(0,o.RF)(((e,n)=>{let{scrollY:r}=e;const o=null==n?void 0:n.scrollY;o&&(l.current?l.current=!1:r>=o?(u(),i(!1)):r<t?i(!1):r+window.innerHeight<document.documentElement.scrollHeight&&i(!0))})),(0,a.S)((e=>{e.location.hash&&(l.current=!0,i(!1))})),{shown:n,scrollToTop:()=>s(0)}}},22768:(e,t,n)=>{"use strict";n.d(t,{h:()=>o,t:()=>a});var r=n(67294);const o="navigation-with-keyboard";function a(){(0,r.useEffect)((()=>{function e(e){"keydown"===e.type&&"Tab"===e.key&&document.body.classList.add(o),"mousedown"===e.type&&document.body.classList.remove(o)}return document.addEventListener("keydown",e),document.addEventListener("mousedown",e),()=>{document.body.classList.remove(o),document.removeEventListener("keydown",e),document.removeEventListener("mousedown",e)}}),[])}},69322:(e,t,n)=>{"use strict";n.d(t,{N:()=>o});var r=n(67294);function o(e){void 0===e&&(e=!0),(0,r.useEffect)((()=>(document.body.style.overflow=e?"hidden":"visible",()=>{document.body.style.overflow="visible"})),[e])}},99401:(e,t,n)=>{"use strict";n.d(t,{p:()=>a});var r=n(70524),o=n(96793);function a(){const{prism:e}=(0,o.L)(),{colorMode:t}=(0,r.I)(),n=e.theme,a=e.darkTheme||n;return"dark"===t?a:n}},78586:(e,t,n)=>{"use strict";n.d(t,{S:()=>s});var r=n(67294),o=n(96793);function a(e){const t=e.getBoundingClientRect();return t.top===t.bottom?a(e.parentNode):t}function i(e,t){let{anchorTopOffset:n}=t;const r=e.find((e=>a(e).top>=n));if(r){return function(e){return e.top>0&&e.bottom<window.innerHeight/2}(a(r))?r:e[e.indexOf(r)-1]??null}return e[e.length-1]??null}function l(){const e=(0,r.useRef)(0),{navbar:{hideOnScroll:t}}=(0,o.L)();return(0,r.useEffect)((()=>{e.current=t?0:document.querySelector(".navbar").clientHeight}),[t]),e}function s(e){const t=(0,r.useRef)(void 0),n=l();(0,r.useEffect)((()=>{if(!e)return()=>{};const{linkClassName:r,linkActiveClassName:o,minHeadingLevel:a,maxHeadingLevel:l}=e;function s(){const e=function(e){return Array.from(document.getElementsByClassName(e))}(r),s=function(e){let{minHeadingLevel:t,maxHeadingLevel:n}=e;const r=[];for(let o=t;o<=n;o+=1)r.push(`h${o}.anchor`);return Array.from(document.querySelectorAll(r.join()))}({minHeadingLevel:a,maxHeadingLevel:l}),u=i(s,{anchorTopOffset:n.current}),c=e.find((e=>u&&u.id===function(e){return decodeURIComponent(e.href.substring(e.href.indexOf("#")+1))}(e)));e.forEach((e=>{!function(e,n){n?(t.current&&t.current!==e&&t.current.classList.remove(o),e.classList.add(o),t.current=e):e.classList.remove(o)}(e,e===c)}))}return document.addEventListener("scroll",s),document.addEventListener("resize",s),s(),()=>{document.removeEventListener("scroll",s),document.removeEventListener("resize",s)}}),[e,n])}},94980:(e,t,n)=>{"use strict";n.d(t,{i:()=>u});var r=n(67294),o=n(19901);const a="desktop",i="mobile",l="ssr";function s(){return o.Z.canUseDOM?window.innerWidth>996?a:i:l}function u(){const[e,t]=(0,r.useState)((()=>s()));return(0,r.useEffect)((()=>{function e(){t(s())}return window.addEventListener("resize",e),()=>{window.removeEventListener("resize",e),clearTimeout(undefined)}}),[]),e}},93945:(e,t,n)=>{"use strict";n.r(t),n.d(t,{Collapsible:()=>S,ErrorBoundaryError:()=>q.aG,ErrorBoundaryTryAgainButton:()=>q.Cw,ErrorCauseBoundary:()=>q.QW,HtmlClassNameProvider:()=>O.FG,NavbarSecondaryMenuFiller:()=>P.Zo,PageMetadata:()=>O.d,ReactContextError:()=>T.i6,SkipToContentFallbackId:()=>V.u,SkipToContentLink:()=>V.l,ThemeClassNames:()=>C.k,composeProviders:()=>T.Qc,createStorageSlot:()=>o.WA,duplicates:()=>z.l,filterDocCardListItems:()=>i.MN,isMultiColumnFooterLinks:()=>F.a,isRegexpStringMatch:()=>B,listStorageKeys:()=>o._f,listTagsByLetters:()=>L,prefersReducedMotion:()=>g.n,processAdmonitionProps:()=>H,translateTagsPageTitle:()=>I,uniq:()=>z.j,useCollapsible:()=>v,useColorMode:()=>D.I,useContextualSearchFilters:()=>a._q,useCurrentSidebarCategory:()=>i.jA,useDocsPreferredVersion:()=>U.J,useEvent:()=>T.zX,useIsomorphicLayoutEffect:()=>T.LI,usePluralForm:()=>p,usePrevious:()=>T.D9,usePrismTheme:()=>$.p,useSearchLinkCreator:()=>M,useSearchQueryString:()=>j,useStorageSlot:()=>o.Nk,useThemeConfig:()=>r.L,useWindowSize:()=>N.i});var r=n(96793),o=n(99200),a=n(39105),i=n(85919),l=n(67294),s=n(6832);const u=["zero","one","two","few","many","other"];function c(e){return u.filter((t=>e.includes(t)))}const d={locale:"en",pluralForms:c(["one","other"]),select:e=>1===e?"one":"other"};function f(){const{i18n:{currentLocale:e}}=(0,s.default)();return(0,l.useMemo)((()=>{try{return function(e){const t=new Intl.PluralRules(e);return{locale:e,pluralForms:c(t.resolvedOptions().pluralCategories),select:e=>t.select(e)}}(e)}catch(t){return console.error(`Failed to use Intl.PluralRules for locale "${e}".\nDocusaurus will fallback to the default (English) implementation.\nError: ${t.message}\n`),d}}),[e])}function p(){const e=f();return{selectMessage:(t,n)=>function(e,t,n){const r=e.split("|");if(1===r.length)return r[0];r.length>n.pluralForms.length&&console.error(`For locale=${n.locale}, a maximum of ${n.pluralForms.length} plural forms are expected (${n.pluralForms.join(",")}), but the message contains ${r.length}: ${e}`);const o=n.select(t),a=n.pluralForms.indexOf(o);return r[Math.min(a,r.length-1)]}(n,t,e)}}var h=n(87462),m=n(19901),g=n(39657);function v(e){let{initialState:t}=e;const[n,r]=(0,l.useState)(t??!1),o=(0,l.useCallback)((()=>{r((e=>!e))}),[]);return{collapsed:n,setCollapsed:r,toggleCollapsed:o}}const b={display:"none",overflow:"hidden",height:"0px"},y={display:"block",overflow:"visible",height:"auto"};function w(e,t){const n=t?b:y;e.style.display=n.display,e.style.overflow=n.overflow,e.style.height=n.height}function x(e){let{collapsibleRef:t,collapsed:n,animation:r}=e;const o=(0,l.useRef)(!1);(0,l.useEffect)((()=>{const e=t.current;function a(){const t=e.scrollHeight,n=(null==r?void 0:r.duration)??function(e){if((0,g.n)())return 1;const t=e/36;return Math.round(10*(4+15*t**.25+t/5))}(t);return{transition:`height ${n}ms ${(null==r?void 0:r.easing)??"ease-in-out"}`,height:`${t}px`}}function i(){const t=a();e.style.transition=t.transition,e.style.height=t.height}if(!o.current)return w(e,n),void(o.current=!0);return e.style.willChange="height",function(){const t=requestAnimationFrame((()=>{n?(i(),requestAnimationFrame((()=>{e.style.height=b.height,e.style.overflow=b.overflow}))):(e.style.display="block",requestAnimationFrame((()=>{i()})))}));return()=>cancelAnimationFrame(t)}()}),[t,n,r])}function _(e){if(!m.Z.canUseDOM)return e?b:y}function k(e){let{as:t="div",collapsed:n,children:r,animation:o,onCollapseTransitionEnd:a,className:i,disableSSRStyle:s}=e;const u=(0,l.useRef)(null);return x({collapsibleRef:u,collapsed:n,animation:o}),l.createElement(t,{ref:u,style:s?void 0:_(n),onTransitionEnd:e=>{"height"===e.propertyName&&(w(u.current,n),null==a||a(n))},className:i},r)}function E(e){let{collapsed:t,...n}=e;const[r,o]=(0,l.useState)(!t),[a,i]=(0,l.useState)(t);return(0,l.useLayoutEffect)((()=>{t||o(!0)}),[t]),(0,l.useLayoutEffect)((()=>{r&&i(t)}),[r,t]),r?l.createElement(k,(0,h.Z)({},n,{collapsed:a})):null}function S(e){let{lazy:t,...n}=e;const r=t?E:k;return l.createElement(r,n)}var C=n(18015),T=n(93478),O=n(44873),D=n(70524),P=n(82306),N=n(94980),A=n(11614);const I=()=>(0,A.translate)({id:"theme.tags.tagsPageTitle",message:"Tags",description:"The title of the tag list page"});function L(e){const t={};return Object.values(e).forEach((e=>{const n=function(e){return e[0].toUpperCase()}(e.label);t[n]??=[],t[n].push(e)})),Object.entries(t).sort(((e,t)=>{let[n]=e,[r]=t;return n.localeCompare(r)})).map((e=>{let[t,n]=e;return{letter:t,tags:n.sort(((e,t)=>e.label.localeCompare(t.label)))}}))}var R=n(34423);function j(){return(0,R.Nc)("q")}function M(){const{siteConfig:{baseUrl:e,themeConfig:t}}=(0,s.default)(),{algolia:{searchPagePath:n}}=t;return(0,l.useCallback)((t=>`${e}${n}?q=${encodeURIComponent(t)}`),[e,n])}var F=n(68211);function B(e,t){return void 0!==e&&void 0!==t&&new RegExp(e,"gi").test(t)}var z=n(20636),$=n(99401),U=n(4049);function H(e){const{mdxAdmonitionTitle:t,rest:n}=function(e){const t=l.Children.toArray(e),n=t.find((e=>{var t;return l.isValidElement(e)&&"mdxAdmonitionTitle"===(null==(t=e.props)?void 0:t.mdxType)})),r=l.createElement(l.Fragment,null,t.filter((e=>e!==n)));return{mdxAdmonitionTitle:null==n?void 0:n.props.children,rest:r}}(e.children),r=e.title??t;return{...e,...r&&{title:r},children:n}}var V=n(66470),q=n(48348)},13616:(e,t,n)=>{"use strict";n.r(t),n.d(t,{AnnouncementBarProvider:()=>c.pl,BlogPostProvider:()=>s.n,Collapsible:()=>r.Collapsible,ColorModeProvider:()=>O.S,DEFAULT_SEARCH_TAG:()=>N.HX,DocProvider:()=>l.b,DocSidebarItemsExpandedStateProvider:()=>o.D,DocsPreferredVersionContextProvider:()=>u.L5,DocsSidebarProvider:()=>i.b,DocsVersionProvider:()=>a.q,ErrorBoundaryError:()=>r.ErrorBoundaryError,ErrorBoundaryTryAgainButton:()=>r.ErrorBoundaryTryAgainButton,ErrorCauseBoundary:()=>r.ErrorCauseBoundary,HtmlClassNameProvider:()=>r.HtmlClassNameProvider,NavbarProvider:()=>U,NavbarSecondaryMenuFiller:()=>r.NavbarSecondaryMenuFiller,PageMetadata:()=>r.PageMetadata,PluginHtmlClassNameProvider:()=>z.VC,ReactContextError:()=>r.ReactContextError,ScrollControllerProvider:()=>F.OC,SkipToContentFallbackId:()=>r.SkipToContentFallbackId,SkipToContentLink:()=>r.SkipToContentLink,ThemeClassNames:()=>r.ThemeClassNames,composeProviders:()=>r.composeProviders,containsLineNumbers:()=>P.nt,createStorageSlot:()=>r.createStorageSlot,docVersionSearchTag:()=>N.os,duplicates:()=>r.duplicates,filterDocCardListItems:()=>r.filterDocCardListItems,findFirstCategoryLink:()=>A.Wl,findSidebarCategory:()=>A.em,getPrismCssVariables:()=>P.QC,isActiveSidebarItem:()=>A._F,isDocsPluginEnabled:()=>A.cE,isMultiColumnFooterLinks:()=>r.isMultiColumnFooterLinks,isRegexpStringMatch:()=>r.isRegexpStringMatch,isSamePath:()=>B.Mg,keyboardFocusedClassName:()=>q.h,listStorageKeys:()=>r.listStorageKeys,listTagsByLetters:()=>r.listTagsByLetters,parseCodeBlockTitle:()=>P.bc,parseLanguage:()=>P.Vo,parseLines:()=>P.nZ,prefersReducedMotion:()=>r.prefersReducedMotion,processAdmonitionProps:()=>r.processAdmonitionProps,splitNavbarItems:()=>$,translateTagsPageTitle:()=>r.translateTagsPageTitle,uniq:()=>r.uniq,useAlternatePageUtils:()=>D.l,useAnnouncementBar:()=>c.nT,useBackToTopButton:()=>Y.a,useBlogPost:()=>s.C,useCodeWordWrap:()=>Q,useCollapsible:()=>r.useCollapsible,useColorMode:()=>r.useColorMode,useContextualSearchFilters:()=>r.useContextualSearchFilters,useCurrentSidebarCategory:()=>r.useCurrentSidebarCategory,useDoc:()=>l.k,useDocById:()=>A.xz,useDocRouteMetadata:()=>A.hI,useDocSidebarItemsExpandedState:()=>o.f,useDocsPreferredVersion:()=>r.useDocsPreferredVersion,useDocsPreferredVersionByPluginId:()=>u.Oh,useDocsSidebar:()=>i.V,useDocsVersion:()=>a.E,useDocsVersionCandidates:()=>A.lO,useEvent:()=>r.useEvent,useFilteredAndTreeifiedTOC:()=>M.b,useHideableNavbar:()=>V,useHistoryPopHandler:()=>p.Rb,useHistorySelector:()=>p.xL,useHomePageRoute:()=>B.Ns,useIsomorphicLayoutEffect:()=>r.useIsomorphicLayoutEffect,useKeyboardNavigation:()=>q.t,useLayoutDoc:()=>A.vY,useLayoutDocsSidebar:()=>A.oz,useLocalPathname:()=>j,useLocationChange:()=>L.S,useLockBodyScroll:()=>G.N,useNavbarMobileSidebar:()=>x.e,useNavbarSecondaryMenu:()=>T,usePluralForm:()=>r.usePluralForm,usePrevious:()=>r.usePrevious,usePrismTheme:()=>r.usePrismTheme,useQueryStringValue:()=>p._X,useScrollController:()=>F.sG,useScrollPosition:()=>F.RF,useScrollPositionBlocker:()=>F.o5,useSearchLinkCreator:()=>r.useSearchLinkCreator,useSearchQueryString:()=>r.useSearchQueryString,useSidebarBreadcrumbs:()=>A.s1,useSmoothScrollTo:()=>F.Ct,useStorageSlot:()=>r.useStorageSlot,useTOCHighlight:()=>H.S,useTabs:()=>w,useThemeConfig:()=>r.useThemeConfig,useTitleFormatter:()=>I.p,useTreeifiedTOC:()=>M.a,useWindowSize:()=>r.useWindowSize});var r=n(93945),o=n(55132),a=n(6141),i=n(50003),l=n(2791),s=n(17762),u=n(4049),c=n(69061),d=n(67294),f=n(16550),p=n(34423),h=n(20636),m=n(99200);function g(e){return function(e){var t;return(null==(t=d.Children.map(e,(e=>{if(!e||(0,d.isValidElement)(e)&&function(e){const{props:t}=e;return!!t&&"object"==typeof t&&"value"in t}(e))return e;throw new Error(`Docusaurus error: Bad <Tabs> child <${"string"==typeof e.type?e.type:e.type.name}>: all children of the <Tabs> component should be <TabItem>, and every <TabItem> should have a unique "value" prop.`)})))?void 0:t.filter(Boolean))??[]}(e).map((e=>{let{props:{value:t,label:n,attributes:r,default:o}}=e;return{value:t,label:n,attributes:r,default:o}}))}function v(e){const{values:t,children:n}=e;return(0,d.useMemo)((()=>{const e=t??g(n);return function(e){const t=(0,h.l)(e,((e,t)=>e.value===t.value));if(t.length>0)throw new Error(`Docusaurus error: Duplicate values "${t.map((e=>e.value)).join(", ")}" found in <Tabs>. Every value needs to be unique.`)}(e),e}),[t,n])}function b(e){let{value:t,tabValues:n}=e;return n.some((e=>e.value===t))}function y(e){let{queryString:t=!1,groupId:n}=e;const r=(0,f.k6)(),o=function(e){let{queryString:t=!1,groupId:n}=e;if("string"==typeof t)return t;if(!1===t)return null;if(!0===t&&!n)throw new Error('Docusaurus error: The <Tabs> component groupId prop is required if queryString=true, because this value is used as the search param name. You can also provide an explicit value such as queryString="my-search-param".');return n??null}({queryString:t,groupId:n});return[(0,p._X)(o),(0,d.useCallback)((e=>{if(!o)return;const t=new URLSearchParams(r.location.search);t.set(o,e),r.replace({...r.location,search:t.toString()})}),[o,r])]}function w(e){const{defaultValue:t,queryString:n=!1,groupId:r}=e,o=v(e),[a,i]=(0,d.useState)((()=>function(e){let{defaultValue:t,tabValues:n}=e;if(0===n.length)throw new Error("Docusaurus error: the <Tabs> component requires at least one <TabItem> children component");if(t){if(!b({value:t,tabValues:n}))throw new Error(`Docusaurus error: The <Tabs> has a defaultValue "${t}" but none of its children has the corresponding value. Available values are: ${n.map((e=>e.value)).join(", ")}. If you intend to show no default tab, use defaultValue={null} instead.`);return t}const r=n.find((e=>e.default))??n[0];if(!r)throw new Error("Unexpected error: 0 tabValues");return r.value}({defaultValue:t,tabValues:o}))),[l,s]=y({queryString:n,groupId:r}),[u,c]=function(e){let{groupId:t}=e;const n=function(e){return e?`docusaurus.tab.${e}`:null}(t),[r,o]=(0,m.Nk)(n);return[r,(0,d.useCallback)((e=>{n&&o.set(e)}),[n,o])]}({groupId:r}),f=(()=>{const e=l??u;return b({value:e,tabValues:o})?e:null})();(0,d.useLayoutEffect)((()=>{f&&i(f)}),[f]);return{selectedValue:a,selectValue:(0,d.useCallback)((e=>{if(!b({value:e,tabValues:o}))throw new Error(`Can't select invalid tab value=${e}`);i(e),s(e),c(e)}),[s,c,o]),tabValues:o}}var x=n(35022),_=n(93478),k=n(82306);const E=d.createContext(null);function S(e){let{children:t}=e;const n=function(){const e=(0,x.e)(),t=(0,k.HY)(),[n,r]=(0,d.useState)(!1),o=null!==t.component,a=(0,_.D9)(o);return(0,d.useEffect)((()=>{o&&!a&&r(!0)}),[o,a]),(0,d.useEffect)((()=>{o?e.shown||r(!0):r(!1)}),[e.shown,o]),(0,d.useMemo)((()=>[n,r]),[n])}();return d.createElement(E.Provider,{value:n},t)}function C(e){if(e.component){const t=e.component;return d.createElement(t,e.props)}}function T(){const e=(0,d.useContext)(E);if(!e)throw new _.i6("NavbarSecondaryMenuDisplayProvider");const[t,n]=e,r=(0,d.useCallback)((()=>n(!1)),[n]),o=(0,k.HY)();return(0,d.useMemo)((()=>({shown:t,hide:r,content:C(o)})),[r,o,t])}var O=n(70524),D=n(13156),P=n(96066),N=n(39105),A=n(85919),I=n(71427),L=n(68265),R=n(6832);function j(){const{siteConfig:{baseUrl:e}}=(0,R.default)(),{pathname:t}=(0,f.TH)();return t.replace(e,"/")}var M=n(94462),F=n(63735),B=n(18407),z=n(44873);function $(e){function t(e){return"left"===(e.position??"right")}return[e.filter(t),e.filter((e=>!t(e)))]}function U(e){let{children:t}=e;return d.createElement(k.n2,null,d.createElement(x.M,null,d.createElement(S,null,t)))}var H=n(78586);function V(e){const[t,n]=(0,d.useState)(e),r=(0,d.useRef)(!1),o=(0,d.useRef)(0),a=(0,d.useCallback)((e=>{null!==e&&(o.current=e.getBoundingClientRect().height)}),[]);return(0,F.RF)(((t,a)=>{let{scrollY:i}=t;if(!e)return;if(i<o.current)return void n(!0);if(r.current)return void(r.current=!1);const l=null==a?void 0:a.scrollY,s=document.documentElement.scrollHeight-o.current,u=window.innerHeight;l&&i>=l?n(!1):i+u<s&&n(!0)})),(0,L.S)((t=>{if(!e)return;const o=t.location.hash;if(o?document.getElementById(o.substring(1)):void 0)return r.current=!0,void n(!1);n(!0)})),{navbarRef:a,isNavbarVisible:t}}var q=n(22768),G=n(69322);const W={attributes:!0,characterData:!0,childList:!0,subtree:!0};function Z(e,t){const[n,r]=(0,d.useState)(),o=(0,d.useCallback)((()=>{var t;r(null==(t=e.current)?void 0:t.closest("[role=tabpanel][hidden]"))}),[e,r]);(0,d.useEffect)((()=>{o()}),[o]),function(e,t,n){void 0===n&&(n=W);const r=(0,_.zX)(t),o=(0,_.Ql)(n);(0,d.useEffect)((()=>{const t=new MutationObserver(r);return e&&t.observe(e,o),()=>t.disconnect()}),[e,r,o])}(n,(e=>{e.forEach((e=>{"attributes"===e.type&&"hidden"===e.attributeName&&(t(),o())}))}),{attributes:!0,characterData:!1,childList:!1,subtree:!1})}function Q(){const[e,t]=(0,d.useState)(!1),[n,r]=(0,d.useState)(!1),o=(0,d.useRef)(null),a=(0,d.useCallback)((()=>{const n=o.current.querySelector("code");e?n.removeAttribute("style"):(n.style.whiteSpace="pre-wrap",n.style.overflowWrap="anywhere"),t((e=>!e))}),[o,e]),i=(0,d.useCallback)((()=>{const{scrollWidth:e,clientWidth:t}=o.current,n=e>t||o.current.querySelector("code").hasAttribute("style");r(n)}),[o]);return Z(o,i),(0,d.useEffect)((()=>{i()}),[e,i]),(0,d.useEffect)((()=>(window.addEventListener("resize",i,{passive:!0}),()=>{window.removeEventListener("resize",i)})),[i]),{codeBlockRef:o,isEnabled:e,isCodeScrollable:n,toggle:a}}var Y=n(20883)},18015:(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:{}}},39657:(e,t,n)=>{"use strict";function r(){return window.matchMedia("(prefers-reduced-motion: reduce)").matches}n.d(t,{n:()=>r})},96066:(e,t,n)=>{"use strict";n.d(t,{QC:()=>p,Vo:()=>d,bc:()=>u,nZ:()=>f,nt:()=>c});var r=n(87594),o=n.n(r);const a=/title=(?<quote>["'])(?<title>.*?)\1/,i=/\{(?<range>[\d,-]+)\}/,l={js:{start:"\\/\\/",end:""},jsBlock:{start:"\\/\\*",end:"\\*\\/"},jsx:{start:"\\{\\s*\\/\\*",end:"\\*\\/\\s*\\}"},bash:{start:"#",end:""},html:{start:"\x3c!--",end:"--\x3e"}};function s(e,t){const n=e.map((e=>{const{start:n,end:r}=l[e];return`(?:${n}\\s*(${t.flatMap((e=>{var t,n;return[e.line,null==(t=e.block)?void 0:t.start,null==(n=e.block)?void 0:n.end].filter(Boolean)})).join("|")})\\s*${r})`})).join("|");return new RegExp(`^\\s*(?:${n})\\s*$`)}function u(e){var t;return(null==e||null==(t=e.match(a))?void 0:t.groups.title)??""}function c(e){return Boolean(null==e?void 0:e.includes("showLineNumbers"))}function d(e){const t=e.split(" ").find((e=>e.startsWith("language-")));return null==t?void 0:t.replace(/language-/,"")}function f(e,t){let n=e.replace(/\n$/,"");const{language:r,magicComments:a,metastring:u}=t;if(u&&i.test(u)){const e=u.match(i).groups.range;if(0===a.length)throw new Error(`A highlight range has been given in code block's metastring (\`\`\` ${u}), but no magic comment config is available. Docusaurus applies the first magic comment entry's className for metastring ranges.`);const t=a[0].className,r=o()(e).filter((e=>e>0)).map((e=>[e-1,[t]]));return{lineClassNames:Object.fromEntries(r),code:n}}if(void 0===r)return{lineClassNames:{},code:n};const c=function(e,t){switch(e){case"js":case"javascript":case"ts":case"typescript":return s(["js","jsBlock"],t);case"jsx":case"tsx":return s(["js","jsBlock","jsx"],t);case"html":return s(["js","jsBlock","html"],t);case"python":case"py":case"bash":return s(["bash"],t);case"markdown":case"md":return s(["html","jsx","bash"],t);default:return s(Object.keys(l),t)}}(r,a),d=n.split("\n"),f=Object.fromEntries(a.map((e=>[e.className,{start:0,range:""}]))),p=Object.fromEntries(a.filter((e=>e.line)).map((e=>{let{className:t,line:n}=e;return[n,t]}))),h=Object.fromEntries(a.filter((e=>e.block)).map((e=>{let{className:t,block:n}=e;return[n.start,t]}))),m=Object.fromEntries(a.filter((e=>e.block)).map((e=>{let{className:t,block:n}=e;return[n.end,t]})));for(let o=0;o<d.length;){const e=d[o].match(c);if(!e){o+=1;continue}const t=e.slice(1).find((e=>void 0!==e));p[t]?f[p[t]].range+=`${o},`:h[t]?f[h[t]].start=o:m[t]&&(f[m[t]].range+=`${f[m[t]].start}-${o-1},`),d.splice(o,1)}n=d.join("\n");const g={};return Object.entries(f).forEach((e=>{let[t,{range:n}]=e;o()(n).forEach((e=>{g[e]??=[],g[e].push(t)}))})),{lineClassNames:g,code:n}}function p(e){const t={color:"--prism-color",backgroundColor:"--prism-background-color"},n={};return Object.entries(e.plain).forEach((e=>{let[r,o]=e;const a=t[r];a&&"string"==typeof o&&(n[a]=o)})),n}},85919:(e,t,n)=>{"use strict";n.d(t,{MN:()=>S,Wl:()=>m,_F:()=>b,cE:()=>f,em:()=>h,hI:()=>E,jA:()=>g,lO:()=>x,oz:()=>_,s1:()=>w,vY:()=>k,xz:()=>p});var r=n(67294),o=n(16550),a=n(18790),i=n(4452),l=n(4049),s=n(6141),u=n(50003),c=n(20636),d=n(18407);const f=!!i.useAllDocsData;function p(e){const t=(0,s.E)();if(!e)return;const n=t.docs[e];if(!n)throw new Error(`no version doc found by id=${e}`);return n}function h(e,t){for(const n of e)if("category"===n.type){if(t(n))return n;const e=h(n.items,t);if(e)return e}}function m(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=m(t);if(e)return e}}}function g(){const{pathname:e}=(0,o.TH)(),t=(0,u.V)();if(!t)throw new Error("Unexpected: cant find current sidebar in context");const n=y({sidebarItems:t.items,pathname:e,onlyCategories:!0}).slice(-1)[0];if(!n)throw new Error(`${e} is not associated with a category. useCurrentSidebarCategory() should only be used on category index pages.`);return n}const v=(e,t)=>void 0!==e&&(0,d.Mg)(e,t);function b(e,t){return"link"===e.type?v(e.href,t):"category"===e.type&&(v(e.href,t)||((e,t)=>e.some((e=>b(e,t))))(e.items,t))}function y(e){let{sidebarItems:t,pathname:n,onlyCategories:r=!1}=e;const o=[];return function e(t){for(const a of t)if("category"===a.type&&((0,d.Mg)(a.href,n)||e(a.items))||"link"===a.type&&(0,d.Mg)(a.href,n)){return r&&"category"!==a.type||o.unshift(a),!0}return!1}(t),o}function w(){var e;const t=(0,u.V)(),{pathname:n}=(0,o.TH)();return!1!==(null==(e=(0,i.useActivePlugin)())?void 0:e.pluginData.breadcrumbs)&&t?y({sidebarItems:t.items,pathname:n}):null}function x(e){const{activeVersion:t}=(0,i.useActiveDocContext)(e),{preferredVersion:n}=(0,l.J)(e),o=(0,i.useLatestVersion)(e);return(0,r.useMemo)((()=>(0,c.j)([t,n,o].filter(Boolean))),[t,n,o])}function _(e,t){const n=x(t);return(0,r.useMemo)((()=>{const t=n.flatMap((e=>e.sidebars?Object.entries(e.sidebars):[])),r=t.find((t=>t[0]===e));if(!r)throw new Error(`Can't find any sidebar with id "${e}" in version${n.length>1?"s":""} ${n.map((e=>e.name)).join(", ")}".\nAvailable sidebar ids are:\n- ${t.map((e=>e[0])).join("\n- ")}`);return r[1]}),[e,n])}function k(e,t){const n=x(t);return(0,r.useMemo)((()=>{const t=n.flatMap((e=>e.docs)),r=t.find((t=>t.id===e));if(!r){if(n.flatMap((e=>e.draftIds)).includes(e))return null;throw new Error(`Couldn't find any doc with id "${e}" in version${n.length>1?"s":""} "${n.map((e=>e.name)).join(", ")}".\nAvailable doc ids are:\n- ${(0,c.j)(t.map((e=>e.id))).join("\n- ")}`)}return r}),[e,n])}function E(e){let{route:t,versionMetadata:n}=e;const r=(0,o.TH)(),i=t.routes,l=i.find((e=>(0,o.LX)(r.pathname,e)));if(!l)return null;const s=l.sidebar,u=s?n.docsSidebars[s]:void 0;return{docElement:(0,a.H)(i),sidebarName:s,sidebarItems:u}}function S(e){return e.filter((e=>"category"!==e.type||!!m(e)))}},48348:(e,t,n)=>{"use strict";n.d(t,{aG:()=>u,Cw:()=>s,QW:()=>c});var r=n(87462),o=n(67294),a=n(11614),i=n(79861);const l="errorBoundaryError_a6uf";function s(e){return o.createElement("button",(0,r.Z)({type:"button"},e),o.createElement(a.default,{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 u(e){let{error:t}=e;const n=(0,i.getErrorCausalChain)(t).map((e=>e.message)).join("\n\nCause:\n");return o.createElement("p",{className:l},n)}class c extends o.Component{componentDidCatch(e,t){throw this.props.onError(e,t)}render(){return this.props.children}}},68211:(e,t,n)=>{"use strict";function r(e){return"title"in e[0]}n.d(t,{a:()=>r})},71427:(e,t,n)=>{"use strict";n.d(t,{p:()=>o});var r=n(6832);function o(e){const{siteConfig:t}=(0,r.default)(),{title:n,titleDelimiter:o}=t;return null!=e&&e.trim().length?`${e.trim()} ${o} ${n}`:n}},34423:(e,t,n)=>{"use strict";n.d(t,{Nc:()=>c,Rb:()=>l,_X:()=>u,xL:()=>s});var r=n(67294),o=n(16550),a=n(61688),i=n(93478);function l(e){!function(e){const t=(0,o.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 s(e){const t=(0,o.k6)();return(0,a.useSyncExternalStore)(t.listen,(()=>e(t)),(()=>e(t)))}function u(e){return s((t=>null===e?null:new URLSearchParams(t.location.search).get(e)))}function c(e){const t=u(e)??"",n=function(){const e=(0,o.k6)();return(0,r.useCallback)(((t,n,r)=>{const o=new URLSearchParams(e.location.search);n?o.set(t,n):o.delete(t),(null!=r&&r.push?e.push:e.replace)({search:o.toString()})}),[e])}();return[t,(0,r.useCallback)(((t,r)=>{n(e,t,r)}),[n,e])]}},20636:(e,t,n)=>{"use strict";function r(e,t){return void 0===t&&(t=(e,t)=>e===t),e.filter(((n,r)=>e.findIndex((e=>t(e,n)))!==r))}function o(e){return Array.from(new Set(e))}n.d(t,{j:()=>o,l:()=>r})},44873:(e,t,n)=>{"use strict";n.d(t,{FG:()=>f,d:()=>c,VC:()=>p});var r=n(67294),o=n(86010),a=n(32411),i=n(66041);function l(){const e=r.useContext(i._);if(!e)throw new Error("Unexpected: no Docusaurus route context found");return e}var s=n(51402),u=n(71427);function c(e){let{title:t,description:n,keywords:o,image:i,children:l}=e;const c=(0,u.p)(t),{withBaseUrl:d}=(0,s.useBaseUrlUtils)(),f=i?d(i,{absolute:!0}):void 0;return r.createElement(a.Z,null,t&&r.createElement("title",null,c),t&&r.createElement("meta",{property:"og:title",content:c}),n&&r.createElement("meta",{name:"description",content:n}),n&&r.createElement("meta",{property:"og:description",content:n}),o&&r.createElement("meta",{name:"keywords",content:Array.isArray(o)?o.join(","):o}),f&&r.createElement("meta",{property:"og:image",content:f}),f&&r.createElement("meta",{name:"twitter:image",content:f}),l)}const d=r.createContext(void 0);function f(e){let{className:t,children:n}=e;const i=r.useContext(d),l=(0,o.default)(i,t);return r.createElement(d.Provider,{value:l},r.createElement(a.Z,null,r.createElement("html",{className:l})),n)}function p(e){let{children:t}=e;const n=l(),a=`plugin-${n.plugin.name.replace(/docusaurus-(?:plugin|theme)-(?:content-)?/gi,"")}`;const i=`plugin-id-${n.plugin.id}`;return r.createElement(f,{className:(0,o.default)(a,i)},t)}},93478:(e,t,n)=>{"use strict";n.d(t,{D9:()=>i,LI:()=>o,Qc:()=>u,Ql:()=>s,i6:()=>l,zX:()=>a});var r=n(67294);const o=n(19901).Z.canUseDOM?r.useLayoutEffect:r.useEffect;function a(e){const t=(0,r.useRef)(e);return o((()=>{t.current=e}),[e]),(0,r.useCallback)((function(){return t.current(...arguments)}),[])}function i(e){const t=(0,r.useRef)();return o((()=>{t.current=e})),t.current}class l extends Error{constructor(e,t){var n,r,o;super(),this.name="ReactContextError",this.message=`Hook ${(null==(n=this.stack)||null==(r=n.split("\n")[1])||null==(o=r.match(/at (?:\w+\.)?(?<name>\w+)/))?void 0:o.groups.name)??""} is called outside the <${e}>. ${t??""}`}}function s(e){const t=Object.entries(e);return t.sort(((e,t)=>e[0].localeCompare(t[0]))),(0,r.useMemo)((()=>e),t.flat())}function u(e){return t=>{let{children:n}=t;return r.createElement(r.Fragment,null,e.reduceRight(((e,t)=>r.createElement(t,null,e)),n))}}},18407:(e,t,n)=>{"use strict";n.d(t,{Mg:()=>i,Ns:()=>l});var r=n(67294),o=n(21204),a=n(6832);function i(e,t){const n=e=>{var t;return null==(t=!e||e.endsWith("/")?e:`${e}/`)?void 0:t.toLowerCase()};return n(e)===n(t)}function l(){const{baseUrl:e}=(0,a.default)().siteConfig;return(0,r.useMemo)((()=>function(e){let{baseUrl:t,routes:n}=e;function r(e){return e.path===t&&!0===e.exact}function o(e){return e.path===t&&!e.exact}return function e(t){if(0===t.length)return;return t.find(r)||e(t.filter(o).flatMap((e=>e.routes??[])))}(n)}({routes:o.Z,baseUrl:e})),[e])}},63735:(e,t,n)=>{"use strict";n.d(t,{Ct:()=>p,OC:()=>s,RF:()=>d,o5:()=>f,sG:()=>u});var r=n(67294),o=n(19901),a=n(5730),i=n(93478);const l=r.createContext(void 0);function s(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(l.Provider,{value:n},t)}function u(){const e=(0,r.useContext)(l);if(null==e)throw new i.i6("ScrollControllerProvider");return e}const c=()=>o.Z.canUseDOM?{scrollX:window.pageXOffset,scrollY:window.pageYOffset}:null;function d(e,t){void 0===t&&(t=[]);const{scrollEventsEnabledRef:n}=u(),o=(0,r.useRef)(c()),a=(0,i.zX)(e);(0,r.useEffect)((()=>{const e=()=>{if(!n.current)return;const e=c();a(e,o.current),o.current=e},t={passive:!0};return e(),window.addEventListener("scroll",e,t),()=>window.removeEventListener("scroll",e,t)}),[a,n,...t])}function f(){const e=u(),t=function(){const e=(0,r.useRef)({elem:null,top:0}),t=(0,r.useCallback)((t=>{e.current={elem:t,top:t.getBoundingClientRect().top}}),[]),n=(0,r.useCallback)((()=>{const{current:{elem:t,top:n}}=e;if(!t)return{restored:!1};const r=t.getBoundingClientRect().top-n;return r&&window.scrollBy({left:0,top:r}),e.current={elem:null,top:0},{restored:0!==r}}),[]);return(0,r.useMemo)((()=>({save:t,restore:n})),[n,t])}(),n=(0,r.useRef)(void 0),o=(0,r.useCallback)((r=>{t.save(r),e.disableScrollEvents(),n.current=()=>{const{restored:r}=t.restore();if(n.current=void 0,r){const t=()=>{e.enableScrollEvents(),window.removeEventListener("scroll",t)};window.addEventListener("scroll",t)}else e.enableScrollEvents()}}),[e,t]);return(0,r.useLayoutEffect)((()=>{queueMicrotask((()=>null==n.current?void 0:n.current()))})),{blockElementScrollPositionUntilNextRender:o}}function p(){const e=(0,r.useRef)(null),t=(0,a.default)()&&"smooth"===getComputedStyle(document.documentElement).scrollBehavior;return{startScroll:n=>{e.current=t?function(e){return window.scrollTo({top:e,behavior:"smooth"}),()=>{}}(n):function(e){let t=null;const n=document.documentElement.scrollTop>e;return function r(){const o=document.documentElement.scrollTop;(n&&o>e||!n&&o<e)&&(t=requestAnimationFrame(r),window.scrollTo(0,Math.floor(.85*(o-e))+e))}(),()=>t&&cancelAnimationFrame(t)}(n)},cancelScroll:()=>null==e.current?void 0:e.current()}}},39105:(e,t,n)=>{"use strict";n.d(t,{HX:()=>i,_q:()=>s,os:()=>l});var r=n(4452),o=n(6832),a=n(4049);const i="default";function l(e,t){return`docs-${e}-${t}`}function s(){const{i18n:e}=(0,o.default)(),t=(0,r.useAllDocsData)(),n=(0,r.useActivePluginAndVersion)(),s=(0,a.Oh)();const u=[i,...Object.keys(t).map((function(e){const r=(null==n?void 0:n.activePlugin.pluginId)===e?n.activeVersion:void 0,o=s[e],a=t[e].versions.find((e=>e.isLast));return l(e,(r??o??a).name)}))];return{locale:e.currentLocale,tags:u}}},66470:(e,t,n)=>{"use strict";n.d(t,{l:()=>f,u:()=>s});var r=n(87462),o=n(67294),a=n(16550),i=n(11614),l=n(68265);const s="__docusaurus_skipToContent_fallback";function u(e){e.setAttribute("tabindex","-1"),e.focus(),e.removeAttribute("tabindex")}function c(){const e=(0,o.useRef)(null),{action:t}=(0,a.k6)(),n=(0,o.useCallback)((e=>{e.preventDefault();const t=document.querySelector("main:first-of-type")??document.getElementById(s);t&&u(t)}),[]);return(0,l.S)((n=>{let{location:r}=n;e.current&&!r.hash&&"PUSH"===t&&u(e.current)})),{containerRef:e,onClick:n}}const d=(0,i.translate)({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 f(e){const t=e.children??d,{containerRef:n,onClick:a}=c();return o.createElement("div",{ref:n,role:"region","aria-label":d},o.createElement("a",(0,r.Z)({},e,{href:`#${s}`,onClick:a}),t))}},99200:(e,t,n)=>{"use strict";n.d(t,{Nk:()=>d,WA:()=>c,_f:()=>f});var r=n(67294),o=n(61688);const a="localStorage";function i(e){let{key:t,oldValue:n,newValue:r,storage:o}=e;if(n===r)return;const a=document.createEvent("StorageEvent");a.initStorageEvent("storage",!1,!1,t,n,r,window.location.href,o),window.dispatchEvent(a)}function l(e){if(void 0===e&&(e=a),"undefined"==typeof window)throw new Error("Browser storage is not available on Node.js/Docusaurus SSR process.");if("none"===e)return null;try{return window[e]}catch(n){return t=n,s||(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),s=!0),null}var t}let s=!1;const u={get:()=>null,set:()=>{},del:()=>{},listen:()=>()=>{}};function c(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=l(null==t?void 0:t.persistence);return null===n?u:{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),i({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),i({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),()=>{}}}}}function d(e,t){const n=(0,r.useRef)((()=>null===e?u:c(e,t))).current(),a=(0,r.useCallback)((e=>"undefined"==typeof window?()=>{}:n.listen(e)),[n]);return[(0,o.useSyncExternalStore)(a,(()=>"undefined"==typeof window?null:n.get()),(()=>null)),n]}function f(e){void 0===e&&(e=a);const t=l(e);if(!t)return[];const n=[];for(let r=0;r<t.length;r+=1){const e=t.key(r);null!==e&&n.push(e)}return n}},94462:(e,t,n)=>{"use strict";n.d(t,{a:()=>a,b:()=>l});var r=n(67294);function o(e){const t=e.map((e=>({...e,parentIndex:-1,children:[]}))),n=Array(7).fill(-1);t.forEach(((e,t)=>{const r=n.slice(2,e.level);e.parentIndex=Math.max(...r),n[e.level]=t}));const r=[];return t.forEach((e=>{const{parentIndex:n,...o}=e;n>=0?t[n].children.push(o):r.push(o)})),r}function a(e){return(0,r.useMemo)((()=>o(e)),[e])}function i(e){let{toc:t,minHeadingLevel:n,maxHeadingLevel:r}=e;return t.flatMap((e=>{const t=i({toc:e.children,minHeadingLevel:n,maxHeadingLevel:r});return function(e){return e.level>=n&&e.level<=r}(e)?[{...e,children:t}]:t}))}function l(e){let{toc:t,minHeadingLevel:n,maxHeadingLevel:a}=e;return(0,r.useMemo)((()=>i({toc:o(t),minHeadingLevel:n,maxHeadingLevel:a})),[t,n,a])}},13156:(e,t,n)=>{"use strict";n.d(t,{l:()=>a});var r=n(6832),o=n(16550);function a(){const{siteConfig:{baseUrl:e,url:t},i18n:{defaultLocale:n,currentLocale:a}}=(0,r.default)(),{pathname:i}=(0,o.TH)(),l=a===n?e:e.replace(`/${a}/`,"/"),s=i.replace(e,"");return{createUrl:function(e){let{locale:r,fullyQualified:o}=e;return`${o?t:""}${function(e){return e===n?`${l}`:`${l}${e}/`}(r)}${s}`}}}},68265:(e,t,n)=>{"use strict";n.d(t,{S:()=>i});var r=n(67294),o=n(16550),a=n(93478);function i(e){const t=(0,o.TH)(),n=(0,a.D9)(t),i=(0,a.zX)(e);(0,r.useEffect)((()=>{n&&t!==n&&i({location:t,previousLocation:n})}),[i,t,n])}},96793:(e,t,n)=>{"use strict";n.d(t,{L:()=>o});var r=n(6832);function o(){return(0,r.default)().siteConfig.themeConfig}},54357:(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[o]=e.split(/[#?]/),a="/"===o||o===r?o:(i=o,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(o,a)}},6009:(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]}},79861: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 o=n(54357);Object.defineProperty(t,"applyTrailingSlash",{enumerable:!0,get:function(){return r(o).default}});var a=n(6009);Object.defineProperty(t,"getErrorCausalChain",{enumerable:!0,get:function(){return a.getErrorCausalChain}})},78007:(e,t,n)=>{"use strict";n.r(t),n.d(t,{fetchIndexes:()=>l,legacyFetchIndexes:()=>s});var r=n(31336),o=n.n(r),a=n(96059);const i=new Map;function l(e,t){const n=`${e}${t}`;let r=i.get(n);return r||(r=s(e,t),i.set(n,r)),r}async function s(e,t){{const n=`${e}${a.searchIndexUrl.replace("{dir}",t?`-${t.replace(/\//g,"-")}`:"")}`;if(new URL(n,location.origin).origin!==location.origin)throw new Error("Unexpected version url");const r=await(await fetch(n)).json(),i=r.map(((e,t)=>{let{documents:n,index:r}=e;return{type:t,documents:n,index:o().Index.load(r)}})),l=r.reduce(((e,t)=>{for(const n of t.index.invertedIndex)/\p{Unified_Ideograph}/u.test(n[0][0])&&e.add(n[0]);return e}),new Set);return{wrappedIndexes:i,zhDictionary:Array.from(l)}}}},58263:(e,t,n)=>{"use strict";n.r(t),n.d(t,{SearchSourceFactory:()=>s});var r=n(31336),o=n.n(r);var a=n(96059);function i(e){return l(e).concat(l(e.filter((e=>{const t=e[e.length-1];return!t.trailing&&t.maybeTyping})),!0))}function l(e,t){return e.map((e=>({tokens:e.map((e=>e.value)),term:e.map((e=>({value:e.value,presence:o().Query.presence.REQUIRED,wildcard:(t?e.trailing||e.maybeTyping:e.trailing)?o().Query.wildcard.TRAILING:o().Query.wildcard.NONE})))})))}function s(e,t,n){return function(r,l){const s=function(e,t){if(1===t.length&&["ja","jp","th"].includes(t[0]))return o()[t[0]].tokenizer(e).map((e=>e.toString()));let n=/[^-\s]+/g;return t.includes("zh")&&(n=/\w+|\p{Unified_Ideograph}+/gu),e.toLowerCase().match(n)||[]}(r,a.language);if(0===s.length)return void l([]);const u=function(e,t){const n=function(e,t){const n=[];return function e(r,o){if(0===r.length)return void n.push(o);const a=r[0];if(/\p{Unified_Ideograph}/u.test(a)){const n=function(e,t){const n=[];return function e(r,o){let a=0,i=!1;for(const l of t)if(r.substr(0,l.length)===l){const t={missed:o.missed,term:o.term.concat({value:l})};r.length>l.length?e(r.substr(l.length),t):n.push(t),i=!0}else for(let t=l.length-1;t>a;t-=1){const s=l.substr(0,t);if(r.substr(0,t)===s){a=t;const l={missed:o.missed,term:o.term.concat({value:s,trailing:!0})};r.length>t?e(r.substr(t),l):n.push(l),i=!0;break}}i||(r.length>0?e(r.substr(1),{missed:o.missed+1,term:o.term}):o.term.length>0&&n.push(o))}(e,{missed:0,term:[]}),n.sort(((e,t)=>{const n=e.missed>0?1:0,r=t.missed>0?1:0;return n!==r?n-r:e.term.length-t.term.length})).map((e=>e.term))}(a,t);for(const t of n){const n=o.concat(...t);e(r.slice(1),n)}}else{const t=o.concat({value:a});e(r.slice(1),t)}}(e,[]),n}(e,t);if(0===n.length)return[{tokens:e,term:e.map((e=>({value:e,presence:o().Query.presence.REQUIRED,wildcard:o().Query.wildcard.LEADING|o().Query.wildcard.TRAILING})))}];for(const o of n)o[o.length-1].maybeTyping=!0;const r=[];for(const i of a.language)if("en"===i)a.removeDefaultStopWordFilter||r.unshift(o().stopWordFilter);else{const e=o()[i];e.stopWordFilter&&r.unshift(e.stopWordFilter)}let l;if(r.length>0){const e=e=>r.reduce(((e,t)=>e.filter((e=>t(e.value)))),e);l=[];const t=[];for(const r of n){const n=e(r);l.push(n),n.length<r.length&&n.length>0&&t.push(n)}n.push(...t)}else l=n.slice();const s=[];for(const o of l)if(o.length>2)for(let e=o.length-1;e>=0;e-=1)s.push(o.slice(0,e).concat(o.slice(e+1)));return i(n).concat(i(s))}(s,t),c=[];e:for(const{term:t,tokens:o}of u)for(const{documents:r,index:a,type:i}of e)if(c.push(...a.query((e=>{for(const n of t)e.term(n.value,{wildcard:n.wildcard,presence:n.presence})})).slice(0,n).filter((e=>!c.some((t=>t.document.i.toString()===e.ref)))).slice(0,n-c.length).map((t=>{const n=r.find((e=>e.i.toString()===t.ref));return{document:n,type:i,page:0!==i&&e[0].documents.find((e=>e.i===n.p)),metadata:t.matchData.metadata,tokens:o,score:t.score}}))),c.length>=n)break e;!function(e){e.forEach(((e,t)=>{e.index=t})),e.sort(((t,n)=>{let r=t.type>0&&t.page?e.findIndex((e=>e.document===t.page)):t.index,o=n.type>0&&n.page?e.findIndex((e=>e.document===n.page)):n.index;return-1===r&&(r=t.index),-1===o&&(o=n.index),r===o?0===t.type?-1:0===n.type?1:t.index-n.index:r-o}))}(c),function(e){e.forEach(((t,n)=>{n>0&&t.page&&e.some((e=>e.document===t.page))&&(n<e.length-1&&e[n+1].page===t.page?t.isInterOfTree=!0:t.isLastOfTree=!0)}))}(c),l(c)}}},84647:(e,t,n)=>{"use strict";function r(e,t){const n=[];for(const r of Object.values(e))r[t]&&n.push(...r[t].position);return n.sort(((e,t)=>e[0]-t[0]||t[1]-e[1]))}n.r(t),n.d(t,{getStemmedPositions:()=>r})},32438:(e,t,n)=>{"use strict";function r(e){return e.replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""").replace(/'/g,"'")}function o(e,t,n){const a=[];for(const i of t){const n=e.toLowerCase().indexOf(i);if(n>=0){n>0&&a.push(o(e.substr(0,n),t)),a.push(`<mark>${r(e.substr(n,i.length))}</mark>`);const l=n+i.length;l<e.length&&a.push(o(e.substr(l),t));break}}return 0===a.length?n?`<mark>${r(e)}</mark>`:r(e):a.join("")}n.r(t),n.d(t,{highlightStemmed:()=>s,splitIntoChunks:()=>u});const a=/\w+|\p{Unified_Ideograph}/u;function i(e){const t=[];let n=0,r=e;for(;r.length>0;){const o=r.match(a);if(!o){t.push(r);break}o.index>0&&t.push(r.substring(0,o.index)),t.push(o[0]),n+=o.index+o[0].length,r=e.substring(n)}return t}var l=n(96059);function s(e,t,n,r){void 0===r&&(r=l.searchResultContextMaxLength);const{chunkIndex:o,chunks:a}=u(e,t,n),i=a.slice(0,o),s=a[o],c=[s.html],d=a.slice(o+1);let f=s.textLength,p=0,h=0,m=!1,g=!1;for(;f<r;)if((p<=h||0===d.length)&&i.length>0){const e=i.pop();f+e.textLength<=r?(c.unshift(e.html),p+=e.textLength,f+=e.textLength):(m=!0,i.length=0)}else{if(!(d.length>0))break;{const e=d.shift();f+e.textLength<=r?(c.push(e.html),h+=e.textLength,f+=e.textLength):(g=!0,d.length=0)}}return(m||i.length>0)&&c.unshift("\u2026"),(g||d.length>0)&&c.push("\u2026"),c.join("")}function u(e,t,n){const a=[];let l=0,s=0,u=-1;for(;l<t.length;){const[c,d]=t[l];if(l+=1,!(c<s)){if(c>s){const t=i(e.substring(s,c)).map((e=>({html:r(e),textLength:e.length})));for(const e of t)a.push(e)}-1===u&&(u=a.length),s=c+d,a.push({html:o(e.substring(c,s),n,!0),textLength:d})}}if(s<e.length){const t=i(e.substring(s)).map((e=>({html:r(e),textLength:e.length})));for(const e of t)a.push(e)}return{chunkIndex:u,chunks:a}}},96059:(e,t,n)=>{"use strict";n.r(t),n.d(t,{Mark:()=>i,docsPluginIdForPreferredVersion:()=>h,explicitSearchResultPath:()=>c,hideSearchBarWithNoSearchContext:()=>v,indexDocs:()=>m,language:()=>r,removeDefaultStemmer:()=>a,removeDefaultStopWordFilter:()=>o,searchBarPosition:()=>p,searchBarShortcut:()=>d,searchBarShortcutHint:()=>f,searchContextByPaths:()=>g,searchIndexUrl:()=>l,searchResultContextMaxLength:()=>u,searchResultLimits:()=>s});n(31336);const r=["en"],o=!1,a=!1,i=null,l="search-index{dir}.json?_=722dc11b",s=8,u=50,c=!1,d=!0,f=!0,p="right",h=void 0,m=!0,g=null,v=!1},9463:(e,t,n)=>{"use strict";n.d(t,{Z:()=>g});var r=function(){function e(e){var t=this;this._insertTag=function(e){var n;n=0===t.tags.length?t.insertionPoint?t.insertionPoint.nextSibling:t.prepend?t.container.firstChild:t.before:t.tags[t.tags.length-1].nextSibling,t.container.insertBefore(e,n),t.tags.push(e)},this.isSpeedy=void 0===e.speedy||e.speedy,this.tags=[],this.ctr=0,this.nonce=e.nonce,this.key=e.key,this.container=e.container,this.prepend=e.prepend,this.insertionPoint=e.insertionPoint,this.before=null}var t=e.prototype;return t.hydrate=function(e){e.forEach(this._insertTag)},t.insert=function(e){this.ctr%(this.isSpeedy?65e3:1)==0&&this._insertTag(function(e){var t=document.createElement("style");return t.setAttribute("data-emotion",e.key),void 0!==e.nonce&&t.setAttribute("nonce",e.nonce),t.appendChild(document.createTextNode("")),t.setAttribute("data-s",""),t}(this));var t=this.tags[this.tags.length-1];if(this.isSpeedy){var n=function(e){if(e.sheet)return e.sheet;for(var t=0;t<document.styleSheets.length;t++)if(document.styleSheets[t].ownerNode===e)return document.styleSheets[t]}(t);try{n.insertRule(e,n.cssRules.length)}catch(r){0}}else t.appendChild(document.createTextNode(e));this.ctr++},t.flush=function(){this.tags.forEach((function(e){return e.parentNode&&e.parentNode.removeChild(e)})),this.tags=[],this.ctr=0},e}(),o=n(46411),a=n(26686),i=n(27563),l=n(20211);var s=n(92190),u=function(e,t,n){for(var r=0,a=0;r=a,a=(0,o.fj)(),38===r&&12===a&&(t[n]=1),!(0,o.r)(a);)(0,o.lp)();return(0,o.tP)(e,o.FK)},c=function(e,t){return(0,o.cE)(function(e,t){var n=-1,r=44;do{switch((0,o.r)(r)){case 0:38===r&&12===(0,o.fj)()&&(t[n]=1),e[n]+=u(o.FK-1,t,n);break;case 2:e[n]+=(0,o.iF)(r);break;case 4:if(44===r){e[++n]=58===(0,o.fj)()?"&\f":"",t[n]=e[n].length;break}default:e[n]+=(0,a.Dp)(r)}}while(r=(0,o.lp)());return e}((0,o.un)(e),t))},d=new WeakMap,f=function(e){if("rule"===e.type&&e.parent&&!(e.length<1)){for(var t=e.value,n=e.parent,r=e.column===n.column&&e.line===n.line;"rule"!==n.type;)if(!(n=n.parent))return;if((1!==e.props.length||58===t.charCodeAt(0)||d.get(n))&&!r){d.set(e,!0);for(var o=[],a=c(t,o),i=n.props,l=0,s=0;l<a.length;l++)for(var u=0;u<i.length;u++,s++)e.props[s]=o[l]?a[l].replace(/&\f/g,i[u]):i[u]+" "+a[l]}}},p=function(e){if("decl"===e.type){var t=e.value;108===t.charCodeAt(0)&&98===t.charCodeAt(2)&&(e.return="",e.value="")}};function h(e,t){switch((0,a.vp)(e,t)){case 5103:return i.G$+"print-"+e+e;case 5737:case 4201:case 3177:case 3433:case 1641:case 4457:case 2921:case 5572:case 6356:case 5844:case 3191:case 6645:case 3005:case 6391:case 5879:case 5623:case 6135:case 4599:case 4855:case 4215:case 6389:case 5109:case 5365:case 5621:case 3829:return i.G$+e+e;case 5349:case 4246:case 4810:case 6968:case 2756:return i.G$+e+i.uj+e+i.MS+e+e;case 6828:case 4268:return i.G$+e+i.MS+e+e;case 6165:return i.G$+e+i.MS+"flex-"+e+e;case 5187:return i.G$+e+(0,a.gx)(e,/(\w+).+(:[^]+)/,i.G$+"box-$1$2"+i.MS+"flex-$1$2")+e;case 5443:return i.G$+e+i.MS+"flex-item-"+(0,a.gx)(e,/flex-|-self/,"")+e;case 4675:return i.G$+e+i.MS+"flex-line-pack"+(0,a.gx)(e,/align-content|flex-|-self/,"")+e;case 5548:return i.G$+e+i.MS+(0,a.gx)(e,"shrink","negative")+e;case 5292:return i.G$+e+i.MS+(0,a.gx)(e,"basis","preferred-size")+e;case 6060:return i.G$+"box-"+(0,a.gx)(e,"-grow","")+i.G$+e+i.MS+(0,a.gx)(e,"grow","positive")+e;case 4554:return i.G$+(0,a.gx)(e,/([^-])(transform)/g,"$1"+i.G$+"$2")+e;case 6187:return(0,a.gx)((0,a.gx)((0,a.gx)(e,/(zoom-|grab)/,i.G$+"$1"),/(image-set)/,i.G$+"$1"),e,"")+e;case 5495:case 3959:return(0,a.gx)(e,/(image-set\([^]*)/,i.G$+"$1$`$1");case 4968:return(0,a.gx)((0,a.gx)(e,/(.+:)(flex-)?(.*)/,i.G$+"box-pack:$3"+i.MS+"flex-pack:$3"),/s.+-b[^;]+/,"justify")+i.G$+e+e;case 4095:case 3583:case 4068:case 2532:return(0,a.gx)(e,/(.+)-inline(.+)/,i.G$+"$1$2")+e;case 8116:case 7059:case 5753:case 5535:case 5445:case 5701:case 4933:case 4677:case 5533:case 5789:case 5021:case 4765:if((0,a.to)(e)-1-t>6)switch((0,a.uO)(e,t+1)){case 109:if(45!==(0,a.uO)(e,t+4))break;case 102:return(0,a.gx)(e,/(.+:)(.+)-([^]+)/,"$1"+i.G$+"$2-$3$1"+i.uj+(108==(0,a.uO)(e,t+3)?"$3":"$2-$3"))+e;case 115:return~(0,a.Cw)(e,"stretch")?h((0,a.gx)(e,"stretch","fill-available"),t)+e:e}break;case 4949:if(115!==(0,a.uO)(e,t+1))break;case 6444:switch((0,a.uO)(e,(0,a.to)(e)-3-(~(0,a.Cw)(e,"!important")&&10))){case 107:return(0,a.gx)(e,":",":"+i.G$)+e;case 101:return(0,a.gx)(e,/(.+:)([^;!]+)(;|!.+)?/,"$1"+i.G$+(45===(0,a.uO)(e,14)?"inline-":"")+"box$3$1"+i.G$+"$2$3$1"+i.MS+"$2box$3")+e}break;case 5936:switch((0,a.uO)(e,t+11)){case 114:return i.G$+e+i.MS+(0,a.gx)(e,/[svh]\w+-[tblr]{2}/,"tb")+e;case 108:return i.G$+e+i.MS+(0,a.gx)(e,/[svh]\w+-[tblr]{2}/,"tb-rl")+e;case 45:return i.G$+e+i.MS+(0,a.gx)(e,/[svh]\w+-[tblr]{2}/,"lr")+e}return i.G$+e+i.MS+e+e}return e}var m=[function(e,t,n,r){if(e.length>-1&&!e.return)switch(e.type){case i.h5:e.return=h(e.value,e.length);break;case i.lK:return(0,l.q)([(0,o.JG)(e,{value:(0,a.gx)(e.value,"@","@"+i.G$)})],r);case i.Fr:if(e.length)return(0,a.$e)(e.props,(function(t){switch((0,a.EQ)(t,/(::plac\w+|:read-\w+)/)){case":read-only":case":read-write":return(0,l.q)([(0,o.JG)(e,{props:[(0,a.gx)(t,/:(read-\w+)/,":"+i.uj+"$1")]})],r);case"::placeholder":return(0,l.q)([(0,o.JG)(e,{props:[(0,a.gx)(t,/:(plac\w+)/,":"+i.G$+"input-$1")]}),(0,o.JG)(e,{props:[(0,a.gx)(t,/:(plac\w+)/,":"+i.uj+"$1")]}),(0,o.JG)(e,{props:[(0,a.gx)(t,/:(plac\w+)/,i.MS+"input-$1")]})],r)}return""}))}}],g=function(e){var t=e.key;if("css"===t){var n=document.querySelectorAll("style[data-emotion]:not([data-s])");Array.prototype.forEach.call(n,(function(e){-1!==e.getAttribute("data-emotion").indexOf(" ")&&(document.head.appendChild(e),e.setAttribute("data-s",""))}))}var o=e.stylisPlugins||m;var i,u,c={},d=[];i=e.container||document.head,Array.prototype.forEach.call(document.querySelectorAll('style[data-emotion^="'+t+' "]'),(function(e){for(var t=e.getAttribute("data-emotion").split(" "),n=1;n<t.length;n++)c[t[n]]=!0;d.push(e)}));var h=[f,p];var g,v,b,y,w=[l.P,(y=function(e){g.insert(e)},function(e){e.root||(e=e.return)&&y(e)})],x=(v=h.concat(o,w),b=(0,a.Ei)(v),function(e,t,n,r){for(var o="",a=0;a<b;a++)o+=v[a](e,t,n,r)||"";return o});u=function(e,t,n,r){var o;g=n,o=e?e+"{"+t.styles+"}":t.styles,(0,l.q)((0,s.MY)(o),x),r&&(_.inserted[t.name]=!0)};var _={key:t,sheet:new r({key:t,container:i,nonce:e.nonce,speedy:e.speedy,prepend:e.prepend,insertionPoint:e.insertionPoint}),nonce:e.nonce,inserted:c,registered:{},insert:u};return _.sheet.hydrate(d),_}},45042:(e,t,n)=>{"use strict";function r(e){var t=Object.create(null);return function(n){return void 0===t[n]&&(t[n]=e(n)),t[n]}}n.d(t,{Z:()=>r})},80123:(e,t,n)=>{"use strict";n.d(t,{C:()=>m,E:()=>C,T:()=>b,_:()=>g,a:()=>x,b:()=>_,c:()=>E,h:()=>p,i:()=>f,u:()=>y,w:()=>v});var r=n(67294),o=n(9463);function a(){return a=Object.assign?Object.assign.bind():function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e},a.apply(this,arguments)}var i=function(e){var t=new WeakMap;return function(n){if(t.has(n))return t.get(n);var r=e(n);return t.set(n,r),r}},l=n(8679),s=n.n(l),u=n(70444),c=n(48137),d=n(27278),f=!0,p={}.hasOwnProperty,h=r.createContext("undefined"!=typeof HTMLElement?(0,o.Z)({key:"css"}):null);var m=h.Provider,g=function(){return(0,r.useContext)(h)},v=function(e){return(0,r.forwardRef)((function(t,n){var o=(0,r.useContext)(h);return e(t,o,n)}))};f||(v=function(e){return function(t){var n=(0,r.useContext)(h);return null===n?(n=(0,o.Z)({key:"css"}),r.createElement(h.Provider,{value:n},e(t,n))):e(t,n)}});var b=r.createContext({});var y=function(){return r.useContext(b)},w=i((function(e){return i((function(t){return function(e,t){return"function"==typeof t?t(e):a({},e,t)}(e,t)}))})),x=function(e){var t=r.useContext(b);return e.theme!==t&&(t=w(t)(e.theme)),r.createElement(b.Provider,{value:t},e.children)};function _(e){var t,n,o=e.displayName||e.name||"Component",i=function(t,n){var o=r.useContext(b);return r.createElement(e,a({theme:o,ref:n},t))},l=r.forwardRef(i);return l.displayName="WithTheme("+o+")",t=l,n=e,s()(t,n)}var k="__EMOTION_TYPE_PLEASE_DO_NOT_USE__",E=function(e,t){var n={};for(var r in t)p.call(t,r)&&(n[r]=t[r]);return n[k]=e,n},S=function(e){var t=e.cache,n=e.serialized,r=e.isStringTag;return(0,u.hC)(t,n,r),(0,d.L)((function(){return(0,u.My)(t,n,r)})),null};var C=v((function(e,t,n){var o=e.css;"string"==typeof o&&void 0!==t.registered[o]&&(o=t.registered[o]);var a=e[k],i=[o],l="";"string"==typeof e.className?l=(0,u.fp)(t.registered,i,e.className):null!=e.className&&(l=e.className+" ");var s=(0,c.O)(i,void 0,r.useContext(b));l+=t.key+"-"+s.name;var d={};for(var f in e)p.call(e,f)&&"css"!==f&&f!==k&&(d[f]=e[f]);return d.ref=n,d.className=l,r.createElement(r.Fragment,null,r.createElement(S,{cache:t,serialized:s,isStringTag:"string"==typeof a}),r.createElement(a,d))}))},70917:(e,t,n)=>{"use strict";n.r(t),n.d(t,{CacheProvider:()=>r.C,ClassNames:()=>m,Global:()=>u,ThemeContext:()=>r.T,ThemeProvider:()=>r.a,__unsafe_useEmotionCache:()=>r._,createElement:()=>s,css:()=>c,jsx:()=>s,keyframes:()=>d,useTheme:()=>r.u,withEmotionCache:()=>r.w,withTheme:()=>r.b});var r=n(80123),o=n(67294),a=n(70444),i=n(27278),l=n(48137),s=(n(9463),n(8679),function(e,t){var n=arguments;if(null==t||!r.h.call(t,"css"))return o.createElement.apply(void 0,n);var a=n.length,i=new Array(a);i[0]=r.E,i[1]=(0,r.c)(e,t);for(var l=2;l<a;l++)i[l]=n[l];return o.createElement.apply(null,i)}),u=(0,r.w)((function(e,t){var n=e.styles,s=(0,l.O)([n],void 0,o.useContext(r.T));if(!r.i){for(var u,c=s.name,d=s.styles,f=s.next;void 0!==f;)c+=" "+f.name,d+=f.styles,f=f.next;var p=!0===t.compat,h=t.insert("",{name:c,styles:d},t.sheet,p);return p?null:o.createElement("style",((u={})["data-emotion"]=t.key+"-global "+c,u.dangerouslySetInnerHTML={__html:h},u.nonce=t.sheet.nonce,u))}var m=o.useRef();return(0,i.j)((function(){var e=t.key+"-global",n=new t.sheet.constructor({key:e,nonce:t.sheet.nonce,container:t.sheet.container,speedy:t.sheet.isSpeedy}),r=!1,o=document.querySelector('style[data-emotion="'+e+" "+s.name+'"]');return t.sheet.tags.length&&(n.before=t.sheet.tags[0]),null!==o&&(r=!0,o.setAttribute("data-emotion",e),n.hydrate([o])),m.current=[n,r],function(){n.flush()}}),[t]),(0,i.j)((function(){var e=m.current,n=e[0];if(e[1])e[1]=!1;else{if(void 0!==s.next&&(0,a.My)(t,s.next,!0),n.tags.length){var r=n.tags[n.tags.length-1].nextElementSibling;n.before=r,n.flush()}t.insert("",s,n,!1)}}),[t,s.name]),null}));function c(){for(var e=arguments.length,t=new Array(e),n=0;n<e;n++)t[n]=arguments[n];return(0,l.O)(t)}var d=function(){var e=c.apply(void 0,arguments),t="animation-"+e.name;return{name:t,styles:"@keyframes "+t+"{"+e.styles+"}",anim:1,toString:function(){return"_EMO_"+this.name+"_"+this.styles+"_EMO_"}}},f=function e(t){for(var n=t.length,r=0,o="";r<n;r++){var a=t[r];if(null!=a){var i=void 0;switch(typeof a){case"boolean":break;case"object":if(Array.isArray(a))i=e(a);else for(var l in i="",a)a[l]&&l&&(i&&(i+=" "),i+=l);break;default:i=a}i&&(o&&(o+=" "),o+=i)}}return o};function p(e,t,n){var r=[],o=(0,a.fp)(e,r,n);return r.length<2?n:o+t(r)}var h=function(e){var t=e.cache,n=e.serializedArr;return(0,i.L)((function(){for(var e=0;e<n.length;e++)(0,a.My)(t,n[e],!1)})),null},m=(0,r.w)((function(e,t){var n=[],i=function(){for(var e=arguments.length,r=new Array(e),o=0;o<e;o++)r[o]=arguments[o];var i=(0,l.O)(r,t.registered);return n.push(i),(0,a.hC)(t,i,!1),t.key+"-"+i.name},s={css:i,cx:function(){for(var e=arguments.length,n=new Array(e),r=0;r<e;r++)n[r]=arguments[r];return p(t.registered,i,f(n))},theme:o.useContext(r.T)},u=e.children(s);return!0,o.createElement(o.Fragment,null,o.createElement(h,{cache:t,serializedArr:n}),u)}))},48137:(e,t,n)=>{"use strict";n.d(t,{O:()=>h});var r={animationIterationCount:1,aspectRatio:1,borderImageOutset:1,borderImageSlice:1,borderImageWidth:1,boxFlex:1,boxFlexGroup:1,boxOrdinalGroup:1,columnCount:1,columns:1,flex:1,flexGrow:1,flexPositive:1,flexShrink:1,flexNegative:1,flexOrder:1,gridRow:1,gridRowEnd:1,gridRowSpan:1,gridRowStart:1,gridColumn:1,gridColumnEnd:1,gridColumnSpan:1,gridColumnStart:1,msGridRow:1,msGridRowSpan:1,msGridColumn:1,msGridColumnSpan:1,fontWeight:1,lineHeight:1,opacity:1,order:1,orphans:1,tabSize:1,widows:1,zIndex:1,zoom:1,WebkitLineClamp:1,fillOpacity:1,floodOpacity:1,stopOpacity:1,strokeDasharray:1,strokeDashoffset:1,strokeMiterlimit:1,strokeOpacity:1,strokeWidth:1},o=n(45042),a=/[A-Z]|^ms/g,i=/_EMO_([^_]+?)_([^]*?)_EMO_/g,l=function(e){return 45===e.charCodeAt(1)},s=function(e){return null!=e&&"boolean"!=typeof e},u=(0,o.Z)((function(e){return l(e)?e:e.replace(a,"-$&").toLowerCase()})),c=function(e,t){switch(e){case"animation":case"animationName":if("string"==typeof t)return t.replace(i,(function(e,t,n){return f={name:t,styles:n,next:f},t}))}return 1===r[e]||l(e)||"number"!=typeof t||0===t?t:t+"px"};function d(e,t,n){if(null==n)return"";if(void 0!==n.__emotion_styles)return n;switch(typeof n){case"boolean":return"";case"object":if(1===n.anim)return f={name:n.name,styles:n.styles,next:f},n.name;if(void 0!==n.styles){var r=n.next;if(void 0!==r)for(;void 0!==r;)f={name:r.name,styles:r.styles,next:f},r=r.next;return n.styles+";"}return function(e,t,n){var r="";if(Array.isArray(n))for(var o=0;o<n.length;o++)r+=d(e,t,n[o])+";";else for(var a in n){var i=n[a];if("object"!=typeof i)null!=t&&void 0!==t[i]?r+=a+"{"+t[i]+"}":s(i)&&(r+=u(a)+":"+c(a,i)+";");else if(!Array.isArray(i)||"string"!=typeof i[0]||null!=t&&void 0!==t[i[0]]){var l=d(e,t,i);switch(a){case"animation":case"animationName":r+=u(a)+":"+l+";";break;default:r+=a+"{"+l+"}"}}else for(var f=0;f<i.length;f++)s(i[f])&&(r+=u(a)+":"+c(a,i[f])+";")}return r}(e,t,n);case"function":if(void 0!==e){var o=f,a=n(e);return f=o,d(e,t,a)}}if(null==t)return n;var i=t[n];return void 0!==i?i:n}var f,p=/label:\s*([^\s;\n{]+)\s*(;|$)/g;var h=function(e,t,n){if(1===e.length&&"object"==typeof e[0]&&null!==e[0]&&void 0!==e[0].styles)return e[0];var r=!0,o="";f=void 0;var a=e[0];null==a||void 0===a.raw?(r=!1,o+=d(n,t,a)):o+=a[0];for(var i=1;i<e.length;i++)o+=d(n,t,e[i]),r&&(o+=a[i]);p.lastIndex=0;for(var l,s="";null!==(l=p.exec(o));)s+="-"+l[1];var u=function(e){for(var t,n=0,r=0,o=e.length;o>=4;++r,o-=4)t=1540483477*(65535&(t=255&e.charCodeAt(r)|(255&e.charCodeAt(++r))<<8|(255&e.charCodeAt(++r))<<16|(255&e.charCodeAt(++r))<<24))+(59797*(t>>>16)<<16),n=1540483477*(65535&(t^=t>>>24))+(59797*(t>>>16)<<16)^1540483477*(65535&n)+(59797*(n>>>16)<<16);switch(o){case 3:n^=(255&e.charCodeAt(r+2))<<16;case 2:n^=(255&e.charCodeAt(r+1))<<8;case 1:n=1540483477*(65535&(n^=255&e.charCodeAt(r)))+(59797*(n>>>16)<<16)}return(((n=1540483477*(65535&(n^=n>>>13))+(59797*(n>>>16)<<16))^n>>>15)>>>0).toString(36)}(o)+s;return{name:u,styles:o,next:f}}},27278:(e,t,n)=>{"use strict";var r;n.d(t,{L:()=>i,j:()=>l});var o=n(67294),a=!!(r||(r=n.t(o,2))).useInsertionEffect&&(r||(r=n.t(o,2))).useInsertionEffect,i=a||function(e){return e()},l=a||o.useLayoutEffect},70444:(e,t,n)=>{"use strict";n.d(t,{My:()=>a,fp:()=>r,hC:()=>o});function r(e,t,n){var r="";return n.split(" ").forEach((function(n){void 0!==e[n]?t.push(e[n]+";"):r+=n+" "})),r}var o=function(e,t,n){var r=e.key+"-"+t.name;!1===n&&void 0===e.registered[r]&&(e.registered[r]=t.styles)},a=function(e,t,n){o(e,t,n);var r=e.key+"-"+t.name;if(void 0===e.inserted[t.name]){var a=t;do{e.insert(t===a?"."+r:"",a,e.sheet,!0),a=a.next}while(void 0!==a)}}},19044:(e,t,n)=>{"use strict";n.r(t),n.d(t,{default:()=>i});var r,o=n(67294);function a(){return a=Object.assign?Object.assign.bind():function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e},a.apply(this,arguments)}const i=e=>{let{title:t,titleId:n,...i}=e;return o.createElement("svg",a({width:18,height:18,viewBox:"0 0 18 18",fill:"none",xmlns:"http://www.w3.org/2000/svg",role:"img","aria-labelledby":n},i),t?o.createElement("title",{id:n},t):null,r||(r=o.createElement("path",{stroke:"#fff",d:"M9 17.5V.5M.5 9h17"})))}},80255:(e,t,n)=>{"use strict";n.r(t),n.d(t,{default:()=>i});var r,o=n(67294);function a(){return a=Object.assign?Object.assign.bind():function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e},a.apply(this,arguments)}const i=e=>{let{title:t,titleId:n,...i}=e;return o.createElement("svg",a({width:20,height:20,viewBox:"0 0 20 20",fill:"none",xmlns:"http://www.w3.org/2000/svg",role:"img","aria-labelledby":n},i),t?o.createElement("title",{id:n},t):null,r||(r=o.createElement("path",{d:"M11.764 5.294 7.06 10l4.705 4.706",stroke:"#000",strokeWidth:2,strokeLinecap:"round",strokeLinejoin:"round"})))}},67146:(e,t,n)=>{"use strict";n.r(t),n.d(t,{default:()=>i});var r,o=n(67294);function a(){return a=Object.assign?Object.assign.bind():function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e},a.apply(this,arguments)}const i=e=>{let{title:t,titleId:n,...i}=e;return o.createElement("svg",a({width:14,height:14,viewBox:"0 0 14 14",fill:"none",xmlns:"http://www.w3.org/2000/svg",role:"img","aria-labelledby":n},i),t?o.createElement("title",{id:n},t):null,r||(r=o.createElement("path",{d:"M11.667 6.417h-7.1l3.261-3.261L7 2.333 2.333 7 7 11.667l.823-.823-3.255-3.26h7.099V6.417Z",fill:"#fff"})))}},68425:(e,t,n)=>{"use strict";n.r(t),n.d(t,{default:()=>l});var r,o,a=n(67294);function i(){return i=Object.assign?Object.assign.bind():function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e},i.apply(this,arguments)}const l=e=>{let{title:t,titleId:n,...l}=e;return a.createElement("svg",i({width:20,height:20,viewBox:"0 0 20 20",fill:"none",xmlns:"http://www.w3.org/2000/svg",role:"img","aria-labelledby":n},l),t?a.createElement("title",{id:n},t):null,r||(r=a.createElement("rect",{width:20,height:20,rx:10,fill:"#000"})),o||(o=a.createElement("path",{d:"m9 8 2 2-2 2",stroke:"#fff",strokeWidth:1.2,strokeLinecap:"round",strokeLinejoin:"round"})))}},88121:(e,t,n)=>{"use strict";n.r(t),n.d(t,{default:()=>i});var r,o=n(67294);function a(){return a=Object.assign?Object.assign.bind():function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e},a.apply(this,arguments)}const i=e=>{let{title:t,titleId:n,...i}=e;return o.createElement("svg",a({width:14,height:14,viewBox:"0 0 14 14",fill:"none",xmlns:"http://www.w3.org/2000/svg",role:"img","aria-labelledby":n},i),t?o.createElement("title",{id:n},t):null,r||(r=o.createElement("path",{d:"m7 2.333-.823.823 3.255 3.26H2.333v1.167h7.1l-3.256 3.261.823.823L11.667 7 7 2.333Z",fill:"#fff"})))}},62082:(e,t,n)=>{"use strict";n.r(t),n.d(t,{default:()=>l});var r,o,a=n(67294);function i(){return i=Object.assign?Object.assign.bind():function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e},i.apply(this,arguments)}const l=e=>{let{title:t,titleId:n,...l}=e;return a.createElement("svg",i({width:40,height:40,viewBox:"0 0 40 40",fill:"none",xmlns:"http://www.w3.org/2000/svg",role:"img","aria-labelledby":n},l),t?a.createElement("title",{id:n},t):null,r||(r=a.createElement("path",{d:"M20 20a3.21 3.21 0 0 1-2.354-.98 3.21 3.21 0 0 1-.98-2.353c0-.917.327-1.702.98-2.355A3.21 3.21 0 0 1 20 13.333a3.21 3.21 0 0 1 2.354.98 3.21 3.21 0 0 1 .98 2.354 3.21 3.21 0 0 1-.98 2.354A3.21 3.21 0 0 1 20 20Zm-6.666 6.667v-2.334c0-.472.121-.906.364-1.302.244-.396.567-.698.969-.906.86-.43 1.736-.754 2.625-.97A11.418 11.418 0 0 1 20 20.834c.917 0 1.82.108 2.709.324.888.215 1.763.538 2.625.968.402.208.725.51.969.907.243.396.364.83.364 1.301v2.334H13.333ZM15 25h10v-.667a.817.817 0 0 0-.417-.708 10.844 10.844 0 0 0-2.27-.843 9.652 9.652 0 0 0-4.625 0c-.764.187-1.521.468-2.271.843a.815.815 0 0 0-.303.292.776.776 0 0 0-.114.416V25Zm5-6.667c.459 0 .851-.163 1.178-.49.326-.326.49-.719.489-1.176 0-.459-.164-.851-.49-1.178A1.602 1.602 0 0 0 20 15c-.458 0-.85.164-1.177.49-.327.328-.49.72-.49 1.178 0 .458.164.85.49 1.177.327.327.72.49 1.177.49Z",fill:"#fff"})),o||(o=a.createElement("rect",{x:.5,y:.5,width:39,height:39,rx:19.5,stroke:"#fff"})))}},80469:(e,t,n)=>{"use strict";n.r(t),n.d(t,{default:()=>i});var r,o=n(67294);function a(){return a=Object.assign?Object.assign.bind():function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e},a.apply(this,arguments)}const i=e=>{let{title:t,titleId:n,...i}=e;return o.createElement("svg",a({width:16,height:16,viewBox:"0 0 16 16",fill:"none",xmlns:"http://www.w3.org/2000/svg",role:"img","aria-labelledby":n},i),t?o.createElement("title",{id:n},t):null,r||(r=o.createElement("path",{d:"m12.667 4.273-.94-.94L8.001 7.06 4.274 3.333l-.94.94L7.061 8l-3.727 3.727.94.94L8.001 8.94l3.726 3.727.94-.94L8.941 8l3.726-3.727Z",fill:"#fff",opacity:.6})))}},94793:(e,t,n)=>{"use strict";n.r(t),n.d(t,{default:()=>i});var r,o=n(67294);function a(){return a=Object.assign?Object.assign.bind():function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e},a.apply(this,arguments)}const i=e=>{let{title:t,titleId:n,...i}=e;return o.createElement("svg",a({width:14,height:14,viewBox:"0 0 14 14",fill:"none",xmlns:"http://www.w3.org/2000/svg",role:"img","aria-labelledby":n},i),t?o.createElement("title",{id:n},t):null,r||(r=o.createElement("path",{d:"M2.917 12.833c-.321 0-.596-.114-.825-.343a1.121 1.121 0 0 1-.342-.823V3.5h1.167v8.167h6.416v1.166H2.917ZM5.25 10.5c-.32 0-.596-.114-.824-.343a1.121 1.121 0 0 1-.343-.824v-7c0-.32.115-.595.343-.824.229-.229.504-.343.824-.342h5.25c.32 0 .596.114.824.343.229.228.343.503.343.823v7c0 .321-.115.596-.343.825a1.121 1.121 0 0 1-.824.342H5.25Zm0-1.167h5.25v-7H5.25v7Z",fill:"#fff"})))}},14607:(e,t,n)=>{"use strict";n.r(t),n.d(t,{default:()=>i});var r,o=n(67294);function a(){return a=Object.assign?Object.assign.bind():function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e},a.apply(this,arguments)}const i=e=>{let{title:t,titleId:n,...i}=e;return o.createElement("svg",a({width:40,height:40,viewBox:"0 0 40 40",fill:"none",xmlns:"http://www.w3.org/2000/svg",role:"img","aria-labelledby":n},i),t?o.createElement("title",{id:n},t):null,r||(r=o.createElement("path",{d:"M14.2 23.077c-1.733 0-3.147-1.575-3.147-3.504 0-1.926 1.379-3.5 3.149-3.5 1.75 0 3.183 1.574 3.148 3.5 0 1.929-1.398 3.504-3.15 3.504Zm11.623 0c-1.733 0-3.15-1.575-3.15-3.504 0-1.926 1.382-3.5 3.15-3.5 1.75 0 3.184 1.574 3.15 3.5 0 1.929-1.381 3.504-3.15 3.504ZM16.875 7.205l-.513-.938-1.057.175a27.255 27.255 0 0 0-6.93 2.133l-.38.177-.237.348C3.403 15.523 2.208 21.847 2.8 28.06l.065.677.55.4a28.181 28.181 0 0 0 8.463 4.238l1.317.403 1.855-4.528c3.183.787 6.717.788 9.898 0l1.845 4.53 1.317-.405a28.033 28.033 0 0 0 8.467-4.24l.545-.397.066-.67c.727-7.2-1.161-13.473-4.93-18.975l-.236-.345-.38-.173a27.625 27.625 0 0 0-6.924-2.133l-1.03-.172-.523.902c-.155.27-.301.544-.438.823a26.463 26.463 0 0 0-5.439 0c-.133-.266-.27-.53-.413-.79Zm-5.683 20.478c.328.19.675.377 1.016.547l-.748 1.827a25.041 25.041 0 0 1-5.713-2.964c-.375-5.231.688-10.508 4.273-15.95a24.256 24.256 0 0 1 4.707-1.521c.1.208.193.411.27.593l.455 1.072 1.153-.169a23.508 23.508 0 0 1 6.817 0l1.15.167.453-1.07c.078-.187.17-.39.267-.593a24.71 24.71 0 0 1 4.713 1.525c3.125 4.7 4.702 9.943 4.243 15.945a24.841 24.841 0 0 1-5.716 2.963l-.742-1.823c.343-.172.69-.359 1.022-.549.816-.47 1.695-1.056 2.255-1.616l-2.134-2.134c-.271.274-.871.7-1.628 1.137-.74.427-1.475.772-1.945.927-3.338 1.105-7.38 1.105-10.72 0-.468-.155-1.203-.5-1.943-.927-.757-.435-1.357-.863-1.63-1.137l-2.134 2.134c.562.56 1.442 1.146 2.259 1.616Z",fill:"#fff"})))}},50437:(e,t,n)=>{"use strict";n.r(t),n.d(t,{default:()=>l});var r,o,a=n(67294);function i(){return i=Object.assign?Object.assign.bind():function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e},i.apply(this,arguments)}const l=e=>{let{title:t,titleId:n,...l}=e;return a.createElement("svg",i({width:71,height:55,viewBox:"0 0 71 55",fill:"none",xmlns:"http://www.w3.org/2000/svg",role:"img","aria-labelledby":n},l),t?a.createElement("title",{id:n},t):null,r||(r=a.createElement("g",{clipPath:"url(#a)"},a.createElement("path",{d:"M60.105 4.898A58.55 58.55 0 0 0 45.653.415a.22.22 0 0 0-.233.11 40.784 40.784 0 0 0-1.8 3.697c-5.456-.817-10.886-.817-16.23 0-.485-1.164-1.201-2.587-1.828-3.697a.228.228 0 0 0-.233-.11 58.386 58.386 0 0 0-14.451 4.483.207.207 0 0 0-.095.082C1.578 18.73-.944 32.144.293 45.39a.244.244 0 0 0 .093.167c6.073 4.46 11.955 7.167 17.729 8.962a.23.23 0 0 0 .249-.082 42.08 42.08 0 0 0 3.627-5.9.225.225 0 0 0-.123-.312 38.772 38.772 0 0 1-5.539-2.64.228.228 0 0 1-.022-.378c.372-.279.744-.569 1.1-.862a.22.22 0 0 1 .23-.03c11.619 5.304 24.198 5.304 35.68 0a.219.219 0 0 1 .233.027c.356.293.728.586 1.103.865a.228.228 0 0 1-.02.378 36.384 36.384 0 0 1-5.54 2.637.227.227 0 0 0-.121.315 47.249 47.249 0 0 0 3.624 5.897.225.225 0 0 0 .249.084c5.801-1.794 11.684-4.502 17.757-8.961a.228.228 0 0 0 .092-.164c1.48-15.315-2.48-28.618-10.497-40.412a.18.18 0 0 0-.093-.084Zm-36.38 32.427c-3.497 0-6.38-3.211-6.38-7.156 0-3.944 2.827-7.156 6.38-7.156 3.583 0 6.438 3.24 6.382 7.156 0 3.945-2.827 7.156-6.381 7.156Zm23.593 0c-3.498 0-6.38-3.211-6.38-7.156 0-3.944 2.826-7.156 6.38-7.156 3.582 0 6.437 3.24 6.38 7.156 0 3.945-2.798 7.156-6.38 7.156Z",fill:"#23272A"}))),o||(o=a.createElement("defs",null,a.createElement("clipPath",{id:"a"},a.createElement("path",{fill:"#fff",d:"M0 0h71v55H0z"})))))}},23179:(e,t,n)=>{"use strict";n.r(t),n.d(t,{default:()=>i});var r,o=n(67294);function a(){return a=Object.assign?Object.assign.bind():function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e},a.apply(this,arguments)}const i=e=>{let{title:t,titleId:n,...i}=e;return o.createElement("svg",a({viewBox:"0 0 24 24",xmlns:"http://www.w3.org/2000/svg",role:"img","aria-labelledby":n},i),void 0===t?o.createElement("title",{id:n},"Discourse"):t?o.createElement("title",{id:n},t):null,r||(r=o.createElement("path",{d:"M12.103 0C18.666 0 24 5.485 24 11.997c0 6.51-5.33 11.99-11.9 11.99L0 24V11.79C0 5.28 5.532 0 12.103 0zm.116 4.563a7.395 7.395 0 0 0-6.337 3.57 7.247 7.247 0 0 0-.148 7.22L4.4 19.61l4.794-1.074a7.424 7.424 0 0 0 8.136-1.39 7.256 7.256 0 0 0 1.737-7.997 7.375 7.375 0 0 0-6.84-4.585h-.008z"})))}},7744:(e,t,n)=>{"use strict";n.r(t),n.d(t,{default:()=>i});var r,o=n(67294);function a(){return a=Object.assign?Object.assign.bind():function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e},a.apply(this,arguments)}const i=e=>{let{title:t,titleId:n,...i}=e;return o.createElement("svg",a({width:16,height:16,viewBox:"0 0 16 16",fill:"none",xmlns:"http://www.w3.org/2000/svg",role:"img","aria-labelledby":n},i),t?o.createElement("title",{id:n},t):null,r||(r=o.createElement("path",{d:"M9.334 1.333H4c-.733 0-1.326.6-1.326 1.334l-.007 10.666c0 .734.593 1.334 1.327 1.334H12c.734 0 1.334-.6 1.334-1.334v-8l-4-4ZM4 13.333V2.667h4.667V6H12v7.333H4Z",fill:"#fff"})))}},19818:(e,t,n)=>{"use strict";n.r(t),n.d(t,{default:()=>i});var r,o=n(67294);function a(){return a=Object.assign?Object.assign.bind():function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e},a.apply(this,arguments)}const i=e=>{let{title:t,titleId:n,...i}=e;return o.createElement("svg",a({width:20,height:20,viewBox:"0 0 20 20",fill:"none",xmlns:"http://www.w3.org/2000/svg",role:"img","aria-labelledby":n},i),t?o.createElement("title",{id:n},t):null,r||(r=o.createElement("circle",{cx:10,cy:10,r:8.333,fill:"#fff"})))}},38981:(e,t,n)=>{"use strict";n.r(t),n.d(t,{default:()=>i});var r,o=n(67294);function a(){return a=Object.assign?Object.assign.bind():function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e},a.apply(this,arguments)}const i=e=>{let{title:t,titleId:n,...i}=e;return o.createElement("svg",a({width:14,height:14,viewBox:"0 0 14 14",fill:"none",xmlns:"http://www.w3.org/2000/svg",role:"img","aria-labelledby":n},i),t?o.createElement("title",{id:n},t):null,r||(r=o.createElement("path",{d:"M7 9.333 4.083 6.417 4.9 5.57l1.517 1.517V2.333h1.166v4.755L9.1 5.57l.817.846L7 9.333Zm-3.5 2.334c-.32 0-.596-.115-.824-.343a1.121 1.121 0 0 1-.343-.824V8.75H3.5v1.75h7V8.75h1.167v1.75c0 .32-.115.596-.343.824a1.121 1.121 0 0 1-.824.343h-7Z",fill:"#fff"})))}},28487:(e,t,n)=>{"use strict";n.r(t),n.d(t,{default:()=>i});var r,o=n(67294);function a(){return a=Object.assign?Object.assign.bind():function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e},a.apply(this,arguments)}const i=e=>{let{title:t,titleId:n,...i}=e;return o.createElement("svg",a({width:12,height:12,viewBox:"0 0 12 12",fill:"none",xmlns:"http://www.w3.org/2000/svg",role:"img","aria-labelledby":n},i),t?o.createElement("title",{id:n},t):null,r||(r=o.createElement("path",{d:"m2 4 4 4 4-4",stroke:"#909091",strokeWidth:1.4,strokeLinecap:"round",strokeLinejoin:"round"})))}},94177:(e,t,n)=>{"use strict";n.r(t),n.d(t,{default:()=>i});var r,o=n(67294);function a(){return a=Object.assign?Object.assign.bind():function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e},a.apply(this,arguments)}const i=e=>{let{title:t,titleId:n,...i}=e;return o.createElement("svg",a({width:16,height:16,viewBox:"0 0 16 16",fill:"none",xmlns:"http://www.w3.org/2000/svg",role:"img","aria-labelledby":n},i),t?o.createElement("title",{id:n},t):null,r||(r=o.createElement("path",{fillRule:"evenodd",clipRule:"evenodd",d:"m12.707 2.393.9.9c.526.52.526 1.367 0 1.887L4.787 14H2v-2.787l6.933-6.94 1.887-1.88c.52-.52 1.367-.52 1.887 0ZM3.333 12.667l.94.04 6.547-6.554-.94-.94-6.547 6.547v.907Z",fill:"#fff"})))}},58611:(e,t,n)=>{"use strict";n.r(t),n.d(t,{default:()=>i});var r,o=n(67294);function a(){return a=Object.assign?Object.assign.bind():function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e},a.apply(this,arguments)}const i=e=>{let{title:t,titleId:n,...i}=e;return o.createElement("svg",a({width:16,height:16,viewBox:"0 0 16 16",fill:"none",xmlns:"http://www.w3.org/2000/svg",role:"img","aria-labelledby":n},i),t?o.createElement("title",{id:n},t):null,r||(r=o.createElement("path",{fillRule:"evenodd",clipRule:"evenodd",d:"M11.192 4H3.428V2.857h9.715v9.715H12V4.808l-8.167 8.168-.809-.808L11.192 4Z",fill:"#fff"})))}},13042:(e,t,n)=>{"use strict";n.r(t),n.d(t,{default:()=>i});var r,o=n(67294);function a(){return a=Object.assign?Object.assign.bind():function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e},a.apply(this,arguments)}const i=e=>{let{title:t,titleId:n,...i}=e;return o.createElement("svg",a({width:20,height:20,viewBox:"0 0 20 20",fill:"none",xmlns:"http://www.w3.org/2000/svg",role:"img","aria-labelledby":n},i),t?o.createElement("title",{id:n},t):null,r||(r=o.createElement("path",{d:"M1.804 16.292a.836.836 0 0 0 .696.374H15a.832.832 0 0 0 .766-.505l2.5-5.833a.833.833 0 0 0-.766-1.162h-.833v-2.5C16.667 5.747 15.919 5 15 5H9.454l-2.13-1.667h-3.99c-.92 0-1.667.748-1.667 1.667v10.833h.006a.834.834 0 0 0 .131.46ZM15 6.666v2.5H5a.832.832 0 0 0-.766.505l-.9 2.103V6.666H15Z",fill:"#000"})))}},96367:(e,t,n)=>{"use strict";n.r(t),n.d(t,{default:()=>i});var r,o=n(67294);function a(){return a=Object.assign?Object.assign.bind():function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e},a.apply(this,arguments)}const i=e=>{let{title:t,titleId:n,...i}=e;return o.createElement("svg",a({width:14,height:14,viewBox:"0 0 14 14",fill:"none",xmlns:"http://www.w3.org/2000/svg",role:"img","aria-labelledby":n},i),t?o.createElement("title",{id:n},t):null,r||(r=o.createElement("path",{d:"M4.667 11.083v-1.75h-1.75V8.166h2.916v2.917H4.667Zm3.5 0V8.166h2.916v1.167h-1.75v1.75H8.167Zm-5.25-5.25V4.666h1.75v-1.75h1.166v2.917H2.917Zm5.25 0V2.916h1.166v1.75h1.75v1.167H8.167Z",fill:"#fff"})))}},6907:(e,t,n)=>{"use strict";n.r(t),n.d(t,{default:()=>i});var r,o=n(67294);function a(){return a=Object.assign?Object.assign.bind():function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e},a.apply(this,arguments)}const i=e=>{let{title:t,titleId:n,...i}=e;return o.createElement("svg",a({width:14,height:14,viewBox:"0 0 14 14",fill:"none",xmlns:"http://www.w3.org/2000/svg",role:"img","aria-labelledby":n},i),t?o.createElement("title",{id:n},t):null,r||(r=o.createElement("path",{d:"M1.75 2.917V5.25h1.167V2.917H5.25V1.75H2.917A1.17 1.17 0 0 0 1.75 2.917ZM2.917 8.75H1.75v2.333a1.17 1.17 0 0 0 1.167 1.167H5.25v-1.167H2.917V8.75Zm8.166 2.333H8.75v1.167h2.333a1.17 1.17 0 0 0 1.167-1.167V8.75h-1.167v2.333Zm0-9.333H8.75v1.167h2.333V5.25h1.167V2.917a1.17 1.17 0 0 0-1.167-1.167Z",fill:"#fff"})))}},59570:(e,t,n)=>{"use strict";n.r(t),n.d(t,{default:()=>i});var r,o=n(67294);function a(){return a=Object.assign?Object.assign.bind():function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e},a.apply(this,arguments)}const i=e=>{let{title:t,titleId:n,...i}=e;return o.createElement("svg",a({width:40,height:40,viewBox:"0 0 40 40",fill:"none",xmlns:"http://www.w3.org/2000/svg",role:"img","aria-labelledby":n},i),t?o.createElement("title",{id:n},t):null,r||(r=o.createElement("path",{d:"M20 4.4a16 16 0 0 0-16 16c0 7.072 4.592 13.072 10.944 15.2.8.128 1.056-.368 1.056-.8v-2.704c-4.432.96-5.376-2.144-5.376-2.144-.736-1.856-1.776-2.352-1.776-2.352-1.456-.992.112-.96.112-.96 1.6.112 2.448 1.648 2.448 1.648C12.8 30.72 15.152 30 16.064 29.616c.144-1.04.56-1.744 1.008-2.144-3.552-.4-7.28-1.776-7.28-7.872 0-1.776.608-3.2 1.648-4.336-.16-.4-.72-2.064.16-4.224 0 0 1.344-.432 4.4 1.632a15.075 15.075 0 0 1 4-.528c1.36 0 2.736.176 4 .528 3.056-2.064 4.4-1.632 4.4-1.632.88 2.16.32 3.824.16 4.224 1.04 1.136 1.648 2.56 1.648 4.336 0 6.112-3.744 7.456-7.312 7.856.576.496 1.104 1.472 1.104 2.96V34.8c0 .432.256.944 1.072.8C31.424 33.456 36 27.472 36 20.4a16.001 16.001 0 0 0-16-16Z",fill:"#fff"})))}},26890:(e,t,n)=>{"use strict";n.r(t),n.d(t,{default:()=>l});var r,o,a=n(67294);function i(){return i=Object.assign?Object.assign.bind():function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e},i.apply(this,arguments)}const l=e=>{let{title:t,titleId:n,...l}=e;return a.createElement("svg",i({xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 512 512",role:"img","aria-labelledby":n},l),t?a.createElement("title",{id:n},t):null,r||(r=a.createElement("path",{d:"M256 411.12 0 202.667 256 0zM256 411.12l256-208.453L256 0z"})),o||(o=a.createElement("circle",{cx:256,cy:362.667,r:149.333})))}},42924:(e,t,n)=>{"use strict";n.r(t),n.d(t,{default:()=>i});var r,o=n(67294);function a(){return a=Object.assign?Object.assign.bind():function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e},a.apply(this,arguments)}const i=e=>{let{title:t,titleId:n,...i}=e;return o.createElement("svg",a({width:16,height:16,viewBox:"0 0 16 16",fill:"none",xmlns:"http://www.w3.org/2000/svg",role:"img","aria-labelledby":n},i),t?o.createElement("title",{id:n},t):null,r||(r=o.createElement("path",{d:"m4 13.333.667-2.666H2.333l.334-1.334H5l.667-2.666H3l.333-1.334H6l.667-2.666H8l-.667 2.666H10l.667-2.666H12l-.667 2.666h2.334l-.334 1.334H11l-.667 2.666H13l-.333 1.334H10l-.667 2.666H8l.667-2.666H6l-.667 2.666H4Zm2.333-4H9l.667-2.666H7l-.667 2.666Z",fill:"#fff"})))}},74297:(e,t,n)=>{"use strict";n.r(t),n.d(t,{default:()=>i});var r,o=n(67294);function a(){return a=Object.assign?Object.assign.bind():function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e},a.apply(this,arguments)}const i=e=>{let{title:t,titleId:n,...i}=e;return o.createElement("svg",a({width:16,height:16,viewBox:"0 0 16 16",fill:"none",xmlns:"http://www.w3.org/2000/svg",role:"img","aria-labelledby":n},i),t?o.createElement("title",{id:n},t):null,r||(r=o.createElement("path",{d:"M8 14c-1.533 0-2.87-.508-4.009-1.525-1.139-1.017-1.791-2.287-1.958-3.808H3.4c.156 1.155.67 2.11 1.542 2.866.872.756 1.892 1.134 3.058 1.134 1.3 0 2.403-.453 3.309-1.359.905-.906 1.358-2.008 1.358-3.308 0-1.3-.453-2.403-1.359-3.309C10.402 3.786 9.3 3.333 8 3.333a4.5 4.5 0 0 0-2.15.534 4.954 4.954 0 0 0-1.683 1.466H6v1.334H2v-4h1.333v1.566A5.954 5.954 0 0 1 8 2c.833 0 1.614.158 2.342.475a6.107 6.107 0 0 1 1.9 1.283c.539.54.966 1.172 1.283 1.9C13.842 6.386 14 7.166 14 8c0 .833-.158 1.614-.475 2.342a6.108 6.108 0 0 1-1.283 1.9 6.11 6.11 0 0 1-1.9 1.283A5.793 5.793 0 0 1 8 14Zm1.867-3.2L7.333 8.267v-3.6h1.334v3.066L10.8 9.867l-.933.933Z",fill:"#fff"})))}},33336:(e,t,n)=>{"use strict";n.r(t),n.d(t,{default:()=>i});var r,o=n(67294);function a(){return a=Object.assign?Object.assign.bind():function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e},a.apply(this,arguments)}const i=e=>{let{title:t,titleId:n,...i}=e;return o.createElement("svg",a({width:16,height:16,viewBox:"0 0 16 16",fill:"none",xmlns:"http://www.w3.org/2000/svg",role:"img","aria-labelledby":n},i),t?o.createElement("title",{id:n},t):null,r||(r=o.createElement("path",{fillRule:"evenodd",clipRule:"evenodd",d:"M0 1.337A1.337 1.337 0 0 1 1.337 0h13.325A1.336 1.336 0 0 1 16 1.337v13.325A1.338 1.338 0 0 1 14.662 16H1.338A1.337 1.337 0 0 1 0 14.662V1.338ZM6.333 6.1H8.5v1.088C8.812 6.563 9.612 6 10.815 6c2.304 0 2.85 1.246 2.85 3.532v4.234h-2.332v-3.714c0-1.301-.313-2.036-1.107-2.036-1.102 0-1.56.792-1.56 2.036v3.714H6.333V6.1Zm-4 7.566h2.333V6H2.333v7.666ZM5 3.5a1.5 1.5 0 1 1-3 .066A1.5 1.5 0 0 1 5 3.5Z",fill:"#000"})))}},78951:(e,t,n)=>{"use strict";n.r(t),n.d(t,{default:()=>i});var r,o=n(67294);function a(){return a=Object.assign?Object.assign.bind():function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e},a.apply(this,arguments)}const i=e=>{let{title:t,titleId:n,...i}=e;return o.createElement("svg",a({width:18,height:18,viewBox:"0 0 18 18",fill:"none",xmlns:"http://www.w3.org/2000/svg",role:"img","aria-labelledby":n},i),t?o.createElement("title",{id:n},t):null,r||(r=o.createElement("path",{stroke:"#fff",d:"M.5 9h17"})))}},84629:(e,t,n)=>{"use strict";n.r(t),n.d(t,{default:()=>l});var r,o,a=n(67294);function i(){return i=Object.assign?Object.assign.bind():function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e},i.apply(this,arguments)}const l=e=>{let{title:t,titleId:n,...l}=e;return a.createElement("svg",i({width:18,height:18,viewBox:"0 0 18 18",fill:"none",xmlns:"http://www.w3.org/2000/svg",role:"img","aria-labelledby":n},l),t?a.createElement("title",{id:n},t):null,r||(r=a.createElement("g",{clipPath:"url(#a)"},a.createElement("path",{fillRule:"evenodd",clipRule:"evenodd",d:"M1.79 6.75a4.979 4.979 0 1 1 9.957 0 4.979 4.979 0 0 1-9.957 0ZM6.768.572a6.179 6.179 0 1 0 3.817 11.037l5.146 5.146a1 1 0 0 0 1.414-1.414l-5.207-5.207A6.179 6.179 0 0 0 6.768.571Z",fill:"#000"}))),o||(o=a.createElement("defs",null,a.createElement("clipPath",{id:"a"},a.createElement("path",{fill:"#fff",d:"M0 0h18v18H0z"})))))}},23816:(e,t,n)=>{"use strict";n.r(t),n.d(t,{default:()=>i});var r,o=n(67294);function a(){return a=Object.assign?Object.assign.bind():function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e},a.apply(this,arguments)}const i=e=>{let{title:t,titleId:n,...i}=e;return o.createElement("svg",a({width:179,height:178,viewBox:"0 0 179 178",fill:"none",xmlns:"http://www.w3.org/2000/svg",role:"img","aria-labelledby":n},i),t?o.createElement("title",{id:n},t):null,r||(r=o.createElement("path",{fillRule:"evenodd",clipRule:"evenodd",d:"M104.512 88.178c-10.667.615-17.352-1.87-28.02-1.254a44.732 44.732 0 0 0-7.853 1.146c1.575-19.73 15.538-36.988 34.525-38.085 11.652-.672 23.298 6.522 23.93 18.2.621 11.479-8.131 19.158-22.58 19.992l-.002.001Zm-28.645 40.355c-11.162.631-22.317-6.104-22.923-17.033-.596-10.742 7.79-17.93 21.633-18.71 10.218-.575 16.623 1.751 26.84 1.174a43.776 43.776 0 0 0 7.522-1.073c-1.506 18.464-14.881 34.617-33.072 35.642ZM89.5.001C40.346 0 .5 39.846.5 89c0 49.154 39.846 89 89 89s89-39.847 89-89-39.846-89-89-89",fill:"#000"})))}},35245:(e,t,n)=>{"use strict";n.r(t),n.d(t,{default:()=>i});var r,o=n(67294);function a(){return a=Object.assign?Object.assign.bind():function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e},a.apply(this,arguments)}const i=e=>{let{title:t,titleId:n,...i}=e;return o.createElement("svg",a({width:40,height:40,viewBox:"0 0 40 40",fill:"none",xmlns:"http://www.w3.org/2000/svg",role:"img","aria-labelledby":n},i),t?o.createElement("title",{id:n},t):null,r||(r=o.createElement("path",{fillRule:"evenodd",clipRule:"evenodd",d:"M4.906 17.987c9.395-4.094 15.66-6.792 18.795-8.096 8.95-3.723 10.81-4.37 12.022-4.39.267-.005.863.06 1.249.374.326.264.416.622.459.873.043.25.096.822.053 1.268-.485 5.097-2.583 17.463-3.65 23.171-.453 2.415-1.342 3.225-2.203 3.304-1.872.172-3.293-1.237-5.106-2.425-2.836-1.86-4.439-3.017-7.192-4.831-3.182-2.097-1.12-3.25.694-5.133.475-.493 8.72-7.993 8.88-8.674.02-.085.039-.402-.15-.57-.188-.167-.466-.11-.667-.064-.284.064-4.816 3.06-13.594 8.985-1.286.883-2.451 1.314-3.495 1.29-1.15-.024-3.364-.65-5.01-1.185-2.018-.656-3.622-1.003-3.483-2.117.073-.58.872-1.174 2.398-1.78Z",fill:"#fff"})))}},68902:(e,t,n)=>{"use strict";n.r(t),n.d(t,{default:()=>i});var r,o=n(67294);function a(){return a=Object.assign?Object.assign.bind():function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e},a.apply(this,arguments)}const i=e=>{let{title:t,titleId:n,...i}=e;return o.createElement("svg",a({width:24,height:24,xmlns:"http://www.w3.org/2000/svg",xmlSpace:"preserve",style:{fillRule:"evenodd",clipRule:"evenodd",strokeLinejoin:"round",strokeMiterlimit:1.41421},role:"img","aria-labelledby":n},i),t?o.createElement("title",{id:n},t):null,r||(r=o.createElement("path",{d:"M12 0C5.374 0 0 5.372 0 12c0 6.627 5.374 12 12 12 6.627 0 12-5.373 12-12 0-6.628-5.373-12-12-12Zm3.224 17.871c.188.133.43.166.646.085a.678.678 0 0 0 .422-.491c.507-2.382 1.737-8.412 2.198-10.578a.457.457 0 0 0-.151-.443.47.47 0 0 0-.465-.082c-2.446.906-9.979 3.732-13.058 4.871a.484.484 0 0 0-.316.467.483.483 0 0 0 .346.445c1.381.413 3.193.988 3.193.988s.847 2.558 1.288 3.858a.512.512 0 0 0 .352.336.505.505 0 0 0 .474-.121l1.805-1.704s2.084 1.527 3.266 2.369Zm-6.423-5.062.98 3.231.218-2.046 5.941-5.358a.162.162 0 0 0 .019-.22.165.165 0 0 0-.219-.037l-6.939 4.43Z"})))}},86089:(e,t,n)=>{"use strict";n.r(t),n.d(t,{default:()=>i});var r,o=n(67294);function a(){return a=Object.assign?Object.assign.bind():function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e},a.apply(this,arguments)}const i=e=>{let{title:t,titleId:n,...i}=e;return o.createElement("svg",a({width:17,height:14,viewBox:"0 0 17 14",fill:"none",xmlns:"http://www.w3.org/2000/svg",role:"img","aria-labelledby":n},i),t?o.createElement("title",{id:n},t):null,r||(r=o.createElement("path",{d:"M16.557 1.597a6.802 6.802 0 0 1-1.95.534A3.406 3.406 0 0 0 16.1.251a6.782 6.782 0 0 1-2.157.824 3.398 3.398 0 0 0-5.788 3.1A9.647 9.647 0 0 1 1.153.624a3.395 3.395 0 0 0-.059 3.31c.264.494.645.915 1.11 1.225a3.389 3.389 0 0 1-1.538-.425v.044a3.398 3.398 0 0 0 2.725 3.33c-.5.136-1.025.156-1.534.06a3.399 3.399 0 0 0 3.173 2.357A6.817 6.817 0 0 1 0 11.934a9.607 9.607 0 0 0 5.207 1.526c6.249 0 9.665-5.176 9.665-9.665 0-.146-.004-.293-.01-.439A6.905 6.905 0 0 0 16.556 1.6l.001-.002Z",fill:"#000"})))}},92358:(e,t,n)=>{"use strict";n.r(t),n.d(t,{default:()=>i});var r,o=n(67294);function a(){return a=Object.assign?Object.assign.bind():function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e},a.apply(this,arguments)}const i=e=>{let{title:t,titleId:n,...i}=e;return o.createElement("svg",a({width:40,height:40,viewBox:"0 0 40 40",fill:"none",xmlns:"http://www.w3.org/2000/svg",role:"img","aria-labelledby":n},i),t?o.createElement("title",{id:n},t):null,r||(r=o.createElement("path",{d:"M22.62 19.134 32.63 7.5h-2.373l-8.69 10.102L14.627 7.5H6.62l10.496 15.275-10.496 12.2h2.372l9.177-10.668 7.33 10.668h8.005L22.62 19.134Zm-3.248 3.776-1.063-1.521L9.847 9.285h3.643l6.829 9.768 1.063 1.521 8.877 12.697h-3.643l-7.244-10.36v-.001Z",fill:"#fff"})))}},86010:(e,t,n)=>{"use strict";function r(e){var t,n,o="";if("string"==typeof e||"number"==typeof e)o+=e;else if("object"==typeof e)if(Array.isArray(e))for(t=0;t<e.length;t++)e[t]&&(n=r(e[t]))&&(o&&(o+=" "),o+=n);else for(t in e)e[t]&&(o&&(o+=" "),o+=t);return o}function o(){for(var e,t,n=0,o="";n<arguments.length;)(e=arguments[n++])&&(t=r(e))&&(o&&(o+=" "),o+=t);return o}n.r(t),n.d(t,{clsx:()=>o,default:()=>a});const a=o},20640:(e,t,n)=>{"use strict";var r=n(11742),o={"text/plain":"Text","text/html":"Url",default:"Text"};e.exports=function(e,t){var n,a,i,l,s,u,c=!1;t||(t={}),n=t.debug||!1;try{if(i=r(),l=document.createRange(),s=document.getSelection(),(u=document.createElement("span")).textContent=e,u.ariaHidden="true",u.style.all="unset",u.style.position="fixed",u.style.top=0,u.style.clip="rect(0, 0, 0, 0)",u.style.whiteSpace="pre",u.style.webkitUserSelect="text",u.style.MozUserSelect="text",u.style.msUserSelect="text",u.style.userSelect="text",u.addEventListener("copy",(function(r){if(r.stopPropagation(),t.format)if(r.preventDefault(),void 0===r.clipboardData){n&&console.warn("unable to use e.clipboardData"),n&&console.warn("trying IE specific stuff"),window.clipboardData.clearData();var a=o[t.format]||o.default;window.clipboardData.setData(a,e)}else r.clipboardData.clearData(),r.clipboardData.setData(t.format,e);t.onCopy&&(r.preventDefault(),t.onCopy(r.clipboardData))})),document.body.appendChild(u),l.selectNodeContents(u),s.addRange(l),!document.execCommand("copy"))throw new Error("copy command was unsuccessful");c=!0}catch(d){n&&console.error("unable to copy using execCommand: ",d),n&&console.warn("trying IE specific stuff");try{window.clipboardData.setData(t.format||"text",e),t.onCopy&&t.onCopy(window.clipboardData),c=!0}catch(d){n&&console.error("unable to copy using clipboardData: ",d),n&&console.error("falling back to prompt"),a=function(e){var t=(/mac os x/i.test(navigator.userAgent)?"\u2318":"Ctrl")+"+C";return e.replace(/#{\s*key\s*}/g,t)}("message"in t?t.message:"Copy to clipboard: #{key}, Enter"),window.prompt(a,e)}}finally{s&&("function"==typeof s.removeRange?s.removeRange(l):s.removeAllRanges()),u&&document.body.removeChild(u),i()}return c}},38252:e=>{"use strict";e.exports=function e(t,n){if(t===n)return!0;if(t&&n&&"object"==typeof t&&"object"==typeof n){if(t.constructor!==n.constructor)return!1;var r,o,a;if(Array.isArray(t)){if((r=t.length)!=n.length)return!1;for(o=r;0!=o--;)if(!e(t[o],n[o]))return!1;return!0}if(t.constructor===RegExp)return t.source===n.source&&t.flags===n.flags;if(t.valueOf!==Object.prototype.valueOf)return t.valueOf()===n.valueOf();if(t.toString!==Object.prototype.toString)return t.toString()===n.toString();if((r=(a=Object.keys(t)).length)!==Object.keys(n).length)return!1;for(o=r;0!=o--;)if(!Object.prototype.hasOwnProperty.call(n,a[o]))return!1;for(o=r;0!=o--;){var i=a[o];if(("_owner"!==i||!t.$$typeof)&&!e(t[i],n[i]))return!1}return!0}return t!=t&&n!=n}},99376:(e,t)=>{var n=Object.keys;t.D=function(e,t){if(e===t)return!0;if(!(e instanceof Object&&t instanceof Object))return!1;for(var r=n(e),o=r.length,a=0;a<o;a++)if(!(r[a]in t))return!1;for(a=0;a<o;a++)if(e[r[a]]!==t[r[a]])return!1;return o===n(t).length}},42358:(e,t,n)=>{"use strict";n.d(t,{lX:()=>k,q_:()=>D,ob:()=>m,PP:()=>N,Ep:()=>h,Hp:()=>g});var r=n(87462);function o(e){return"/"===e.charAt(0)}function a(e,t){for(var n=t,r=n+1,o=e.length;r<o;n+=1,r+=1)e[n]=e[r];e.pop()}const i=function(e,t){void 0===t&&(t="");var n,r=e&&e.split("/")||[],i=t&&t.split("/")||[],l=e&&o(e),s=t&&o(t),u=l||s;if(e&&o(e)?i=r:r.length&&(i.pop(),i=i.concat(r)),!i.length)return"/";if(i.length){var c=i[i.length-1];n="."===c||".."===c||""===c}else n=!1;for(var d=0,f=i.length;f>=0;f--){var p=i[f];"."===p?a(i,f):".."===p?(a(i,f),d++):d&&(a(i,f),d--)}if(!u)for(;d--;d)i.unshift("..");!u||""===i[0]||i[0]&&o(i[0])||i.unshift("");var h=i.join("/");return n&&"/"!==h.substr(-1)&&(h+="/"),h};function l(e){return e.valueOf?e.valueOf():Object.prototype.valueOf.call(e)}const s=function e(t,n){if(t===n)return!0;if(null==t||null==n)return!1;if(Array.isArray(t))return Array.isArray(n)&&t.length===n.length&&t.every((function(t,r){return e(t,n[r])}));if("object"==typeof t||"object"==typeof n){var r=l(t),o=l(n);return r!==t||o!==n?e(r,o):Object.keys(Object.assign({},t,n)).every((function(r){return e(t[r],n[r])}))}return!1};var u=n(38776);function c(e){return"/"===e.charAt(0)?e:"/"+e}function d(e){return"/"===e.charAt(0)?e.substr(1):e}function f(e,t){return function(e,t){return 0===e.toLowerCase().indexOf(t.toLowerCase())&&-1!=="/?#".indexOf(e.charAt(t.length))}(e,t)?e.substr(t.length):e}function p(e){return"/"===e.charAt(e.length-1)?e.slice(0,-1):e}function h(e){var t=e.pathname,n=e.search,r=e.hash,o=t||"/";return n&&"?"!==n&&(o+="?"===n.charAt(0)?n:"?"+n),r&&"#"!==r&&(o+="#"===r.charAt(0)?r:"#"+r),o}function m(e,t,n,o){var a;"string"==typeof e?(a=function(e){var t=e||"/",n="",r="",o=t.indexOf("#");-1!==o&&(r=t.substr(o),t=t.substr(0,o));var a=t.indexOf("?");return-1!==a&&(n=t.substr(a),t=t.substr(0,a)),{pathname:t,search:"?"===n?"":n,hash:"#"===r?"":r}}(e),a.state=t):(void 0===(a=(0,r.Z)({},e)).pathname&&(a.pathname=""),a.search?"?"!==a.search.charAt(0)&&(a.search="?"+a.search):a.search="",a.hash?"#"!==a.hash.charAt(0)&&(a.hash="#"+a.hash):a.hash="",void 0!==t&&void 0===a.state&&(a.state=t));try{a.pathname=decodeURI(a.pathname)}catch(l){throw l instanceof URIError?new URIError('Pathname "'+a.pathname+'" could not be decoded. This is likely caused by an invalid percent-encoding.'):l}return n&&(a.key=n),o?a.pathname?"/"!==a.pathname.charAt(0)&&(a.pathname=i(a.pathname,o.pathname)):a.pathname=o.pathname:a.pathname||(a.pathname="/"),a}function g(e,t){return e.pathname===t.pathname&&e.search===t.search&&e.hash===t.hash&&e.key===t.key&&s(e.state,t.state)}function v(){var e=null;var t=[];return{setPrompt:function(t){return e=t,function(){e===t&&(e=null)}},confirmTransitionTo:function(t,n,r,o){if(null!=e){var a="function"==typeof e?e(t,n):e;"string"==typeof a?"function"==typeof r?r(a,o):o(!0):o(!1!==a)}else o(!0)},appendListener:function(e){var n=!0;function r(){n&&e.apply(void 0,arguments)}return t.push(r),function(){n=!1,t=t.filter((function(e){return e!==r}))}},notifyListeners:function(){for(var e=arguments.length,n=new Array(e),r=0;r<e;r++)n[r]=arguments[r];t.forEach((function(e){return e.apply(void 0,n)}))}}}var b=!("undefined"==typeof window||!window.document||!window.document.createElement);function y(e,t){t(window.confirm(e))}var w="popstate",x="hashchange";function _(){try{return window.history.state||{}}catch(e){return{}}}function k(e){void 0===e&&(e={}),b||(0,u.Z)(!1);var t,n=window.history,o=(-1===(t=window.navigator.userAgent).indexOf("Android 2.")&&-1===t.indexOf("Android 4.0")||-1===t.indexOf("Mobile Safari")||-1!==t.indexOf("Chrome")||-1!==t.indexOf("Windows Phone"))&&window.history&&"pushState"in window.history,a=!(-1===window.navigator.userAgent.indexOf("Trident")),i=e,l=i.forceRefresh,s=void 0!==l&&l,d=i.getUserConfirmation,g=void 0===d?y:d,k=i.keyLength,E=void 0===k?6:k,S=e.basename?p(c(e.basename)):"";function C(e){var t=e||{},n=t.key,r=t.state,o=window.location,a=o.pathname+o.search+o.hash;return S&&(a=f(a,S)),m(a,r,n)}function T(){return Math.random().toString(36).substr(2,E)}var O=v();function D(e){(0,r.Z)($,e),$.length=n.length,O.notifyListeners($.location,$.action)}function P(e){(function(e){return void 0===e.state&&-1===navigator.userAgent.indexOf("CriOS")})(e)||I(C(e.state))}function N(){I(C(_()))}var A=!1;function I(e){if(A)A=!1,D();else{O.confirmTransitionTo(e,"POP",g,(function(t){t?D({action:"POP",location:e}):function(e){var t=$.location,n=R.indexOf(t.key);-1===n&&(n=0);var r=R.indexOf(e.key);-1===r&&(r=0);var o=n-r;o&&(A=!0,M(o))}(e)}))}}var L=C(_()),R=[L.key];function j(e){return S+h(e)}function M(e){n.go(e)}var F=0;function B(e){1===(F+=e)&&1===e?(window.addEventListener(w,P),a&&window.addEventListener(x,N)):0===F&&(window.removeEventListener(w,P),a&&window.removeEventListener(x,N))}var z=!1;var $={length:n.length,action:"POP",location:L,createHref:j,push:function(e,t){var r="PUSH",a=m(e,t,T(),$.location);O.confirmTransitionTo(a,r,g,(function(e){if(e){var t=j(a),i=a.key,l=a.state;if(o)if(n.pushState({key:i,state:l},null,t),s)window.location.href=t;else{var u=R.indexOf($.location.key),c=R.slice(0,u+1);c.push(a.key),R=c,D({action:r,location:a})}else window.location.href=t}}))},replace:function(e,t){var r="REPLACE",a=m(e,t,T(),$.location);O.confirmTransitionTo(a,r,g,(function(e){if(e){var t=j(a),i=a.key,l=a.state;if(o)if(n.replaceState({key:i,state:l},null,t),s)window.location.replace(t);else{var u=R.indexOf($.location.key);-1!==u&&(R[u]=a.key),D({action:r,location:a})}else window.location.replace(t)}}))},go:M,goBack:function(){M(-1)},goForward:function(){M(1)},block:function(e){void 0===e&&(e=!1);var t=O.setPrompt(e);return z||(B(1),z=!0),function(){return z&&(z=!1,B(-1)),t()}},listen:function(e){var t=O.appendListener(e);return B(1),function(){B(-1),t()}}};return $}var E="hashchange",S={hashbang:{encodePath:function(e){return"!"===e.charAt(0)?e:"!/"+d(e)},decodePath:function(e){return"!"===e.charAt(0)?e.substr(1):e}},noslash:{encodePath:d,decodePath:c},slash:{encodePath:c,decodePath:c}};function C(e){var t=e.indexOf("#");return-1===t?e:e.slice(0,t)}function T(){var e=window.location.href,t=e.indexOf("#");return-1===t?"":e.substring(t+1)}function O(e){window.location.replace(C(window.location.href)+"#"+e)}function D(e){void 0===e&&(e={}),b||(0,u.Z)(!1);var t=window.history,n=(window.navigator.userAgent.indexOf("Firefox"),e),o=n.getUserConfirmation,a=void 0===o?y:o,i=n.hashType,l=void 0===i?"slash":i,s=e.basename?p(c(e.basename)):"",d=S[l],g=d.encodePath,w=d.decodePath;function x(){var e=w(T());return s&&(e=f(e,s)),m(e)}var _=v();function k(e){(0,r.Z)(z,e),z.length=t.length,_.notifyListeners(z.location,z.action)}var D=!1,P=null;function N(){var e,t,n=T(),r=g(n);if(n!==r)O(r);else{var o=x(),i=z.location;if(!D&&(t=o,(e=i).pathname===t.pathname&&e.search===t.search&&e.hash===t.hash))return;if(P===h(o))return;P=null,function(e){if(D)D=!1,k();else{var t="POP";_.confirmTransitionTo(e,t,a,(function(n){n?k({action:t,location:e}):function(e){var t=z.location,n=R.lastIndexOf(h(t));-1===n&&(n=0);var r=R.lastIndexOf(h(e));-1===r&&(r=0);var o=n-r;o&&(D=!0,j(o))}(e)}))}}(o)}}var A=T(),I=g(A);A!==I&&O(I);var L=x(),R=[h(L)];function j(e){t.go(e)}var M=0;function F(e){1===(M+=e)&&1===e?window.addEventListener(E,N):0===M&&window.removeEventListener(E,N)}var B=!1;var z={length:t.length,action:"POP",location:L,createHref:function(e){var t=document.querySelector("base"),n="";return t&&t.getAttribute("href")&&(n=C(window.location.href)),n+"#"+g(s+h(e))},push:function(e,t){var n="PUSH",r=m(e,void 0,void 0,z.location);_.confirmTransitionTo(r,n,a,(function(e){if(e){var t=h(r),o=g(s+t);if(T()!==o){P=t,function(e){window.location.hash=e}(o);var a=R.lastIndexOf(h(z.location)),i=R.slice(0,a+1);i.push(t),R=i,k({action:n,location:r})}else k()}}))},replace:function(e,t){var n="REPLACE",r=m(e,void 0,void 0,z.location);_.confirmTransitionTo(r,n,a,(function(e){if(e){var t=h(r),o=g(s+t);T()!==o&&(P=t,O(o));var a=R.indexOf(h(z.location));-1!==a&&(R[a]=t),k({action:n,location:r})}}))},go:j,goBack:function(){j(-1)},goForward:function(){j(1)},block:function(e){void 0===e&&(e=!1);var t=_.setPrompt(e);return B||(F(1),B=!0),function(){return B&&(B=!1,F(-1)),t()}},listen:function(e){var t=_.appendListener(e);return F(1),function(){F(-1),t()}}};return z}function P(e,t,n){return Math.min(Math.max(e,t),n)}function N(e){void 0===e&&(e={});var t=e,n=t.getUserConfirmation,o=t.initialEntries,a=void 0===o?["/"]:o,i=t.initialIndex,l=void 0===i?0:i,s=t.keyLength,u=void 0===s?6:s,c=v();function d(e){(0,r.Z)(w,e),w.length=w.entries.length,c.notifyListeners(w.location,w.action)}function f(){return Math.random().toString(36).substr(2,u)}var p=P(l,0,a.length-1),g=a.map((function(e){return m(e,void 0,"string"==typeof e?f():e.key||f())})),b=h;function y(e){var t=P(w.index+e,0,w.entries.length-1),r=w.entries[t];c.confirmTransitionTo(r,"POP",n,(function(e){e?d({action:"POP",location:r,index:t}):d()}))}var w={length:g.length,action:"POP",location:g[p],index:p,entries:g,createHref:b,push:function(e,t){var r="PUSH",o=m(e,t,f(),w.location);c.confirmTransitionTo(o,r,n,(function(e){if(e){var t=w.index+1,n=w.entries.slice(0);n.length>t?n.splice(t,n.length-t,o):n.push(o),d({action:r,location:o,index:t,entries:n})}}))},replace:function(e,t){var r="REPLACE",o=m(e,t,f(),w.location);c.confirmTransitionTo(o,r,n,(function(e){e&&(w.entries[w.index]=o,d({action:r,location:o}))}))},go:y,goBack:function(){y(-1)},goForward:function(){y(1)},canGo:function(e){var t=w.index+e;return t>=0&&t<w.entries.length},block:function(e){return void 0===e&&(e=!1),c.setPrompt(e)},listen:function(e){return c.appendListener(e)}};return w}},8679:(e,t,n)=>{"use strict";var r=n(59864),o={childContextTypes:!0,contextType:!0,contextTypes:!0,defaultProps:!0,displayName:!0,getDefaultProps:!0,getDerivedStateFromError:!0,getDerivedStateFromProps:!0,mixins:!0,propTypes:!0,type:!0},a={name:!0,length:!0,prototype:!0,caller:!0,callee:!0,arguments:!0,arity:!0},i={$$typeof:!0,compare:!0,defaultProps:!0,displayName:!0,propTypes:!0,type:!0},l={};function s(e){return r.isMemo(e)?i:l[e.$$typeof]||o}l[r.ForwardRef]={$$typeof:!0,render:!0,defaultProps:!0,displayName:!0,propTypes:!0},l[r.Memo]=i;var u=Object.defineProperty,c=Object.getOwnPropertyNames,d=Object.getOwnPropertySymbols,f=Object.getOwnPropertyDescriptor,p=Object.getPrototypeOf,h=Object.prototype;e.exports=function e(t,n,r){if("string"!=typeof n){if(h){var o=p(n);o&&o!==h&&e(t,o,r)}var i=c(n);d&&(i=i.concat(d(n)));for(var l=s(t),m=s(n),g=0;g<i.length;++g){var v=i[g];if(!(a[v]||r&&r[v]||m&&m[v]||l&&l[v])){var b=f(n,v);try{u(t,v,b)}catch(y){}}}}return t}},41143:e=>{"use strict";e.exports=function(e,t,n,r,o,a,i,l){if(!e){var s;if(void 0===t)s=new Error("Minified exception occurred; use the non-minified dev environment for the full error message and additional helpful warnings.");else{var u=[n,r,o,a,i,l],c=0;(s=new Error(t.replace(/%s/g,(function(){return u[c++]})))).name="Invariant Violation"}throw s.framesToPop=1,s}}},36808:(e,t,n)=>{var r,o;!function(a){if(void 0===(o="function"==typeof(r=a)?r.call(t,n,t,e):r)||(e.exports=o),!0,e.exports=a(),!!0){var i=window.Cookies,l=window.Cookies=a();l.noConflict=function(){return window.Cookies=i,l}}}((function(){function e(){for(var e=0,t={};e<arguments.length;e++){var n=arguments[e];for(var r in n)t[r]=n[r]}return t}function t(e){return e.replace(/(%[0-9A-Z]{2})+/g,decodeURIComponent)}return function n(r){function o(){}function a(t,n,a){if("undefined"!=typeof document){"number"==typeof(a=e({path:"/"},o.defaults,a)).expires&&(a.expires=new Date(1*new Date+864e5*a.expires)),a.expires=a.expires?a.expires.toUTCString():"";try{var i=JSON.stringify(n);/^[\{\[]/.test(i)&&(n=i)}catch(u){}n=r.write?r.write(n,t):encodeURIComponent(String(n)).replace(/%(23|24|26|2B|3A|3C|3E|3D|2F|3F|40|5B|5D|5E|60|7B|7D|7C)/g,decodeURIComponent),t=encodeURIComponent(String(t)).replace(/%(23|24|26|2B|5E|60|7C)/g,decodeURIComponent).replace(/[\(\)]/g,escape);var l="";for(var s in a)a[s]&&(l+="; "+s,!0!==a[s]&&(l+="="+a[s].split(";")[0]));return document.cookie=t+"="+n+l}}function i(e,n){if("undefined"!=typeof document){for(var o={},a=document.cookie?document.cookie.split("; "):[],i=0;i<a.length;i++){var l=a[i].split("="),s=l.slice(1).join("=");n||'"'!==s.charAt(0)||(s=s.slice(1,-1));try{var u=t(l[0]);if(s=(r.read||r)(s,u)||t(s),n)try{s=JSON.parse(s)}catch(c){}if(o[u]=s,e===u)break}catch(c){}}return e?o[e]:o}}return o.set=a,o.get=function(e){return i(e,!1)},o.getJSON=function(e){return i(e,!0)},o.remove=function(t,n){a(t,"",e(n,{expires:-1}))},o.defaults={},o.withConverter=n,o}((function(){}))}))},18552:(e,t,n)=>{var r=n(10852)(n(55639),"DataView");e.exports=r},1989:(e,t,n)=>{var r=n(51789),o=n(80401),a=n(57667),i=n(21327),l=n(81866);function s(e){var t=-1,n=null==e?0:e.length;for(this.clear();++t<n;){var r=e[t];this.set(r[0],r[1])}}s.prototype.clear=r,s.prototype.delete=o,s.prototype.get=a,s.prototype.has=i,s.prototype.set=l,e.exports=s},38407:(e,t,n)=>{var r=n(27040),o=n(14125),a=n(82117),i=n(67518),l=n(54705);function s(e){var t=-1,n=null==e?0:e.length;for(this.clear();++t<n;){var r=e[t];this.set(r[0],r[1])}}s.prototype.clear=r,s.prototype.delete=o,s.prototype.get=a,s.prototype.has=i,s.prototype.set=l,e.exports=s},57071:(e,t,n)=>{var r=n(10852)(n(55639),"Map");e.exports=r},83369:(e,t,n)=>{var r=n(24785),o=n(11285),a=n(96e3),i=n(49916),l=n(95265);function s(e){var t=-1,n=null==e?0:e.length;for(this.clear();++t<n;){var r=e[t];this.set(r[0],r[1])}}s.prototype.clear=r,s.prototype.delete=o,s.prototype.get=a,s.prototype.has=i,s.prototype.set=l,e.exports=s},53818:(e,t,n)=>{var r=n(10852)(n(55639),"Promise");e.exports=r},58525:(e,t,n)=>{var r=n(10852)(n(55639),"Set");e.exports=r},88668:(e,t,n)=>{var r=n(83369),o=n(90619),a=n(72385);function i(e){var t=-1,n=null==e?0:e.length;for(this.__data__=new r;++t<n;)this.add(e[t])}i.prototype.add=i.prototype.push=o,i.prototype.has=a,e.exports=i},46384:(e,t,n)=>{var r=n(38407),o=n(37465),a=n(63779),i=n(67599),l=n(44758),s=n(34309);function u(e){var t=this.__data__=new r(e);this.size=t.size}u.prototype.clear=o,u.prototype.delete=a,u.prototype.get=i,u.prototype.has=l,u.prototype.set=s,e.exports=u},62705:(e,t,n)=>{var r=n(55639).Symbol;e.exports=r},11149:(e,t,n)=>{var r=n(55639).Uint8Array;e.exports=r},70577:(e,t,n)=>{var r=n(10852)(n(55639),"WeakMap");e.exports=r},96874:e=>{e.exports=function(e,t,n){switch(n.length){case 0:return e.call(t);case 1:return e.call(t,n[0]);case 2:return e.call(t,n[0],n[1]);case 3:return e.call(t,n[0],n[1],n[2])}return e.apply(t,n)}},44174:e=>{e.exports=function(e,t,n,r){for(var o=-1,a=null==e?0:e.length;++o<a;){var i=e[o];t(r,i,n(i),e)}return r}},77412:e=>{e.exports=function(e,t){for(var n=-1,r=null==e?0:e.length;++n<r&&!1!==t(e[n],n,e););return e}},34963:e=>{e.exports=function(e,t){for(var n=-1,r=null==e?0:e.length,o=0,a=[];++n<r;){var i=e[n];t(i,n,e)&&(a[o++]=i)}return a}},14636:(e,t,n)=>{var r=n(22545),o=n(35694),a=n(1469),i=n(44144),l=n(65776),s=n(36719),u=Object.prototype.hasOwnProperty;e.exports=function(e,t){var n=a(e),c=!n&&o(e),d=!n&&!c&&i(e),f=!n&&!c&&!d&&s(e),p=n||c||d||f,h=p?r(e.length,String):[],m=h.length;for(var g in e)!t&&!u.call(e,g)||p&&("length"==g||d&&("offset"==g||"parent"==g)||f&&("buffer"==g||"byteLength"==g||"byteOffset"==g)||l(g,m))||h.push(g);return h}},29932:e=>{e.exports=function(e,t){for(var n=-1,r=null==e?0:e.length,o=Array(r);++n<r;)o[n]=t(e[n],n,e);return o}},62488:e=>{e.exports=function(e,t){for(var n=-1,r=t.length,o=e.length;++n<r;)e[o+n]=t[n];return e}},82908:e=>{e.exports=function(e,t){for(var n=-1,r=null==e?0:e.length;++n<r;)if(t(e[n],n,e))return!0;return!1}},34865:(e,t,n)=>{var r=n(89465),o=n(77813),a=Object.prototype.hasOwnProperty;e.exports=function(e,t,n){var i=e[t];a.call(e,t)&&o(i,n)&&(void 0!==n||t in e)||r(e,t,n)}},18470:(e,t,n)=>{var r=n(77813);e.exports=function(e,t){for(var n=e.length;n--;)if(r(e[n][0],t))return n;return-1}},81119:(e,t,n)=>{var r=n(89881);e.exports=function(e,t,n,o){return r(e,(function(e,r,a){t(o,e,n(e),a)})),o}},44037:(e,t,n)=>{var r=n(98363),o=n(3674);e.exports=function(e,t){return e&&r(t,o(t),e)}},63886:(e,t,n)=>{var r=n(98363),o=n(81704);e.exports=function(e,t){return e&&r(t,o(t),e)}},89465:(e,t,n)=>{var r=n(38777);e.exports=function(e,t,n){"__proto__"==t&&r?r(e,t,{configurable:!0,enumerable:!0,value:n,writable:!0}):e[t]=n}},85990:(e,t,n)=>{var r=n(46384),o=n(77412),a=n(34865),i=n(44037),l=n(63886),s=n(64626),u=n(278),c=n(18805),d=n(1911),f=n(58234),p=n(46904),h=n(64160),m=n(43824),g=n(29148),v=n(38517),b=n(1469),y=n(44144),w=n(56688),x=n(13218),_=n(72928),k=n(3674),E=n(81704),S="[object Arguments]",C="[object Function]",T="[object Object]",O={};O[S]=O["[object Array]"]=O["[object ArrayBuffer]"]=O["[object DataView]"]=O["[object Boolean]"]=O["[object Date]"]=O["[object Float32Array]"]=O["[object Float64Array]"]=O["[object Int8Array]"]=O["[object Int16Array]"]=O["[object Int32Array]"]=O["[object Map]"]=O["[object Number]"]=O[T]=O["[object RegExp]"]=O["[object Set]"]=O["[object String]"]=O["[object Symbol]"]=O["[object Uint8Array]"]=O["[object Uint8ClampedArray]"]=O["[object Uint16Array]"]=O["[object Uint32Array]"]=!0,O["[object Error]"]=O[C]=O["[object WeakMap]"]=!1,e.exports=function e(t,n,D,P,N,A){var I,L=1&n,R=2&n,j=4&n;if(D&&(I=N?D(t,P,N,A):D(t)),void 0!==I)return I;if(!x(t))return t;var M=b(t);if(M){if(I=m(t),!L)return u(t,I)}else{var F=h(t),B=F==C||"[object GeneratorFunction]"==F;if(y(t))return s(t,L);if(F==T||F==S||B&&!N){if(I=R||B?{}:v(t),!L)return R?d(t,l(I,t)):c(t,i(I,t))}else{if(!O[F])return N?t:{};I=g(t,F,L)}}A||(A=new r);var z=A.get(t);if(z)return z;A.set(t,I),_(t)?t.forEach((function(r){I.add(e(r,n,D,r,t,A))})):w(t)&&t.forEach((function(r,o){I.set(o,e(r,n,D,o,t,A))}));var $=M?void 0:(j?R?p:f:R?E:k)(t);return o($||t,(function(r,o){$&&(r=t[o=r]),a(I,o,e(r,n,D,o,t,A))})),I}},3118:(e,t,n)=>{var r=n(13218),o=Object.create,a=function(){function e(){}return function(t){if(!r(t))return{};if(o)return o(t);e.prototype=t;var n=new e;return e.prototype=void 0,n}}();e.exports=a},89881:(e,t,n)=>{var r=n(47816),o=n(99291)(r);e.exports=o},21078:(e,t,n)=>{var r=n(62488),o=n(37285);e.exports=function e(t,n,a,i,l){var s=-1,u=t.length;for(a||(a=o),l||(l=[]);++s<u;){var c=t[s];n>0&&a(c)?n>1?e(c,n-1,a,i,l):r(l,c):i||(l[l.length]=c)}return l}},28483:(e,t,n)=>{var r=n(25063)();e.exports=r},47816:(e,t,n)=>{var r=n(28483),o=n(3674);e.exports=function(e,t){return e&&r(e,t,o)}},97786:(e,t,n)=>{var r=n(71811),o=n(40327);e.exports=function(e,t){for(var n=0,a=(t=r(t,e)).length;null!=e&&n<a;)e=e[o(t[n++])];return n&&n==a?e:void 0}},68866:(e,t,n)=>{var r=n(62488),o=n(1469);e.exports=function(e,t,n){var a=t(e);return o(e)?a:r(a,n(e))}},44239:(e,t,n)=>{var r=n(62705),o=n(89607),a=n(2333),i=r?r.toStringTag:void 0;e.exports=function(e){return null==e?void 0===e?"[object Undefined]":"[object Null]":i&&i in Object(e)?o(e):a(e)}},13:e=>{e.exports=function(e,t){return null!=e&&t in Object(e)}},9454:(e,t,n)=>{var r=n(44239),o=n(37005);e.exports=function(e){return o(e)&&"[object Arguments]"==r(e)}},90939:(e,t,n)=>{var r=n(2492),o=n(37005);e.exports=function e(t,n,a,i,l){return t===n||(null==t||null==n||!o(t)&&!o(n)?t!=t&&n!=n:r(t,n,a,i,e,l))}},2492:(e,t,n)=>{var r=n(46384),o=n(67114),a=n(18351),i=n(16096),l=n(64160),s=n(1469),u=n(44144),c=n(36719),d="[object Arguments]",f="[object Array]",p="[object Object]",h=Object.prototype.hasOwnProperty;e.exports=function(e,t,n,m,g,v){var b=s(e),y=s(t),w=b?f:l(e),x=y?f:l(t),_=(w=w==d?p:w)==p,k=(x=x==d?p:x)==p,E=w==x;if(E&&u(e)){if(!u(t))return!1;b=!0,_=!1}if(E&&!_)return v||(v=new r),b||c(e)?o(e,t,n,m,g,v):a(e,t,w,n,m,g,v);if(!(1&n)){var S=_&&h.call(e,"__wrapped__"),C=k&&h.call(t,"__wrapped__");if(S||C){var T=S?e.value():e,O=C?t.value():t;return v||(v=new r),g(T,O,n,m,v)}}return!!E&&(v||(v=new r),i(e,t,n,m,g,v))}},25588:(e,t,n)=>{var r=n(64160),o=n(37005);e.exports=function(e){return o(e)&&"[object Map]"==r(e)}},2958:(e,t,n)=>{var r=n(46384),o=n(90939);e.exports=function(e,t,n,a){var i=n.length,l=i,s=!a;if(null==e)return!l;for(e=Object(e);i--;){var u=n[i];if(s&&u[2]?u[1]!==e[u[0]]:!(u[0]in e))return!1}for(;++i<l;){var c=(u=n[i])[0],d=e[c],f=u[1];if(s&&u[2]){if(void 0===d&&!(c in e))return!1}else{var p=new r;if(a)var h=a(d,f,c,e,t,p);if(!(void 0===h?o(f,d,3,a,p):h))return!1}}return!0}},28458:(e,t,n)=>{var r=n(23560),o=n(15346),a=n(13218),i=n(80346),l=/^\[object .+?Constructor\]$/,s=Function.prototype,u=Object.prototype,c=s.toString,d=u.hasOwnProperty,f=RegExp("^"+c.call(d).replace(/[\\^$.*+?()[\]{}|]/g,"\\$&").replace(/hasOwnProperty|(function).*?(?=\\\()| for .+?(?=\\\])/g,"$1.*?")+"$");e.exports=function(e){return!(!a(e)||o(e))&&(r(e)?f:l).test(i(e))}},29221:(e,t,n)=>{var r=n(64160),o=n(37005);e.exports=function(e){return o(e)&&"[object Set]"==r(e)}},38749:(e,t,n)=>{var r=n(44239),o=n(41780),a=n(37005),i={};i["[object Float32Array]"]=i["[object Float64Array]"]=i["[object Int8Array]"]=i["[object Int16Array]"]=i["[object Int32Array]"]=i["[object Uint8Array]"]=i["[object Uint8ClampedArray]"]=i["[object Uint16Array]"]=i["[object Uint32Array]"]=!0,i["[object Arguments]"]=i["[object Array]"]=i["[object ArrayBuffer]"]=i["[object Boolean]"]=i["[object DataView]"]=i["[object Date]"]=i["[object Error]"]=i["[object Function]"]=i["[object Map]"]=i["[object Number]"]=i["[object Object]"]=i["[object RegExp]"]=i["[object Set]"]=i["[object String]"]=i["[object WeakMap]"]=!1,e.exports=function(e){return a(e)&&o(e.length)&&!!i[r(e)]}},67206:(e,t,n)=>{var r=n(91573),o=n(16432),a=n(6557),i=n(1469),l=n(39601);e.exports=function(e){return"function"==typeof e?e:null==e?a:"object"==typeof e?i(e)?o(e[0],e[1]):r(e):l(e)}},280:(e,t,n)=>{var r=n(25726),o=n(86916),a=Object.prototype.hasOwnProperty;e.exports=function(e){if(!r(e))return o(e);var t=[];for(var n in Object(e))a.call(e,n)&&"constructor"!=n&&t.push(n);return t}},10313:(e,t,n)=>{var r=n(13218),o=n(25726),a=n(33498),i=Object.prototype.hasOwnProperty;e.exports=function(e){if(!r(e))return a(e);var t=o(e),n=[];for(var l in e)("constructor"!=l||!t&&i.call(e,l))&&n.push(l);return n}},91573:(e,t,n)=>{var r=n(2958),o=n(1499),a=n(42634);e.exports=function(e){var t=o(e);return 1==t.length&&t[0][2]?a(t[0][0],t[0][1]):function(n){return n===e||r(n,e,t)}}},16432:(e,t,n)=>{var r=n(90939),o=n(27361),a=n(79095),i=n(15403),l=n(89162),s=n(42634),u=n(40327);e.exports=function(e,t){return i(e)&&l(t)?s(u(e),t):function(n){var i=o(n,e);return void 0===i&&i===t?a(n,e):r(t,i,3)}}},40371:e=>{e.exports=function(e){return function(t){return null==t?void 0:t[e]}}},79152:(e,t,n)=>{var r=n(97786);e.exports=function(e){return function(t){return r(t,e)}}},56560:(e,t,n)=>{var r=n(75703),o=n(38777),a=n(6557),i=o?function(e,t){return o(e,"toString",{configurable:!0,enumerable:!1,value:r(t),writable:!0})}:a;e.exports=i},14259:e=>{e.exports=function(e,t,n){var r=-1,o=e.length;t<0&&(t=-t>o?0:o+t),(n=n>o?o:n)<0&&(n+=o),o=t>n?0:n-t>>>0,t>>>=0;for(var a=Array(o);++r<o;)a[r]=e[r+t];return a}},22545:e=>{e.exports=function(e,t){for(var n=-1,r=Array(e);++n<e;)r[n]=t(n);return r}},80531:(e,t,n)=>{var r=n(62705),o=n(29932),a=n(1469),i=n(33448),l=r?r.prototype:void 0,s=l?l.toString:void 0;e.exports=function e(t){if("string"==typeof t)return t;if(a(t))return o(t,e)+"";if(i(t))return s?s.call(t):"";var n=t+"";return"0"==n&&1/t==-Infinity?"-0":n}},7518:e=>{e.exports=function(e){return function(t){return e(t)}}},57406:(e,t,n)=>{var r=n(71811),o=n(10928),a=n(40292),i=n(40327);e.exports=function(e,t){return t=r(t,e),null==(e=a(e,t))||delete e[i(o(t))]}},74757:e=>{e.exports=function(e,t){return e.has(t)}},71811:(e,t,n)=>{var r=n(1469),o=n(15403),a=n(55514),i=n(79833);e.exports=function(e,t){return r(e)?e:o(e,t)?[e]:a(i(e))}},74318:(e,t,n)=>{var r=n(11149);e.exports=function(e){var t=new e.constructor(e.byteLength);return new r(t).set(new r(e)),t}},64626:(e,t,n)=>{e=n.nmd(e);var r=n(55639),o=t&&!t.nodeType&&t,a=o&&e&&!e.nodeType&&e,i=a&&a.exports===o?r.Buffer:void 0,l=i?i.allocUnsafe:void 0;e.exports=function(e,t){if(t)return e.slice();var n=e.length,r=l?l(n):new e.constructor(n);return e.copy(r),r}},57157:(e,t,n)=>{var r=n(74318);e.exports=function(e,t){var n=t?r(e.buffer):e.buffer;return new e.constructor(n,e.byteOffset,e.byteLength)}},93147:e=>{var t=/\w*$/;e.exports=function(e){var n=new e.constructor(e.source,t.exec(e));return n.lastIndex=e.lastIndex,n}},40419:(e,t,n)=>{var r=n(62705),o=r?r.prototype:void 0,a=o?o.valueOf:void 0;e.exports=function(e){return a?Object(a.call(e)):{}}},77133:(e,t,n)=>{var r=n(74318);e.exports=function(e,t){var n=t?r(e.buffer):e.buffer;return new e.constructor(n,e.byteOffset,e.length)}},278:e=>{e.exports=function(e,t){var n=-1,r=e.length;for(t||(t=Array(r));++n<r;)t[n]=e[n];return t}},98363:(e,t,n)=>{var r=n(34865),o=n(89465);e.exports=function(e,t,n,a){var i=!n;n||(n={});for(var l=-1,s=t.length;++l<s;){var u=t[l],c=a?a(n[u],e[u],u,n,e):void 0;void 0===c&&(c=e[u]),i?o(n,u,c):r(n,u,c)}return n}},18805:(e,t,n)=>{var r=n(98363),o=n(99551);e.exports=function(e,t){return r(e,o(e),t)}},1911:(e,t,n)=>{var r=n(98363),o=n(51442);e.exports=function(e,t){return r(e,o(e),t)}},14429:(e,t,n)=>{var r=n(55639)["__core-js_shared__"];e.exports=r},55189:(e,t,n)=>{var r=n(44174),o=n(81119),a=n(67206),i=n(1469);e.exports=function(e,t){return function(n,l){var s=i(n)?r:o,u=t?t():{};return s(n,e,a(l,2),u)}}},99291:(e,t,n)=>{var r=n(98612);e.exports=function(e,t){return function(n,o){if(null==n)return n;if(!r(n))return e(n,o);for(var a=n.length,i=t?a:-1,l=Object(n);(t?i--:++i<a)&&!1!==o(l[i],i,l););return n}}},25063:e=>{e.exports=function(e){return function(t,n,r){for(var o=-1,a=Object(t),i=r(t),l=i.length;l--;){var s=i[e?l:++o];if(!1===n(a[s],s,a))break}return t}}},60696:(e,t,n)=>{var r=n(68630);e.exports=function(e){return r(e)?void 0:e}},38777:(e,t,n)=>{var r=n(10852),o=function(){try{var e=r(Object,"defineProperty");return e({},"",{}),e}catch(t){}}();e.exports=o},67114:(e,t,n)=>{var r=n(88668),o=n(82908),a=n(74757);e.exports=function(e,t,n,i,l,s){var u=1&n,c=e.length,d=t.length;if(c!=d&&!(u&&d>c))return!1;var f=s.get(e),p=s.get(t);if(f&&p)return f==t&&p==e;var h=-1,m=!0,g=2&n?new r:void 0;for(s.set(e,t),s.set(t,e);++h<c;){var v=e[h],b=t[h];if(i)var y=u?i(b,v,h,t,e,s):i(v,b,h,e,t,s);if(void 0!==y){if(y)continue;m=!1;break}if(g){if(!o(t,(function(e,t){if(!a(g,t)&&(v===e||l(v,e,n,i,s)))return g.push(t)}))){m=!1;break}}else if(v!==b&&!l(v,b,n,i,s)){m=!1;break}}return s.delete(e),s.delete(t),m}},18351:(e,t,n)=>{var r=n(62705),o=n(11149),a=n(77813),i=n(67114),l=n(68776),s=n(21814),u=r?r.prototype:void 0,c=u?u.valueOf:void 0;e.exports=function(e,t,n,r,u,d,f){switch(n){case"[object DataView]":if(e.byteLength!=t.byteLength||e.byteOffset!=t.byteOffset)return!1;e=e.buffer,t=t.buffer;case"[object ArrayBuffer]":return!(e.byteLength!=t.byteLength||!d(new o(e),new o(t)));case"[object Boolean]":case"[object Date]":case"[object Number]":return a(+e,+t);case"[object Error]":return e.name==t.name&&e.message==t.message;case"[object RegExp]":case"[object String]":return e==t+"";case"[object Map]":var p=l;case"[object Set]":var h=1&r;if(p||(p=s),e.size!=t.size&&!h)return!1;var m=f.get(e);if(m)return m==t;r|=2,f.set(e,t);var g=i(p(e),p(t),r,u,d,f);return f.delete(e),g;case"[object Symbol]":if(c)return c.call(e)==c.call(t)}return!1}},16096:(e,t,n)=>{var r=n(58234),o=Object.prototype.hasOwnProperty;e.exports=function(e,t,n,a,i,l){var s=1&n,u=r(e),c=u.length;if(c!=r(t).length&&!s)return!1;for(var d=c;d--;){var f=u[d];if(!(s?f in t:o.call(t,f)))return!1}var p=l.get(e),h=l.get(t);if(p&&h)return p==t&&h==e;var m=!0;l.set(e,t),l.set(t,e);for(var g=s;++d<c;){var v=e[f=u[d]],b=t[f];if(a)var y=s?a(b,v,f,t,e,l):a(v,b,f,e,t,l);if(!(void 0===y?v===b||i(v,b,n,a,l):y)){m=!1;break}g||(g="constructor"==f)}if(m&&!g){var w=e.constructor,x=t.constructor;w==x||!("constructor"in e)||!("constructor"in t)||"function"==typeof w&&w instanceof w&&"function"==typeof x&&x instanceof x||(m=!1)}return l.delete(e),l.delete(t),m}},99021:(e,t,n)=>{var r=n(85564),o=n(45357),a=n(30061);e.exports=function(e){return a(o(e,void 0,r),e+"")}},31957:(e,t,n)=>{var r="object"==typeof n.g&&n.g&&n.g.Object===Object&&n.g;e.exports=r},58234:(e,t,n)=>{var r=n(68866),o=n(99551),a=n(3674);e.exports=function(e){return r(e,a,o)}},46904:(e,t,n)=>{var r=n(68866),o=n(51442),a=n(81704);e.exports=function(e){return r(e,a,o)}},45050:(e,t,n)=>{var r=n(37019);e.exports=function(e,t){var n=e.__data__;return r(t)?n["string"==typeof t?"string":"hash"]:n.map}},1499:(e,t,n)=>{var r=n(89162),o=n(3674);e.exports=function(e){for(var t=o(e),n=t.length;n--;){var a=t[n],i=e[a];t[n]=[a,i,r(i)]}return t}},10852:(e,t,n)=>{var r=n(28458),o=n(47801);e.exports=function(e,t){var n=o(e,t);return r(n)?n:void 0}},85924:(e,t,n)=>{var r=n(5569)(Object.getPrototypeOf,Object);e.exports=r},89607:(e,t,n)=>{var r=n(62705),o=Object.prototype,a=o.hasOwnProperty,i=o.toString,l=r?r.toStringTag:void 0;e.exports=function(e){var t=a.call(e,l),n=e[l];try{e[l]=void 0;var r=!0}catch(s){}var o=i.call(e);return r&&(t?e[l]=n:delete e[l]),o}},99551:(e,t,n)=>{var r=n(34963),o=n(70479),a=Object.prototype.propertyIsEnumerable,i=Object.getOwnPropertySymbols,l=i?function(e){return null==e?[]:(e=Object(e),r(i(e),(function(t){return a.call(e,t)})))}:o;e.exports=l},51442:(e,t,n)=>{var r=n(62488),o=n(85924),a=n(99551),i=n(70479),l=Object.getOwnPropertySymbols?function(e){for(var t=[];e;)r(t,a(e)),e=o(e);return t}:i;e.exports=l},64160:(e,t,n)=>{var r=n(18552),o=n(57071),a=n(53818),i=n(58525),l=n(70577),s=n(44239),u=n(80346),c="[object Map]",d="[object Promise]",f="[object Set]",p="[object WeakMap]",h="[object DataView]",m=u(r),g=u(o),v=u(a),b=u(i),y=u(l),w=s;(r&&w(new r(new ArrayBuffer(1)))!=h||o&&w(new o)!=c||a&&w(a.resolve())!=d||i&&w(new i)!=f||l&&w(new l)!=p)&&(w=function(e){var t=s(e),n="[object Object]"==t?e.constructor:void 0,r=n?u(n):"";if(r)switch(r){case m:return h;case g:return c;case v:return d;case b:return f;case y:return p}return t}),e.exports=w},47801:e=>{e.exports=function(e,t){return null==e?void 0:e[t]}},222:(e,t,n)=>{var r=n(71811),o=n(35694),a=n(1469),i=n(65776),l=n(41780),s=n(40327);e.exports=function(e,t,n){for(var u=-1,c=(t=r(t,e)).length,d=!1;++u<c;){var f=s(t[u]);if(!(d=null!=e&&n(e,f)))break;e=e[f]}return d||++u!=c?d:!!(c=null==e?0:e.length)&&l(c)&&i(f,c)&&(a(e)||o(e))}},51789:(e,t,n)=>{var r=n(94536);e.exports=function(){this.__data__=r?r(null):{},this.size=0}},80401:e=>{e.exports=function(e){var t=this.has(e)&&delete this.__data__[e];return this.size-=t?1:0,t}},57667:(e,t,n)=>{var r=n(94536),o=Object.prototype.hasOwnProperty;e.exports=function(e){var t=this.__data__;if(r){var n=t[e];return"__lodash_hash_undefined__"===n?void 0:n}return o.call(t,e)?t[e]:void 0}},21327:(e,t,n)=>{var r=n(94536),o=Object.prototype.hasOwnProperty;e.exports=function(e){var t=this.__data__;return r?void 0!==t[e]:o.call(t,e)}},81866:(e,t,n)=>{var r=n(94536);e.exports=function(e,t){var n=this.__data__;return this.size+=this.has(e)?0:1,n[e]=r&&void 0===t?"__lodash_hash_undefined__":t,this}},43824:e=>{var t=Object.prototype.hasOwnProperty;e.exports=function(e){var n=e.length,r=new e.constructor(n);return n&&"string"==typeof e[0]&&t.call(e,"index")&&(r.index=e.index,r.input=e.input),r}},29148:(e,t,n)=>{var r=n(74318),o=n(57157),a=n(93147),i=n(40419),l=n(77133);e.exports=function(e,t,n){var s=e.constructor;switch(t){case"[object ArrayBuffer]":return r(e);case"[object Boolean]":case"[object Date]":return new s(+e);case"[object DataView]":return o(e,n);case"[object Float32Array]":case"[object Float64Array]":case"[object Int8Array]":case"[object Int16Array]":case"[object Int32Array]":case"[object Uint8Array]":case"[object Uint8ClampedArray]":case"[object Uint16Array]":case"[object Uint32Array]":return l(e,n);case"[object Map]":case"[object Set]":return new s;case"[object Number]":case"[object String]":return new s(e);case"[object RegExp]":return a(e);case"[object Symbol]":return i(e)}}},38517:(e,t,n)=>{var r=n(3118),o=n(85924),a=n(25726);e.exports=function(e){return"function"!=typeof e.constructor||a(e)?{}:r(o(e))}},37285:(e,t,n)=>{var r=n(62705),o=n(35694),a=n(1469),i=r?r.isConcatSpreadable:void 0;e.exports=function(e){return a(e)||o(e)||!!(i&&e&&e[i])}},65776:e=>{var t=/^(?:0|[1-9]\d*)$/;e.exports=function(e,n){var r=typeof e;return!!(n=null==n?9007199254740991:n)&&("number"==r||"symbol"!=r&&t.test(e))&&e>-1&&e%1==0&&e<n}},15403:(e,t,n)=>{var r=n(1469),o=n(33448),a=/\.|\[(?:[^[\]]*|(["'])(?:(?!\1)[^\\]|\\.)*?\1)\]/,i=/^\w*$/;e.exports=function(e,t){if(r(e))return!1;var n=typeof e;return!("number"!=n&&"symbol"!=n&&"boolean"!=n&&null!=e&&!o(e))||(i.test(e)||!a.test(e)||null!=t&&e in Object(t))}},37019:e=>{e.exports=function(e){var t=typeof e;return"string"==t||"number"==t||"symbol"==t||"boolean"==t?"__proto__"!==e:null===e}},15346:(e,t,n)=>{var r,o=n(14429),a=(r=/[^.]+$/.exec(o&&o.keys&&o.keys.IE_PROTO||""))?"Symbol(src)_1."+r:"";e.exports=function(e){return!!a&&a in e}},25726:e=>{var t=Object.prototype;e.exports=function(e){var n=e&&e.constructor;return e===("function"==typeof n&&n.prototype||t)}},89162:(e,t,n)=>{var r=n(13218);e.exports=function(e){return e==e&&!r(e)}},27040:e=>{e.exports=function(){this.__data__=[],this.size=0}},14125:(e,t,n)=>{var r=n(18470),o=Array.prototype.splice;e.exports=function(e){var t=this.__data__,n=r(t,e);return!(n<0)&&(n==t.length-1?t.pop():o.call(t,n,1),--this.size,!0)}},82117:(e,t,n)=>{var r=n(18470);e.exports=function(e){var t=this.__data__,n=r(t,e);return n<0?void 0:t[n][1]}},67518:(e,t,n)=>{var r=n(18470);e.exports=function(e){return r(this.__data__,e)>-1}},54705:(e,t,n)=>{var r=n(18470);e.exports=function(e,t){var n=this.__data__,o=r(n,e);return o<0?(++this.size,n.push([e,t])):n[o][1]=t,this}},24785:(e,t,n)=>{var r=n(1989),o=n(38407),a=n(57071);e.exports=function(){this.size=0,this.__data__={hash:new r,map:new(a||o),string:new r}}},11285:(e,t,n)=>{var r=n(45050);e.exports=function(e){var t=r(this,e).delete(e);return this.size-=t?1:0,t}},96e3:(e,t,n)=>{var r=n(45050);e.exports=function(e){return r(this,e).get(e)}},49916:(e,t,n)=>{var r=n(45050);e.exports=function(e){return r(this,e).has(e)}},95265:(e,t,n)=>{var r=n(45050);e.exports=function(e,t){var n=r(this,e),o=n.size;return n.set(e,t),this.size+=n.size==o?0:1,this}},68776:e=>{e.exports=function(e){var t=-1,n=Array(e.size);return e.forEach((function(e,r){n[++t]=[r,e]})),n}},42634:e=>{e.exports=function(e,t){return function(n){return null!=n&&(n[e]===t&&(void 0!==t||e in Object(n)))}}},24523:(e,t,n)=>{var r=n(88306);e.exports=function(e){var t=r(e,(function(e){return 500===n.size&&n.clear(),e})),n=t.cache;return t}},94536:(e,t,n)=>{var r=n(10852)(Object,"create");e.exports=r},86916:(e,t,n)=>{var r=n(5569)(Object.keys,Object);e.exports=r},33498:e=>{e.exports=function(e){var t=[];if(null!=e)for(var n in Object(e))t.push(n);return t}},31167:(e,t,n)=>{e=n.nmd(e);var r=n(31957),o=t&&!t.nodeType&&t,a=o&&e&&!e.nodeType&&e,i=a&&a.exports===o&&r.process,l=function(){try{var e=a&&a.require&&a.require("util").types;return e||i&&i.binding&&i.binding("util")}catch(t){}}();e.exports=l},2333:e=>{var t=Object.prototype.toString;e.exports=function(e){return t.call(e)}},5569:e=>{e.exports=function(e,t){return function(n){return e(t(n))}}},45357:(e,t,n)=>{var r=n(96874),o=Math.max;e.exports=function(e,t,n){return t=o(void 0===t?e.length-1:t,0),function(){for(var a=arguments,i=-1,l=o(a.length-t,0),s=Array(l);++i<l;)s[i]=a[t+i];i=-1;for(var u=Array(t+1);++i<t;)u[i]=a[i];return u[t]=n(s),r(e,this,u)}}},40292:(e,t,n)=>{var r=n(97786),o=n(14259);e.exports=function(e,t){return t.length<2?e:r(e,o(t,0,-1))}},55639:(e,t,n)=>{var r=n(31957),o="object"==typeof self&&self&&self.Object===Object&&self,a=r||o||Function("return this")();e.exports=a},90619:e=>{e.exports=function(e){return this.__data__.set(e,"__lodash_hash_undefined__"),this}},72385:e=>{e.exports=function(e){return this.__data__.has(e)}},21814:e=>{e.exports=function(e){var t=-1,n=Array(e.size);return e.forEach((function(e){n[++t]=e})),n}},30061:(e,t,n)=>{var r=n(56560),o=n(21275)(r);e.exports=o},21275:e=>{var t=Date.now;e.exports=function(e){var n=0,r=0;return function(){var o=t(),a=16-(o-r);if(r=o,a>0){if(++n>=800)return arguments[0]}else n=0;return e.apply(void 0,arguments)}}},37465:(e,t,n)=>{var r=n(38407);e.exports=function(){this.__data__=new r,this.size=0}},63779:e=>{e.exports=function(e){var t=this.__data__,n=t.delete(e);return this.size=t.size,n}},67599:e=>{e.exports=function(e){return this.__data__.get(e)}},44758:e=>{e.exports=function(e){return this.__data__.has(e)}},34309:(e,t,n)=>{var r=n(38407),o=n(57071),a=n(83369);e.exports=function(e,t){var n=this.__data__;if(n instanceof r){var i=n.__data__;if(!o||i.length<199)return i.push([e,t]),this.size=++n.size,this;n=this.__data__=new a(i)}return n.set(e,t),this.size=n.size,this}},55514:(e,t,n)=>{var r=n(24523),o=/[^.[\]]+|\[(?:(-?\d+(?:\.\d+)?)|(["'])((?:(?!\2)[^\\]|\\.)*?)\2)\]|(?=(?:\.|\[\])(?:\.|\[\]|$))/g,a=/\\(\\)?/g,i=r((function(e){var t=[];return 46===e.charCodeAt(0)&&t.push(""),e.replace(o,(function(e,n,r,o){t.push(r?o.replace(a,"$1"):n||e)})),t}));e.exports=i},40327:(e,t,n)=>{var r=n(33448);e.exports=function(e){if("string"==typeof e||r(e))return e;var t=e+"";return"0"==t&&1/e==-Infinity?"-0":t}},80346:e=>{var t=Function.prototype.toString;e.exports=function(e){if(null!=e){try{return t.call(e)}catch(n){}try{return e+""}catch(n){}}return""}},75703:e=>{e.exports=function(e){return function(){return e}}},77813:e=>{e.exports=function(e,t){return e===t||e!=e&&t!=t}},85564:(e,t,n)=>{var r=n(21078);e.exports=function(e){return(null==e?0:e.length)?r(e,1):[]}},27361:(e,t,n)=>{var r=n(97786);e.exports=function(e,t,n){var o=null==e?void 0:r(e,t);return void 0===o?n:o}},7739:(e,t,n)=>{var r=n(89465),o=n(55189),a=Object.prototype.hasOwnProperty,i=o((function(e,t,n){a.call(e,n)?e[n].push(t):r(e,n,[t])}));e.exports=i},79095:(e,t,n)=>{var r=n(13),o=n(222);e.exports=function(e,t){return null!=e&&o(e,t,r)}},6557:e=>{e.exports=function(e){return e}},35694:(e,t,n)=>{var r=n(9454),o=n(37005),a=Object.prototype,i=a.hasOwnProperty,l=a.propertyIsEnumerable,s=r(function(){return arguments}())?r:function(e){return o(e)&&i.call(e,"callee")&&!l.call(e,"callee")};e.exports=s},1469:e=>{var t=Array.isArray;e.exports=t},98612:(e,t,n)=>{var r=n(23560),o=n(41780);e.exports=function(e){return null!=e&&o(e.length)&&!r(e)}},44144:(e,t,n)=>{e=n.nmd(e);var r=n(55639),o=n(95062),a=t&&!t.nodeType&&t,i=a&&e&&!e.nodeType&&e,l=i&&i.exports===a?r.Buffer:void 0,s=(l?l.isBuffer:void 0)||o;e.exports=s},23560:(e,t,n)=>{var r=n(44239),o=n(13218);e.exports=function(e){if(!o(e))return!1;var t=r(e);return"[object Function]"==t||"[object GeneratorFunction]"==t||"[object AsyncFunction]"==t||"[object Proxy]"==t}},41780:e=>{e.exports=function(e){return"number"==typeof e&&e>-1&&e%1==0&&e<=9007199254740991}},56688:(e,t,n)=>{var r=n(25588),o=n(7518),a=n(31167),i=a&&a.isMap,l=i?o(i):r;e.exports=l},13218:e=>{e.exports=function(e){var t=typeof e;return null!=e&&("object"==t||"function"==t)}},37005:e=>{e.exports=function(e){return null!=e&&"object"==typeof e}},68630:(e,t,n)=>{var r=n(44239),o=n(85924),a=n(37005),i=Function.prototype,l=Object.prototype,s=i.toString,u=l.hasOwnProperty,c=s.call(Object);e.exports=function(e){if(!a(e)||"[object Object]"!=r(e))return!1;var t=o(e);if(null===t)return!0;var n=u.call(t,"constructor")&&t.constructor;return"function"==typeof n&&n instanceof n&&s.call(n)==c}},72928:(e,t,n)=>{var r=n(29221),o=n(7518),a=n(31167),i=a&&a.isSet,l=i?o(i):r;e.exports=l},33448:(e,t,n)=>{var r=n(44239),o=n(37005);e.exports=function(e){return"symbol"==typeof e||o(e)&&"[object Symbol]"==r(e)}},36719:(e,t,n)=>{var r=n(38749),o=n(7518),a=n(31167),i=a&&a.isTypedArray,l=i?o(i):r;e.exports=l},3674:(e,t,n)=>{var r=n(14636),o=n(280),a=n(98612);e.exports=function(e){return a(e)?r(e):o(e)}},81704:(e,t,n)=>{var r=n(14636),o=n(10313),a=n(98612);e.exports=function(e){return a(e)?r(e,!0):o(e)}},10928:e=>{e.exports=function(e){var t=null==e?0:e.length;return t?e[t-1]:void 0}},88306:(e,t,n)=>{var r=n(83369);function o(e,t){if("function"!=typeof e||null!=t&&"function"!=typeof t)throw new TypeError("Expected a function");var n=function(){var r=arguments,o=t?t.apply(this,r):r[0],a=n.cache;if(a.has(o))return a.get(o);var i=e.apply(this,r);return n.cache=a.set(o,i)||a,i};return n.cache=new(o.Cache||r),n}o.Cache=r,e.exports=o},57557:(e,t,n)=>{var r=n(29932),o=n(85990),a=n(57406),i=n(71811),l=n(98363),s=n(60696),u=n(99021),c=n(46904),d=u((function(e,t){var n={};if(null==e)return n;var u=!1;t=r(t,(function(t){return t=i(t,e),u||(u=t.length>1),t})),l(e,c(e),n),u&&(n=o(n,7,s));for(var d=t.length;d--;)a(n,t[d]);return n}));e.exports=d},39601:(e,t,n)=>{var r=n(40371),o=n(79152),a=n(15403),i=n(40327);e.exports=function(e){return a(e)?r(i(e)):o(e)}},70479:e=>{e.exports=function(){return[]}},95062:e=>{e.exports=function(){return!1}},79833:(e,t,n)=>{var r=n(80531);e.exports=function(e){return null==e?"":r(e)}},31336:(e,t,n)=>{var r,o;!function(){var a,i,l,s,u,c,d,f,p,h,m,g,v,b,y,w,x,_,k,E,S,C,T,O,D,P,N=function(e){var t=new N.Builder;return t.pipeline.add(N.trimmer,N.stopWordFilter,N.stemmer),t.searchPipeline.add(N.stemmer),e.call(t,t),t.build()};N.version="2.3.9",N.utils={},N.utils.warn=(a=this,function(e){a.console&&console.warn&&console.warn(e)}),N.utils.asString=function(e){return null==e?"":e.toString()},N.utils.clone=function(e){if(null==e)return e;for(var t=Object.create(null),n=Object.keys(e),r=0;r<n.length;r++){var o=n[r],a=e[o];if(Array.isArray(a))t[o]=a.slice();else{if("string"!=typeof a&&"number"!=typeof a&&"boolean"!=typeof a)throw new TypeError("clone is not deep and does not support nested objects");t[o]=a}}return t},N.FieldRef=function(e,t,n){this.docRef=e,this.fieldName=t,this._stringValue=n},N.FieldRef.joiner="/",N.FieldRef.fromString=function(e){var t=e.indexOf(N.FieldRef.joiner);if(-1===t)throw"malformed field ref string";var n=e.slice(0,t),r=e.slice(t+1);return new N.FieldRef(r,n,e)},N.FieldRef.prototype.toString=function(){return null==this._stringValue&&(this._stringValue=this.fieldName+N.FieldRef.joiner+this.docRef),this._stringValue},N.Set=function(e){if(this.elements=Object.create(null),e){this.length=e.length;for(var t=0;t<this.length;t++)this.elements[e[t]]=!0}else this.length=0},N.Set.complete={intersect:function(e){return e},union:function(){return this},contains:function(){return!0}},N.Set.empty={intersect:function(){return this},union:function(e){return e},contains:function(){return!1}},N.Set.prototype.contains=function(e){return!!this.elements[e]},N.Set.prototype.intersect=function(e){var t,n,r,o=[];if(e===N.Set.complete)return this;if(e===N.Set.empty)return e;this.length<e.length?(t=this,n=e):(t=e,n=this),r=Object.keys(t.elements);for(var a=0;a<r.length;a++){var i=r[a];i in n.elements&&o.push(i)}return new N.Set(o)},N.Set.prototype.union=function(e){return e===N.Set.complete?N.Set.complete:e===N.Set.empty?this:new N.Set(Object.keys(this.elements).concat(Object.keys(e.elements)))},N.idf=function(e,t){var n=0;for(var r in e)"_index"!=r&&(n+=Object.keys(e[r]).length);var o=(t-n+.5)/(n+.5);return Math.log(1+Math.abs(o))},N.Token=function(e,t){this.str=e||"",this.metadata=t||{}},N.Token.prototype.toString=function(){return this.str},N.Token.prototype.update=function(e){return this.str=e(this.str,this.metadata),this},N.Token.prototype.clone=function(e){return e=e||function(e){return e},new N.Token(e(this.str,this.metadata),this.metadata)},N.tokenizer=function(e,t){if(null==e||null==e)return[];if(Array.isArray(e))return e.map((function(e){return new N.Token(N.utils.asString(e).toLowerCase(),N.utils.clone(t))}));for(var n=e.toString().toLowerCase(),r=n.length,o=[],a=0,i=0;a<=r;a++){var l=a-i;if(n.charAt(a).match(N.tokenizer.separator)||a==r){if(l>0){var s=N.utils.clone(t)||{};s.position=[i,l],s.index=o.length,o.push(new N.Token(n.slice(i,a),s))}i=a+1}}return o},N.tokenizer.separator=/[\s\-]+/,N.Pipeline=function(){this._stack=[]},N.Pipeline.registeredFunctions=Object.create(null),N.Pipeline.registerFunction=function(e,t){t in this.registeredFunctions&&N.utils.warn("Overwriting existing registered function: "+t),e.label=t,N.Pipeline.registeredFunctions[e.label]=e},N.Pipeline.warnIfFunctionNotRegistered=function(e){e.label&&e.label in this.registeredFunctions||N.utils.warn("Function is not registered with pipeline. This may cause problems when serialising the index.\n",e)},N.Pipeline.load=function(e){var t=new N.Pipeline;return e.forEach((function(e){var n=N.Pipeline.registeredFunctions[e];if(!n)throw new Error("Cannot load unregistered function: "+e);t.add(n)})),t},N.Pipeline.prototype.add=function(){var e=Array.prototype.slice.call(arguments);e.forEach((function(e){N.Pipeline.warnIfFunctionNotRegistered(e),this._stack.push(e)}),this)},N.Pipeline.prototype.after=function(e,t){N.Pipeline.warnIfFunctionNotRegistered(t);var n=this._stack.indexOf(e);if(-1==n)throw new Error("Cannot find existingFn");n+=1,this._stack.splice(n,0,t)},N.Pipeline.prototype.before=function(e,t){N.Pipeline.warnIfFunctionNotRegistered(t);var n=this._stack.indexOf(e);if(-1==n)throw new Error("Cannot find existingFn");this._stack.splice(n,0,t)},N.Pipeline.prototype.remove=function(e){var t=this._stack.indexOf(e);-1!=t&&this._stack.splice(t,1)},N.Pipeline.prototype.run=function(e){for(var t=this._stack.length,n=0;n<t;n++){for(var r=this._stack[n],o=[],a=0;a<e.length;a++){var i=r(e[a],a,e);if(null!=i&&""!==i)if(Array.isArray(i))for(var l=0;l<i.length;l++)o.push(i[l]);else o.push(i)}e=o}return e},N.Pipeline.prototype.runString=function(e,t){var n=new N.Token(e,t);return this.run([n]).map((function(e){return e.toString()}))},N.Pipeline.prototype.reset=function(){this._stack=[]},N.Pipeline.prototype.toJSON=function(){return this._stack.map((function(e){return N.Pipeline.warnIfFunctionNotRegistered(e),e.label}))},N.Vector=function(e){this._magnitude=0,this.elements=e||[]},N.Vector.prototype.positionForIndex=function(e){if(0==this.elements.length)return 0;for(var t=0,n=this.elements.length/2,r=n-t,o=Math.floor(r/2),a=this.elements[2*o];r>1&&(a<e&&(t=o),a>e&&(n=o),a!=e);)r=n-t,o=t+Math.floor(r/2),a=this.elements[2*o];return a==e||a>e?2*o:a<e?2*(o+1):void 0},N.Vector.prototype.insert=function(e,t){this.upsert(e,t,(function(){throw"duplicate index"}))},N.Vector.prototype.upsert=function(e,t,n){this._magnitude=0;var r=this.positionForIndex(e);this.elements[r]==e?this.elements[r+1]=n(this.elements[r+1],t):this.elements.splice(r,0,e,t)},N.Vector.prototype.magnitude=function(){if(this._magnitude)return this._magnitude;for(var e=0,t=this.elements.length,n=1;n<t;n+=2){var r=this.elements[n];e+=r*r}return this._magnitude=Math.sqrt(e)},N.Vector.prototype.dot=function(e){for(var t=0,n=this.elements,r=e.elements,o=n.length,a=r.length,i=0,l=0,s=0,u=0;s<o&&u<a;)(i=n[s])<(l=r[u])?s+=2:i>l?u+=2:i==l&&(t+=n[s+1]*r[u+1],s+=2,u+=2);return t},N.Vector.prototype.similarity=function(e){return this.dot(e)/this.magnitude()||0},N.Vector.prototype.toArray=function(){for(var e=new Array(this.elements.length/2),t=1,n=0;t<this.elements.length;t+=2,n++)e[n]=this.elements[t];return e},N.Vector.prototype.toJSON=function(){return this.elements},N.stemmer=(i={ational:"ate",tional:"tion",enci:"ence",anci:"ance",izer:"ize",bli:"ble",alli:"al",entli:"ent",eli:"e",ousli:"ous",ization:"ize",ation:"ate",ator:"ate",alism:"al",iveness:"ive",fulness:"ful",ousness:"ous",aliti:"al",iviti:"ive",biliti:"ble",logi:"log"},l={icate:"ic",ative:"",alize:"al",iciti:"ic",ical:"ic",ful:"",ness:""},s="[aeiouy]",u="[^aeiou][^aeiouy]*",c=new RegExp("^([^aeiou][^aeiouy]*)?[aeiouy][aeiou]*[^aeiou][^aeiouy]*"),d=new RegExp("^([^aeiou][^aeiouy]*)?[aeiouy][aeiou]*[^aeiou][^aeiouy]*[aeiouy][aeiou]*[^aeiou][^aeiouy]*"),f=new RegExp("^([^aeiou][^aeiouy]*)?[aeiouy][aeiou]*[^aeiou][^aeiouy]*([aeiouy][aeiou]*)?$"),p=new RegExp("^([^aeiou][^aeiouy]*)?[aeiouy]"),h=/^(.+?)(ss|i)es$/,m=/^(.+?)([^s])s$/,g=/^(.+?)eed$/,v=/^(.+?)(ed|ing)$/,b=/.$/,y=/(at|bl|iz)$/,w=new RegExp("([^aeiouylsz])\\1$"),x=new RegExp("^"+u+s+"[^aeiouwxy]$"),_=/^(.+?[^aeiou])y$/,k=/^(.+?)(ational|tional|enci|anci|izer|bli|alli|entli|eli|ousli|ization|ation|ator|alism|iveness|fulness|ousness|aliti|iviti|biliti|logi)$/,E=/^(.+?)(icate|ative|alize|iciti|ical|ful|ness)$/,S=/^(.+?)(al|ance|ence|er|ic|able|ible|ant|ement|ment|ent|ou|ism|ate|iti|ous|ive|ize)$/,C=/^(.+?)(s|t)(ion)$/,T=/^(.+?)e$/,O=/ll$/,D=new RegExp("^"+u+s+"[^aeiouwxy]$"),P=function(e){var t,n,r,o,a,s,u;if(e.length<3)return e;if("y"==(r=e.substr(0,1))&&(e=r.toUpperCase()+e.substr(1)),a=m,(o=h).test(e)?e=e.replace(o,"$1$2"):a.test(e)&&(e=e.replace(a,"$1$2")),a=v,(o=g).test(e)){var P=o.exec(e);(o=c).test(P[1])&&(o=b,e=e.replace(o,""))}else a.test(e)&&(t=(P=a.exec(e))[1],(a=p).test(t)&&(s=w,u=x,(a=y).test(e=t)?e+="e":s.test(e)?(o=b,e=e.replace(o,"")):u.test(e)&&(e+="e")));return(o=_).test(e)&&(e=(t=(P=o.exec(e))[1])+"i"),(o=k).test(e)&&(t=(P=o.exec(e))[1],n=P[2],(o=c).test(t)&&(e=t+i[n])),(o=E).test(e)&&(t=(P=o.exec(e))[1],n=P[2],(o=c).test(t)&&(e=t+l[n])),a=C,(o=S).test(e)?(t=(P=o.exec(e))[1],(o=d).test(t)&&(e=t)):a.test(e)&&(t=(P=a.exec(e))[1]+P[2],(a=d).test(t)&&(e=t)),(o=T).test(e)&&(t=(P=o.exec(e))[1],a=f,s=D,((o=d).test(t)||a.test(t)&&!s.test(t))&&(e=t)),a=d,(o=O).test(e)&&a.test(e)&&(o=b,e=e.replace(o,"")),"y"==r&&(e=r.toLowerCase()+e.substr(1)),e},function(e){return e.update(P)}),N.Pipeline.registerFunction(N.stemmer,"stemmer"),N.generateStopWordFilter=function(e){var t=e.reduce((function(e,t){return e[t]=t,e}),{});return function(e){if(e&&t[e.toString()]!==e.toString())return e}},N.stopWordFilter=N.generateStopWordFilter(["a","able","about","across","after","all","almost","also","am","among","an","and","any","are","as","at","be","because","been","but","by","can","cannot","could","dear","did","do","does","either","else","ever","every","for","from","get","got","had","has","have","he","her","hers","him","his","how","however","i","if","in","into","is","it","its","just","least","let","like","likely","may","me","might","most","must","my","neither","no","nor","not","of","off","often","on","only","or","other","our","own","rather","said","say","says","she","should","since","so","some","than","that","the","their","them","then","there","these","they","this","tis","to","too","twas","us","wants","was","we","were","what","when","where","which","while","who","whom","why","will","with","would","yet","you","your"]),N.Pipeline.registerFunction(N.stopWordFilter,"stopWordFilter"),N.trimmer=function(e){return e.update((function(e){return e.replace(/^\W+/,"").replace(/\W+$/,"")}))},N.Pipeline.registerFunction(N.trimmer,"trimmer"),N.TokenSet=function(){this.final=!1,this.edges={},this.id=N.TokenSet._nextId,N.TokenSet._nextId+=1},N.TokenSet._nextId=1,N.TokenSet.fromArray=function(e){for(var t=new N.TokenSet.Builder,n=0,r=e.length;n<r;n++)t.insert(e[n]);return t.finish(),t.root},N.TokenSet.fromClause=function(e){return"editDistance"in e?N.TokenSet.fromFuzzyString(e.term,e.editDistance):N.TokenSet.fromString(e.term)},N.TokenSet.fromFuzzyString=function(e,t){for(var n=new N.TokenSet,r=[{node:n,editsRemaining:t,str:e}];r.length;){var o=r.pop();if(o.str.length>0){var a,i=o.str.charAt(0);i in o.node.edges?a=o.node.edges[i]:(a=new N.TokenSet,o.node.edges[i]=a),1==o.str.length&&(a.final=!0),r.push({node:a,editsRemaining:o.editsRemaining,str:o.str.slice(1)})}if(0!=o.editsRemaining){if("*"in o.node.edges)var l=o.node.edges["*"];else{l=new N.TokenSet;o.node.edges["*"]=l}if(0==o.str.length&&(l.final=!0),r.push({node:l,editsRemaining:o.editsRemaining-1,str:o.str}),o.str.length>1&&r.push({node:o.node,editsRemaining:o.editsRemaining-1,str:o.str.slice(1)}),1==o.str.length&&(o.node.final=!0),o.str.length>=1){if("*"in o.node.edges)var s=o.node.edges["*"];else{s=new N.TokenSet;o.node.edges["*"]=s}1==o.str.length&&(s.final=!0),r.push({node:s,editsRemaining:o.editsRemaining-1,str:o.str.slice(1)})}if(o.str.length>1){var u,c=o.str.charAt(0),d=o.str.charAt(1);d in o.node.edges?u=o.node.edges[d]:(u=new N.TokenSet,o.node.edges[d]=u),1==o.str.length&&(u.final=!0),r.push({node:u,editsRemaining:o.editsRemaining-1,str:c+o.str.slice(2)})}}}return n},N.TokenSet.fromString=function(e){for(var t=new N.TokenSet,n=t,r=0,o=e.length;r<o;r++){var a=e[r],i=r==o-1;if("*"==a)t.edges[a]=t,t.final=i;else{var l=new N.TokenSet;l.final=i,t.edges[a]=l,t=l}}return n},N.TokenSet.prototype.toArray=function(){for(var e=[],t=[{prefix:"",node:this}];t.length;){var n=t.pop(),r=Object.keys(n.node.edges),o=r.length;n.node.final&&(n.prefix.charAt(0),e.push(n.prefix));for(var a=0;a<o;a++){var i=r[a];t.push({prefix:n.prefix.concat(i),node:n.node.edges[i]})}}return e},N.TokenSet.prototype.toString=function(){if(this._str)return this._str;for(var e=this.final?"1":"0",t=Object.keys(this.edges).sort(),n=t.length,r=0;r<n;r++){var o=t[r];e=e+o+this.edges[o].id}return e},N.TokenSet.prototype.intersect=function(e){for(var t=new N.TokenSet,n=void 0,r=[{qNode:e,output:t,node:this}];r.length;){n=r.pop();for(var o=Object.keys(n.qNode.edges),a=o.length,i=Object.keys(n.node.edges),l=i.length,s=0;s<a;s++)for(var u=o[s],c=0;c<l;c++){var d=i[c];if(d==u||"*"==u){var f=n.node.edges[d],p=n.qNode.edges[u],h=f.final&&p.final,m=void 0;d in n.output.edges?(m=n.output.edges[d]).final=m.final||h:((m=new N.TokenSet).final=h,n.output.edges[d]=m),r.push({qNode:p,output:m,node:f})}}}return t},N.TokenSet.Builder=function(){this.previousWord="",this.root=new N.TokenSet,this.uncheckedNodes=[],this.minimizedNodes={}},N.TokenSet.Builder.prototype.insert=function(e){var t,n=0;if(e<this.previousWord)throw new Error("Out of order word insertion");for(var r=0;r<e.length&&r<this.previousWord.length&&e[r]==this.previousWord[r];r++)n++;this.minimize(n),t=0==this.uncheckedNodes.length?this.root:this.uncheckedNodes[this.uncheckedNodes.length-1].child;for(r=n;r<e.length;r++){var o=new N.TokenSet,a=e[r];t.edges[a]=o,this.uncheckedNodes.push({parent:t,char:a,child:o}),t=o}t.final=!0,this.previousWord=e},N.TokenSet.Builder.prototype.finish=function(){this.minimize(0)},N.TokenSet.Builder.prototype.minimize=function(e){for(var t=this.uncheckedNodes.length-1;t>=e;t--){var n=this.uncheckedNodes[t],r=n.child.toString();r in this.minimizedNodes?n.parent.edges[n.char]=this.minimizedNodes[r]:(n.child._str=r,this.minimizedNodes[r]=n.child),this.uncheckedNodes.pop()}},N.Index=function(e){this.invertedIndex=e.invertedIndex,this.fieldVectors=e.fieldVectors,this.tokenSet=e.tokenSet,this.fields=e.fields,this.pipeline=e.pipeline},N.Index.prototype.search=function(e){return this.query((function(t){new N.QueryParser(e,t).parse()}))},N.Index.prototype.query=function(e){for(var t=new N.Query(this.fields),n=Object.create(null),r=Object.create(null),o=Object.create(null),a=Object.create(null),i=Object.create(null),l=0;l<this.fields.length;l++)r[this.fields[l]]=new N.Vector;e.call(t,t);for(l=0;l<t.clauses.length;l++){var s=t.clauses[l],u=null,c=N.Set.empty;u=s.usePipeline?this.pipeline.runString(s.term,{fields:s.fields}):[s.term];for(var d=0;d<u.length;d++){var f=u[d];s.term=f;var p=N.TokenSet.fromClause(s),h=this.tokenSet.intersect(p).toArray();if(0===h.length&&s.presence===N.Query.presence.REQUIRED){for(var m=0;m<s.fields.length;m++){a[A=s.fields[m]]=N.Set.empty}break}for(var g=0;g<h.length;g++){var v=h[g],b=this.invertedIndex[v],y=b._index;for(m=0;m<s.fields.length;m++){var w=b[A=s.fields[m]],x=Object.keys(w),_=v+"/"+A,k=new N.Set(x);if(s.presence==N.Query.presence.REQUIRED&&(c=c.union(k),void 0===a[A]&&(a[A]=N.Set.complete)),s.presence!=N.Query.presence.PROHIBITED){if(r[A].upsert(y,s.boost,(function(e,t){return e+t})),!o[_]){for(var E=0;E<x.length;E++){var S,C=x[E],T=new N.FieldRef(C,A),O=w[C];void 0===(S=n[T])?n[T]=new N.MatchData(v,A,O):S.add(v,A,O)}o[_]=!0}}else void 0===i[A]&&(i[A]=N.Set.empty),i[A]=i[A].union(k)}}}if(s.presence===N.Query.presence.REQUIRED)for(m=0;m<s.fields.length;m++){a[A=s.fields[m]]=a[A].intersect(c)}}var D=N.Set.complete,P=N.Set.empty;for(l=0;l<this.fields.length;l++){var A;a[A=this.fields[l]]&&(D=D.intersect(a[A])),i[A]&&(P=P.union(i[A]))}var I=Object.keys(n),L=[],R=Object.create(null);if(t.isNegated()){I=Object.keys(this.fieldVectors);for(l=0;l<I.length;l++){T=I[l];var j=N.FieldRef.fromString(T);n[T]=new N.MatchData}}for(l=0;l<I.length;l++){var M=(j=N.FieldRef.fromString(I[l])).docRef;if(D.contains(M)&&!P.contains(M)){var F,B=this.fieldVectors[j],z=r[j.fieldName].similarity(B);if(void 0!==(F=R[M]))F.score+=z,F.matchData.combine(n[j]);else{var $={ref:M,score:z,matchData:n[j]};R[M]=$,L.push($)}}}return L.sort((function(e,t){return t.score-e.score}))},N.Index.prototype.toJSON=function(){var e=Object.keys(this.invertedIndex).sort().map((function(e){return[e,this.invertedIndex[e]]}),this),t=Object.keys(this.fieldVectors).map((function(e){return[e,this.fieldVectors[e].toJSON()]}),this);return{version:N.version,fields:this.fields,fieldVectors:t,invertedIndex:e,pipeline:this.pipeline.toJSON()}},N.Index.load=function(e){var t={},n={},r=e.fieldVectors,o=Object.create(null),a=e.invertedIndex,i=new N.TokenSet.Builder,l=N.Pipeline.load(e.pipeline);e.version!=N.version&&N.utils.warn("Version mismatch when loading serialised index. Current version of lunr '"+N.version+"' does not match serialized index '"+e.version+"'");for(var s=0;s<r.length;s++){var u=(d=r[s])[0],c=d[1];n[u]=new N.Vector(c)}for(s=0;s<a.length;s++){var d,f=(d=a[s])[0],p=d[1];i.insert(f),o[f]=p}return i.finish(),t.fields=e.fields,t.fieldVectors=n,t.invertedIndex=o,t.tokenSet=i.root,t.pipeline=l,new N.Index(t)},N.Builder=function(){this._ref="id",this._fields=Object.create(null),this._documents=Object.create(null),this.invertedIndex=Object.create(null),this.fieldTermFrequencies={},this.fieldLengths={},this.tokenizer=N.tokenizer,this.pipeline=new N.Pipeline,this.searchPipeline=new N.Pipeline,this.documentCount=0,this._b=.75,this._k1=1.2,this.termIndex=0,this.metadataWhitelist=[]},N.Builder.prototype.ref=function(e){this._ref=e},N.Builder.prototype.field=function(e,t){if(/\//.test(e))throw new RangeError("Field '"+e+"' contains illegal character '/'");this._fields[e]=t||{}},N.Builder.prototype.b=function(e){this._b=e<0?0:e>1?1:e},N.Builder.prototype.k1=function(e){this._k1=e},N.Builder.prototype.add=function(e,t){var n=e[this._ref],r=Object.keys(this._fields);this._documents[n]=t||{},this.documentCount+=1;for(var o=0;o<r.length;o++){var a=r[o],i=this._fields[a].extractor,l=i?i(e):e[a],s=this.tokenizer(l,{fields:[a]}),u=this.pipeline.run(s),c=new N.FieldRef(n,a),d=Object.create(null);this.fieldTermFrequencies[c]=d,this.fieldLengths[c]=0,this.fieldLengths[c]+=u.length;for(var f=0;f<u.length;f++){var p=u[f];if(null==d[p]&&(d[p]=0),d[p]+=1,null==this.invertedIndex[p]){var h=Object.create(null);h._index=this.termIndex,this.termIndex+=1;for(var m=0;m<r.length;m++)h[r[m]]=Object.create(null);this.invertedIndex[p]=h}null==this.invertedIndex[p][a][n]&&(this.invertedIndex[p][a][n]=Object.create(null));for(var g=0;g<this.metadataWhitelist.length;g++){var v=this.metadataWhitelist[g],b=p.metadata[v];null==this.invertedIndex[p][a][n][v]&&(this.invertedIndex[p][a][n][v]=[]),this.invertedIndex[p][a][n][v].push(b)}}}},N.Builder.prototype.calculateAverageFieldLengths=function(){for(var e=Object.keys(this.fieldLengths),t=e.length,n={},r={},o=0;o<t;o++){var a=N.FieldRef.fromString(e[o]),i=a.fieldName;r[i]||(r[i]=0),r[i]+=1,n[i]||(n[i]=0),n[i]+=this.fieldLengths[a]}var l=Object.keys(this._fields);for(o=0;o<l.length;o++){var s=l[o];n[s]=n[s]/r[s]}this.averageFieldLength=n},N.Builder.prototype.createFieldVectors=function(){for(var e={},t=Object.keys(this.fieldTermFrequencies),n=t.length,r=Object.create(null),o=0;o<n;o++){for(var a=N.FieldRef.fromString(t[o]),i=a.fieldName,l=this.fieldLengths[a],s=new N.Vector,u=this.fieldTermFrequencies[a],c=Object.keys(u),d=c.length,f=this._fields[i].boost||1,p=this._documents[a.docRef].boost||1,h=0;h<d;h++){var m,g,v,b=c[h],y=u[b],w=this.invertedIndex[b]._index;void 0===r[b]?(m=N.idf(this.invertedIndex[b],this.documentCount),r[b]=m):m=r[b],g=m*((this._k1+1)*y)/(this._k1*(1-this._b+this._b*(l/this.averageFieldLength[i]))+y),g*=f,g*=p,v=Math.round(1e3*g)/1e3,s.insert(w,v)}e[a]=s}this.fieldVectors=e},N.Builder.prototype.createTokenSet=function(){this.tokenSet=N.TokenSet.fromArray(Object.keys(this.invertedIndex).sort())},N.Builder.prototype.build=function(){return this.calculateAverageFieldLengths(),this.createFieldVectors(),this.createTokenSet(),new N.Index({invertedIndex:this.invertedIndex,fieldVectors:this.fieldVectors,tokenSet:this.tokenSet,fields:Object.keys(this._fields),pipeline:this.searchPipeline})},N.Builder.prototype.use=function(e){var t=Array.prototype.slice.call(arguments,1);t.unshift(this),e.apply(this,t)},N.MatchData=function(e,t,n){for(var r=Object.create(null),o=Object.keys(n||{}),a=0;a<o.length;a++){var i=o[a];r[i]=n[i].slice()}this.metadata=Object.create(null),void 0!==e&&(this.metadata[e]=Object.create(null),this.metadata[e][t]=r)},N.MatchData.prototype.combine=function(e){for(var t=Object.keys(e.metadata),n=0;n<t.length;n++){var r=t[n],o=Object.keys(e.metadata[r]);null==this.metadata[r]&&(this.metadata[r]=Object.create(null));for(var a=0;a<o.length;a++){var i=o[a],l=Object.keys(e.metadata[r][i]);null==this.metadata[r][i]&&(this.metadata[r][i]=Object.create(null));for(var s=0;s<l.length;s++){var u=l[s];null==this.metadata[r][i][u]?this.metadata[r][i][u]=e.metadata[r][i][u]:this.metadata[r][i][u]=this.metadata[r][i][u].concat(e.metadata[r][i][u])}}}},N.MatchData.prototype.add=function(e,t,n){if(!(e in this.metadata))return this.metadata[e]=Object.create(null),void(this.metadata[e][t]=n);if(t in this.metadata[e])for(var r=Object.keys(n),o=0;o<r.length;o++){var a=r[o];a in this.metadata[e][t]?this.metadata[e][t][a]=this.metadata[e][t][a].concat(n[a]):this.metadata[e][t][a]=n[a]}else this.metadata[e][t]=n},N.Query=function(e){this.clauses=[],this.allFields=e},N.Query.wildcard=new String("*"),N.Query.wildcard.NONE=0,N.Query.wildcard.LEADING=1,N.Query.wildcard.TRAILING=2,N.Query.presence={OPTIONAL:1,REQUIRED:2,PROHIBITED:3},N.Query.prototype.clause=function(e){return"fields"in e||(e.fields=this.allFields),"boost"in e||(e.boost=1),"usePipeline"in e||(e.usePipeline=!0),"wildcard"in e||(e.wildcard=N.Query.wildcard.NONE),e.wildcard&N.Query.wildcard.LEADING&&e.term.charAt(0)!=N.Query.wildcard&&(e.term="*"+e.term),e.wildcard&N.Query.wildcard.TRAILING&&e.term.slice(-1)!=N.Query.wildcard&&(e.term=e.term+"*"),"presence"in e||(e.presence=N.Query.presence.OPTIONAL),this.clauses.push(e),this},N.Query.prototype.isNegated=function(){for(var e=0;e<this.clauses.length;e++)if(this.clauses[e].presence!=N.Query.presence.PROHIBITED)return!1;return!0},N.Query.prototype.term=function(e,t){if(Array.isArray(e))return e.forEach((function(e){this.term(e,N.utils.clone(t))}),this),this;var n=t||{};return n.term=e.toString(),this.clause(n),this},N.QueryParseError=function(e,t,n){this.name="QueryParseError",this.message=e,this.start=t,this.end=n},N.QueryParseError.prototype=new Error,N.QueryLexer=function(e){this.lexemes=[],this.str=e,this.length=e.length,this.pos=0,this.start=0,this.escapeCharPositions=[]},N.QueryLexer.prototype.run=function(){for(var e=N.QueryLexer.lexText;e;)e=e(this)},N.QueryLexer.prototype.sliceString=function(){for(var e=[],t=this.start,n=this.pos,r=0;r<this.escapeCharPositions.length;r++)n=this.escapeCharPositions[r],e.push(this.str.slice(t,n)),t=n+1;return e.push(this.str.slice(t,this.pos)),this.escapeCharPositions.length=0,e.join("")},N.QueryLexer.prototype.emit=function(e){this.lexemes.push({type:e,str:this.sliceString(),start:this.start,end:this.pos}),this.start=this.pos},N.QueryLexer.prototype.escapeCharacter=function(){this.escapeCharPositions.push(this.pos-1),this.pos+=1},N.QueryLexer.prototype.next=function(){if(this.pos>=this.length)return N.QueryLexer.EOS;var e=this.str.charAt(this.pos);return this.pos+=1,e},N.QueryLexer.prototype.width=function(){return this.pos-this.start},N.QueryLexer.prototype.ignore=function(){this.start==this.pos&&(this.pos+=1),this.start=this.pos},N.QueryLexer.prototype.backup=function(){this.pos-=1},N.QueryLexer.prototype.acceptDigitRun=function(){var e,t;do{t=(e=this.next()).charCodeAt(0)}while(t>47&&t<58);e!=N.QueryLexer.EOS&&this.backup()},N.QueryLexer.prototype.more=function(){return this.pos<this.length},N.QueryLexer.EOS="EOS",N.QueryLexer.FIELD="FIELD",N.QueryLexer.TERM="TERM",N.QueryLexer.EDIT_DISTANCE="EDIT_DISTANCE",N.QueryLexer.BOOST="BOOST",N.QueryLexer.PRESENCE="PRESENCE",N.QueryLexer.lexField=function(e){return e.backup(),e.emit(N.QueryLexer.FIELD),e.ignore(),N.QueryLexer.lexText},N.QueryLexer.lexTerm=function(e){if(e.width()>1&&(e.backup(),e.emit(N.QueryLexer.TERM)),e.ignore(),e.more())return N.QueryLexer.lexText},N.QueryLexer.lexEditDistance=function(e){return e.ignore(),e.acceptDigitRun(),e.emit(N.QueryLexer.EDIT_DISTANCE),N.QueryLexer.lexText},N.QueryLexer.lexBoost=function(e){return e.ignore(),e.acceptDigitRun(),e.emit(N.QueryLexer.BOOST),N.QueryLexer.lexText},N.QueryLexer.lexEOS=function(e){e.width()>0&&e.emit(N.QueryLexer.TERM)},N.QueryLexer.termSeparator=N.tokenizer.separator,N.QueryLexer.lexText=function(e){for(;;){var t=e.next();if(t==N.QueryLexer.EOS)return N.QueryLexer.lexEOS;if(92!=t.charCodeAt(0)){if(":"==t)return N.QueryLexer.lexField;if("~"==t)return e.backup(),e.width()>0&&e.emit(N.QueryLexer.TERM),N.QueryLexer.lexEditDistance;if("^"==t)return e.backup(),e.width()>0&&e.emit(N.QueryLexer.TERM),N.QueryLexer.lexBoost;if("+"==t&&1===e.width())return e.emit(N.QueryLexer.PRESENCE),N.QueryLexer.lexText;if("-"==t&&1===e.width())return e.emit(N.QueryLexer.PRESENCE),N.QueryLexer.lexText;if(t.match(N.QueryLexer.termSeparator))return N.QueryLexer.lexTerm}else e.escapeCharacter()}},N.QueryParser=function(e,t){this.lexer=new N.QueryLexer(e),this.query=t,this.currentClause={},this.lexemeIdx=0},N.QueryParser.prototype.parse=function(){this.lexer.run(),this.lexemes=this.lexer.lexemes;for(var e=N.QueryParser.parseClause;e;)e=e(this);return this.query},N.QueryParser.prototype.peekLexeme=function(){return this.lexemes[this.lexemeIdx]},N.QueryParser.prototype.consumeLexeme=function(){var e=this.peekLexeme();return this.lexemeIdx+=1,e},N.QueryParser.prototype.nextClause=function(){var e=this.currentClause;this.query.clause(e),this.currentClause={}},N.QueryParser.parseClause=function(e){var t=e.peekLexeme();if(null!=t)switch(t.type){case N.QueryLexer.PRESENCE:return N.QueryParser.parsePresence;case N.QueryLexer.FIELD:return N.QueryParser.parseField;case N.QueryLexer.TERM:return N.QueryParser.parseTerm;default:var n="expected either a field or a term, found "+t.type;throw t.str.length>=1&&(n+=" with value '"+t.str+"'"),new N.QueryParseError(n,t.start,t.end)}},N.QueryParser.parsePresence=function(e){var t=e.consumeLexeme();if(null!=t){switch(t.str){case"-":e.currentClause.presence=N.Query.presence.PROHIBITED;break;case"+":e.currentClause.presence=N.Query.presence.REQUIRED;break;default:var n="unrecognised presence operator'"+t.str+"'";throw new N.QueryParseError(n,t.start,t.end)}var r=e.peekLexeme();if(null==r){n="expecting term or field, found nothing";throw new N.QueryParseError(n,t.start,t.end)}switch(r.type){case N.QueryLexer.FIELD:return N.QueryParser.parseField;case N.QueryLexer.TERM:return N.QueryParser.parseTerm;default:n="expecting term or field, found '"+r.type+"'";throw new N.QueryParseError(n,r.start,r.end)}}},N.QueryParser.parseField=function(e){var t=e.consumeLexeme();if(null!=t){if(-1==e.query.allFields.indexOf(t.str)){var n=e.query.allFields.map((function(e){return"'"+e+"'"})).join(", "),r="unrecognised field '"+t.str+"', possible fields: "+n;throw new N.QueryParseError(r,t.start,t.end)}e.currentClause.fields=[t.str];var o=e.peekLexeme();if(null==o){r="expecting term, found nothing";throw new N.QueryParseError(r,t.start,t.end)}if(o.type===N.QueryLexer.TERM)return N.QueryParser.parseTerm;r="expecting term, found '"+o.type+"'";throw new N.QueryParseError(r,o.start,o.end)}},N.QueryParser.parseTerm=function(e){var t=e.consumeLexeme();if(null!=t){e.currentClause.term=t.str.toLowerCase(),-1!=t.str.indexOf("*")&&(e.currentClause.usePipeline=!1);var n=e.peekLexeme();if(null!=n)switch(n.type){case N.QueryLexer.TERM:return e.nextClause(),N.QueryParser.parseTerm;case N.QueryLexer.FIELD:return e.nextClause(),N.QueryParser.parseField;case N.QueryLexer.EDIT_DISTANCE:return N.QueryParser.parseEditDistance;case N.QueryLexer.BOOST:return N.QueryParser.parseBoost;case N.QueryLexer.PRESENCE:return e.nextClause(),N.QueryParser.parsePresence;default:var r="Unexpected lexeme type '"+n.type+"'";throw new N.QueryParseError(r,n.start,n.end)}else e.nextClause()}},N.QueryParser.parseEditDistance=function(e){var t=e.consumeLexeme();if(null!=t){var n=parseInt(t.str,10);if(isNaN(n)){var r="edit distance must be numeric";throw new N.QueryParseError(r,t.start,t.end)}e.currentClause.editDistance=n;var o=e.peekLexeme();if(null!=o)switch(o.type){case N.QueryLexer.TERM:return e.nextClause(),N.QueryParser.parseTerm;case N.QueryLexer.FIELD:return e.nextClause(),N.QueryParser.parseField;case N.QueryLexer.EDIT_DISTANCE:return N.QueryParser.parseEditDistance;case N.QueryLexer.BOOST:return N.QueryParser.parseBoost;case N.QueryLexer.PRESENCE:return e.nextClause(),N.QueryParser.parsePresence;default:r="Unexpected lexeme type '"+o.type+"'";throw new N.QueryParseError(r,o.start,o.end)}else e.nextClause()}},N.QueryParser.parseBoost=function(e){var t=e.consumeLexeme();if(null!=t){var n=parseInt(t.str,10);if(isNaN(n)){var r="boost must be numeric";throw new N.QueryParseError(r,t.start,t.end)}e.currentClause.boost=n;var o=e.peekLexeme();if(null!=o)switch(o.type){case N.QueryLexer.TERM:return e.nextClause(),N.QueryParser.parseTerm;case N.QueryLexer.FIELD:return e.nextClause(),N.QueryParser.parseField;case N.QueryLexer.EDIT_DISTANCE:return N.QueryParser.parseEditDistance;case N.QueryLexer.BOOST:return N.QueryParser.parseBoost;case N.QueryLexer.PRESENCE:return e.nextClause(),N.QueryParser.parsePresence;default:r="Unexpected lexeme type '"+o.type+"'";throw new N.QueryParseError(r,o.start,o.end)}else e.nextClause()}},void 0===(o="function"==typeof(r=function(){return N})?r.call(t,n,t,e):r)||(e.exports=o)}()},27861:(e,t,n)=>{"use strict";n.r(t),n.d(t,{default:()=>r});const r={icon:"icon_S7Kx",s:"s_AZDZ",m:"m_thRi",l:"l_WHPt",fill:"fill_hNhN",stroke:"stroke_N8dm"}},10153:(e,t,n)=>{"use strict";n.r(t),n.d(t,{default:()=>r});const r={backdrop:"backdrop_Ifvc",navWrapper:"navWrapper_ybYI",nav:"nav_cMpg",visible:"visible_ynAX",wrapper:"wrapper_SWrM",fullscreenButton:"fullscreenButton_Bocn",active:"active_qZD5"}},8633:(e,t,n)=>{"use strict";n.r(t),n.d(t,{default:()=>r});const r={toggle:"toggle_K23S",toggleButton:"toggleButton_dl49",darkToggleIcon:"darkToggleIcon_lKkA",lightToggleIcon:"lightToggleIcon_K4TL",toggleButtonDisabled:"toggleButtonDisabled_AAS_"}},79762:(e,t,n)=>{"use strict";n.r(t),n.d(t,{default:()=>r});const r={firstRow:"firstRow_ar1q",secondRow:"secondRow__ww3",backToTop:"backToTop_wDfN"}},90826:(e,t,n)=>{"use strict";n.r(t),n.d(t,{default:()=>r});const r={colorModeToggle:"colorModeToggle_GSaI",rightSection:"rightSection_CLeF",iconButtonGroup:"iconButtonGroup_ktNv"}},83244:(e,t,n)=>{"use strict";n.r(t),n.d(t,{default:()=>r});const r={dropdownNavbarItem:"dropdownNavbarItem_o23I"}},31259:(e,t,n)=>{"use strict";n.r(t),n.d(t,{default:()=>r});const r={modal:"modal_kLVz",closeButton:"closeButton_Rr0e",header:"header_QwCa"}},61699:(e,t,n)=>{"use strict";n.r(t),n.d(t,{default:()=>r});const r={root:"root_ONDG",empty:"empty_a7qb",title:"title_uwS_",item:"item_RHYF",itemTitle:"itemTitle_jtAv"}},9592:(e,t,n)=>{"use strict";n.r(t),n.d(t,{default:()=>r});const r={root:"root_xZfc",textField:"textField_af43"}},1443:(e,t,n)=>{"use strict";n.r(t),n.d(t,{default:()=>r});const r={root:"root_N57j"}},18589:(e,t,n)=>{"use strict";n.r(t),n.d(t,{default:()=>r});const r={root:"root_Ooa0",level1:"level1_fpUf",icon:"icon_sZn2",fill:"fill_fkan",stroke:"stroke_j3wH"}},86620:(e,t,n)=>{"use strict";n.r(t),n.d(t,{default:()=>r});const r={root:"root_JWD1"}},38076:(e,t,n)=>{"use strict";n.r(t),n.d(t,{default:()=>r});const r={root:"root_EFVO"}},20550:(e,t,n)=>{"use strict";n.r(t),n.d(t,{default:()=>r});const r={root:"root_ltHz",noResults:"noResults_mD2O",groups:"groups_p1lF",divider:"divider_eGUz",topBar:"topBar_Dtew"}},22473:(e,t,n)=>{"use strict";n.r(t)},11057:(e,t,n)=>{"use strict";n.r(t)},93878:(e,t,n)=>{"use strict";n.r(t)},32497:(e,t,n)=>{"use strict";n.r(t)},97087:(e,t,n)=>{"use strict";n.r(t),n.d(t,{default:()=>r});const r={navbarHideable:"navbarHideable_OoEf",navbarHidden:"navbarHidden_zoxl"}},88822:(e,t,n)=>{"use strict";n.r(t),n.d(t,{default:()=>r});const r={linkContent:"linkContent__x3v",externalLinkIcon:"externalLinkIcon_Qfue"}},36459:(e,t,n)=>{"use strict";n.r(t),n.d(t,{default:()=>r});const r={root:"root_QACb"}},97142:(e,t)=>{"use strict";t.I=function(e){e.client&&(document.head.appendChild(e.msh=document.createElement("style")),e.createRule=function(t,n){var r=t+"{}";n&&(r=n+"{"+r+"}");var o=n?e.msh.sheet:e.sh.sheet,a=o.insertRule(r,o.cssRules.length),i=(o.cssRules||o.rules)[a];if(i.index=a,n){var l=(i.cssRules||i.rules)[0];i.style=l.style,i.styleMap=l.styleMap}return i})}},52099:(e,t,n)=>{"use strict";var r=n(39662).D;t.I=function(e){if(e.client){0;var t=e.kebab;n.prototype.diff=function(e){var n,r=this.decl,o=this.rule.style;for(n in r)void 0===e[n]&&o.removeProperty(n);for(n in e)e[n]!==r[n]&&o.setProperty(t(n),e[n]);this.decl=e},n.prototype.del=function(){r(this.rule)},o.prototype.diff=function(e){var t=this.tree;for(var r in t)if(void 0===e[r]){var o=t[r];for(var a in o)o[a].del()}for(var r in e)if(void 0===t[r])for(var a in e[r]){(s=new n(a,r)).diff(e[r][a]),e[r][a]=s}else{var i=t[r],l=e[r];for(var a in i)l[a]||i[a].del();for(var a in l){var s;(s=i[a])?(s.diff(l[a]),l[a]=s):((s=new n(a,r)).diff(l[a]),l[a]=s)}}this.tree=e},e.VRule=n,e.VSheet=o}function n(t,n){this.rule=e.createRule(t,n),this.decl={}}function o(){this.tree={}}}},87749:(e,t)=>{t.z=function e(t,n,r,o){var a,i,l={},s=!1;for(a in n)"object"!=typeof(i=n[a])&&(s=!0,l[a]=i);for(a in s&&(t[o]||(t[o]={}),t[o][r]=l),n)if("object"==typeof(i=n[a]))if("@"===a[0])e(t,i,r,a);else{var u=a.indexOf("&")>-1,c=r.split(",");if(u)for(var d=0;d<c.length;d++)c[d]=a.replace(/&/g,c[d]);else for(d=0;d<c.length;d++)c[d]=c[d]+" "+a;e(t,i,c.join(","),o)}}},39662:(e,t)=>{t.D=function(e){var t=e.index,n=e.parentStyleSheet,r=n.cssRules||n.rules;for(t=Math.max(t,r.length-1);t>=0;){if(r[t]===e){n.deleteRule(t);break}t--}}},40818:(e,t)=>{"use strict";var n=/[A-Z]/g;t.U=function(e){var t=(e=e||{}).assign||Object.assign;var r=t({raw:"",pfx:"_",client:"object"==typeof window,assign:t,stringify:JSON.stringify,kebab:function(e){return e.replace(n,"-$&").toLowerCase()},decl:function(e,t){return(e=r.kebab(e))+":"+t+";"},hash:function(e){return function(e){for(var t=5381,n=e.length;n;)t=33*t^e.charCodeAt(--n);return"_"+(t>>>0).toString(36)}(r.stringify(e))},selector:function(e,t){return e+(":"===t[0]?"":" ")+t},putRaw:function(e){r.raw+=e}},e);return r.client&&(r.sh||document.head.appendChild(r.sh=document.createElement("style")),r.putRaw=function(e){var t=r.sh.sheet;try{t.insertRule(e,t.cssRules.length)}catch(n){}}),r.put=function(e,t,n){var o,a,i="",l=[];for(o in t)(a=t[o])instanceof Object&&!(a instanceof Array)?l.push(o):i+=r.decl(o,a,e,n);i&&(i=e+"{"+i+"}",r.putRaw(n?n+"{"+i+"}":i));for(var s=0;s<l.length;s++)"@"===(o=l[s])[0]&&"@font-face"!==o?r.putAt(e,t[o],o):r.put(r.selector(e,o),t[o],n)},r.putAt=r.put,r}},74865:function(e,t,n){var r,o;r=function(){var e,t,n={version:"0.2.0"},r=n.settings={minimum:.08,easing:"ease",positionUsing:"",speed:200,trickle:!0,trickleRate:.02,trickleSpeed:800,showSpinner:!0,barSelector:'[role="bar"]',spinnerSelector:'[role="spinner"]',parent:"body",template:'<div class="bar" role="bar"><div class="peg"></div></div><div class="spinner" role="spinner"><div class="spinner-icon"></div></div>'};function o(e,t,n){return e<t?t:e>n?n:e}function a(e){return 100*(-1+e)}function i(e,t,n){var o;return(o="translate3d"===r.positionUsing?{transform:"translate3d("+a(e)+"%,0,0)"}:"translate"===r.positionUsing?{transform:"translate("+a(e)+"%,0)"}:{"margin-left":a(e)+"%"}).transition="all "+t+"ms "+n,o}n.configure=function(e){var t,n;for(t in e)void 0!==(n=e[t])&&e.hasOwnProperty(t)&&(r[t]=n);return this},n.status=null,n.set=function(e){var t=n.isStarted();e=o(e,r.minimum,1),n.status=1===e?null:e;var a=n.render(!t),u=a.querySelector(r.barSelector),c=r.speed,d=r.easing;return a.offsetWidth,l((function(t){""===r.positionUsing&&(r.positionUsing=n.getPositioningCSS()),s(u,i(e,c,d)),1===e?(s(a,{transition:"none",opacity:1}),a.offsetWidth,setTimeout((function(){s(a,{transition:"all "+c+"ms linear",opacity:0}),setTimeout((function(){n.remove(),t()}),c)}),c)):setTimeout(t,c)})),this},n.isStarted=function(){return"number"==typeof n.status},n.start=function(){n.status||n.set(0);var e=function(){setTimeout((function(){n.status&&(n.trickle(),e())}),r.trickleSpeed)};return r.trickle&&e(),this},n.done=function(e){return e||n.status?n.inc(.3+.5*Math.random()).set(1):this},n.inc=function(e){var t=n.status;return t?("number"!=typeof e&&(e=(1-t)*o(Math.random()*t,.1,.95)),t=o(t+e,0,.994),n.set(t)):n.start()},n.trickle=function(){return n.inc(Math.random()*r.trickleRate)},e=0,t=0,n.promise=function(r){return r&&"resolved"!==r.state()?(0===t&&n.start(),e++,t++,r.always((function(){0==--t?(e=0,n.done()):n.set((e-t)/e)})),this):this},n.render=function(e){if(n.isRendered())return document.getElementById("nprogress");c(document.documentElement,"nprogress-busy");var t=document.createElement("div");t.id="nprogress",t.innerHTML=r.template;var o,i=t.querySelector(r.barSelector),l=e?"-100":a(n.status||0),u=document.querySelector(r.parent);return s(i,{transition:"all 0 linear",transform:"translate3d("+l+"%,0,0)"}),r.showSpinner||(o=t.querySelector(r.spinnerSelector))&&p(o),u!=document.body&&c(u,"nprogress-custom-parent"),u.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 l=function(){var e=[];function t(){var n=e.shift();n&&n(t)}return function(n){e.push(n),1==e.length&&t()}}(),s=function(){var e=["Webkit","O","Moz","ms"],t={};function n(e){return e.replace(/^-ms-/,"ms-").replace(/-([\da-z])/gi,(function(e,t){return t.toUpperCase()}))}function r(t){var n=document.body.style;if(t in n)return t;for(var r,o=e.length,a=t.charAt(0).toUpperCase()+t.slice(1);o--;)if((r=e[o]+a)in n)return r;return t}function o(e){return e=n(e),t[e]||(t[e]=r(e))}function a(e,t,n){t=o(t),e.style[t]=n}return function(e,t){var n,r,o=arguments;if(2==o.length)for(n in t)void 0!==(r=t[n])&&t.hasOwnProperty(n)&&a(e,n,r);else a(e,o[1],o[2])}}();function u(e,t){return("string"==typeof e?e:f(e)).indexOf(" "+t+" ")>=0}function c(e,t){var n=f(e),r=n+t;u(n,t)||(e.className=r.substring(1))}function d(e,t){var n,r=f(e);u(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===(o="function"==typeof r?r.call(t,n,t,e):r)||(e.exports=o)},27418:e=>{"use strict";var t=Object.getOwnPropertySymbols,n=Object.prototype.hasOwnProperty,r=Object.prototype.propertyIsEnumerable;function o(e){if(null==e)throw new TypeError("Object.assign cannot be called with null or undefined");return Object(e)}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(o){return!1}}()?Object.assign:function(e,a){for(var i,l,s=o(e),u=1;u<arguments.length;u++){for(var c in i=Object(arguments[u]))n.call(i,c)&&(s[c]=i[c]);if(t){l=t(i);for(var d=0;d<l.length;d++)r.call(i,l[d])&&(s[l[d]]=i[l[d]])}}return s}},87594:(e,t)=>{function n(e){let t,n=[];for(let r of e.split(",").map((e=>e.trim())))if(/^-?\d+$/.test(r))n.push(parseInt(r,10));else if(t=r.match(/^(-?\d+)(-|\.\.\.?|\u2025|\u2026|\u22EF)(-?\d+)$/)){let[e,r,o,a]=t;if(r&&a){r=parseInt(r),a=parseInt(a);const e=r<a?1:-1;"-"!==o&&".."!==o&&"\u2025"!==o||(a+=e);for(let t=r;t!==a;t+=e)n.push(t)}}return n}t.default=n,e.exports=n},87410:(e,t,n)=>{"use strict";n.d(t,{Z:()=>a});var r=function(){var e=/(?:^|\s)lang(?:uage)?-([\w-]+)(?=\s|$)/i,t=0,n={},r={util:{encode:function e(t){return t instanceof o?new o(t.type,e(t.content),t.alias):Array.isArray(t)?t.map(e):t.replace(/&/g,"&").replace(/</g,"<").replace(/\u00a0/g," ")},type:function(e){return Object.prototype.toString.call(e).slice(8,-1)},objId:function(e){return e.__id||Object.defineProperty(e,"__id",{value:++t}),e.__id},clone:function e(t,n){var o,a;switch(n=n||{},r.util.type(t)){case"Object":if(a=r.util.objId(t),n[a])return n[a];for(var i in o={},n[a]=o,t)t.hasOwnProperty(i)&&(o[i]=e(t[i],n));return o;case"Array":return a=r.util.objId(t),n[a]?n[a]:(o=[],n[a]=o,t.forEach((function(t,r){o[r]=e(t,n)})),o);default:return t}},getLanguage:function(t){for(;t;){var n=e.exec(t.className);if(n)return n[1].toLowerCase();t=t.parentElement}return"none"},setLanguage:function(t,n){t.className=t.className.replace(RegExp(e,"gi"),""),t.classList.add("language-"+n)},isActive:function(e,t,n){for(var r="no-"+t;e;){var o=e.classList;if(o.contains(t))return!0;if(o.contains(r))return!1;e=e.parentElement}return!!n}},languages:{plain:n,plaintext:n,text:n,txt:n,extend:function(e,t){var n=r.util.clone(r.languages[e]);for(var o in t)n[o]=t[o];return n},insertBefore:function(e,t,n,o){var a=(o=o||r.languages)[e],i={};for(var l in a)if(a.hasOwnProperty(l)){if(l==t)for(var s in n)n.hasOwnProperty(s)&&(i[s]=n[s]);n.hasOwnProperty(l)||(i[l]=a[l])}var u=o[e];return o[e]=i,r.languages.DFS(r.languages,(function(t,n){n===u&&t!=e&&(this[t]=i)})),i},DFS:function e(t,n,o,a){a=a||{};var i=r.util.objId;for(var l in t)if(t.hasOwnProperty(l)){n.call(t,l,t[l],o||l);var s=t[l],u=r.util.type(s);"Object"!==u||a[i(s)]?"Array"!==u||a[i(s)]||(a[i(s)]=!0,e(s,n,l,a)):(a[i(s)]=!0,e(s,n,null,a))}}},plugins:{},highlight:function(e,t,n){var a={code:e,grammar:t,language:n};return r.hooks.run("before-tokenize",a),a.tokens=r.tokenize(a.code,a.grammar),r.hooks.run("after-tokenize",a),o.stringify(r.util.encode(a.tokens),a.language)},tokenize:function(e,t){var n=t.rest;if(n){for(var r in n)t[r]=n[r];delete t.rest}var o=new l;return s(o,o.head,e),i(e,o,t,o.head,0),function(e){var t=[],n=e.head.next;for(;n!==e.tail;)t.push(n.value),n=n.next;return t}(o)},hooks:{all:{},add:function(e,t){var n=r.hooks.all;n[e]=n[e]||[],n[e].push(t)},run:function(e,t){var n=r.hooks.all[e];if(n&&n.length)for(var o,a=0;o=n[a++];)o(t)}},Token:o};function o(e,t,n,r){this.type=e,this.content=t,this.alias=n,this.length=0|(r||"").length}function a(e,t,n,r){e.lastIndex=t;var o=e.exec(n);if(o&&r&&o[1]){var a=o[1].length;o.index+=a,o[0]=o[0].slice(a)}return o}function i(e,t,n,l,c,d){for(var f in n)if(n.hasOwnProperty(f)&&n[f]){var p=n[f];p=Array.isArray(p)?p:[p];for(var h=0;h<p.length;++h){if(d&&d.cause==f+","+h)return;var m=p[h],g=m.inside,v=!!m.lookbehind,b=!!m.greedy,y=m.alias;if(b&&!m.pattern.global){var w=m.pattern.toString().match(/[imsuy]*$/)[0];m.pattern=RegExp(m.pattern.source,w+"g")}for(var x=m.pattern||m,_=l.next,k=c;_!==t.tail&&!(d&&k>=d.reach);k+=_.value.length,_=_.next){var E=_.value;if(t.length>e.length)return;if(!(E instanceof o)){var S,C=1;if(b){if(!(S=a(x,k,e,v))||S.index>=e.length)break;var T=S.index,O=S.index+S[0].length,D=k;for(D+=_.value.length;T>=D;)D+=(_=_.next).value.length;if(k=D-=_.value.length,_.value instanceof o)continue;for(var P=_;P!==t.tail&&(D<O||"string"==typeof P.value);P=P.next)C++,D+=P.value.length;C--,E=e.slice(k,D),S.index-=k}else if(!(S=a(x,0,E,v)))continue;T=S.index;var N=S[0],A=E.slice(0,T),I=E.slice(T+N.length),L=k+E.length;d&&L>d.reach&&(d.reach=L);var R=_.prev;if(A&&(R=s(t,R,A),k+=A.length),u(t,R,C),_=s(t,R,new o(f,g?r.tokenize(N,g):N,y,N)),I&&s(t,_,I),C>1){var j={cause:f+","+h,reach:L};i(e,t,n,_.prev,k,j),d&&j.reach>d.reach&&(d.reach=j.reach)}}}}}}function l(){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 s(e,t,n){var r=t.next,o={value:n,prev:t,next:r};return t.next=o,r.prev=o,e.length++,o}function u(e,t,n){for(var r=t.next,o=0;o<n&&r!==e.tail;o++)r=r.next;t.next=r,r.prev=t,e.length-=o}return o.stringify=function e(t,n){if("string"==typeof t)return t;if(Array.isArray(t)){var o="";return t.forEach((function(t){o+=e(t,n)})),o}var a={type:t.type,content:e(t.content,n),tag:"span",classes:["token",t.type],attributes:{},language:n},i=t.alias;i&&(Array.isArray(i)?Array.prototype.push.apply(a.classes,i):a.classes.push(i)),r.hooks.run("wrap",a);var l="";for(var s in a.attributes)l+=" "+s+'="'+(a.attributes[s]||"").replace(/"/g,""")+'"';return"<"+a.tag+' class="'+a.classes.join(" ")+'"'+l+">"+a.content+"</"+a.tag+">"},r}(),o=r;r.default=r,o.languages.markup={comment:{pattern:/<!--(?:(?!<!--)[\s\S])*?-->/,greedy:!0},prolog:{pattern:/<\?[\s\S]+?\?>/,greedy:!0},doctype:{pattern:/<!DOCTYPE(?:[^>"'[\]]|"[^"]*"|'[^']*')+(?:\[(?:[^<"'\]]|"[^"]*"|'[^']*'|<(?!!--)|<!--(?:[^-]|-(?!->))*-->)*\]\s*)?>/i,greedy:!0,inside:{"internal-subset":{pattern:/(^[^\[]*\[)[\s\S]+(?=\]>$)/,lookbehind:!0,greedy:!0,inside:null},string:{pattern:/"[^"]*"|'[^']*'/,greedy:!0},punctuation:/^<!|>$|[[\]]/,"doctype-tag":/^DOCTYPE/i,name:/[^\s<>'"]+/}},cdata:{pattern:/<!\[CDATA\[[\s\S]*?\]\]>/i,greedy:!0},tag:{pattern:/<\/?(?!\d)[^\s>\/=$<%]+(?:\s(?:\s*[^\s>\/=]+(?:\s*=\s*(?:"[^"]*"|'[^']*'|[^\s'">=]+(?=[\s>]))|(?=[\s/>])))+)?\s*\/?>/,greedy:!0,inside:{tag:{pattern:/^<\/?[^\s>\/]+/,inside:{punctuation:/^<\/?/,namespace:/^[^\s>\/:]+:/}},"special-attr":[],"attr-value":{pattern:/=\s*(?:"[^"]*"|'[^']*'|[^\s'">=]+)/,inside:{punctuation:[{pattern:/^=/,alias:"attr-equals"},/"|'/]}},punctuation:/\/?>/,"attr-name":{pattern:/[^\s>\/]+/,inside:{namespace:/^[^\s>\/:]+:/}}}},entity:[{pattern:/&[\da-z]{1,8};/i,alias:"named-entity"},/&#x?[\da-f]{1,8};/i]},o.languages.markup.tag.inside["attr-value"].inside.entity=o.languages.markup.entity,o.languages.markup.doctype.inside["internal-subset"].inside=o.languages.markup,o.hooks.add("wrap",(function(e){"entity"===e.type&&(e.attributes.title=e.content.replace(/&/,"&"))})),Object.defineProperty(o.languages.markup.tag,"addInlined",{value:function(e,t){var n={};n["language-"+t]={pattern:/(^<!\[CDATA\[)[\s\S]+?(?=\]\]>$)/i,lookbehind:!0,inside:o.languages[t]},n.cdata=/^<!\[CDATA\[|\]\]>$/i;var r={"included-cdata":{pattern:/<!\[CDATA\[[\s\S]*?\]\]>/i,inside:n}};r["language-"+t]={pattern:/[\s\S]+/,inside:o.languages[t]};var a={};a[e]={pattern:RegExp(/(<__[^>]*>)(?:<!\[CDATA\[(?:[^\]]|\](?!\]>))*\]\]>|(?!<!\[CDATA\[)[\s\S])*?(?=<\/__>)/.source.replace(/__/g,(function(){return e})),"i"),lookbehind:!0,greedy:!0,inside:r},o.languages.insertBefore("markup","cdata",a)}}),Object.defineProperty(o.languages.markup.tag,"addAttribute",{value:function(e,t){o.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:o.languages[t]},punctuation:[{pattern:/^=/,alias:"attr-equals"},/"|'/]}}}})}}),o.languages.html=o.languages.markup,o.languages.mathml=o.languages.markup,o.languages.svg=o.languages.markup,o.languages.xml=o.languages.extend("markup",{}),o.languages.ssml=o.languages.xml,o.languages.atom=o.languages.xml,o.languages.rss=o.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 o=["comment","function-name","for-or-select","assign-left","string","environment","function","keyword","builtin","boolean","file-descriptor","operator","punctuation","number"],a=r.variable[1].inside,i=0;i<o.length;i++)a[o[i]]=e.languages.bash[o[i]];e.languages.shell=e.languages.bash}(o),o.languages.clike={comment:[{pattern:/(^|[^\\])\/\*[\s\S]*?(?:\*\/|$)/,lookbehind:!0,greedy:!0},{pattern:/(^|[^\\:])\/\/.*/,lookbehind:!0,greedy:!0}],string:{pattern:/(["'])(?:\\(?:\r\n|[\s\S])|(?!\1)[^\\\r\n])*\1/,greedy:!0},"class-name":{pattern:/(\b(?:class|extends|implements|instanceof|interface|new|trait)\s+|\bcatch\s+\()[\w.\\]+/i,lookbehind:!0,inside:{punctuation:/[.\\]/}},keyword:/\b(?:break|catch|continue|do|else|finally|for|function|if|in|instanceof|new|null|return|throw|try|while)\b/,boolean:/\b(?:false|true)\b/,function:/\b\w+(?=\()/,number:/\b0x[\da-f]+\b|(?:\b\d+(?:\.\d*)?|\B\.\d+)(?:e[+-]?\d+)?/i,operator:/[<>]=?|[!=]=?=?|--?|\+\+?|&&?|\|\|?|[?*/~^%]/,punctuation:/[{}[\];(),.:]/},o.languages.c=o.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|[?:~]|[-+*/%&|^!=<>]=?/}),o.languages.insertBefore("c","string",{char:{pattern:/'(?:\\(?:\r\n|[\s\S])|[^'\\\r\n]){0,32}'/,greedy:!0}}),o.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},o.languages.c.string],char:o.languages.c.char,comment:o.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:o.languages.c}}}}),o.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 o.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(?!<keyword>)\w+(?:\s*\.\s*\w+)*\b/.source.replace(/<keyword>/g,(function(){return t.source}));e.languages.cpp=e.languages.extend("c",{"class-name":[{pattern:RegExp(/(\b(?:class|concept|enum|struct|typename)\s+)(?!<keyword>)\w+/.source.replace(/<keyword>/g,(function(){return t.source}))),lookbehind:!0},/\b[A-Z]\w*(?=\s*::\s*\w+\s*\()/,/\b[A-Z_]\w*(?=\s*::\s*~\w+\s*\()/i,/\b\w+(?=\s*<(?:[^<>]|<(?:[^<>]|<[^<>]*>)*>)*>\s*::\s*\w+\s*\()/],keyword:t,number:{pattern:/(?:\b0b[01']+|\b0x(?:[\da-f']+(?:\.[\da-f']*)?|\.[\da-f']+)(?:p[+-]?[\d']+)?|(?:\b[\d']+(?:\.[\d']*)?|\B\.[\d']+)(?:e[+-]?[\d']+)?)[ful]{0,4}/i,greedy:!0},operator:/>>=?|<<=?|->|--|\+\+|&&|\|\||[?:~]|<=>|[-+*/%&|^!=<>]=?|\b(?:and|and_eq|bitand|bitor|not|not_eq|or|or_eq|xor|xor_eq)\b/,boolean:/\b(?:false|true)\b/}),e.languages.insertBefore("cpp","string",{module:{pattern:RegExp(/(\b(?:import|module)\s+)/.source+"(?:"+/"(?:\\(?:\r\n|[\s\S])|[^"\\\r\n])*"|<[^<>\r\n]*>/.source+"|"+/<mod-name>(?:\s*:\s*<mod-name>)?|:\s*<mod-name>/.source.replace(/<mod-name>/g,(function(){return n}))+")"),lookbehind:!0,greedy:!0,inside:{string:/^[<"][\s\S]+/,operator:/:/,punctuation:/\./}},"raw-string":{pattern:/R"([^()\\ ]{0,16})\([\s\S]*?\)\1"/,alias:"string",greedy:!0}}),e.languages.insertBefore("cpp","keyword",{"generic-function":{pattern:/\b(?!operator\b)[a-z_]\w*\s*<(?:[^<>]|<[^<>]*>)*>(?=\s*\()/i,inside:{function:/^\w+/,generic:{pattern:/<[\s\S]+/,alias:"class-name",inside:e.languages.cpp}}}}),e.languages.insertBefore("cpp","operator",{"double-colon":{pattern:/::/,alias:"punctuation"}}),e.languages.insertBefore("cpp","class-name",{"base-clause":{pattern:/(\b(?:class|struct)\s+\w+\s*:\s*)[^;{}"'\s]+(?:\s+[^;{}"'\s]+)*(?=\s*[;{])/,lookbehind:!0,greedy:!0,inside:e.languages.extend("cpp",{})}}),e.languages.insertBefore("inside","double-colon",{"class-name":/\b[a-z_]\w*\b(?!\s*::)/i},e.languages.cpp["base-clause"])}(o),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"))}(o),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},o={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:o,function:/[\w-]+(?=\()/,punctuation:/[(),]/}}],entity:/\\[\da-f]{1,8}/i,unit:r,number:o})}(o),o.languages.javascript=o.languages.extend("clike",{"class-name":[o.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}|\?\?=?|\?\.?|[~:]/}),o.languages.javascript["class-name"][0].pattern=/(\b(?:class|extends|implements|instanceof|interface|new)\s+)[\w.\\]+/,o.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:o.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:o.languages.javascript},{pattern:/(^|[^$\w\xA0-\uFFFF])(?!\s)[_$a-z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\s*=>)/i,lookbehind:!0,inside:o.languages.javascript},{pattern:/(\(\s*)(?!\s)(?:[^()\s]|\s+(?![\s)])|\([^()]*\))+(?=\s*\)\s*=>)/,lookbehind:!0,inside:o.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:o.languages.javascript}],constant:/\b[A-Z](?:[A-Z_]|\dx?)*\b/}),o.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:o.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"}}),o.languages.insertBefore("javascript","operator",{"literal-property":{pattern:/((?:^|[,{])[ \t]*)(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\s*:)/m,lookbehind:!0,alias:"property"}}),o.languages.markup&&(o.languages.markup.tag.addInlined("script","javascript"),o.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")),o.languages.js=o.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}(o),function(e){var t=/[*&][^\s[\]{},]+/,n=/!(?:<[\w\-%#;/?:@&=+$,.!~*'()[\]]+>|(?:[a-zA-Z\d-]*!)?[\w\-%#;/?:@&=+$.~*'()]+)?/,r="(?:"+n.source+"(?:[ \t]+"+t.source+")?|"+t.source+"(?:[ \t]+"+n.source+")?)",o=/(?:[^\s\x00-\x08\x0e-\x1f!"#%&'*,\-:>?@[\]`{|}\x7f-\x84\x86-\x9f\ud800-\udfff\ufffe\uffff]|[?:-]<PLAIN>)(?:[ \t]*(?:(?![#:])<PLAIN>|:<PLAIN>))*/.source.replace(/<PLAIN>/g,(function(){return/[^\s\x00-\x08\x0e-\x1f,[\]{}\x7f-\x84\x86-\x9f\ud800-\udfff\ufffe\uffff]/.source})),a=/"(?:[^"\\\r\n]|\\.)*"|'(?:[^'\\\r\n]|\\.)*'/.source;function i(e,t){t=(t||"").replace(/m/g,"")+"m";var n=/([:\-,[{]\s*(?:\s<<prop>>[ \t]+)?)(?:<<value>>)(?=[ \t]*(?:$|,|\]|\}|(?:[\r\n]\s*)?#))/.source.replace(/<<prop>>/g,(function(){return r})).replace(/<<value>>/g,(function(){return e}));return RegExp(n,t)}e.languages.yaml={scalar:{pattern:RegExp(/([\-:]\s*(?:\s<<prop>>[ \t]+)?[|>])[ \t]*(?:((?:\r?\n|\r)[ \t]+)\S[^\r\n]*(?:\2[^\r\n]+)*)/.source.replace(/<<prop>>/g,(function(){return r}))),lookbehind:!0,alias:"string"},comment:/#.*/,key:{pattern:RegExp(/((?:^|[:\-,[{\r\n?])[ \t]*(?:<<prop>>[ \t]+)?)<<key>>(?=\s*:\s)/.source.replace(/<<prop>>/g,(function(){return r})).replace(/<<key>>/g,(function(){return"(?:"+o+"|"+a+")"}))),lookbehind:!0,greedy:!0,alias:"atrule"},directive:{pattern:/(^[ \t]*)%.+/m,lookbehind:!0,alias:"important"},datetime:{pattern:i(/\d{4}-\d\d?-\d\d?(?:[tT]|[ \t]+)\d\d?:\d{2}:\d{2}(?:\.\d*)?(?:[ \t]*(?:Z|[-+]\d\d?(?::\d{2})?))?|\d{4}-\d{2}-\d{2}|\d\d?:\d{2}(?::\d{2}(?:\.\d*)?)?/.source),lookbehind:!0,alias:"number"},boolean:{pattern:i(/false|true/.source,"i"),lookbehind:!0,alias:"important"},null:{pattern:i(/null|~/.source,"i"),lookbehind:!0,alias:"important"},string:{pattern:i(a),lookbehind:!0,greedy:!0},number:{pattern:i(/[+-]?(?:0x[\da-f]+|0o[0-7]+|(?:\d+(?:\.\d*)?|\.\d+)(?:e[+-]?\d+)?|\.inf|\.nan)/.source,"i"),lookbehind:!0},tag:n,important:t,punctuation:/---|[:[\]{}\-,|>?]|\.\.\./},e.languages.yml=e.languages.yaml}(o),function(e){var t=/(?:\\.|[^\\\n\r]|(?:\n|\r\n?)(?![\r\n]))/.source;function n(e){return e=e.replace(/<inner>/g,(function(){return t})),RegExp(/((?:^|[^\\])(?:\\{2})*)/.source+"(?:"+e+")")}var r=/(?:\\.|``(?:[^`\r\n]|`(?!`))+``|`[^`\r\n]+`|[^\\|\r\n`])+/.source,o=/\|?__(?:\|__)+\|?(?:(?:\n|\r\n?)|(?![\s\S]))/.source.replace(/__/g,(function(){return r})),a=/\|?[ \t]*:?-{3,}:?[ \t]*(?:\|[ \t]*:?-{3,}:?[ \t]*)+\|?(?:\n|\r\n?)/.source;e.languages.markdown=e.languages.extend("markup",{}),e.languages.insertBefore("markdown","prolog",{"front-matter-block":{pattern:/(^(?:\s*[\r\n])?)---(?!.)[\s\S]*?[\r\n]---(?!.)/,lookbehind:!0,greedy:!0,inside:{punctuation:/^---|---$/,"front-matter":{pattern:/\S+(?:\s+\S+)*/,alias:["yaml","language-yaml"],inside:e.languages.yaml}}},blockquote:{pattern:/^>(?:[\t ]*>)*/m,alias:"punctuation"},table:{pattern:RegExp("^"+o+a+"(?:"+o+")*","m"),inside:{"table-data-rows":{pattern:RegExp("^("+o+a+")(?:"+o+")*$"),lookbehind:!0,inside:{"table-data":{pattern:RegExp(r),inside:e.languages.markdown},punctuation:/\|/}},"table-line":{pattern:RegExp("^("+o+")"+a+"$"),lookbehind:!0,inside:{punctuation:/\||:?-{3,}:?/}},"table-header-row":{pattern:RegExp("^"+o+"$"),inside:{"table-header":{pattern:RegExp(r),alias:"important",inside:e.languages.markdown},punctuation:/\|/}}}},code:[{pattern:/((?:^|\n)[ \t]*\n|(?:^|\r\n?)[ \t]*\r\n?)(?: {4}|\t).+(?:(?:\n|\r\n?)(?: {4}|\t).+)*/,lookbehind:!0,alias:"keyword"},{pattern:/^```[\s\S]*?^```$/m,greedy:!0,inside:{"code-block":{pattern:/^(```.*(?:\n|\r\n?))[\s\S]+?(?=(?:\n|\r\n?)^```$)/m,lookbehind:!0},"code-language":{pattern:/^(```).+/,lookbehind:!0},punctuation:/```/}}],title:[{pattern:/\S.*(?:\n|\r\n?)(?:==+|--+)(?=[ \t]*$)/m,alias:"important",inside:{punctuation:/==+$|--+$/}},{pattern:/(^\s*)#.+/m,lookbehind:!0,alias:"important",inside:{punctuation:/^#+|#+$/}}],hr:{pattern:/(^\s*)([*-])(?:[\t ]*\2){2,}(?=\s*$)/m,lookbehind:!0,alias:"punctuation"},list:{pattern:/(^\s*)(?:[*+-]|\d+\.)(?=[\t ].)/m,lookbehind:!0,alias:"punctuation"},"url-reference":{pattern:/!?\[[^\]]+\]:[\t ]+(?:\S+|<(?:\\.|[^>\\])+>)(?:[\t ]+(?:"(?:\\.|[^"\\])*"|'(?:\\.|[^'\\])*'|\((?:\\.|[^)\\])*\)))?/,inside:{variable:{pattern:/^(!?\[)[^\]]+/,lookbehind:!0},string:/(?:"(?:\\.|[^"\\])*"|'(?:\\.|[^'\\])*'|\((?:\\.|[^)\\])*\))$/,punctuation:/^[\[\]!:]|[<>]/},alias:"url"},bold:{pattern:n(/\b__(?:(?!_)<inner>|_(?:(?!_)<inner>)+_)+__\b|\*\*(?:(?!\*)<inner>|\*(?:(?!\*)<inner>)+\*)+\*\*/.source),lookbehind:!0,greedy:!0,inside:{content:{pattern:/(^..)[\s\S]+(?=..$)/,lookbehind:!0,inside:{}},punctuation:/\*\*|__/}},italic:{pattern:n(/\b_(?:(?!_)<inner>|__(?:(?!_)<inner>)+__)+_\b|\*(?:(?!\*)<inner>|\*\*(?:(?!\*)<inner>)+\*\*)+\*/.source),lookbehind:!0,greedy:!0,inside:{content:{pattern:/(^.)[\s\S]+(?=.$)/,lookbehind:!0,inside:{}},punctuation:/[*_]/}},strike:{pattern:n(/(~~?)(?:(?!~)<inner>)+\2/.source),lookbehind:!0,greedy:!0,inside:{content:{pattern:/(^~~?)[\s\S]+(?=\1$)/,lookbehind:!0,inside:{}},punctuation:/~~?/}},"code-snippet":{pattern:/(^|[^\\`])(?:``[^`\r\n]+(?:`[^`\r\n]+)*``(?!`)|`[^`\r\n]+`(?!`))/,lookbehind:!0,greedy:!0,alias:["code","keyword"]},url:{pattern:n(/!?\[(?:(?!\])<inner>)+\](?:\([^\s)]+(?:[\t ]+"(?:\\.|[^"\\])*")?\)|[ \t]?\[(?:(?!\])<inner>)+\])/.source),lookbehind:!0,greedy:!0,inside:{operator:/^!/,content:{pattern:/(^\[)[^\]]+(?=\])/,lookbehind:!0,inside:{}},variable:{pattern:/(^\][ \t]?\[)[^\]]+(?=\]$)/,lookbehind:!0},url:{pattern:/(^\]\()[^\s)]+/,lookbehind:!0},string:{pattern:/(^[ \t]+)"(?:\\.|[^"\\])*"(?=\)$)/,lookbehind:!0}}}}),["url","bold","italic","strike"].forEach((function(t){["url","bold","italic","strike","code-snippet"].forEach((function(n){t!==n&&(e.languages.markdown[t].inside.content.inside[n]=e.languages.markdown[n])}))})),e.hooks.add("after-tokenize",(function(e){"markdown"!==e.language&&"md"!==e.language||function e(t){if(t&&"string"!=typeof t)for(var n=0,r=t.length;n<r;n++){var o=t[n];if("code"===o.type){var a=o.content[1],i=o.content[3];if(a&&i&&"code-language"===a.type&&"code-block"===i.type&&"string"==typeof a.content){var l=a.content.replace(/\b#/g,"sharp").replace(/\b\+\+/g,"pp"),s="language-"+(l=(/[a-z][\w-]*/i.exec(l)||[""])[0].toLowerCase());i.alias?"string"==typeof i.alias?i.alias=[i.alias,s]:i.alias.push(s):i.alias=[s]}}else e(o.content)}}(e.tokens)})),e.hooks.add("wrap",(function(t){if("code-block"===t.type){for(var n="",r=0,o=t.classes.length;r<o;r++){var a=t.classes[r],u=/language-(.+)/.exec(a);if(u){n=u[1];break}}var c,d=e.languages[n];if(d)t.content=e.highlight((c=t.content,c.replace(i,"").replace(/&(\w{1,8}|#x?[\da-f]{1,8});/gi,(function(e,t){var n;if("#"===(t=t.toLowerCase())[0])return n="x"===t[1]?parseInt(t.slice(2),16):Number(t.slice(1)),s(n);var r=l[t];return r||e}))),d,n);else if(n&&"none"!==n&&e.plugins.autoloader){var f="md-"+(new Date).valueOf()+"-"+Math.floor(1e16*Math.random());t.attributes.id=f,e.plugins.autoloader.loadLanguages(n,(function(){var t=document.getElementById(f);t&&(t.innerHTML=e.highlight(t.textContent,e.languages[n],n))}))}}}));var i=RegExp(e.languages.markup.tag.pattern.source,"gi"),l={amp:"&",lt:"<",gt:">",quot:'"'},s=String.fromCodePoint||String.fromCharCode;e.languages.md=e.languages.markdown}(o),o.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:o.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+/},o.hooks.add("after-tokenize",(function(e){if("graphql"===e.language)for(var t=e.tokens.filter((function(e){return"string"!=typeof e&&"comment"!==e.type&&"scalar"!==e.type})),n=0;n<t.length;){var r=t[n++];if("keyword"===r.type&&"mutation"===r.content){var o=[];if(d(["definition-mutation","punctuation"])&&"("===c(1).content){n+=2;var a=f(/^\($/,/^\)$/);if(-1===a)continue;for(;n<a;n++){var i=c(0);"variable"===i.type&&(p(i,"variable-input"),o.push(i.content))}n=a+1}if(d(["punctuation","property-query"])&&"{"===c(0).content&&(n++,p(c(0),"property-mutation"),o.length>0)){var l=f(/^\{$/,/^\}$/);if(-1===l)continue;for(var s=n;s<l;s++){var u=t[s];"variable"===u.type&&o.indexOf(u.content)>=0&&p(u,"variable-input")}}}}function c(e){return t[n+e]}function d(e,t){t=t||0;for(var n=0;n<e.length;n++){var r=c(n+t);if(!r||r.type!==e[n])return!1}return!0}function f(e,r){for(var o=1,a=n;a<t.length;a++){var i=t[a],l=i.content;if("punctuation"===i.type&&"string"==typeof l)if(e.test(l))o++;else if(r.test(l)&&0===--o)return a}return-1}function p(e,t){var n=e.alias;n?Array.isArray(n)||(e.alias=n=[n]):e.alias=n=[],n.push(t)}})),o.languages.sql={comment:{pattern:/(^|[^\\])(?:\/\*[\s\S]*?\*\/|(?:--|\/\/|#).*)/,lookbehind:!0},variable:[{pattern:/@(["'`])(?:\\[\s\S]|(?!\1)[^\\])+\1/,greedy:!0},/@[\w.$]+/],string:{pattern:/(^|[^@\\])("|')(?:\\[\s\S]|(?!\2)[^\\]|\2\2)*\2/,greedy:!0,lookbehind:!0},identifier:{pattern:/(^|[^@\\])`(?:\\[\s\S]|[^`\\]|``)*`/,greedy:!0,lookbehind:!0,inside:{punctuation:/^`|`$/}},function:/\b(?:AVG|COUNT|FIRST|FORMAT|LAST|LCASE|LEN|MAX|MID|MIN|MOD|NOW|ROUND|SUM|UCASE)(?=\s*\()/i,keyword:/\b(?:ACTION|ADD|AFTER|ALGORITHM|ALL|ALTER|ANALYZE|ANY|APPLY|AS|ASC|AUTHORIZATION|AUTO_INCREMENT|BACKUP|BDB|BEGIN|BERKELEYDB|BIGINT|BINARY|BIT|BLOB|BOOL|BOOLEAN|BREAK|BROWSE|BTREE|BULK|BY|CALL|CASCADED?|CASE|CHAIN|CHAR(?:ACTER|SET)?|CHECK(?:POINT)?|CLOSE|CLUSTERED|COALESCE|COLLATE|COLUMNS?|COMMENT|COMMIT(?:TED)?|COMPUTE|CONNECT|CONSISTENT|CONSTRAINT|CONTAINS(?:TABLE)?|CONTINUE|CONVERT|CREATE|CROSS|CURRENT(?:_DATE|_TIME|_TIMESTAMP|_USER)?|CURSOR|CYCLE|DATA(?:BASES?)?|DATE(?:TIME)?|DAY|DBCC|DEALLOCATE|DEC|DECIMAL|DECLARE|DEFAULT|DEFINER|DELAYED|DELETE|DELIMITERS?|DENY|DESC|DESCRIBE|DETERMINISTIC|DISABLE|DISCARD|DISK|DISTINCT|DISTINCTROW|DISTRIBUTED|DO|DOUBLE|DROP|DUMMY|DUMP(?:FILE)?|DUPLICATE|ELSE(?:IF)?|ENABLE|ENCLOSED|END|ENGINE|ENUM|ERRLVL|ERRORS|ESCAPED?|EXCEPT|EXEC(?:UTE)?|EXISTS|EXIT|EXPLAIN|EXTENDED|FETCH|FIELDS|FILE|FILLFACTOR|FIRST|FIXED|FLOAT|FOLLOWING|FOR(?: EACH ROW)?|FORCE|FOREIGN|FREETEXT(?:TABLE)?|FROM|FULL|FUNCTION|GEOMETRY(?:COLLECTION)?|GLOBAL|GOTO|GRANT|GROUP|HANDLER|HASH|HAVING|HOLDLOCK|HOUR|IDENTITY(?:COL|_INSERT)?|IF|IGNORE|IMPORT|INDEX|INFILE|INNER|INNODB|INOUT|INSERT|INT|INTEGER|INTERSECT|INTERVAL|INTO|INVOKER|ISOLATION|ITERATE|JOIN|KEYS?|KILL|LANGUAGE|LAST|LEAVE|LEFT|LEVEL|LIMIT|LINENO|LINES|LINESTRING|LOAD|LOCAL|LOCK|LONG(?:BLOB|TEXT)|LOOP|MATCH(?:ED)?|MEDIUM(?:BLOB|INT|TEXT)|MERGE|MIDDLEINT|MINUTE|MODE|MODIFIES|MODIFY|MONTH|MULTI(?:LINESTRING|POINT|POLYGON)|NATIONAL|NATURAL|NCHAR|NEXT|NO|NONCLUSTERED|NULLIF|NUMERIC|OFF?|OFFSETS?|ON|OPEN(?:DATASOURCE|QUERY|ROWSET)?|OPTIMIZE|OPTION(?:ALLY)?|ORDER|OUT(?:ER|FILE)?|OVER|PARTIAL|PARTITION|PERCENT|PIVOT|PLAN|POINT|POLYGON|PRECEDING|PRECISION|PREPARE|PREV|PRIMARY|PRINT|PRIVILEGES|PROC(?:EDURE)?|PUBLIC|PURGE|QUICK|RAISERROR|READS?|REAL|RECONFIGURE|REFERENCES|RELEASE|RENAME|REPEAT(?:ABLE)?|REPLACE|REPLICATION|REQUIRE|RESIGNAL|RESTORE|RESTRICT|RETURN(?:ING|S)?|REVOKE|RIGHT|ROLLBACK|ROUTINE|ROW(?:COUNT|GUIDCOL|S)?|RTREE|RULE|SAVE(?:POINT)?|SCHEMA|SECOND|SELECT|SERIAL(?:IZABLE)?|SESSION(?:_USER)?|SET(?:USER)?|SHARE|SHOW|SHUTDOWN|SIMPLE|SMALLINT|SNAPSHOT|SOME|SONAME|SQL|START(?:ING)?|STATISTICS|STATUS|STRIPED|SYSTEM_USER|TABLES?|TABLESPACE|TEMP(?:ORARY|TABLE)?|TERMINATED|TEXT(?:SIZE)?|THEN|TIME(?:STAMP)?|TINY(?:BLOB|INT|TEXT)|TOP?|TRAN(?:SACTIONS?)?|TRIGGER|TRUNCATE|TSEQUAL|TYPES?|UNBOUNDED|UNCOMMITTED|UNDEFINED|UNION|UNIQUE|UNLOCK|UNPIVOT|UNSIGNED|UPDATE(?:TEXT)?|USAGE|USE|USER|USING|VALUES?|VAR(?:BINARY|CHAR|CHARACTER|YING)|VIEW|WAITFOR|WARNINGS|WHEN|WHERE|WHILE|WITH(?: ROLLUP|IN)?|WORK|WRITE(?:TEXT)?|YEAR)\b/i,boolean:/\b(?:FALSE|NULL|TRUE)\b/i,number:/\b0x[\da-f]+\b|\b\d+(?:\.\d*)?|\B\.\d+\b/i,operator:/[-+*\/=%^~]|&&?|\|\|?|!=?|<(?:=>?|<|>)?|>[>=]?|\b(?:AND|BETWEEN|DIV|ILIKE|IN|IS|LIKE|NOT|OR|REGEXP|RLIKE|SOUNDS LIKE|XOR)\b/i,punctuation:/[;[\]()`,.]/},function(e){var t=e.languages.javascript["template-string"],n=t.pattern.source,r=t.inside.interpolation,o=r.inside["interpolation-punctuation"],a=r.pattern.source;function i(t,r){if(e.languages[t])return{pattern:RegExp("((?:"+r+")\\s*)"+n),lookbehind:!0,greedy:!0,inside:{"template-punctuation":{pattern:/^`|`$/,alias:"string"},"embedded-code":{pattern:/[\s\S]+/,alias:t}}}}function l(e,t){return"___"+t.toUpperCase()+"_"+e+"___"}function s(t,n,r){var o={code:t,grammar:n,language:r};return e.hooks.run("before-tokenize",o),o.tokens=e.tokenize(o.code,o.grammar),e.hooks.run("after-tokenize",o),o.tokens}function u(t){var n={};n["interpolation-punctuation"]=o;var a=e.tokenize(t,n);if(3===a.length){var i=[1,1];i.push.apply(i,s(a[1],e.languages.javascript,"javascript")),a.splice.apply(a,i)}return new e.Token("interpolation",a,r.alias,t)}function c(t,n,r){var o=e.tokenize(t,{interpolation:{pattern:RegExp(a),lookbehind:!0}}),i=0,c={},d=s(o.map((function(e){if("string"==typeof e)return e;for(var n,o=e.content;-1!==t.indexOf(n=l(i++,r)););return c[n]=o,n})).join(""),n,r),f=Object.keys(c);return i=0,function e(t){for(var n=0;n<t.length;n++){if(i>=f.length)return;var r=t[n];if("string"==typeof r||"string"==typeof r.content){var o=f[i],a="string"==typeof r?r:r.content,l=a.indexOf(o);if(-1!==l){++i;var s=a.substring(0,l),d=u(c[o]),p=a.substring(l+o.length),h=[];if(s&&h.push(s),h.push(d),p){var m=[p];e(m),h.push.apply(h,m)}"string"==typeof r?(t.splice.apply(t,[n,1].concat(h)),n+=h.length-1):r.content=h}}else{var g=r.content;Array.isArray(g)?e(g):e([g])}}}(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,o=n.length;r<o;r++){var a=n[r];if("string"!=typeof a){var i=a.content;if(Array.isArray(i))if("template-string"===a.type){var l=i[1];if(3===i.length&&"string"!=typeof l&&"embedded-code"===l.type){var s=f(l),u=l.alias,d=Array.isArray(u)?u[0]:u,p=e.languages[d];if(!p)continue;i[1]=c(s,p,d)}}else t(i);else"string"!=typeof i&&t([i])}}}(t.tokens)}))}(o),function(e){e.languages.typescript=e.languages.extend("javascript",{"class-name":{pattern:/(\b(?:class|extends|implements|instanceof|interface|new|type)\s+)(?!keyof\b)(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?:\s*<(?:[^<>]|<(?:[^<>]|<[^<>]*>)*>)*>)?/,lookbehind:!0,greedy:!0,inside:null},builtin:/\b(?:Array|Function|Promise|any|boolean|console|never|number|string|symbol|unknown)\b/}),e.languages.typescript.keyword.push(/\b(?:abstract|declare|is|keyof|readonly|require)\b/,/\b(?:asserts|infer|interface|module|namespace|type)\b(?=\s*(?:[{_$a-zA-Z\xA0-\uFFFF]|$))/,/\btype\b(?=\s*(?:[\{*]|$))/),delete e.languages.typescript.parameter,delete e.languages.typescript["literal-property"];var t=e.languages.extend("typescript",{});delete t["class-name"],e.languages.typescript["class-name"].inside=t,e.languages.insertBefore("typescript","function",{decorator:{pattern:/@[$\w\xA0-\uFFFF]+/,inside:{at:{pattern:/^@/,alias:"operator"},function:/^[\s\S]+/}},"generic-function":{pattern:/#?(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*\s*<(?:[^<>]|<(?:[^<>]|<[^<>]*>)*>)*>(?=\s*\()/,greedy:!0,inside:{function:/^#?(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*/,generic:{pattern:/<[\s\S]+/,alias:"class-name",inside:t}}}}),e.languages.ts=e.languages.typescript}(o),function(e){function t(e,t){return RegExp(e.replace(/<ID>/g,(function(){return/(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*/.source})),t)}e.languages.insertBefore("javascript","function-variable",{"method-variable":{pattern:RegExp("(\\.\\s*)"+e.languages.javascript["function-variable"].pattern.source),lookbehind:!0,alias:["function-variable","method","function","property-access"]}}),e.languages.insertBefore("javascript","function",{method:{pattern:RegExp("(\\.\\s*)"+e.languages.javascript.function.source),lookbehind:!0,alias:["function","property-access"]}}),e.languages.insertBefore("javascript","constant",{"known-class-name":[{pattern:/\b(?:(?:Float(?:32|64)|(?:Int|Uint)(?:8|16|32)|Uint8Clamped)?Array|ArrayBuffer|BigInt|Boolean|DataView|Date|Error|Function|Intl|JSON|(?:Weak)?(?:Map|Set)|Math|Number|Object|Promise|Proxy|Reflect|RegExp|String|Symbol|WebAssembly)\b/,alias:"class-name"},{pattern:/\b(?:[A-Z]\w*)Error\b/,alias:"class-name"}]}),e.languages.insertBefore("javascript","keyword",{imports:{pattern:t(/(\bimport\b\s*)(?:<ID>(?:\s*,\s*(?:\*\s*as\s+<ID>|\{[^{}]*\}))?|\*\s*as\s+<ID>|\{[^{}]*\})(?=\s*\bfrom\b)/.source),lookbehind:!0,inside:e.languages.javascript},exports:{pattern:t(/(\bexport\b\s*)(?:\*(?:\s*as\s+<ID>)?(?=\s*\bfrom\b)|\{[^{}]*\})/.source),lookbehind:!0,inside:e.languages.javascript}}),e.languages.javascript.keyword.unshift({pattern:/\b(?:as|default|export|from|import)\b/,alias:"module"},{pattern:/\b(?:await|break|catch|continue|do|else|finally|for|if|return|switch|throw|try|while|yield)\b/,alias:"control-flow"},{pattern:/\bnull\b/,alias:["null","nil"]},{pattern:/\bundefined\b/,alias:"nil"}),e.languages.insertBefore("javascript","operator",{spread:{pattern:/\.{3}/,alias:"operator"},arrow:{pattern:/=>/,alias:"operator"}}),e.languages.insertBefore("javascript","punctuation",{"property-access":{pattern:t(/(\.\s*)#?<ID>/.source),lookbehind:!0},"maybe-class-name":{pattern:/(^|[^$\w\xA0-\uFFFF])[A-Z][$\w\xA0-\uFFFF]+/,lookbehind:!0},dom:{pattern:/\b(?:document|(?:local|session)Storage|location|navigator|performance|window)\b/,alias:"variable"},console:{pattern:/\bconsole(?=\s*\.)/,alias:"class-name"}});for(var n=["function","function-variable","method","method-variable","property-access"],r=0;r<n.length;r++){var o=n[r],a=e.languages.javascript[o];"RegExp"===e.util.type(a)&&(a=e.languages.javascript[o]={pattern:a});var i=a.inside||{};a.inside=i,i["maybe-class-name"]=/^[A-Z][\s\S]*/}}(o),function(e){var t=e.util.clone(e.languages.javascript),n=/(?:\s|\/\/.*(?!.)|\/\*(?:[^*]|\*(?!\/))\*\/)/.source,r=/(?:\{(?:\{(?:\{[^{}]*\}|[^{}])*\}|[^{}])*\})/.source,o=/(?:\{<S>*\.{3}(?:[^{}]|<BRACES>)*\})/.source;function a(e,t){return e=e.replace(/<S>/g,(function(){return n})).replace(/<BRACES>/g,(function(){return r})).replace(/<SPREAD>/g,(function(){return o})),RegExp(e,t)}o=a(o).source,e.languages.jsx=e.languages.extend("markup",t),e.languages.jsx.tag.pattern=a(/<\/?(?:[\w.:-]+(?:<S>+(?:[\w.:$-]+(?:=(?:"(?:\\[\s\S]|[^\\"])*"|'(?:\\[\s\S]|[^\\'])*'|[^\s{'"/>=]+|<BRACES>))?|<SPREAD>))*<S>*\/?)?>/.source),e.languages.jsx.tag.inside.tag.pattern=/^<\/?[^\s>\/]*/,e.languages.jsx.tag.inside["attr-value"].pattern=/=(?!\{)(?:"(?:\\[\s\S]|[^\\"])*"|'(?:\\[\s\S]|[^\\'])*'|[^\s'">]+)/,e.languages.jsx.tag.inside.tag.inside["class-name"]=/^[A-Z]\w*(?:\.[A-Z]\w*)*$/,e.languages.jsx.tag.inside.comment=t.comment,e.languages.insertBefore("inside","attr-name",{spread:{pattern:a(/<SPREAD>/.source),inside:e.languages.jsx}},e.languages.jsx.tag),e.languages.insertBefore("inside","special-attr",{script:{pattern:a(/=<BRACES>/.source),alias:"language-javascript",inside:{"script-punctuation":{pattern:/^=(?=\{)/,alias:"punctuation"},rest:e.languages.jsx}}},e.languages.jsx.tag);var i=function(e){return e?"string"==typeof e?e:"string"==typeof e.content?e.content:e.content.map(i).join(""):""},l=function(t){for(var n=[],r=0;r<t.length;r++){var o=t[r],a=!1;if("string"!=typeof o&&("tag"===o.type&&o.content[0]&&"tag"===o.content[0].type?"</"===o.content[0].content[0].content?n.length>0&&n[n.length-1].tagName===i(o.content[0].content[1])&&n.pop():"/>"===o.content[o.content.length-1].content||n.push({tagName:i(o.content[0].content[1]),openedBraces:0}):n.length>0&&"punctuation"===o.type&&"{"===o.content?n[n.length-1].openedBraces++:n.length>0&&n[n.length-1].openedBraces>0&&"punctuation"===o.type&&"}"===o.content?n[n.length-1].openedBraces--:a=!0),(a||"string"==typeof o)&&n.length>0&&0===n[n.length-1].openedBraces){var s=i(o);r<t.length-1&&("string"==typeof t[r+1]||"plain-text"===t[r+1].type)&&(s+=i(t[r+1]),t.splice(r+1,1)),r>0&&("string"==typeof t[r-1]||"plain-text"===t[r-1].type)&&(s=i(t[r-1])+s,t.splice(r-1,1),r--),t[r]=new e.Token("plain-text",s,null,s)}o.content&&"string"!=typeof o.content&&l(o.content)}};e.hooks.add("after-tokenize",(function(e){"jsx"!==e.language&&"tsx"!==e.language||l(e.tokens)}))}(o),function(e){e.languages.diff={coord:[/^(?:\*{3}|-{3}|\+{3}).*$/m,/^@@.*@@$/m,/^\d.*$/m]};var t={"deleted-sign":"-","deleted-arrow":"<","inserted-sign":"+","inserted-arrow":">",unchanged:" ",diff:"!"};Object.keys(t).forEach((function(n){var r=t[n],o=[];/^\w+$/.test(n)||o.push(/\w+/.exec(n)[0]),"diff"===n&&o.push("bold"),e.languages.diff[n]={pattern:RegExp("^(?:["+r+"].*(?:\r\n?|\n|(?![\\s\\S])))+","m"),alias:o,inside:{line:{pattern:/(.)(?=[\s\S]).*(?:\r\n?|\n)?/,lookbehind:!0},prefix:{pattern:/[\s\S]/,alias:/\w+/.exec(n)[0]}}}})),Object.defineProperty(e.languages.diff,"PREFIXES",{value:t})}(o),o.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},o.languages.go=o.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/}),o.languages.insertBefore("go","string",{char:{pattern:/'(?:\\.|[^'\\\r\n]){0,10}'/,greedy:!0}}),delete o.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,o,a){if(n.language===r){var i=n.tokenStack=[];n.code=n.code.replace(o,(function(e){if("function"==typeof a&&!a(e))return e;for(var o,l=i.length;-1!==n.code.indexOf(o=t(r,l));)++l;return i[l]=e,o})),n.grammar=e.languages.markup}}},tokenizePlaceholders:{value:function(n,r){if(n.language===r&&n.tokenStack){n.grammar=e.languages[r];var o=0,a=Object.keys(n.tokenStack);!function i(l){for(var s=0;s<l.length&&!(o>=a.length);s++){var u=l[s];if("string"==typeof u||u.content&&"string"==typeof u.content){var c=a[o],d=n.tokenStack[c],f="string"==typeof u?u:u.content,p=t(r,c),h=f.indexOf(p);if(h>-1){++o;var m=f.substring(0,h),g=new e.Token(r,e.tokenize(d,n.grammar),"language-"+r,d),v=f.substring(h+p.length),b=[];m&&b.push.apply(b,i([m])),b.push(g),v&&b.push.apply(b,i([v])),"string"==typeof u?l.splice.apply(l,[s,1].concat(b)):u.content=b}}else u.content&&i(u.content)}return l}(n.tokens)}}}})}(o),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}(o),o.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"}},o.languages.webmanifest=o.languages.json,o.languages.less=o.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:/[+\-*\/]/}),o.languages.insertBefore("less","property",{variable:[{pattern:/@[\w-]+\s*:/,inside:{punctuation:/:/}},/@@?[\w-]+/],"mixin-usage":{pattern:/([{;]\s*)[.#](?!\d)[\w-].*?(?=[(;])/,lookbehind:!0,alias:"function"}}),o.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:/[:;(){}]/},o.languages.objectivec=o.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 o.languages.objectivec["class-name"],o.languages.objc=o.languages.objectivec,o.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/},o.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:/[{}[\];(),.:]/},o.languages.python["string-interpolation"].inside.interpolation.inside.rest=o.languages.python,o.languages.py=o.languages.python,o.languages.reason=o.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/}),o.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 o.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}})}(o),o.languages.scss=o.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]+\}/}}}),o.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}]}),o.languages.insertBefore("scss","important",{variable:/\$[-\w]+|#\{\$[-\w]+\}/}),o.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}}),o.languages.scss.atrule.inside.rest=o.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:/[{}()\[\];:.]/}}(o),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}(o),o.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 a=o},29901: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 <a href="https://webplatform.github.io/docs/">WebPlatform.org documentation</a>. The links open in a new tab.'},"custom-class":{title:"Custom Class",description:"This plugin allows you to prefix Prism's default classes (<code>.comment</code> can become <code>.namespace--comment</code>) or replace them with your defined ones (like <code>.editor__comment</code>). 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 <code>highlightAll</code> and <code>highlightAllUnder</code> 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(29901),o=n(39642),a=new Set;function i(e){void 0===e?e=Object.keys(r.languages).filter((e=>"meta"!=e)):Array.isArray(e)||(e=[e]);const t=[...a,...Object.keys(Prism.languages)];o(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(16500).resolve(t)],delete Prism.languages[e],n(16500)(t),a.add(e)}))}i.silent=!1,e.exports=i},6726:(e,t,n)=>{var r={"./":2885};function o(e){var t=a(e);return n(t)}function a(e){if(!n.o(r,e)){var t=new Error("Cannot find module '"+e+"'");throw t.code="MODULE_NOT_FOUND",t}return r[e]}o.keys=function(){return Object.keys(r)},o.resolve=a,e.exports=o,o.id=6726},16500:(e,t,n)=>{var r={"./":2885};function o(e){var t=a(e);return n(t)}function a(e){if(!n.o(r,e)){var t=new Error("Cannot find module '"+e+"'");throw t.code="MODULE_NOT_FOUND",t}return r[e]}o.keys=function(){return Object.keys(r)},o.resolve=a,e.exports=o,o.id=16500},39642: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<r;n++)t[e[n]]=!0;return t}function r(e){var n={},r=[];function o(r,a){if(!(r in n)){a.push(r);var i=a.indexOf(r);if(i<a.length-1)throw new Error("Circular dependency: "+a.slice(i).join(" -> "));var l={},s=e[r];if(s){function u(t){if(!(t in e))throw new Error(r+" depends on an unknown component "+t);if(!(t in l))for(var i in o(t,a),l[t]=!0,n[t])l[i]=!0}t(s.require,u),t(s.optional,u),t(s.modify,u)}n[r]=l,a.pop()}}return function(e){var t=n[e];return t||(o(e,r),t=n[e]),t}}function o(e){for(var t in e)return!0;return!1}return function(a,i,l){var s=function(e){var t={};for(var n in e){var r=e[n];for(var o in r)if("meta"!=o){var a=r[o];t[o]="string"==typeof a?{title:a}:a}}return t}(a),u=function(e){var n;return function(r){if(r in e)return r;if(!n)for(var o in n={},e){var a=e[o];t(a&&a.alias,(function(t){if(t in n)throw new Error(t+" cannot be alias for both "+o+" and "+n[t]);if(t in e)throw new Error(t+" cannot be alias of "+o+" because it is a component.");n[t]=o}))}return n[r]||r}}(s);i=i.map(u),l=(l||[]).map(u);var c=n(i),d=n(l);i.forEach((function e(n){var r=s[n];t(r&&r.require,(function(t){t in d||(c[t]=!0,e(t))}))}));for(var f,p=r(s),h=c;o(h);){for(var m in f={},h){var g=s[m];t(g&&g.modify,(function(e){e in d&&(f[e]=!0)}))}for(var v in d)if(!(v in c))for(var b in p(v))if(b in c){f[v]=!0;break}for(var y in h=f)c[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,o){var a=o?o.series:void 0,i=o?o.parallel:e,l={},s={};function u(e){if(e in l)return l[e];s[e]=!0;var o,c=[];for(var d in t(e))d in n&&c.push(d);if(0===c.length)o=r(e);else{var f=i(c.map((function(e){var t=u(e);return delete s[e],t})));a?o=a(f,(function(){return r(e)})):r(e)}return l[e]=o}for(var c in n)u(c);var d=[];for(var f in s)d.push(l[f]);return i(d)}(p,c,t,n)}};return w}}();e.exports=t},92703:(e,t,n)=>{"use strict";var r=n(50414);function o(){}function a(){}a.resetWarningCache=o,e.exports=function(){function e(e,t,n,o,a,i){if(i!==r){var l=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 l.name="Invariant Violation",l}}function t(){return e}e.isRequired=e;var n={array:e,bigint:e,bool:e,func:e,number:e,object:e,string:e,symbol:e,any:e,arrayOf:t,element:e,elementType:e,instanceOf:t,node:e,objectOf:t,oneOf:t,oneOfType:t,shape:t,exact:t,checkPropTypes:a,resetWarningCache:o};return n.PropTypes=n,n}},45697:(e,t,n)=>{e.exports=n(92703)()},50414:e=>{"use strict";e.exports="SECRET_DO_NOT_PASS_THIS_OR_YOU_WILL_BE_FIRED"},64448:(e,t,n)=>{"use strict";var r=n(67294),o=n(27418),a=n(63840);function i(e){for(var t="https://reactjs.org/docs/error-decoder.html?invariant="+e,n=1;n<arguments.length;n++)t+="&args[]="+encodeURIComponent(arguments[n]);return"Minified React error #"+e+"; visit "+t+" for the full message or use the non-minified dev environment for full errors and additional helpful warnings."}if(!r)throw Error(i(227));var l=new Set,s={};function u(e,t){c(e,t),c(e+"Capture",t)}function c(e,t){for(s[e]=t,e=0;e<t.length;e++)l.add(t[e])}var d=!("undefined"==typeof window||void 0===window.document||void 0===window.document.createElement),f=/^[:A-Z_a-z\u00C0-\u00D6\u00D8-\u00F6\u00F8-\u02FF\u0370-\u037D\u037F-\u1FFF\u200C-\u200D\u2070-\u218F\u2C00-\u2FEF\u3001-\uD7FF\uF900-\uFDCF\uFDF0-\uFFFD][:A-Z_a-z\u00C0-\u00D6\u00D8-\u00F6\u00F8-\u02FF\u0370-\u037D\u037F-\u1FFF\u200C-\u200D\u2070-\u218F\u2C00-\u2FEF\u3001-\uD7FF\uF900-\uFDCF\uFDF0-\uFFFD\-.0-9\u00B7\u0300-\u036F\u203F-\u2040]*$/,p=Object.prototype.hasOwnProperty,h={},m={};function g(e,t,n,r,o,a,i){this.acceptsBooleans=2===t||3===t||4===t,this.attributeName=r,this.attributeNamespace=o,this.mustUseProperty=n,this.propertyName=e,this.type=t,this.sanitizeURL=a,this.removeEmptyString=i}var v={};"children dangerouslySetInnerHTML defaultValue defaultChecked innerHTML suppressContentEditableWarning suppressHydrationWarning style".split(" ").forEach((function(e){v[e]=new g(e,0,!1,e,null,!1,!1)})),[["acceptCharset","accept-charset"],["className","class"],["htmlFor","for"],["httpEquiv","http-equiv"]].forEach((function(e){var t=e[0];v[t]=new g(t,1,!1,e[1],null,!1,!1)})),["contentEditable","draggable","spellCheck","value"].forEach((function(e){v[e]=new g(e,2,!1,e.toLowerCase(),null,!1,!1)})),["autoReverse","externalResourcesRequired","focusable","preserveAlpha"].forEach((function(e){v[e]=new g(e,2,!1,e,null,!1,!1)})),"allowFullScreen async autoFocus autoPlay controls default defer disabled disablePictureInPicture disableRemotePlayback formNoValidate hidden loop noModule noValidate open playsInline readOnly required reversed scoped seamless itemScope".split(" ").forEach((function(e){v[e]=new g(e,3,!1,e.toLowerCase(),null,!1,!1)})),["checked","multiple","muted","selected"].forEach((function(e){v[e]=new g(e,3,!0,e,null,!1,!1)})),["capture","download"].forEach((function(e){v[e]=new g(e,4,!1,e,null,!1,!1)})),["cols","rows","size","span"].forEach((function(e){v[e]=new g(e,6,!1,e,null,!1,!1)})),["rowSpan","start"].forEach((function(e){v[e]=new g(e,5,!1,e.toLowerCase(),null,!1,!1)}));var b=/[\-:]([a-z])/g;function y(e){return e[1].toUpperCase()}function w(e,t,n,r){var o=v.hasOwnProperty(t)?v[t]:null;(null!==o?0===o.type:!r&&(2<t.length&&("o"===t[0]||"O"===t[0])&&("n"===t[1]||"N"===t[1])))||(function(e,t,n,r){if(null==t||function(e,t,n,r){if(null!==n&&0===n.type)return!1;switch(typeof t){case"function":case"symbol":return!0;case"boolean":return!r&&(null!==n?!n.acceptsBooleans:"data-"!==(e=e.toLowerCase().slice(0,5))&&"aria-"!==e);default:return!1}}(e,t,n,r))return!0;if(r)return!1;if(null!==n)switch(n.type){case 3:return!t;case 4:return!1===t;case 5:return isNaN(t);case 6:return isNaN(t)||1>t}return!1}(t,n,o,r)&&(n=null),r||null===o?function(e){return!!p.call(m,e)||!p.call(h,e)&&(f.test(e)?m[e]=!0:(h[e]=!0,!1))}(t)&&(null===n?e.removeAttribute(t):e.setAttribute(t,""+n)):o.mustUseProperty?e[o.propertyName]=null===n?3!==o.type&&"":n:(t=o.attributeName,r=o.attributeNamespace,null===n?e.removeAttribute(t):(n=3===(o=o.type)||4===o&&!0===n?"":""+n,r?e.setAttributeNS(r,t,n):e.setAttribute(t,n))))}"accent-height alignment-baseline arabic-form baseline-shift cap-height clip-path clip-rule color-interpolation color-interpolation-filters color-profile color-rendering dominant-baseline enable-background fill-opacity fill-rule flood-color flood-opacity font-family font-size font-size-adjust font-stretch font-style font-variant font-weight glyph-name glyph-orientation-horizontal glyph-orientation-vertical horiz-adv-x horiz-origin-x image-rendering letter-spacing lighting-color marker-end marker-mid marker-start overline-position overline-thickness paint-order panose-1 pointer-events rendering-intent shape-rendering stop-color stop-opacity strikethrough-position strikethrough-thickness stroke-dasharray stroke-dashoffset stroke-linecap stroke-linejoin stroke-miterlimit stroke-opacity stroke-width text-anchor text-decoration text-rendering underline-position underline-thickness unicode-bidi unicode-range units-per-em v-alphabetic v-hanging v-ideographic v-mathematical vector-effect vert-adv-y vert-origin-x vert-origin-y word-spacing writing-mode xmlns:xlink x-height".split(" ").forEach((function(e){var t=e.replace(b,y);v[t]=new g(t,1,!1,e,null,!1,!1)})),"xlink:actuate xlink:arcrole xlink:role xlink:show xlink:title xlink:type".split(" ").forEach((function(e){var t=e.replace(b,y);v[t]=new g(t,1,!1,e,"http://www.w3.org/1999/xlink",!1,!1)})),["xml:base","xml:lang","xml:space"].forEach((function(e){var t=e.replace(b,y);v[t]=new g(t,1,!1,e,"http://www.w3.org/XML/1998/namespace",!1,!1)})),["tabIndex","crossOrigin"].forEach((function(e){v[e]=new g(e,1,!1,e.toLowerCase(),null,!1,!1)})),v.xlinkHref=new g("xlinkHref",1,!1,"xlink:href","http://www.w3.org/1999/xlink",!0,!1),["src","href","action","formAction"].forEach((function(e){v[e]=new g(e,1,!1,e.toLowerCase(),null,!0,!0)}));var x=r.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED,_=60103,k=60106,E=60107,S=60108,C=60114,T=60109,O=60110,D=60112,P=60113,N=60120,A=60115,I=60116,L=60121,R=60128,j=60129,M=60130,F=60131;if("function"==typeof Symbol&&Symbol.for){var B=Symbol.for;_=B("react.element"),k=B("react.portal"),E=B("react.fragment"),S=B("react.strict_mode"),C=B("react.profiler"),T=B("react.provider"),O=B("react.context"),D=B("react.forward_ref"),P=B("react.suspense"),N=B("react.suspense_list"),A=B("react.memo"),I=B("react.lazy"),L=B("react.block"),B("react.scope"),R=B("react.opaque.id"),j=B("react.debug_trace_mode"),M=B("react.offscreen"),F=B("react.legacy_hidden")}var z,$="function"==typeof Symbol&&Symbol.iterator;function U(e){return null===e||"object"!=typeof e?null:"function"==typeof(e=$&&e[$]||e["@@iterator"])?e:null}function H(e){if(void 0===z)try{throw Error()}catch(n){var t=n.stack.trim().match(/\n( *(at )?)/);z=t&&t[1]||""}return"\n"+z+e}var V=!1;function q(e,t){if(!e||V)return"";V=!0;var n=Error.prepareStackTrace;Error.prepareStackTrace=void 0;try{if(t)if(t=function(){throw Error()},Object.defineProperty(t.prototype,"props",{set:function(){throw Error()}}),"object"==typeof Reflect&&Reflect.construct){try{Reflect.construct(t,[])}catch(s){var r=s}Reflect.construct(e,[],t)}else{try{t.call()}catch(s){r=s}e.call(t.prototype)}else{try{throw Error()}catch(s){r=s}e()}}catch(s){if(s&&r&&"string"==typeof s.stack){for(var o=s.stack.split("\n"),a=r.stack.split("\n"),i=o.length-1,l=a.length-1;1<=i&&0<=l&&o[i]!==a[l];)l--;for(;1<=i&&0<=l;i--,l--)if(o[i]!==a[l]){if(1!==i||1!==l)do{if(i--,0>--l||o[i]!==a[l])return"\n"+o[i].replace(" at new "," at ")}while(1<=i&&0<=l);break}}}finally{V=!1,Error.prepareStackTrace=n}return(e=e?e.displayName||e.name:"")?H(e):""}function G(e){switch(e.tag){case 5:return H(e.type);case 16:return H("Lazy");case 13:return H("Suspense");case 19:return H("SuspenseList");case 0:case 2:case 15:return e=q(e.type,!1);case 11:return e=q(e.type.render,!1);case 22:return e=q(e.type._render,!1);case 1:return e=q(e.type,!0);default:return""}}function W(e){if(null==e)return null;if("function"==typeof e)return e.displayName||e.name||null;if("string"==typeof e)return e;switch(e){case E:return"Fragment";case k:return"Portal";case C:return"Profiler";case S:return"StrictMode";case P:return"Suspense";case N:return"SuspenseList"}if("object"==typeof e)switch(e.$$typeof){case O:return(e.displayName||"Context")+".Consumer";case T:return(e._context.displayName||"Context")+".Provider";case D:var t=e.render;return t=t.displayName||t.name||"",e.displayName||(""!==t?"ForwardRef("+t+")":"ForwardRef");case A:return W(e.type);case L:return W(e._render);case I:t=e._payload,e=e._init;try{return W(e(t))}catch(n){}}return null}function Z(e){switch(typeof e){case"boolean":case"number":case"object":case"string":case"undefined":return e;default:return""}}function Q(e){var t=e.type;return(e=e.nodeName)&&"input"===e.toLowerCase()&&("checkbox"===t||"radio"===t)}function Y(e){e._valueTracker||(e._valueTracker=function(e){var t=Q(e)?"checked":"value",n=Object.getOwnPropertyDescriptor(e.constructor.prototype,t),r=""+e[t];if(!e.hasOwnProperty(t)&&void 0!==n&&"function"==typeof n.get&&"function"==typeof n.set){var o=n.get,a=n.set;return Object.defineProperty(e,t,{configurable:!0,get:function(){return o.call(this)},set:function(e){r=""+e,a.call(this,e)}}),Object.defineProperty(e,t,{enumerable:n.enumerable}),{getValue:function(){return r},setValue:function(e){r=""+e},stopTracking:function(){e._valueTracker=null,delete e[t]}}}}(e))}function X(e){if(!e)return!1;var t=e._valueTracker;if(!t)return!0;var n=t.getValue(),r="";return e&&(r=Q(e)?e.checked?"true":"false":e.value),(e=r)!==n&&(t.setValue(e),!0)}function K(e){if(void 0===(e=e||("undefined"!=typeof document?document:void 0)))return null;try{return e.activeElement||e.body}catch(t){return e.body}}function J(e,t){var n=t.checked;return o({},t,{defaultChecked:void 0,defaultValue:void 0,value:void 0,checked:null!=n?n:e._wrapperState.initialChecked})}function ee(e,t){var n=null==t.defaultValue?"":t.defaultValue,r=null!=t.checked?t.checked:t.defaultChecked;n=Z(null!=t.value?t.value:n),e._wrapperState={initialChecked:r,initialValue:n,controlled:"checkbox"===t.type||"radio"===t.type?null!=t.checked:null!=t.value}}function te(e,t){null!=(t=t.checked)&&w(e,"checked",t,!1)}function ne(e,t){te(e,t);var n=Z(t.value),r=t.type;if(null!=n)"number"===r?(0===n&&""===e.value||e.value!=n)&&(e.value=""+n):e.value!==""+n&&(e.value=""+n);else if("submit"===r||"reset"===r)return void e.removeAttribute("value");t.hasOwnProperty("value")?oe(e,t.type,n):t.hasOwnProperty("defaultValue")&&oe(e,t.type,Z(t.defaultValue)),null==t.checked&&null!=t.defaultChecked&&(e.defaultChecked=!!t.defaultChecked)}function re(e,t,n){if(t.hasOwnProperty("value")||t.hasOwnProperty("defaultValue")){var r=t.type;if(!("submit"!==r&&"reset"!==r||void 0!==t.value&&null!==t.value))return;t=""+e._wrapperState.initialValue,n||t===e.value||(e.value=t),e.defaultValue=t}""!==(n=e.name)&&(e.name=""),e.defaultChecked=!!e._wrapperState.initialChecked,""!==n&&(e.name=n)}function oe(e,t,n){"number"===t&&K(e.ownerDocument)===e||(null==n?e.defaultValue=""+e._wrapperState.initialValue:e.defaultValue!==""+n&&(e.defaultValue=""+n))}function ae(e,t){return e=o({children:void 0},t),(t=function(e){var t="";return r.Children.forEach(e,(function(e){null!=e&&(t+=e)})),t}(t.children))&&(e.children=t),e}function ie(e,t,n,r){if(e=e.options,t){t={};for(var o=0;o<n.length;o++)t["$"+n[o]]=!0;for(n=0;n<e.length;n++)o=t.hasOwnProperty("$"+e[n].value),e[n].selected!==o&&(e[n].selected=o),o&&r&&(e[n].defaultSelected=!0)}else{for(n=""+Z(n),t=null,o=0;o<e.length;o++){if(e[o].value===n)return e[o].selected=!0,void(r&&(e[o].defaultSelected=!0));null!==t||e[o].disabled||(t=e[o])}null!==t&&(t.selected=!0)}}function le(e,t){if(null!=t.dangerouslySetInnerHTML)throw Error(i(91));return o({},t,{value:void 0,defaultValue:void 0,children:""+e._wrapperState.initialValue})}function se(e,t){var n=t.value;if(null==n){if(n=t.children,t=t.defaultValue,null!=n){if(null!=t)throw Error(i(92));if(Array.isArray(n)){if(!(1>=n.length))throw Error(i(93));n=n[0]}t=n}null==t&&(t=""),n=t}e._wrapperState={initialValue:Z(n)}}function ue(e,t){var n=Z(t.value),r=Z(t.defaultValue);null!=n&&((n=""+n)!==e.value&&(e.value=n),null==t.defaultValue&&e.defaultValue!==n&&(e.defaultValue=n)),null!=r&&(e.defaultValue=""+r)}function ce(e){var t=e.textContent;t===e._wrapperState.initialValue&&""!==t&&null!==t&&(e.value=t)}var de="http://www.w3.org/1999/xhtml",fe="http://www.w3.org/2000/svg";function pe(e){switch(e){case"svg":return"http://www.w3.org/2000/svg";case"math":return"http://www.w3.org/1998/Math/MathML";default:return"http://www.w3.org/1999/xhtml"}}function he(e,t){return null==e||"http://www.w3.org/1999/xhtml"===e?pe(t):"http://www.w3.org/2000/svg"===e&&"foreignObject"===t?"http://www.w3.org/1999/xhtml":e}var me,ge,ve=(ge=function(e,t){if(e.namespaceURI!==fe||"innerHTML"in e)e.innerHTML=t;else{for((me=me||document.createElement("div")).innerHTML="<svg>"+t.valueOf().toString()+"</svg>",t=me.firstChild;e.firstChild;)e.removeChild(e.firstChild);for(;t.firstChild;)e.appendChild(t.firstChild)}},"undefined"!=typeof MSApp&&MSApp.execUnsafeLocalFunction?function(e,t,n,r){MSApp.execUnsafeLocalFunction((function(){return ge(e,t)}))}:ge);function be(e,t){if(t){var n=e.firstChild;if(n&&n===e.lastChild&&3===n.nodeType)return void(n.nodeValue=t)}e.textContent=t}var ye={animationIterationCount:!0,borderImageOutset:!0,borderImageSlice:!0,borderImageWidth:!0,boxFlex:!0,boxFlexGroup:!0,boxOrdinalGroup:!0,columnCount:!0,columns:!0,flex:!0,flexGrow:!0,flexPositive:!0,flexShrink:!0,flexNegative:!0,flexOrder:!0,gridArea:!0,gridRow:!0,gridRowEnd:!0,gridRowSpan:!0,gridRowStart:!0,gridColumn:!0,gridColumnEnd:!0,gridColumnSpan:!0,gridColumnStart:!0,fontWeight:!0,lineClamp:!0,lineHeight:!0,opacity:!0,order:!0,orphans:!0,tabSize:!0,widows:!0,zIndex:!0,zoom:!0,fillOpacity:!0,floodOpacity:!0,stopOpacity:!0,strokeDasharray:!0,strokeDashoffset:!0,strokeMiterlimit:!0,strokeOpacity:!0,strokeWidth:!0},we=["Webkit","ms","Moz","O"];function xe(e,t,n){return null==t||"boolean"==typeof t||""===t?"":n||"number"!=typeof t||0===t||ye.hasOwnProperty(e)&&ye[e]?(""+t).trim():t+"px"}function _e(e,t){for(var n in e=e.style,t)if(t.hasOwnProperty(n)){var r=0===n.indexOf("--"),o=xe(n,t[n],r);"float"===n&&(n="cssFloat"),r?e.setProperty(n,o):e[n]=o}}Object.keys(ye).forEach((function(e){we.forEach((function(t){t=t+e.charAt(0).toUpperCase()+e.substring(1),ye[t]=ye[e]}))}));var ke=o({menuitem:!0},{area:!0,base:!0,br:!0,col:!0,embed:!0,hr:!0,img:!0,input:!0,keygen:!0,link:!0,meta:!0,param:!0,source:!0,track:!0,wbr:!0});function Ee(e,t){if(t){if(ke[e]&&(null!=t.children||null!=t.dangerouslySetInnerHTML))throw Error(i(137,e));if(null!=t.dangerouslySetInnerHTML){if(null!=t.children)throw Error(i(60));if("object"!=typeof t.dangerouslySetInnerHTML||!("__html"in t.dangerouslySetInnerHTML))throw Error(i(61))}if(null!=t.style&&"object"!=typeof t.style)throw Error(i(62))}}function Se(e,t){if(-1===e.indexOf("-"))return"string"==typeof t.is;switch(e){case"annotation-xml":case"color-profile":case"font-face":case"font-face-src":case"font-face-uri":case"font-face-format":case"font-face-name":case"missing-glyph":return!1;default:return!0}}function Ce(e){return(e=e.target||e.srcElement||window).correspondingUseElement&&(e=e.correspondingUseElement),3===e.nodeType?e.parentNode:e}var Te=null,Oe=null,De=null;function Pe(e){if(e=ro(e)){if("function"!=typeof Te)throw Error(i(280));var t=e.stateNode;t&&(t=ao(t),Te(e.stateNode,e.type,t))}}function Ne(e){Oe?De?De.push(e):De=[e]:Oe=e}function Ae(){if(Oe){var e=Oe,t=De;if(De=Oe=null,Pe(e),t)for(e=0;e<t.length;e++)Pe(t[e])}}function Ie(e,t){return e(t)}function Le(e,t,n,r,o){return e(t,n,r,o)}function Re(){}var je=Ie,Me=!1,Fe=!1;function Be(){null===Oe&&null===De||(Re(),Ae())}function ze(e,t){var n=e.stateNode;if(null===n)return null;var r=ao(n);if(null===r)return null;n=r[t];e:switch(t){case"onClick":case"onClickCapture":case"onDoubleClick":case"onDoubleClickCapture":case"onMouseDown":case"onMouseDownCapture":case"onMouseMove":case"onMouseMoveCapture":case"onMouseUp":case"onMouseUpCapture":case"onMouseEnter":(r=!r.disabled)||(r=!("button"===(e=e.type)||"input"===e||"select"===e||"textarea"===e)),e=!r;break e;default:e=!1}if(e)return null;if(n&&"function"!=typeof n)throw Error(i(231,t,typeof n));return n}var $e=!1;if(d)try{var Ue={};Object.defineProperty(Ue,"passive",{get:function(){$e=!0}}),window.addEventListener("test",Ue,Ue),window.removeEventListener("test",Ue,Ue)}catch(ge){$e=!1}function He(e,t,n,r,o,a,i,l,s){var u=Array.prototype.slice.call(arguments,3);try{t.apply(n,u)}catch(c){this.onError(c)}}var Ve=!1,qe=null,Ge=!1,We=null,Ze={onError:function(e){Ve=!0,qe=e}};function Qe(e,t,n,r,o,a,i,l,s){Ve=!1,qe=null,He.apply(Ze,arguments)}function Ye(e){var t=e,n=e;if(e.alternate)for(;t.return;)t=t.return;else{e=t;do{0!=(1026&(t=e).flags)&&(n=t.return),e=t.return}while(e)}return 3===t.tag?n:null}function Xe(e){if(13===e.tag){var t=e.memoizedState;if(null===t&&(null!==(e=e.alternate)&&(t=e.memoizedState)),null!==t)return t.dehydrated}return null}function Ke(e){if(Ye(e)!==e)throw Error(i(188))}function Je(e){if(e=function(e){var t=e.alternate;if(!t){if(null===(t=Ye(e)))throw Error(i(188));return t!==e?null:e}for(var n=e,r=t;;){var o=n.return;if(null===o)break;var a=o.alternate;if(null===a){if(null!==(r=o.return)){n=r;continue}break}if(o.child===a.child){for(a=o.child;a;){if(a===n)return Ke(o),e;if(a===r)return Ke(o),t;a=a.sibling}throw Error(i(188))}if(n.return!==r.return)n=o,r=a;else{for(var l=!1,s=o.child;s;){if(s===n){l=!0,n=o,r=a;break}if(s===r){l=!0,r=o,n=a;break}s=s.sibling}if(!l){for(s=a.child;s;){if(s===n){l=!0,n=a,r=o;break}if(s===r){l=!0,r=a,n=o;break}s=s.sibling}if(!l)throw Error(i(189))}}if(n.alternate!==r)throw Error(i(190))}if(3!==n.tag)throw Error(i(188));return n.stateNode.current===n?e:t}(e),!e)return null;for(var t=e;;){if(5===t.tag||6===t.tag)return t;if(t.child)t.child.return=t,t=t.child;else{if(t===e)break;for(;!t.sibling;){if(!t.return||t.return===e)return null;t=t.return}t.sibling.return=t.return,t=t.sibling}}return null}function et(e,t){for(var n=e.alternate;null!==t;){if(t===e||t===n)return!0;t=t.return}return!1}var tt,nt,rt,ot,at=!1,it=[],lt=null,st=null,ut=null,ct=new Map,dt=new Map,ft=[],pt="mousedown mouseup touchcancel touchend touchstart auxclick dblclick pointercancel pointerdown pointerup dragend dragstart drop compositionend compositionstart keydown keypress keyup input textInput copy cut paste click change contextmenu reset submit".split(" ");function ht(e,t,n,r,o){return{blockedOn:e,domEventName:t,eventSystemFlags:16|n,nativeEvent:o,targetContainers:[r]}}function mt(e,t){switch(e){case"focusin":case"focusout":lt=null;break;case"dragenter":case"dragleave":st=null;break;case"mouseover":case"mouseout":ut=null;break;case"pointerover":case"pointerout":ct.delete(t.pointerId);break;case"gotpointercapture":case"lostpointercapture":dt.delete(t.pointerId)}}function gt(e,t,n,r,o,a){return null===e||e.nativeEvent!==a?(e=ht(t,n,r,o,a),null!==t&&(null!==(t=ro(t))&&nt(t)),e):(e.eventSystemFlags|=r,t=e.targetContainers,null!==o&&-1===t.indexOf(o)&&t.push(o),e)}function vt(e){var t=no(e.target);if(null!==t){var n=Ye(t);if(null!==n)if(13===(t=n.tag)){if(null!==(t=Xe(n)))return e.blockedOn=t,void ot(e.lanePriority,(function(){a.unstable_runWithPriority(e.priority,(function(){rt(n)}))}))}else if(3===t&&n.stateNode.hydrate)return void(e.blockedOn=3===n.tag?n.stateNode.containerInfo:null)}e.blockedOn=null}function bt(e){if(null!==e.blockedOn)return!1;for(var t=e.targetContainers;0<t.length;){var n=Jt(e.domEventName,e.eventSystemFlags,t[0],e.nativeEvent);if(null!==n)return null!==(t=ro(n))&&nt(t),e.blockedOn=n,!1;t.shift()}return!0}function yt(e,t,n){bt(e)&&n.delete(t)}function wt(){for(at=!1;0<it.length;){var e=it[0];if(null!==e.blockedOn){null!==(e=ro(e.blockedOn))&&tt(e);break}for(var t=e.targetContainers;0<t.length;){var n=Jt(e.domEventName,e.eventSystemFlags,t[0],e.nativeEvent);if(null!==n){e.blockedOn=n;break}t.shift()}null===e.blockedOn&&it.shift()}null!==lt&&bt(lt)&&(lt=null),null!==st&&bt(st)&&(st=null),null!==ut&&bt(ut)&&(ut=null),ct.forEach(yt),dt.forEach(yt)}function xt(e,t){e.blockedOn===t&&(e.blockedOn=null,at||(at=!0,a.unstable_scheduleCallback(a.unstable_NormalPriority,wt)))}function _t(e){function t(t){return xt(t,e)}if(0<it.length){xt(it[0],e);for(var n=1;n<it.length;n++){var r=it[n];r.blockedOn===e&&(r.blockedOn=null)}}for(null!==lt&&xt(lt,e),null!==st&&xt(st,e),null!==ut&&xt(ut,e),ct.forEach(t),dt.forEach(t),n=0;n<ft.length;n++)(r=ft[n]).blockedOn===e&&(r.blockedOn=null);for(;0<ft.length&&null===(n=ft[0]).blockedOn;)vt(n),null===n.blockedOn&&ft.shift()}function kt(e,t){var n={};return n[e.toLowerCase()]=t.toLowerCase(),n["Webkit"+e]="webkit"+t,n["Moz"+e]="moz"+t,n}var Et={animationend:kt("Animation","AnimationEnd"),animationiteration:kt("Animation","AnimationIteration"),animationstart:kt("Animation","AnimationStart"),transitionend:kt("Transition","TransitionEnd")},St={},Ct={};function Tt(e){if(St[e])return St[e];if(!Et[e])return e;var t,n=Et[e];for(t in n)if(n.hasOwnProperty(t)&&t in Ct)return St[e]=n[t];return e}d&&(Ct=document.createElement("div").style,"AnimationEvent"in window||(delete Et.animationend.animation,delete Et.animationiteration.animation,delete Et.animationstart.animation),"TransitionEvent"in window||delete Et.transitionend.transition);var Ot=Tt("animationend"),Dt=Tt("animationiteration"),Pt=Tt("animationstart"),Nt=Tt("transitionend"),At=new Map,It=new Map,Lt=["abort","abort",Ot,"animationEnd",Dt,"animationIteration",Pt,"animationStart","canplay","canPlay","canplaythrough","canPlayThrough","durationchange","durationChange","emptied","emptied","encrypted","encrypted","ended","ended","error","error","gotpointercapture","gotPointerCapture","load","load","loadeddata","loadedData","loadedmetadata","loadedMetadata","loadstart","loadStart","lostpointercapture","lostPointerCapture","playing","playing","progress","progress","seeking","seeking","stalled","stalled","suspend","suspend","timeupdate","timeUpdate",Nt,"transitionEnd","waiting","waiting"];function Rt(e,t){for(var n=0;n<e.length;n+=2){var r=e[n],o=e[n+1];o="on"+(o[0].toUpperCase()+o.slice(1)),It.set(r,t),At.set(r,o),u(o,[r])}}(0,a.unstable_now)();var jt=8;function Mt(e){if(0!=(1&e))return jt=15,1;if(0!=(2&e))return jt=14,2;if(0!=(4&e))return jt=13,4;var t=24&e;return 0!==t?(jt=12,t):0!=(32&e)?(jt=11,32):0!==(t=192&e)?(jt=10,t):0!=(256&e)?(jt=9,256):0!==(t=3584&e)?(jt=8,t):0!=(4096&e)?(jt=7,4096):0!==(t=4186112&e)?(jt=6,t):0!==(t=62914560&e)?(jt=5,t):67108864&e?(jt=4,67108864):0!=(134217728&e)?(jt=3,134217728):0!==(t=805306368&e)?(jt=2,t):0!=(1073741824&e)?(jt=1,1073741824):(jt=8,e)}function Ft(e,t){var n=e.pendingLanes;if(0===n)return jt=0;var r=0,o=0,a=e.expiredLanes,i=e.suspendedLanes,l=e.pingedLanes;if(0!==a)r=a,o=jt=15;else if(0!==(a=134217727&n)){var s=a&~i;0!==s?(r=Mt(s),o=jt):0!==(l&=a)&&(r=Mt(l),o=jt)}else 0!==(a=n&~i)?(r=Mt(a),o=jt):0!==l&&(r=Mt(l),o=jt);if(0===r)return 0;if(r=n&((0>(r=31-Vt(r))?0:1<<r)<<1)-1,0!==t&&t!==r&&0==(t&i)){if(Mt(t),o<=jt)return t;jt=o}if(0!==(t=e.entangledLanes))for(e=e.entanglements,t&=r;0<t;)o=1<<(n=31-Vt(t)),r|=e[n],t&=~o;return r}function Bt(e){return 0!==(e=-1073741825&e.pendingLanes)?e:1073741824&e?1073741824:0}function zt(e,t){switch(e){case 15:return 1;case 14:return 2;case 12:return 0===(e=$t(24&~t))?zt(10,t):e;case 10:return 0===(e=$t(192&~t))?zt(8,t):e;case 8:return 0===(e=$t(3584&~t))&&(0===(e=$t(4186112&~t))&&(e=512)),e;case 2:return 0===(t=$t(805306368&~t))&&(t=268435456),t}throw Error(i(358,e))}function $t(e){return e&-e}function Ut(e){for(var t=[],n=0;31>n;n++)t.push(e);return t}function Ht(e,t,n){e.pendingLanes|=t;var r=t-1;e.suspendedLanes&=r,e.pingedLanes&=r,(e=e.eventTimes)[t=31-Vt(t)]=n}var Vt=Math.clz32?Math.clz32:function(e){return 0===e?32:31-(qt(e)/Gt|0)|0},qt=Math.log,Gt=Math.LN2;var Wt=a.unstable_UserBlockingPriority,Zt=a.unstable_runWithPriority,Qt=!0;function Yt(e,t,n,r){Me||Re();var o=Kt,a=Me;Me=!0;try{Le(o,e,t,n,r)}finally{(Me=a)||Be()}}function Xt(e,t,n,r){Zt(Wt,Kt.bind(null,e,t,n,r))}function Kt(e,t,n,r){var o;if(Qt)if((o=0==(4&t))&&0<it.length&&-1<pt.indexOf(e))e=ht(null,e,t,n,r),it.push(e);else{var a=Jt(e,t,n,r);if(null===a)o&&mt(e,r);else{if(o){if(-1<pt.indexOf(e))return e=ht(a,e,t,n,r),void it.push(e);if(function(e,t,n,r,o){switch(t){case"focusin":return lt=gt(lt,e,t,n,r,o),!0;case"dragenter":return st=gt(st,e,t,n,r,o),!0;case"mouseover":return ut=gt(ut,e,t,n,r,o),!0;case"pointerover":var a=o.pointerId;return ct.set(a,gt(ct.get(a)||null,e,t,n,r,o)),!0;case"gotpointercapture":return a=o.pointerId,dt.set(a,gt(dt.get(a)||null,e,t,n,r,o)),!0}return!1}(a,e,t,n,r))return;mt(e,r)}Rr(e,t,r,null,n)}}}function Jt(e,t,n,r){var o=Ce(r);if(null!==(o=no(o))){var a=Ye(o);if(null===a)o=null;else{var i=a.tag;if(13===i){if(null!==(o=Xe(a)))return o;o=null}else if(3===i){if(a.stateNode.hydrate)return 3===a.tag?a.stateNode.containerInfo:null;o=null}else a!==o&&(o=null)}}return Rr(e,t,r,o,n),null}var en=null,tn=null,nn=null;function rn(){if(nn)return nn;var e,t,n=tn,r=n.length,o="value"in en?en.value:en.textContent,a=o.length;for(e=0;e<r&&n[e]===o[e];e++);var i=r-e;for(t=1;t<=i&&n[r-t]===o[a-t];t++);return nn=o.slice(e,1<t?1-t:void 0)}function on(e){var t=e.keyCode;return"charCode"in e?0===(e=e.charCode)&&13===t&&(e=13):e=t,10===e&&(e=13),32<=e||13===e?e:0}function an(){return!0}function ln(){return!1}function sn(e){function t(t,n,r,o,a){for(var i in this._reactName=t,this._targetInst=r,this.type=n,this.nativeEvent=o,this.target=a,this.currentTarget=null,e)e.hasOwnProperty(i)&&(t=e[i],this[i]=t?t(o):o[i]);return this.isDefaultPrevented=(null!=o.defaultPrevented?o.defaultPrevented:!1===o.returnValue)?an:ln,this.isPropagationStopped=ln,this}return o(t.prototype,{preventDefault:function(){this.defaultPrevented=!0;var e=this.nativeEvent;e&&(e.preventDefault?e.preventDefault():"unknown"!=typeof e.returnValue&&(e.returnValue=!1),this.isDefaultPrevented=an)},stopPropagation:function(){var e=this.nativeEvent;e&&(e.stopPropagation?e.stopPropagation():"unknown"!=typeof e.cancelBubble&&(e.cancelBubble=!0),this.isPropagationStopped=an)},persist:function(){},isPersistent:an}),t}var un,cn,dn,fn={eventPhase:0,bubbles:0,cancelable:0,timeStamp:function(e){return e.timeStamp||Date.now()},defaultPrevented:0,isTrusted:0},pn=sn(fn),hn=o({},fn,{view:0,detail:0}),mn=sn(hn),gn=o({},hn,{screenX:0,screenY:0,clientX:0,clientY:0,pageX:0,pageY:0,ctrlKey:0,shiftKey:0,altKey:0,metaKey:0,getModifierState:On,button:0,buttons:0,relatedTarget:function(e){return void 0===e.relatedTarget?e.fromElement===e.srcElement?e.toElement:e.fromElement:e.relatedTarget},movementX:function(e){return"movementX"in e?e.movementX:(e!==dn&&(dn&&"mousemove"===e.type?(un=e.screenX-dn.screenX,cn=e.screenY-dn.screenY):cn=un=0,dn=e),un)},movementY:function(e){return"movementY"in e?e.movementY:cn}}),vn=sn(gn),bn=sn(o({},gn,{dataTransfer:0})),yn=sn(o({},hn,{relatedTarget:0})),wn=sn(o({},fn,{animationName:0,elapsedTime:0,pseudoElement:0})),xn=o({},fn,{clipboardData:function(e){return"clipboardData"in e?e.clipboardData:window.clipboardData}}),_n=sn(xn),kn=sn(o({},fn,{data:0})),En={Esc:"Escape",Spacebar:" ",Left:"ArrowLeft",Up:"ArrowUp",Right:"ArrowRight",Down:"ArrowDown",Del:"Delete",Win:"OS",Menu:"ContextMenu",Apps:"ContextMenu",Scroll:"ScrollLock",MozPrintableKey:"Unidentified"},Sn={8:"Backspace",9:"Tab",12:"Clear",13:"Enter",16:"Shift",17:"Control",18:"Alt",19:"Pause",20:"CapsLock",27:"Escape",32:" ",33:"PageUp",34:"PageDown",35:"End",36:"Home",37:"ArrowLeft",38:"ArrowUp",39:"ArrowRight",40:"ArrowDown",45:"Insert",46:"Delete",112:"F1",113:"F2",114:"F3",115:"F4",116:"F5",117:"F6",118:"F7",119:"F8",120:"F9",121:"F10",122:"F11",123:"F12",144:"NumLock",145:"ScrollLock",224:"Meta"},Cn={Alt:"altKey",Control:"ctrlKey",Meta:"metaKey",Shift:"shiftKey"};function Tn(e){var t=this.nativeEvent;return t.getModifierState?t.getModifierState(e):!!(e=Cn[e])&&!!t[e]}function On(){return Tn}var Dn=o({},hn,{key:function(e){if(e.key){var t=En[e.key]||e.key;if("Unidentified"!==t)return t}return"keypress"===e.type?13===(e=on(e))?"Enter":String.fromCharCode(e):"keydown"===e.type||"keyup"===e.type?Sn[e.keyCode]||"Unidentified":""},code:0,location:0,ctrlKey:0,shiftKey:0,altKey:0,metaKey:0,repeat:0,locale:0,getModifierState:On,charCode:function(e){return"keypress"===e.type?on(e):0},keyCode:function(e){return"keydown"===e.type||"keyup"===e.type?e.keyCode:0},which:function(e){return"keypress"===e.type?on(e):"keydown"===e.type||"keyup"===e.type?e.keyCode:0}}),Pn=sn(Dn),Nn=sn(o({},gn,{pointerId:0,width:0,height:0,pressure:0,tangentialPressure:0,tiltX:0,tiltY:0,twist:0,pointerType:0,isPrimary:0})),An=sn(o({},hn,{touches:0,targetTouches:0,changedTouches:0,altKey:0,metaKey:0,ctrlKey:0,shiftKey:0,getModifierState:On})),In=sn(o({},fn,{propertyName:0,elapsedTime:0,pseudoElement:0})),Ln=o({},gn,{deltaX:function(e){return"deltaX"in e?e.deltaX:"wheelDeltaX"in e?-e.wheelDeltaX:0},deltaY:function(e){return"deltaY"in e?e.deltaY:"wheelDeltaY"in e?-e.wheelDeltaY:"wheelDelta"in e?-e.wheelDelta:0},deltaZ:0,deltaMode:0}),Rn=sn(Ln),jn=[9,13,27,32],Mn=d&&"CompositionEvent"in window,Fn=null;d&&"documentMode"in document&&(Fn=document.documentMode);var Bn=d&&"TextEvent"in window&&!Fn,zn=d&&(!Mn||Fn&&8<Fn&&11>=Fn),$n=String.fromCharCode(32),Un=!1;function Hn(e,t){switch(e){case"keyup":return-1!==jn.indexOf(t.keyCode);case"keydown":return 229!==t.keyCode;case"keypress":case"mousedown":case"focusout":return!0;default:return!1}}function Vn(e){return"object"==typeof(e=e.detail)&&"data"in e?e.data:null}var qn=!1;var Gn={color:!0,date:!0,datetime:!0,"datetime-local":!0,email:!0,month:!0,number:!0,password:!0,range:!0,search:!0,tel:!0,text:!0,time:!0,url:!0,week:!0};function Wn(e){var t=e&&e.nodeName&&e.nodeName.toLowerCase();return"input"===t?!!Gn[e.type]:"textarea"===t}function Zn(e,t,n,r){Ne(r),0<(t=Mr(t,"onChange")).length&&(n=new pn("onChange","change",null,n,r),e.push({event:n,listeners:t}))}var Qn=null,Yn=null;function Xn(e){Dr(e,0)}function Kn(e){if(X(oo(e)))return e}function Jn(e,t){if("change"===e)return t}var er=!1;if(d){var tr;if(d){var nr="oninput"in document;if(!nr){var rr=document.createElement("div");rr.setAttribute("oninput","return;"),nr="function"==typeof rr.oninput}tr=nr}else tr=!1;er=tr&&(!document.documentMode||9<document.documentMode)}function or(){Qn&&(Qn.detachEvent("onpropertychange",ar),Yn=Qn=null)}function ar(e){if("value"===e.propertyName&&Kn(Yn)){var t=[];if(Zn(t,Yn,e,Ce(e)),e=Xn,Me)e(t);else{Me=!0;try{Ie(e,t)}finally{Me=!1,Be()}}}}function ir(e,t,n){"focusin"===e?(or(),Yn=n,(Qn=t).attachEvent("onpropertychange",ar)):"focusout"===e&&or()}function lr(e){if("selectionchange"===e||"keyup"===e||"keydown"===e)return Kn(Yn)}function sr(e,t){if("click"===e)return Kn(t)}function ur(e,t){if("input"===e||"change"===e)return Kn(t)}var cr="function"==typeof Object.is?Object.is:function(e,t){return e===t&&(0!==e||1/e==1/t)||e!=e&&t!=t},dr=Object.prototype.hasOwnProperty;function fr(e,t){if(cr(e,t))return!0;if("object"!=typeof e||null===e||"object"!=typeof t||null===t)return!1;var n=Object.keys(e),r=Object.keys(t);if(n.length!==r.length)return!1;for(r=0;r<n.length;r++)if(!dr.call(t,n[r])||!cr(e[n[r]],t[n[r]]))return!1;return!0}function pr(e){for(;e&&e.firstChild;)e=e.firstChild;return e}function hr(e,t){var n,r=pr(e);for(e=0;r;){if(3===r.nodeType){if(n=e+r.textContent.length,e<=t&&n>=t)return{node:r,offset:t-e};e=n}e:{for(;r;){if(r.nextSibling){r=r.nextSibling;break e}r=r.parentNode}r=void 0}r=pr(r)}}function mr(e,t){return!(!e||!t)&&(e===t||(!e||3!==e.nodeType)&&(t&&3===t.nodeType?mr(e,t.parentNode):"contains"in e?e.contains(t):!!e.compareDocumentPosition&&!!(16&e.compareDocumentPosition(t))))}function gr(){for(var e=window,t=K();t instanceof e.HTMLIFrameElement;){try{var n="string"==typeof t.contentWindow.location.href}catch(r){n=!1}if(!n)break;t=K((e=t.contentWindow).document)}return t}function vr(e){var t=e&&e.nodeName&&e.nodeName.toLowerCase();return t&&("input"===t&&("text"===e.type||"search"===e.type||"tel"===e.type||"url"===e.type||"password"===e.type)||"textarea"===t||"true"===e.contentEditable)}var br=d&&"documentMode"in document&&11>=document.documentMode,yr=null,wr=null,xr=null,_r=!1;function kr(e,t,n){var r=n.window===n?n.document:9===n.nodeType?n:n.ownerDocument;_r||null==yr||yr!==K(r)||("selectionStart"in(r=yr)&&vr(r)?r={start:r.selectionStart,end:r.selectionEnd}:r={anchorNode:(r=(r.ownerDocument&&r.ownerDocument.defaultView||window).getSelection()).anchorNode,anchorOffset:r.anchorOffset,focusNode:r.focusNode,focusOffset:r.focusOffset},xr&&fr(xr,r)||(xr=r,0<(r=Mr(wr,"onSelect")).length&&(t=new pn("onSelect","select",null,t,n),e.push({event:t,listeners:r}),t.target=yr)))}Rt("cancel cancel click click close close contextmenu contextMenu copy copy cut cut auxclick auxClick dblclick doubleClick dragend dragEnd dragstart dragStart drop drop focusin focus focusout blur input input invalid invalid keydown keyDown keypress keyPress keyup keyUp mousedown mouseDown mouseup mouseUp paste paste pause pause play play pointercancel pointerCancel pointerdown pointerDown pointerup pointerUp ratechange rateChange reset reset seeked seeked submit submit touchcancel touchCancel touchend touchEnd touchstart touchStart volumechange volumeChange".split(" "),0),Rt("drag drag dragenter dragEnter dragexit dragExit dragleave dragLeave dragover dragOver mousemove mouseMove mouseout mouseOut mouseover mouseOver pointermove pointerMove pointerout pointerOut pointerover pointerOver scroll scroll toggle toggle touchmove touchMove wheel wheel".split(" "),1),Rt(Lt,2);for(var Er="change selectionchange textInput compositionstart compositionend compositionupdate".split(" "),Sr=0;Sr<Er.length;Sr++)It.set(Er[Sr],0);c("onMouseEnter",["mouseout","mouseover"]),c("onMouseLeave",["mouseout","mouseover"]),c("onPointerEnter",["pointerout","pointerover"]),c("onPointerLeave",["pointerout","pointerover"]),u("onChange","change click focusin focusout input keydown keyup selectionchange".split(" ")),u("onSelect","focusout contextmenu dragend focusin keydown keyup mousedown mouseup selectionchange".split(" ")),u("onBeforeInput",["compositionend","keypress","textInput","paste"]),u("onCompositionEnd","compositionend focusout keydown keypress keyup mousedown".split(" ")),u("onCompositionStart","compositionstart focusout keydown keypress keyup mousedown".split(" ")),u("onCompositionUpdate","compositionupdate focusout keydown keypress keyup mousedown".split(" "));var Cr="abort canplay canplaythrough durationchange emptied encrypted ended error loadeddata loadedmetadata loadstart pause play playing progress ratechange seeked seeking stalled suspend timeupdate volumechange waiting".split(" "),Tr=new Set("cancel close invalid load scroll toggle".split(" ").concat(Cr));function Or(e,t,n){var r=e.type||"unknown-event";e.currentTarget=n,function(e,t,n,r,o,a,l,s,u){if(Qe.apply(this,arguments),Ve){if(!Ve)throw Error(i(198));var c=qe;Ve=!1,qe=null,Ge||(Ge=!0,We=c)}}(r,t,void 0,e),e.currentTarget=null}function Dr(e,t){t=0!=(4&t);for(var n=0;n<e.length;n++){var r=e[n],o=r.event;r=r.listeners;e:{var a=void 0;if(t)for(var i=r.length-1;0<=i;i--){var l=r[i],s=l.instance,u=l.currentTarget;if(l=l.listener,s!==a&&o.isPropagationStopped())break e;Or(o,l,u),a=s}else for(i=0;i<r.length;i++){if(s=(l=r[i]).instance,u=l.currentTarget,l=l.listener,s!==a&&o.isPropagationStopped())break e;Or(o,l,u),a=s}}}if(Ge)throw e=We,Ge=!1,We=null,e}function Pr(e,t){var n=io(t),r=e+"__bubble";n.has(r)||(Lr(t,e,2,!1),n.add(r))}var Nr="_reactListening"+Math.random().toString(36).slice(2);function Ar(e){e[Nr]||(e[Nr]=!0,l.forEach((function(t){Tr.has(t)||Ir(t,!1,e,null),Ir(t,!0,e,null)})))}function Ir(e,t,n,r){var o=4<arguments.length&&void 0!==arguments[4]?arguments[4]:0,a=n;if("selectionchange"===e&&9!==n.nodeType&&(a=n.ownerDocument),null!==r&&!t&&Tr.has(e)){if("scroll"!==e)return;o|=2,a=r}var i=io(a),l=e+"__"+(t?"capture":"bubble");i.has(l)||(t&&(o|=4),Lr(a,e,o,t),i.add(l))}function Lr(e,t,n,r){var o=It.get(t);switch(void 0===o?2:o){case 0:o=Yt;break;case 1:o=Xt;break;default:o=Kt}n=o.bind(null,t,n,e),o=void 0,!$e||"touchstart"!==t&&"touchmove"!==t&&"wheel"!==t||(o=!0),r?void 0!==o?e.addEventListener(t,n,{capture:!0,passive:o}):e.addEventListener(t,n,!0):void 0!==o?e.addEventListener(t,n,{passive:o}):e.addEventListener(t,n,!1)}function Rr(e,t,n,r,o){var a=r;if(0==(1&t)&&0==(2&t)&&null!==r)e:for(;;){if(null===r)return;var i=r.tag;if(3===i||4===i){var l=r.stateNode.containerInfo;if(l===o||8===l.nodeType&&l.parentNode===o)break;if(4===i)for(i=r.return;null!==i;){var s=i.tag;if((3===s||4===s)&&((s=i.stateNode.containerInfo)===o||8===s.nodeType&&s.parentNode===o))return;i=i.return}for(;null!==l;){if(null===(i=no(l)))return;if(5===(s=i.tag)||6===s){r=a=i;continue e}l=l.parentNode}}r=r.return}!function(e,t,n){if(Fe)return e(t,n);Fe=!0;try{je(e,t,n)}finally{Fe=!1,Be()}}((function(){var r=a,o=Ce(n),i=[];e:{var l=At.get(e);if(void 0!==l){var s=pn,u=e;switch(e){case"keypress":if(0===on(n))break e;case"keydown":case"keyup":s=Pn;break;case"focusin":u="focus",s=yn;break;case"focusout":u="blur",s=yn;break;case"beforeblur":case"afterblur":s=yn;break;case"click":if(2===n.button)break e;case"auxclick":case"dblclick":case"mousedown":case"mousemove":case"mouseup":case"mouseout":case"mouseover":case"contextmenu":s=vn;break;case"drag":case"dragend":case"dragenter":case"dragexit":case"dragleave":case"dragover":case"dragstart":case"drop":s=bn;break;case"touchcancel":case"touchend":case"touchmove":case"touchstart":s=An;break;case Ot:case Dt:case Pt:s=wn;break;case Nt:s=In;break;case"scroll":s=mn;break;case"wheel":s=Rn;break;case"copy":case"cut":case"paste":s=_n;break;case"gotpointercapture":case"lostpointercapture":case"pointercancel":case"pointerdown":case"pointermove":case"pointerout":case"pointerover":case"pointerup":s=Nn}var c=0!=(4&t),d=!c&&"scroll"===e,f=c?null!==l?l+"Capture":null:l;c=[];for(var p,h=r;null!==h;){var m=(p=h).stateNode;if(5===p.tag&&null!==m&&(p=m,null!==f&&(null!=(m=ze(h,f))&&c.push(jr(h,m,p)))),d)break;h=h.return}0<c.length&&(l=new s(l,u,null,n,o),i.push({event:l,listeners:c}))}}if(0==(7&t)){if(s="mouseout"===e||"pointerout"===e,(!(l="mouseover"===e||"pointerover"===e)||0!=(16&t)||!(u=n.relatedTarget||n.fromElement)||!no(u)&&!u[eo])&&(s||l)&&(l=o.window===o?o:(l=o.ownerDocument)?l.defaultView||l.parentWindow:window,s?(s=r,null!==(u=(u=n.relatedTarget||n.toElement)?no(u):null)&&(u!==(d=Ye(u))||5!==u.tag&&6!==u.tag)&&(u=null)):(s=null,u=r),s!==u)){if(c=vn,m="onMouseLeave",f="onMouseEnter",h="mouse","pointerout"!==e&&"pointerover"!==e||(c=Nn,m="onPointerLeave",f="onPointerEnter",h="pointer"),d=null==s?l:oo(s),p=null==u?l:oo(u),(l=new c(m,h+"leave",s,n,o)).target=d,l.relatedTarget=p,m=null,no(o)===r&&((c=new c(f,h+"enter",u,n,o)).target=p,c.relatedTarget=d,m=c),d=m,s&&u)e:{for(f=u,h=0,p=c=s;p;p=Fr(p))h++;for(p=0,m=f;m;m=Fr(m))p++;for(;0<h-p;)c=Fr(c),h--;for(;0<p-h;)f=Fr(f),p--;for(;h--;){if(c===f||null!==f&&c===f.alternate)break e;c=Fr(c),f=Fr(f)}c=null}else c=null;null!==s&&Br(i,l,s,c,!1),null!==u&&null!==d&&Br(i,d,u,c,!0)}if("select"===(s=(l=r?oo(r):window).nodeName&&l.nodeName.toLowerCase())||"input"===s&&"file"===l.type)var g=Jn;else if(Wn(l))if(er)g=ur;else{g=lr;var v=ir}else(s=l.nodeName)&&"input"===s.toLowerCase()&&("checkbox"===l.type||"radio"===l.type)&&(g=sr);switch(g&&(g=g(e,r))?Zn(i,g,n,o):(v&&v(e,l,r),"focusout"===e&&(v=l._wrapperState)&&v.controlled&&"number"===l.type&&oe(l,"number",l.value)),v=r?oo(r):window,e){case"focusin":(Wn(v)||"true"===v.contentEditable)&&(yr=v,wr=r,xr=null);break;case"focusout":xr=wr=yr=null;break;case"mousedown":_r=!0;break;case"contextmenu":case"mouseup":case"dragend":_r=!1,kr(i,n,o);break;case"selectionchange":if(br)break;case"keydown":case"keyup":kr(i,n,o)}var b;if(Mn)e:{switch(e){case"compositionstart":var y="onCompositionStart";break e;case"compositionend":y="onCompositionEnd";break e;case"compositionupdate":y="onCompositionUpdate";break e}y=void 0}else qn?Hn(e,n)&&(y="onCompositionEnd"):"keydown"===e&&229===n.keyCode&&(y="onCompositionStart");y&&(zn&&"ko"!==n.locale&&(qn||"onCompositionStart"!==y?"onCompositionEnd"===y&&qn&&(b=rn()):(tn="value"in(en=o)?en.value:en.textContent,qn=!0)),0<(v=Mr(r,y)).length&&(y=new kn(y,e,null,n,o),i.push({event:y,listeners:v}),b?y.data=b:null!==(b=Vn(n))&&(y.data=b))),(b=Bn?function(e,t){switch(e){case"compositionend":return Vn(t);case"keypress":return 32!==t.which?null:(Un=!0,$n);case"textInput":return(e=t.data)===$n&&Un?null:e;default:return null}}(e,n):function(e,t){if(qn)return"compositionend"===e||!Mn&&Hn(e,t)?(e=rn(),nn=tn=en=null,qn=!1,e):null;switch(e){case"paste":default:return null;case"keypress":if(!(t.ctrlKey||t.altKey||t.metaKey)||t.ctrlKey&&t.altKey){if(t.char&&1<t.char.length)return t.char;if(t.which)return String.fromCharCode(t.which)}return null;case"compositionend":return zn&&"ko"!==t.locale?null:t.data}}(e,n))&&(0<(r=Mr(r,"onBeforeInput")).length&&(o=new kn("onBeforeInput","beforeinput",null,n,o),i.push({event:o,listeners:r}),o.data=b))}Dr(i,t)}))}function jr(e,t,n){return{instance:e,listener:t,currentTarget:n}}function Mr(e,t){for(var n=t+"Capture",r=[];null!==e;){var o=e,a=o.stateNode;5===o.tag&&null!==a&&(o=a,null!=(a=ze(e,n))&&r.unshift(jr(e,a,o)),null!=(a=ze(e,t))&&r.push(jr(e,a,o))),e=e.return}return r}function Fr(e){if(null===e)return null;do{e=e.return}while(e&&5!==e.tag);return e||null}function Br(e,t,n,r,o){for(var a=t._reactName,i=[];null!==n&&n!==r;){var l=n,s=l.alternate,u=l.stateNode;if(null!==s&&s===r)break;5===l.tag&&null!==u&&(l=u,o?null!=(s=ze(n,a))&&i.unshift(jr(n,s,l)):o||null!=(s=ze(n,a))&&i.push(jr(n,s,l))),n=n.return}0!==i.length&&e.push({event:t,listeners:i})}function zr(){}var $r=null,Ur=null;function Hr(e,t){switch(e){case"button":case"input":case"select":case"textarea":return!!t.autoFocus}return!1}function Vr(e,t){return"textarea"===e||"option"===e||"noscript"===e||"string"==typeof t.children||"number"==typeof t.children||"object"==typeof t.dangerouslySetInnerHTML&&null!==t.dangerouslySetInnerHTML&&null!=t.dangerouslySetInnerHTML.__html}var qr="function"==typeof setTimeout?setTimeout:void 0,Gr="function"==typeof clearTimeout?clearTimeout:void 0;function Wr(e){1===e.nodeType?e.textContent="":9===e.nodeType&&(null!=(e=e.body)&&(e.textContent=""))}function Zr(e){for(;null!=e;e=e.nextSibling){var t=e.nodeType;if(1===t||3===t)break}return e}function Qr(e){e=e.previousSibling;for(var t=0;e;){if(8===e.nodeType){var n=e.data;if("$"===n||"$!"===n||"$?"===n){if(0===t)return e;t--}else"/$"===n&&t++}e=e.previousSibling}return null}var Yr=0;var Xr=Math.random().toString(36).slice(2),Kr="__reactFiber$"+Xr,Jr="__reactProps$"+Xr,eo="__reactContainer$"+Xr,to="__reactEvents$"+Xr;function no(e){var t=e[Kr];if(t)return t;for(var n=e.parentNode;n;){if(t=n[eo]||n[Kr]){if(n=t.alternate,null!==t.child||null!==n&&null!==n.child)for(e=Qr(e);null!==e;){if(n=e[Kr])return n;e=Qr(e)}return t}n=(e=n).parentNode}return null}function ro(e){return!(e=e[Kr]||e[eo])||5!==e.tag&&6!==e.tag&&13!==e.tag&&3!==e.tag?null:e}function oo(e){if(5===e.tag||6===e.tag)return e.stateNode;throw Error(i(33))}function ao(e){return e[Jr]||null}function io(e){var t=e[to];return void 0===t&&(t=e[to]=new Set),t}var lo=[],so=-1;function uo(e){return{current:e}}function co(e){0>so||(e.current=lo[so],lo[so]=null,so--)}function fo(e,t){so++,lo[so]=e.current,e.current=t}var po={},ho=uo(po),mo=uo(!1),go=po;function vo(e,t){var n=e.type.contextTypes;if(!n)return po;var r=e.stateNode;if(r&&r.__reactInternalMemoizedUnmaskedChildContext===t)return r.__reactInternalMemoizedMaskedChildContext;var o,a={};for(o in n)a[o]=t[o];return r&&((e=e.stateNode).__reactInternalMemoizedUnmaskedChildContext=t,e.__reactInternalMemoizedMaskedChildContext=a),a}function bo(e){return null!=(e=e.childContextTypes)}function yo(){co(mo),co(ho)}function wo(e,t,n){if(ho.current!==po)throw Error(i(168));fo(ho,t),fo(mo,n)}function xo(e,t,n){var r=e.stateNode;if(e=t.childContextTypes,"function"!=typeof r.getChildContext)return n;for(var a in r=r.getChildContext())if(!(a in e))throw Error(i(108,W(t)||"Unknown",a));return o({},n,r)}function _o(e){return e=(e=e.stateNode)&&e.__reactInternalMemoizedMergedChildContext||po,go=ho.current,fo(ho,e),fo(mo,mo.current),!0}function ko(e,t,n){var r=e.stateNode;if(!r)throw Error(i(169));n?(e=xo(e,t,go),r.__reactInternalMemoizedMergedChildContext=e,co(mo),co(ho),fo(ho,e)):co(mo),fo(mo,n)}var Eo=null,So=null,Co=a.unstable_runWithPriority,To=a.unstable_scheduleCallback,Oo=a.unstable_cancelCallback,Do=a.unstable_shouldYield,Po=a.unstable_requestPaint,No=a.unstable_now,Ao=a.unstable_getCurrentPriorityLevel,Io=a.unstable_ImmediatePriority,Lo=a.unstable_UserBlockingPriority,Ro=a.unstable_NormalPriority,jo=a.unstable_LowPriority,Mo=a.unstable_IdlePriority,Fo={},Bo=void 0!==Po?Po:function(){},zo=null,$o=null,Uo=!1,Ho=No(),Vo=1e4>Ho?No:function(){return No()-Ho};function qo(){switch(Ao()){case Io:return 99;case Lo:return 98;case Ro:return 97;case jo:return 96;case Mo:return 95;default:throw Error(i(332))}}function Go(e){switch(e){case 99:return Io;case 98:return Lo;case 97:return Ro;case 96:return jo;case 95:return Mo;default:throw Error(i(332))}}function Wo(e,t){return e=Go(e),Co(e,t)}function Zo(e,t,n){return e=Go(e),To(e,t,n)}function Qo(){if(null!==$o){var e=$o;$o=null,Oo(e)}Yo()}function Yo(){if(!Uo&&null!==zo){Uo=!0;var e=0;try{var t=zo;Wo(99,(function(){for(;e<t.length;e++){var n=t[e];do{n=n(!0)}while(null!==n)}})),zo=null}catch(n){throw null!==zo&&(zo=zo.slice(e+1)),To(Io,Qo),n}finally{Uo=!1}}}var Xo=x.ReactCurrentBatchConfig;function Ko(e,t){if(e&&e.defaultProps){for(var n in t=o({},t),e=e.defaultProps)void 0===t[n]&&(t[n]=e[n]);return t}return t}var Jo=uo(null),ea=null,ta=null,na=null;function ra(){na=ta=ea=null}function oa(e){var t=Jo.current;co(Jo),e.type._context._currentValue=t}function aa(e,t){for(;null!==e;){var n=e.alternate;if((e.childLanes&t)===t){if(null===n||(n.childLanes&t)===t)break;n.childLanes|=t}else e.childLanes|=t,null!==n&&(n.childLanes|=t);e=e.return}}function ia(e,t){ea=e,na=ta=null,null!==(e=e.dependencies)&&null!==e.firstContext&&(0!=(e.lanes&t)&&(Mi=!0),e.firstContext=null)}function la(e,t){if(na!==e&&!1!==t&&0!==t)if("number"==typeof t&&1073741823!==t||(na=e,t=1073741823),t={context:e,observedBits:t,next:null},null===ta){if(null===ea)throw Error(i(308));ta=t,ea.dependencies={lanes:0,firstContext:t,responders:null}}else ta=ta.next=t;return e._currentValue}var sa=!1;function ua(e){e.updateQueue={baseState:e.memoizedState,firstBaseUpdate:null,lastBaseUpdate:null,shared:{pending:null},effects:null}}function ca(e,t){e=e.updateQueue,t.updateQueue===e&&(t.updateQueue={baseState:e.baseState,firstBaseUpdate:e.firstBaseUpdate,lastBaseUpdate:e.lastBaseUpdate,shared:e.shared,effects:e.effects})}function da(e,t){return{eventTime:e,lane:t,tag:0,payload:null,callback:null,next:null}}function fa(e,t){if(null!==(e=e.updateQueue)){var n=(e=e.shared).pending;null===n?t.next=t:(t.next=n.next,n.next=t),e.pending=t}}function pa(e,t){var n=e.updateQueue,r=e.alternate;if(null!==r&&n===(r=r.updateQueue)){var o=null,a=null;if(null!==(n=n.firstBaseUpdate)){do{var i={eventTime:n.eventTime,lane:n.lane,tag:n.tag,payload:n.payload,callback:n.callback,next:null};null===a?o=a=i:a=a.next=i,n=n.next}while(null!==n);null===a?o=a=t:a=a.next=t}else o=a=t;return n={baseState:r.baseState,firstBaseUpdate:o,lastBaseUpdate:a,shared:r.shared,effects:r.effects},void(e.updateQueue=n)}null===(e=n.lastBaseUpdate)?n.firstBaseUpdate=t:e.next=t,n.lastBaseUpdate=t}function ha(e,t,n,r){var a=e.updateQueue;sa=!1;var i=a.firstBaseUpdate,l=a.lastBaseUpdate,s=a.shared.pending;if(null!==s){a.shared.pending=null;var u=s,c=u.next;u.next=null,null===l?i=c:l.next=c,l=u;var d=e.alternate;if(null!==d){var f=(d=d.updateQueue).lastBaseUpdate;f!==l&&(null===f?d.firstBaseUpdate=c:f.next=c,d.lastBaseUpdate=u)}}if(null!==i){for(f=a.baseState,l=0,d=c=u=null;;){s=i.lane;var p=i.eventTime;if((r&s)===s){null!==d&&(d=d.next={eventTime:p,lane:0,tag:i.tag,payload:i.payload,callback:i.callback,next:null});e:{var h=e,m=i;switch(s=t,p=n,m.tag){case 1:if("function"==typeof(h=m.payload)){f=h.call(p,f,s);break e}f=h;break e;case 3:h.flags=-4097&h.flags|64;case 0:if(null==(s="function"==typeof(h=m.payload)?h.call(p,f,s):h))break e;f=o({},f,s);break e;case 2:sa=!0}}null!==i.callback&&(e.flags|=32,null===(s=a.effects)?a.effects=[i]:s.push(i))}else p={eventTime:p,lane:s,tag:i.tag,payload:i.payload,callback:i.callback,next:null},null===d?(c=d=p,u=f):d=d.next=p,l|=s;if(null===(i=i.next)){if(null===(s=a.shared.pending))break;i=s.next,s.next=null,a.lastBaseUpdate=s,a.shared.pending=null}}null===d&&(u=f),a.baseState=u,a.firstBaseUpdate=c,a.lastBaseUpdate=d,$l|=l,e.lanes=l,e.memoizedState=f}}function ma(e,t,n){if(e=t.effects,t.effects=null,null!==e)for(t=0;t<e.length;t++){var r=e[t],o=r.callback;if(null!==o){if(r.callback=null,r=n,"function"!=typeof o)throw Error(i(191,o));o.call(r)}}}var ga=(new r.Component).refs;function va(e,t,n,r){n=null==(n=n(r,t=e.memoizedState))?t:o({},t,n),e.memoizedState=n,0===e.lanes&&(e.updateQueue.baseState=n)}var ba={isMounted:function(e){return!!(e=e._reactInternals)&&Ye(e)===e},enqueueSetState:function(e,t,n){e=e._reactInternals;var r=fs(),o=ps(e),a=da(r,o);a.payload=t,null!=n&&(a.callback=n),fa(e,a),hs(e,o,r)},enqueueReplaceState:function(e,t,n){e=e._reactInternals;var r=fs(),o=ps(e),a=da(r,o);a.tag=1,a.payload=t,null!=n&&(a.callback=n),fa(e,a),hs(e,o,r)},enqueueForceUpdate:function(e,t){e=e._reactInternals;var n=fs(),r=ps(e),o=da(n,r);o.tag=2,null!=t&&(o.callback=t),fa(e,o),hs(e,r,n)}};function ya(e,t,n,r,o,a,i){return"function"==typeof(e=e.stateNode).shouldComponentUpdate?e.shouldComponentUpdate(r,a,i):!t.prototype||!t.prototype.isPureReactComponent||(!fr(n,r)||!fr(o,a))}function wa(e,t,n){var r=!1,o=po,a=t.contextType;return"object"==typeof a&&null!==a?a=la(a):(o=bo(t)?go:ho.current,a=(r=null!=(r=t.contextTypes))?vo(e,o):po),t=new t(n,a),e.memoizedState=null!==t.state&&void 0!==t.state?t.state:null,t.updater=ba,e.stateNode=t,t._reactInternals=e,r&&((e=e.stateNode).__reactInternalMemoizedUnmaskedChildContext=o,e.__reactInternalMemoizedMaskedChildContext=a),t}function xa(e,t,n,r){e=t.state,"function"==typeof t.componentWillReceiveProps&&t.componentWillReceiveProps(n,r),"function"==typeof t.UNSAFE_componentWillReceiveProps&&t.UNSAFE_componentWillReceiveProps(n,r),t.state!==e&&ba.enqueueReplaceState(t,t.state,null)}function _a(e,t,n,r){var o=e.stateNode;o.props=n,o.state=e.memoizedState,o.refs=ga,ua(e);var a=t.contextType;"object"==typeof a&&null!==a?o.context=la(a):(a=bo(t)?go:ho.current,o.context=vo(e,a)),ha(e,n,o,r),o.state=e.memoizedState,"function"==typeof(a=t.getDerivedStateFromProps)&&(va(e,t,a,n),o.state=e.memoizedState),"function"==typeof t.getDerivedStateFromProps||"function"==typeof o.getSnapshotBeforeUpdate||"function"!=typeof o.UNSAFE_componentWillMount&&"function"!=typeof o.componentWillMount||(t=o.state,"function"==typeof o.componentWillMount&&o.componentWillMount(),"function"==typeof o.UNSAFE_componentWillMount&&o.UNSAFE_componentWillMount(),t!==o.state&&ba.enqueueReplaceState(o,o.state,null),ha(e,n,o,r),o.state=e.memoizedState),"function"==typeof o.componentDidMount&&(e.flags|=4)}var ka=Array.isArray;function Ea(e,t,n){if(null!==(e=n.ref)&&"function"!=typeof e&&"object"!=typeof e){if(n._owner){if(n=n._owner){if(1!==n.tag)throw Error(i(309));var r=n.stateNode}if(!r)throw Error(i(147,e));var o=""+e;return null!==t&&null!==t.ref&&"function"==typeof t.ref&&t.ref._stringRef===o?t.ref:(t=function(e){var t=r.refs;t===ga&&(t=r.refs={}),null===e?delete t[o]:t[o]=e},t._stringRef=o,t)}if("string"!=typeof e)throw Error(i(284));if(!n._owner)throw Error(i(290,e))}return e}function Sa(e,t){if("textarea"!==e.type)throw Error(i(31,"[object Object]"===Object.prototype.toString.call(t)?"object with keys {"+Object.keys(t).join(", ")+"}":t))}function Ca(e){function t(t,n){if(e){var r=t.lastEffect;null!==r?(r.nextEffect=n,t.lastEffect=n):t.firstEffect=t.lastEffect=n,n.nextEffect=null,n.flags=8}}function n(n,r){if(!e)return null;for(;null!==r;)t(n,r),r=r.sibling;return null}function r(e,t){for(e=new Map;null!==t;)null!==t.key?e.set(t.key,t):e.set(t.index,t),t=t.sibling;return e}function o(e,t){return(e=Gs(e,t)).index=0,e.sibling=null,e}function a(t,n,r){return t.index=r,e?null!==(r=t.alternate)?(r=r.index)<n?(t.flags=2,n):r:(t.flags=2,n):n}function l(t){return e&&null===t.alternate&&(t.flags=2),t}function s(e,t,n,r){return null===t||6!==t.tag?((t=Ys(n,e.mode,r)).return=e,t):((t=o(t,n)).return=e,t)}function u(e,t,n,r){return null!==t&&t.elementType===n.type?((r=o(t,n.props)).ref=Ea(e,t,n),r.return=e,r):((r=Ws(n.type,n.key,n.props,null,e.mode,r)).ref=Ea(e,t,n),r.return=e,r)}function c(e,t,n,r){return null===t||4!==t.tag||t.stateNode.containerInfo!==n.containerInfo||t.stateNode.implementation!==n.implementation?((t=Xs(n,e.mode,r)).return=e,t):((t=o(t,n.children||[])).return=e,t)}function d(e,t,n,r,a){return null===t||7!==t.tag?((t=Zs(n,e.mode,r,a)).return=e,t):((t=o(t,n)).return=e,t)}function f(e,t,n){if("string"==typeof t||"number"==typeof t)return(t=Ys(""+t,e.mode,n)).return=e,t;if("object"==typeof t&&null!==t){switch(t.$$typeof){case _:return(n=Ws(t.type,t.key,t.props,null,e.mode,n)).ref=Ea(e,null,t),n.return=e,n;case k:return(t=Xs(t,e.mode,n)).return=e,t}if(ka(t)||U(t))return(t=Zs(t,e.mode,n,null)).return=e,t;Sa(e,t)}return null}function p(e,t,n,r){var o=null!==t?t.key:null;if("string"==typeof n||"number"==typeof n)return null!==o?null:s(e,t,""+n,r);if("object"==typeof n&&null!==n){switch(n.$$typeof){case _:return n.key===o?n.type===E?d(e,t,n.props.children,r,o):u(e,t,n,r):null;case k:return n.key===o?c(e,t,n,r):null}if(ka(n)||U(n))return null!==o?null:d(e,t,n,r,null);Sa(e,n)}return null}function h(e,t,n,r,o){if("string"==typeof r||"number"==typeof r)return s(t,e=e.get(n)||null,""+r,o);if("object"==typeof r&&null!==r){switch(r.$$typeof){case _:return e=e.get(null===r.key?n:r.key)||null,r.type===E?d(t,e,r.props.children,o,r.key):u(t,e,r,o);case k:return c(t,e=e.get(null===r.key?n:r.key)||null,r,o)}if(ka(r)||U(r))return d(t,e=e.get(n)||null,r,o,null);Sa(t,r)}return null}function m(o,i,l,s){for(var u=null,c=null,d=i,m=i=0,g=null;null!==d&&m<l.length;m++){d.index>m?(g=d,d=null):g=d.sibling;var v=p(o,d,l[m],s);if(null===v){null===d&&(d=g);break}e&&d&&null===v.alternate&&t(o,d),i=a(v,i,m),null===c?u=v:c.sibling=v,c=v,d=g}if(m===l.length)return n(o,d),u;if(null===d){for(;m<l.length;m++)null!==(d=f(o,l[m],s))&&(i=a(d,i,m),null===c?u=d:c.sibling=d,c=d);return u}for(d=r(o,d);m<l.length;m++)null!==(g=h(d,o,m,l[m],s))&&(e&&null!==g.alternate&&d.delete(null===g.key?m:g.key),i=a(g,i,m),null===c?u=g:c.sibling=g,c=g);return e&&d.forEach((function(e){return t(o,e)})),u}function g(o,l,s,u){var c=U(s);if("function"!=typeof c)throw Error(i(150));if(null==(s=c.call(s)))throw Error(i(151));for(var d=c=null,m=l,g=l=0,v=null,b=s.next();null!==m&&!b.done;g++,b=s.next()){m.index>g?(v=m,m=null):v=m.sibling;var y=p(o,m,b.value,u);if(null===y){null===m&&(m=v);break}e&&m&&null===y.alternate&&t(o,m),l=a(y,l,g),null===d?c=y:d.sibling=y,d=y,m=v}if(b.done)return n(o,m),c;if(null===m){for(;!b.done;g++,b=s.next())null!==(b=f(o,b.value,u))&&(l=a(b,l,g),null===d?c=b:d.sibling=b,d=b);return c}for(m=r(o,m);!b.done;g++,b=s.next())null!==(b=h(m,o,g,b.value,u))&&(e&&null!==b.alternate&&m.delete(null===b.key?g:b.key),l=a(b,l,g),null===d?c=b:d.sibling=b,d=b);return e&&m.forEach((function(e){return t(o,e)})),c}return function(e,r,a,s){var u="object"==typeof a&&null!==a&&a.type===E&&null===a.key;u&&(a=a.props.children);var c="object"==typeof a&&null!==a;if(c)switch(a.$$typeof){case _:e:{for(c=a.key,u=r;null!==u;){if(u.key===c){if(7===u.tag){if(a.type===E){n(e,u.sibling),(r=o(u,a.props.children)).return=e,e=r;break e}}else if(u.elementType===a.type){n(e,u.sibling),(r=o(u,a.props)).ref=Ea(e,u,a),r.return=e,e=r;break e}n(e,u);break}t(e,u),u=u.sibling}a.type===E?((r=Zs(a.props.children,e.mode,s,a.key)).return=e,e=r):((s=Ws(a.type,a.key,a.props,null,e.mode,s)).ref=Ea(e,r,a),s.return=e,e=s)}return l(e);case k:e:{for(u=a.key;null!==r;){if(r.key===u){if(4===r.tag&&r.stateNode.containerInfo===a.containerInfo&&r.stateNode.implementation===a.implementation){n(e,r.sibling),(r=o(r,a.children||[])).return=e,e=r;break e}n(e,r);break}t(e,r),r=r.sibling}(r=Xs(a,e.mode,s)).return=e,e=r}return l(e)}if("string"==typeof a||"number"==typeof a)return a=""+a,null!==r&&6===r.tag?(n(e,r.sibling),(r=o(r,a)).return=e,e=r):(n(e,r),(r=Ys(a,e.mode,s)).return=e,e=r),l(e);if(ka(a))return m(e,r,a,s);if(U(a))return g(e,r,a,s);if(c&&Sa(e,a),void 0===a&&!u)switch(e.tag){case 1:case 22:case 0:case 11:case 15:throw Error(i(152,W(e.type)||"Component"))}return n(e,r)}}var Ta=Ca(!0),Oa=Ca(!1),Da={},Pa=uo(Da),Na=uo(Da),Aa=uo(Da);function Ia(e){if(e===Da)throw Error(i(174));return e}function La(e,t){switch(fo(Aa,t),fo(Na,e),fo(Pa,Da),e=t.nodeType){case 9:case 11:t=(t=t.documentElement)?t.namespaceURI:he(null,"");break;default:t=he(t=(e=8===e?t.parentNode:t).namespaceURI||null,e=e.tagName)}co(Pa),fo(Pa,t)}function Ra(){co(Pa),co(Na),co(Aa)}function ja(e){Ia(Aa.current);var t=Ia(Pa.current),n=he(t,e.type);t!==n&&(fo(Na,e),fo(Pa,n))}function Ma(e){Na.current===e&&(co(Pa),co(Na))}var Fa=uo(0);function Ba(e){for(var t=e;null!==t;){if(13===t.tag){var n=t.memoizedState;if(null!==n&&(null===(n=n.dehydrated)||"$?"===n.data||"$!"===n.data))return t}else if(19===t.tag&&void 0!==t.memoizedProps.revealOrder){if(0!=(64&t.flags))return t}else if(null!==t.child){t.child.return=t,t=t.child;continue}if(t===e)break;for(;null===t.sibling;){if(null===t.return||t.return===e)return null;t=t.return}t.sibling.return=t.return,t=t.sibling}return null}var za=null,$a=null,Ua=!1;function Ha(e,t){var n=Vs(5,null,null,0);n.elementType="DELETED",n.type="DELETED",n.stateNode=t,n.return=e,n.flags=8,null!==e.lastEffect?(e.lastEffect.nextEffect=n,e.lastEffect=n):e.firstEffect=e.lastEffect=n}function Va(e,t){switch(e.tag){case 5:var n=e.type;return null!==(t=1!==t.nodeType||n.toLowerCase()!==t.nodeName.toLowerCase()?null:t)&&(e.stateNode=t,!0);case 6:return null!==(t=""===e.pendingProps||3!==t.nodeType?null:t)&&(e.stateNode=t,!0);default:return!1}}function qa(e){if(Ua){var t=$a;if(t){var n=t;if(!Va(e,t)){if(!(t=Zr(n.nextSibling))||!Va(e,t))return e.flags=-1025&e.flags|2,Ua=!1,void(za=e);Ha(za,n)}za=e,$a=Zr(t.firstChild)}else e.flags=-1025&e.flags|2,Ua=!1,za=e}}function Ga(e){for(e=e.return;null!==e&&5!==e.tag&&3!==e.tag&&13!==e.tag;)e=e.return;za=e}function Wa(e){if(e!==za)return!1;if(!Ua)return Ga(e),Ua=!0,!1;var t=e.type;if(5!==e.tag||"head"!==t&&"body"!==t&&!Vr(t,e.memoizedProps))for(t=$a;t;)Ha(e,t),t=Zr(t.nextSibling);if(Ga(e),13===e.tag){if(!(e=null!==(e=e.memoizedState)?e.dehydrated:null))throw Error(i(317));e:{for(e=e.nextSibling,t=0;e;){if(8===e.nodeType){var n=e.data;if("/$"===n){if(0===t){$a=Zr(e.nextSibling);break e}t--}else"$"!==n&&"$!"!==n&&"$?"!==n||t++}e=e.nextSibling}$a=null}}else $a=za?Zr(e.stateNode.nextSibling):null;return!0}function Za(){$a=za=null,Ua=!1}var Qa=[];function Ya(){for(var e=0;e<Qa.length;e++)Qa[e]._workInProgressVersionPrimary=null;Qa.length=0}var Xa=x.ReactCurrentDispatcher,Ka=x.ReactCurrentBatchConfig,Ja=0,ei=null,ti=null,ni=null,ri=!1,oi=!1;function ai(){throw Error(i(321))}function ii(e,t){if(null===t)return!1;for(var n=0;n<t.length&&n<e.length;n++)if(!cr(e[n],t[n]))return!1;return!0}function li(e,t,n,r,o,a){if(Ja=a,ei=t,t.memoizedState=null,t.updateQueue=null,t.lanes=0,Xa.current=null===e||null===e.memoizedState?Ii:Li,e=n(r,o),oi){a=0;do{if(oi=!1,!(25>a))throw Error(i(301));a+=1,ni=ti=null,t.updateQueue=null,Xa.current=Ri,e=n(r,o)}while(oi)}if(Xa.current=Ai,t=null!==ti&&null!==ti.next,Ja=0,ni=ti=ei=null,ri=!1,t)throw Error(i(300));return e}function si(){var e={memoizedState:null,baseState:null,baseQueue:null,queue:null,next:null};return null===ni?ei.memoizedState=ni=e:ni=ni.next=e,ni}function ui(){if(null===ti){var e=ei.alternate;e=null!==e?e.memoizedState:null}else e=ti.next;var t=null===ni?ei.memoizedState:ni.next;if(null!==t)ni=t,ti=e;else{if(null===e)throw Error(i(310));e={memoizedState:(ti=e).memoizedState,baseState:ti.baseState,baseQueue:ti.baseQueue,queue:ti.queue,next:null},null===ni?ei.memoizedState=ni=e:ni=ni.next=e}return ni}function ci(e,t){return"function"==typeof t?t(e):t}function di(e){var t=ui(),n=t.queue;if(null===n)throw Error(i(311));n.lastRenderedReducer=e;var r=ti,o=r.baseQueue,a=n.pending;if(null!==a){if(null!==o){var l=o.next;o.next=a.next,a.next=l}r.baseQueue=o=a,n.pending=null}if(null!==o){o=o.next,r=r.baseState;var s=l=a=null,u=o;do{var c=u.lane;if((Ja&c)===c)null!==s&&(s=s.next={lane:0,action:u.action,eagerReducer:u.eagerReducer,eagerState:u.eagerState,next:null}),r=u.eagerReducer===e?u.eagerState:e(r,u.action);else{var d={lane:c,action:u.action,eagerReducer:u.eagerReducer,eagerState:u.eagerState,next:null};null===s?(l=s=d,a=r):s=s.next=d,ei.lanes|=c,$l|=c}u=u.next}while(null!==u&&u!==o);null===s?a=r:s.next=l,cr(r,t.memoizedState)||(Mi=!0),t.memoizedState=r,t.baseState=a,t.baseQueue=s,n.lastRenderedState=r}return[t.memoizedState,n.dispatch]}function fi(e){var t=ui(),n=t.queue;if(null===n)throw Error(i(311));n.lastRenderedReducer=e;var r=n.dispatch,o=n.pending,a=t.memoizedState;if(null!==o){n.pending=null;var l=o=o.next;do{a=e(a,l.action),l=l.next}while(l!==o);cr(a,t.memoizedState)||(Mi=!0),t.memoizedState=a,null===t.baseQueue&&(t.baseState=a),n.lastRenderedState=a}return[a,r]}function pi(e,t,n){var r=t._getVersion;r=r(t._source);var o=t._workInProgressVersionPrimary;if(null!==o?e=o===r:(e=e.mutableReadLanes,(e=(Ja&e)===e)&&(t._workInProgressVersionPrimary=r,Qa.push(t))),e)return n(t._source);throw Qa.push(t),Error(i(350))}function hi(e,t,n,r){var o=Il;if(null===o)throw Error(i(349));var a=t._getVersion,l=a(t._source),s=Xa.current,u=s.useState((function(){return pi(o,t,n)})),c=u[1],d=u[0];u=ni;var f=e.memoizedState,p=f.refs,h=p.getSnapshot,m=f.source;f=f.subscribe;var g=ei;return e.memoizedState={refs:p,source:t,subscribe:r},s.useEffect((function(){p.getSnapshot=n,p.setSnapshot=c;var e=a(t._source);if(!cr(l,e)){e=n(t._source),cr(d,e)||(c(e),e=ps(g),o.mutableReadLanes|=e&o.pendingLanes),e=o.mutableReadLanes,o.entangledLanes|=e;for(var r=o.entanglements,i=e;0<i;){var s=31-Vt(i),u=1<<s;r[s]|=e,i&=~u}}}),[n,t,r]),s.useEffect((function(){return r(t._source,(function(){var e=p.getSnapshot,n=p.setSnapshot;try{n(e(t._source));var r=ps(g);o.mutableReadLanes|=r&o.pendingLanes}catch(a){n((function(){throw a}))}}))}),[t,r]),cr(h,n)&&cr(m,t)&&cr(f,r)||((e={pending:null,dispatch:null,lastRenderedReducer:ci,lastRenderedState:d}).dispatch=c=Ni.bind(null,ei,e),u.queue=e,u.baseQueue=null,d=pi(o,t,n),u.memoizedState=u.baseState=d),d}function mi(e,t,n){return hi(ui(),e,t,n)}function gi(e){var t=si();return"function"==typeof e&&(e=e()),t.memoizedState=t.baseState=e,e=(e=t.queue={pending:null,dispatch:null,lastRenderedReducer:ci,lastRenderedState:e}).dispatch=Ni.bind(null,ei,e),[t.memoizedState,e]}function vi(e,t,n,r){return e={tag:e,create:t,destroy:n,deps:r,next:null},null===(t=ei.updateQueue)?(t={lastEffect:null},ei.updateQueue=t,t.lastEffect=e.next=e):null===(n=t.lastEffect)?t.lastEffect=e.next=e:(r=n.next,n.next=e,e.next=r,t.lastEffect=e),e}function bi(e){return e={current:e},si().memoizedState=e}function yi(){return ui().memoizedState}function wi(e,t,n,r){var o=si();ei.flags|=e,o.memoizedState=vi(1|t,n,void 0,void 0===r?null:r)}function xi(e,t,n,r){var o=ui();r=void 0===r?null:r;var a=void 0;if(null!==ti){var i=ti.memoizedState;if(a=i.destroy,null!==r&&ii(r,i.deps))return void vi(t,n,a,r)}ei.flags|=e,o.memoizedState=vi(1|t,n,a,r)}function _i(e,t){return wi(516,4,e,t)}function ki(e,t){return xi(516,4,e,t)}function Ei(e,t){return xi(4,2,e,t)}function Si(e,t){return"function"==typeof t?(e=e(),t(e),function(){t(null)}):null!=t?(e=e(),t.current=e,function(){t.current=null}):void 0}function Ci(e,t,n){return n=null!=n?n.concat([e]):null,xi(4,2,Si.bind(null,t,e),n)}function Ti(){}function Oi(e,t){var n=ui();t=void 0===t?null:t;var r=n.memoizedState;return null!==r&&null!==t&&ii(t,r[1])?r[0]:(n.memoizedState=[e,t],e)}function Di(e,t){var n=ui();t=void 0===t?null:t;var r=n.memoizedState;return null!==r&&null!==t&&ii(t,r[1])?r[0]:(e=e(),n.memoizedState=[e,t],e)}function Pi(e,t){var n=qo();Wo(98>n?98:n,(function(){e(!0)})),Wo(97<n?97:n,(function(){var n=Ka.transition;Ka.transition=1;try{e(!1),t()}finally{Ka.transition=n}}))}function Ni(e,t,n){var r=fs(),o=ps(e),a={lane:o,action:n,eagerReducer:null,eagerState:null,next:null},i=t.pending;if(null===i?a.next=a:(a.next=i.next,i.next=a),t.pending=a,i=e.alternate,e===ei||null!==i&&i===ei)oi=ri=!0;else{if(0===e.lanes&&(null===i||0===i.lanes)&&null!==(i=t.lastRenderedReducer))try{var l=t.lastRenderedState,s=i(l,n);if(a.eagerReducer=i,a.eagerState=s,cr(s,l))return}catch(u){}hs(e,o,r)}}var Ai={readContext:la,useCallback:ai,useContext:ai,useEffect:ai,useImperativeHandle:ai,useLayoutEffect:ai,useMemo:ai,useReducer:ai,useRef:ai,useState:ai,useDebugValue:ai,useDeferredValue:ai,useTransition:ai,useMutableSource:ai,useOpaqueIdentifier:ai,unstable_isNewReconciler:!1},Ii={readContext:la,useCallback:function(e,t){return si().memoizedState=[e,void 0===t?null:t],e},useContext:la,useEffect:_i,useImperativeHandle:function(e,t,n){return n=null!=n?n.concat([e]):null,wi(4,2,Si.bind(null,t,e),n)},useLayoutEffect:function(e,t){return wi(4,2,e,t)},useMemo:function(e,t){var n=si();return t=void 0===t?null:t,e=e(),n.memoizedState=[e,t],e},useReducer:function(e,t,n){var r=si();return t=void 0!==n?n(t):t,r.memoizedState=r.baseState=t,e=(e=r.queue={pending:null,dispatch:null,lastRenderedReducer:e,lastRenderedState:t}).dispatch=Ni.bind(null,ei,e),[r.memoizedState,e]},useRef:bi,useState:gi,useDebugValue:Ti,useDeferredValue:function(e){var t=gi(e),n=t[0],r=t[1];return _i((function(){var t=Ka.transition;Ka.transition=1;try{r(e)}finally{Ka.transition=t}}),[e]),n},useTransition:function(){var e=gi(!1),t=e[0];return bi(e=Pi.bind(null,e[1])),[e,t]},useMutableSource:function(e,t,n){var r=si();return r.memoizedState={refs:{getSnapshot:t,setSnapshot:null},source:e,subscribe:n},hi(r,e,t,n)},useOpaqueIdentifier:function(){if(Ua){var e=!1,t=function(e){return{$$typeof:R,toString:e,valueOf:e}}((function(){throw e||(e=!0,n("r:"+(Yr++).toString(36))),Error(i(355))})),n=gi(t)[1];return 0==(2&ei.mode)&&(ei.flags|=516,vi(5,(function(){n("r:"+(Yr++).toString(36))}),void 0,null)),t}return gi(t="r:"+(Yr++).toString(36)),t},unstable_isNewReconciler:!1},Li={readContext:la,useCallback:Oi,useContext:la,useEffect:ki,useImperativeHandle:Ci,useLayoutEffect:Ei,useMemo:Di,useReducer:di,useRef:yi,useState:function(){return di(ci)},useDebugValue:Ti,useDeferredValue:function(e){var t=di(ci),n=t[0],r=t[1];return ki((function(){var t=Ka.transition;Ka.transition=1;try{r(e)}finally{Ka.transition=t}}),[e]),n},useTransition:function(){var e=di(ci)[0];return[yi().current,e]},useMutableSource:mi,useOpaqueIdentifier:function(){return di(ci)[0]},unstable_isNewReconciler:!1},Ri={readContext:la,useCallback:Oi,useContext:la,useEffect:ki,useImperativeHandle:Ci,useLayoutEffect:Ei,useMemo:Di,useReducer:fi,useRef:yi,useState:function(){return fi(ci)},useDebugValue:Ti,useDeferredValue:function(e){var t=fi(ci),n=t[0],r=t[1];return ki((function(){var t=Ka.transition;Ka.transition=1;try{r(e)}finally{Ka.transition=t}}),[e]),n},useTransition:function(){var e=fi(ci)[0];return[yi().current,e]},useMutableSource:mi,useOpaqueIdentifier:function(){return fi(ci)[0]},unstable_isNewReconciler:!1},ji=x.ReactCurrentOwner,Mi=!1;function Fi(e,t,n,r){t.child=null===e?Oa(t,null,n,r):Ta(t,e.child,n,r)}function Bi(e,t,n,r,o){n=n.render;var a=t.ref;return ia(t,o),r=li(e,t,n,r,a,o),null===e||Mi?(t.flags|=1,Fi(e,t,r,o),t.child):(t.updateQueue=e.updateQueue,t.flags&=-517,e.lanes&=~o,al(e,t,o))}function zi(e,t,n,r,o,a){if(null===e){var i=n.type;return"function"!=typeof i||qs(i)||void 0!==i.defaultProps||null!==n.compare||void 0!==n.defaultProps?((e=Ws(n.type,null,r,t,t.mode,a)).ref=t.ref,e.return=t,t.child=e):(t.tag=15,t.type=i,$i(e,t,i,r,o,a))}return i=e.child,0==(o&a)&&(o=i.memoizedProps,(n=null!==(n=n.compare)?n:fr)(o,r)&&e.ref===t.ref)?al(e,t,a):(t.flags|=1,(e=Gs(i,r)).ref=t.ref,e.return=t,t.child=e)}function $i(e,t,n,r,o,a){if(null!==e&&fr(e.memoizedProps,r)&&e.ref===t.ref){if(Mi=!1,0==(a&o))return t.lanes=e.lanes,al(e,t,a);0!=(16384&e.flags)&&(Mi=!0)}return Vi(e,t,n,r,a)}function Ui(e,t,n){var r=t.pendingProps,o=r.children,a=null!==e?e.memoizedState:null;if("hidden"===r.mode||"unstable-defer-without-hiding"===r.mode)if(0==(4&t.mode))t.memoizedState={baseLanes:0},_s(t,n);else{if(0==(1073741824&n))return e=null!==a?a.baseLanes|n:n,t.lanes=t.childLanes=1073741824,t.memoizedState={baseLanes:e},_s(t,e),null;t.memoizedState={baseLanes:0},_s(t,null!==a?a.baseLanes:n)}else null!==a?(r=a.baseLanes|n,t.memoizedState=null):r=n,_s(t,r);return Fi(e,t,o,n),t.child}function Hi(e,t){var n=t.ref;(null===e&&null!==n||null!==e&&e.ref!==n)&&(t.flags|=128)}function Vi(e,t,n,r,o){var a=bo(n)?go:ho.current;return a=vo(t,a),ia(t,o),n=li(e,t,n,r,a,o),null===e||Mi?(t.flags|=1,Fi(e,t,n,o),t.child):(t.updateQueue=e.updateQueue,t.flags&=-517,e.lanes&=~o,al(e,t,o))}function qi(e,t,n,r,o){if(bo(n)){var a=!0;_o(t)}else a=!1;if(ia(t,o),null===t.stateNode)null!==e&&(e.alternate=null,t.alternate=null,t.flags|=2),wa(t,n,r),_a(t,n,r,o),r=!0;else if(null===e){var i=t.stateNode,l=t.memoizedProps;i.props=l;var s=i.context,u=n.contextType;"object"==typeof u&&null!==u?u=la(u):u=vo(t,u=bo(n)?go:ho.current);var c=n.getDerivedStateFromProps,d="function"==typeof c||"function"==typeof i.getSnapshotBeforeUpdate;d||"function"!=typeof i.UNSAFE_componentWillReceiveProps&&"function"!=typeof i.componentWillReceiveProps||(l!==r||s!==u)&&xa(t,i,r,u),sa=!1;var f=t.memoizedState;i.state=f,ha(t,r,i,o),s=t.memoizedState,l!==r||f!==s||mo.current||sa?("function"==typeof c&&(va(t,n,c,r),s=t.memoizedState),(l=sa||ya(t,n,l,r,f,s,u))?(d||"function"!=typeof i.UNSAFE_componentWillMount&&"function"!=typeof i.componentWillMount||("function"==typeof i.componentWillMount&&i.componentWillMount(),"function"==typeof i.UNSAFE_componentWillMount&&i.UNSAFE_componentWillMount()),"function"==typeof i.componentDidMount&&(t.flags|=4)):("function"==typeof i.componentDidMount&&(t.flags|=4),t.memoizedProps=r,t.memoizedState=s),i.props=r,i.state=s,i.context=u,r=l):("function"==typeof i.componentDidMount&&(t.flags|=4),r=!1)}else{i=t.stateNode,ca(e,t),l=t.memoizedProps,u=t.type===t.elementType?l:Ko(t.type,l),i.props=u,d=t.pendingProps,f=i.context,"object"==typeof(s=n.contextType)&&null!==s?s=la(s):s=vo(t,s=bo(n)?go:ho.current);var p=n.getDerivedStateFromProps;(c="function"==typeof p||"function"==typeof i.getSnapshotBeforeUpdate)||"function"!=typeof i.UNSAFE_componentWillReceiveProps&&"function"!=typeof i.componentWillReceiveProps||(l!==d||f!==s)&&xa(t,i,r,s),sa=!1,f=t.memoizedState,i.state=f,ha(t,r,i,o);var h=t.memoizedState;l!==d||f!==h||mo.current||sa?("function"==typeof p&&(va(t,n,p,r),h=t.memoizedState),(u=sa||ya(t,n,u,r,f,h,s))?(c||"function"!=typeof i.UNSAFE_componentWillUpdate&&"function"!=typeof i.componentWillUpdate||("function"==typeof i.componentWillUpdate&&i.componentWillUpdate(r,h,s),"function"==typeof i.UNSAFE_componentWillUpdate&&i.UNSAFE_componentWillUpdate(r,h,s)),"function"==typeof i.componentDidUpdate&&(t.flags|=4),"function"==typeof i.getSnapshotBeforeUpdate&&(t.flags|=256)):("function"!=typeof i.componentDidUpdate||l===e.memoizedProps&&f===e.memoizedState||(t.flags|=4),"function"!=typeof i.getSnapshotBeforeUpdate||l===e.memoizedProps&&f===e.memoizedState||(t.flags|=256),t.memoizedProps=r,t.memoizedState=h),i.props=r,i.state=h,i.context=s,r=u):("function"!=typeof i.componentDidUpdate||l===e.memoizedProps&&f===e.memoizedState||(t.flags|=4),"function"!=typeof i.getSnapshotBeforeUpdate||l===e.memoizedProps&&f===e.memoizedState||(t.flags|=256),r=!1)}return Gi(e,t,n,r,a,o)}function Gi(e,t,n,r,o,a){Hi(e,t);var i=0!=(64&t.flags);if(!r&&!i)return o&&ko(t,n,!1),al(e,t,a);r=t.stateNode,ji.current=t;var l=i&&"function"!=typeof n.getDerivedStateFromError?null:r.render();return t.flags|=1,null!==e&&i?(t.child=Ta(t,e.child,null,a),t.child=Ta(t,null,l,a)):Fi(e,t,l,a),t.memoizedState=r.state,o&&ko(t,n,!0),t.child}function Wi(e){var t=e.stateNode;t.pendingContext?wo(0,t.pendingContext,t.pendingContext!==t.context):t.context&&wo(0,t.context,!1),La(e,t.containerInfo)}var Zi,Qi,Yi,Xi={dehydrated:null,retryLane:0};function Ki(e,t,n){var r,o=t.pendingProps,a=Fa.current,i=!1;return(r=0!=(64&t.flags))||(r=(null===e||null!==e.memoizedState)&&0!=(2&a)),r?(i=!0,t.flags&=-65):null!==e&&null===e.memoizedState||void 0===o.fallback||!0===o.unstable_avoidThisFallback||(a|=1),fo(Fa,1&a),null===e?(void 0!==o.fallback&&qa(t),e=o.children,a=o.fallback,i?(e=Ji(t,e,a,n),t.child.memoizedState={baseLanes:n},t.memoizedState=Xi,e):"number"==typeof o.unstable_expectedLoadTime?(e=Ji(t,e,a,n),t.child.memoizedState={baseLanes:n},t.memoizedState=Xi,t.lanes=33554432,e):((n=Qs({mode:"visible",children:e},t.mode,n,null)).return=t,t.child=n)):(e.memoizedState,i?(o=tl(e,t,o.children,o.fallback,n),i=t.child,a=e.child.memoizedState,i.memoizedState=null===a?{baseLanes:n}:{baseLanes:a.baseLanes|n},i.childLanes=e.childLanes&~n,t.memoizedState=Xi,o):(n=el(e,t,o.children,n),t.memoizedState=null,n))}function Ji(e,t,n,r){var o=e.mode,a=e.child;return t={mode:"hidden",children:t},0==(2&o)&&null!==a?(a.childLanes=0,a.pendingProps=t):a=Qs(t,o,0,null),n=Zs(n,o,r,null),a.return=e,n.return=e,a.sibling=n,e.child=a,n}function el(e,t,n,r){var o=e.child;return e=o.sibling,n=Gs(o,{mode:"visible",children:n}),0==(2&t.mode)&&(n.lanes=r),n.return=t,n.sibling=null,null!==e&&(e.nextEffect=null,e.flags=8,t.firstEffect=t.lastEffect=e),t.child=n}function tl(e,t,n,r,o){var a=t.mode,i=e.child;e=i.sibling;var l={mode:"hidden",children:n};return 0==(2&a)&&t.child!==i?((n=t.child).childLanes=0,n.pendingProps=l,null!==(i=n.lastEffect)?(t.firstEffect=n.firstEffect,t.lastEffect=i,i.nextEffect=null):t.firstEffect=t.lastEffect=null):n=Gs(i,l),null!==e?r=Gs(e,r):(r=Zs(r,a,o,null)).flags|=2,r.return=t,n.return=t,n.sibling=r,t.child=n,r}function nl(e,t){e.lanes|=t;var n=e.alternate;null!==n&&(n.lanes|=t),aa(e.return,t)}function rl(e,t,n,r,o,a){var i=e.memoizedState;null===i?e.memoizedState={isBackwards:t,rendering:null,renderingStartTime:0,last:r,tail:n,tailMode:o,lastEffect:a}:(i.isBackwards=t,i.rendering=null,i.renderingStartTime=0,i.last=r,i.tail=n,i.tailMode=o,i.lastEffect=a)}function ol(e,t,n){var r=t.pendingProps,o=r.revealOrder,a=r.tail;if(Fi(e,t,r.children,n),0!=(2&(r=Fa.current)))r=1&r|2,t.flags|=64;else{if(null!==e&&0!=(64&e.flags))e:for(e=t.child;null!==e;){if(13===e.tag)null!==e.memoizedState&&nl(e,n);else if(19===e.tag)nl(e,n);else if(null!==e.child){e.child.return=e,e=e.child;continue}if(e===t)break e;for(;null===e.sibling;){if(null===e.return||e.return===t)break e;e=e.return}e.sibling.return=e.return,e=e.sibling}r&=1}if(fo(Fa,r),0==(2&t.mode))t.memoizedState=null;else switch(o){case"forwards":for(n=t.child,o=null;null!==n;)null!==(e=n.alternate)&&null===Ba(e)&&(o=n),n=n.sibling;null===(n=o)?(o=t.child,t.child=null):(o=n.sibling,n.sibling=null),rl(t,!1,o,n,a,t.lastEffect);break;case"backwards":for(n=null,o=t.child,t.child=null;null!==o;){if(null!==(e=o.alternate)&&null===Ba(e)){t.child=o;break}e=o.sibling,o.sibling=n,n=o,o=e}rl(t,!0,n,null,a,t.lastEffect);break;case"together":rl(t,!1,null,null,void 0,t.lastEffect);break;default:t.memoizedState=null}return t.child}function al(e,t,n){if(null!==e&&(t.dependencies=e.dependencies),$l|=t.lanes,0!=(n&t.childLanes)){if(null!==e&&t.child!==e.child)throw Error(i(153));if(null!==t.child){for(n=Gs(e=t.child,e.pendingProps),t.child=n,n.return=t;null!==e.sibling;)e=e.sibling,(n=n.sibling=Gs(e,e.pendingProps)).return=t;n.sibling=null}return t.child}return null}function il(e,t){if(!Ua)switch(e.tailMode){case"hidden":t=e.tail;for(var n=null;null!==t;)null!==t.alternate&&(n=t),t=t.sibling;null===n?e.tail=null:n.sibling=null;break;case"collapsed":n=e.tail;for(var r=null;null!==n;)null!==n.alternate&&(r=n),n=n.sibling;null===r?t||null===e.tail?e.tail=null:e.tail.sibling=null:r.sibling=null}}function ll(e,t,n){var r=t.pendingProps;switch(t.tag){case 2:case 16:case 15:case 0:case 11:case 7:case 8:case 12:case 9:case 14:return null;case 1:case 17:return bo(t.type)&&yo(),null;case 3:return Ra(),co(mo),co(ho),Ya(),(r=t.stateNode).pendingContext&&(r.context=r.pendingContext,r.pendingContext=null),null!==e&&null!==e.child||(Wa(t)?t.flags|=4:r.hydrate||(t.flags|=256)),null;case 5:Ma(t);var a=Ia(Aa.current);if(n=t.type,null!==e&&null!=t.stateNode)Qi(e,t,n,r),e.ref!==t.ref&&(t.flags|=128);else{if(!r){if(null===t.stateNode)throw Error(i(166));return null}if(e=Ia(Pa.current),Wa(t)){r=t.stateNode,n=t.type;var l=t.memoizedProps;switch(r[Kr]=t,r[Jr]=l,n){case"dialog":Pr("cancel",r),Pr("close",r);break;case"iframe":case"object":case"embed":Pr("load",r);break;case"video":case"audio":for(e=0;e<Cr.length;e++)Pr(Cr[e],r);break;case"source":Pr("error",r);break;case"img":case"image":case"link":Pr("error",r),Pr("load",r);break;case"details":Pr("toggle",r);break;case"input":ee(r,l),Pr("invalid",r);break;case"select":r._wrapperState={wasMultiple:!!l.multiple},Pr("invalid",r);break;case"textarea":se(r,l),Pr("invalid",r)}for(var u in Ee(n,l),e=null,l)l.hasOwnProperty(u)&&(a=l[u],"children"===u?"string"==typeof a?r.textContent!==a&&(e=["children",a]):"number"==typeof a&&r.textContent!==""+a&&(e=["children",""+a]):s.hasOwnProperty(u)&&null!=a&&"onScroll"===u&&Pr("scroll",r));switch(n){case"input":Y(r),re(r,l,!0);break;case"textarea":Y(r),ce(r);break;case"select":case"option":break;default:"function"==typeof l.onClick&&(r.onclick=zr)}r=e,t.updateQueue=r,null!==r&&(t.flags|=4)}else{switch(u=9===a.nodeType?a:a.ownerDocument,e===de&&(e=pe(n)),e===de?"script"===n?((e=u.createElement("div")).innerHTML="<script><\/script>",e=e.removeChild(e.firstChild)):"string"==typeof r.is?e=u.createElement(n,{is:r.is}):(e=u.createElement(n),"select"===n&&(u=e,r.multiple?u.multiple=!0:r.size&&(u.size=r.size))):e=u.createElementNS(e,n),e[Kr]=t,e[Jr]=r,Zi(e,t),t.stateNode=e,u=Se(n,r),n){case"dialog":Pr("cancel",e),Pr("close",e),a=r;break;case"iframe":case"object":case"embed":Pr("load",e),a=r;break;case"video":case"audio":for(a=0;a<Cr.length;a++)Pr(Cr[a],e);a=r;break;case"source":Pr("error",e),a=r;break;case"img":case"image":case"link":Pr("error",e),Pr("load",e),a=r;break;case"details":Pr("toggle",e),a=r;break;case"input":ee(e,r),a=J(e,r),Pr("invalid",e);break;case"option":a=ae(e,r);break;case"select":e._wrapperState={wasMultiple:!!r.multiple},a=o({},r,{value:void 0}),Pr("invalid",e);break;case"textarea":se(e,r),a=le(e,r),Pr("invalid",e);break;default:a=r}Ee(n,a);var c=a;for(l in c)if(c.hasOwnProperty(l)){var d=c[l];"style"===l?_e(e,d):"dangerouslySetInnerHTML"===l?null!=(d=d?d.__html:void 0)&&ve(e,d):"children"===l?"string"==typeof d?("textarea"!==n||""!==d)&&be(e,d):"number"==typeof d&&be(e,""+d):"suppressContentEditableWarning"!==l&&"suppressHydrationWarning"!==l&&"autoFocus"!==l&&(s.hasOwnProperty(l)?null!=d&&"onScroll"===l&&Pr("scroll",e):null!=d&&w(e,l,d,u))}switch(n){case"input":Y(e),re(e,r,!1);break;case"textarea":Y(e),ce(e);break;case"option":null!=r.value&&e.setAttribute("value",""+Z(r.value));break;case"select":e.multiple=!!r.multiple,null!=(l=r.value)?ie(e,!!r.multiple,l,!1):null!=r.defaultValue&&ie(e,!!r.multiple,r.defaultValue,!0);break;default:"function"==typeof a.onClick&&(e.onclick=zr)}Hr(n,r)&&(t.flags|=4)}null!==t.ref&&(t.flags|=128)}return null;case 6:if(e&&null!=t.stateNode)Yi(0,t,e.memoizedProps,r);else{if("string"!=typeof r&&null===t.stateNode)throw Error(i(166));n=Ia(Aa.current),Ia(Pa.current),Wa(t)?(r=t.stateNode,n=t.memoizedProps,r[Kr]=t,r.nodeValue!==n&&(t.flags|=4)):((r=(9===n.nodeType?n:n.ownerDocument).createTextNode(r))[Kr]=t,t.stateNode=r)}return null;case 13:return co(Fa),r=t.memoizedState,0!=(64&t.flags)?(t.lanes=n,t):(r=null!==r,n=!1,null===e?void 0!==t.memoizedProps.fallback&&Wa(t):n=null!==e.memoizedState,r&&!n&&0!=(2&t.mode)&&(null===e&&!0!==t.memoizedProps.unstable_avoidThisFallback||0!=(1&Fa.current)?0===Fl&&(Fl=3):(0!==Fl&&3!==Fl||(Fl=4),null===Il||0==(134217727&$l)&&0==(134217727&Ul)||bs(Il,Rl))),(r||n)&&(t.flags|=4),null);case 4:return Ra(),null===e&&Ar(t.stateNode.containerInfo),null;case 10:return oa(t),null;case 19:if(co(Fa),null===(r=t.memoizedState))return null;if(l=0!=(64&t.flags),null===(u=r.rendering))if(l)il(r,!1);else{if(0!==Fl||null!==e&&0!=(64&e.flags))for(e=t.child;null!==e;){if(null!==(u=Ba(e))){for(t.flags|=64,il(r,!1),null!==(l=u.updateQueue)&&(t.updateQueue=l,t.flags|=4),null===r.lastEffect&&(t.firstEffect=null),t.lastEffect=r.lastEffect,r=n,n=t.child;null!==n;)e=r,(l=n).flags&=2,l.nextEffect=null,l.firstEffect=null,l.lastEffect=null,null===(u=l.alternate)?(l.childLanes=0,l.lanes=e,l.child=null,l.memoizedProps=null,l.memoizedState=null,l.updateQueue=null,l.dependencies=null,l.stateNode=null):(l.childLanes=u.childLanes,l.lanes=u.lanes,l.child=u.child,l.memoizedProps=u.memoizedProps,l.memoizedState=u.memoizedState,l.updateQueue=u.updateQueue,l.type=u.type,e=u.dependencies,l.dependencies=null===e?null:{lanes:e.lanes,firstContext:e.firstContext}),n=n.sibling;return fo(Fa,1&Fa.current|2),t.child}e=e.sibling}null!==r.tail&&Vo()>Gl&&(t.flags|=64,l=!0,il(r,!1),t.lanes=33554432)}else{if(!l)if(null!==(e=Ba(u))){if(t.flags|=64,l=!0,null!==(n=e.updateQueue)&&(t.updateQueue=n,t.flags|=4),il(r,!0),null===r.tail&&"hidden"===r.tailMode&&!u.alternate&&!Ua)return null!==(t=t.lastEffect=r.lastEffect)&&(t.nextEffect=null),null}else 2*Vo()-r.renderingStartTime>Gl&&1073741824!==n&&(t.flags|=64,l=!0,il(r,!1),t.lanes=33554432);r.isBackwards?(u.sibling=t.child,t.child=u):(null!==(n=r.last)?n.sibling=u:t.child=u,r.last=u)}return null!==r.tail?(n=r.tail,r.rendering=n,r.tail=n.sibling,r.lastEffect=t.lastEffect,r.renderingStartTime=Vo(),n.sibling=null,t=Fa.current,fo(Fa,l?1&t|2:1&t),n):null;case 23:case 24:return ks(),null!==e&&null!==e.memoizedState!=(null!==t.memoizedState)&&"unstable-defer-without-hiding"!==r.mode&&(t.flags|=4),null}throw Error(i(156,t.tag))}function sl(e){switch(e.tag){case 1:bo(e.type)&&yo();var t=e.flags;return 4096&t?(e.flags=-4097&t|64,e):null;case 3:if(Ra(),co(mo),co(ho),Ya(),0!=(64&(t=e.flags)))throw Error(i(285));return e.flags=-4097&t|64,e;case 5:return Ma(e),null;case 13:return co(Fa),4096&(t=e.flags)?(e.flags=-4097&t|64,e):null;case 19:return co(Fa),null;case 4:return Ra(),null;case 10:return oa(e),null;case 23:case 24:return ks(),null;default:return null}}function ul(e,t){try{var n="",r=t;do{n+=G(r),r=r.return}while(r);var o=n}catch(a){o="\nError generating stack: "+a.message+"\n"+a.stack}return{value:e,source:t,stack:o}}function cl(e,t){try{console.error(t.value)}catch(n){setTimeout((function(){throw n}))}}Zi=function(e,t){for(var n=t.child;null!==n;){if(5===n.tag||6===n.tag)e.appendChild(n.stateNode);else if(4!==n.tag&&null!==n.child){n.child.return=n,n=n.child;continue}if(n===t)break;for(;null===n.sibling;){if(null===n.return||n.return===t)return;n=n.return}n.sibling.return=n.return,n=n.sibling}},Qi=function(e,t,n,r){var a=e.memoizedProps;if(a!==r){e=t.stateNode,Ia(Pa.current);var i,l=null;switch(n){case"input":a=J(e,a),r=J(e,r),l=[];break;case"option":a=ae(e,a),r=ae(e,r),l=[];break;case"select":a=o({},a,{value:void 0}),r=o({},r,{value:void 0}),l=[];break;case"textarea":a=le(e,a),r=le(e,r),l=[];break;default:"function"!=typeof a.onClick&&"function"==typeof r.onClick&&(e.onclick=zr)}for(d in Ee(n,r),n=null,a)if(!r.hasOwnProperty(d)&&a.hasOwnProperty(d)&&null!=a[d])if("style"===d){var u=a[d];for(i in u)u.hasOwnProperty(i)&&(n||(n={}),n[i]="")}else"dangerouslySetInnerHTML"!==d&&"children"!==d&&"suppressContentEditableWarning"!==d&&"suppressHydrationWarning"!==d&&"autoFocus"!==d&&(s.hasOwnProperty(d)?l||(l=[]):(l=l||[]).push(d,null));for(d in r){var c=r[d];if(u=null!=a?a[d]:void 0,r.hasOwnProperty(d)&&c!==u&&(null!=c||null!=u))if("style"===d)if(u){for(i in u)!u.hasOwnProperty(i)||c&&c.hasOwnProperty(i)||(n||(n={}),n[i]="");for(i in c)c.hasOwnProperty(i)&&u[i]!==c[i]&&(n||(n={}),n[i]=c[i])}else n||(l||(l=[]),l.push(d,n)),n=c;else"dangerouslySetInnerHTML"===d?(c=c?c.__html:void 0,u=u?u.__html:void 0,null!=c&&u!==c&&(l=l||[]).push(d,c)):"children"===d?"string"!=typeof c&&"number"!=typeof c||(l=l||[]).push(d,""+c):"suppressContentEditableWarning"!==d&&"suppressHydrationWarning"!==d&&(s.hasOwnProperty(d)?(null!=c&&"onScroll"===d&&Pr("scroll",e),l||u===c||(l=[])):"object"==typeof c&&null!==c&&c.$$typeof===R?c.toString():(l=l||[]).push(d,c))}n&&(l=l||[]).push("style",n);var d=l;(t.updateQueue=d)&&(t.flags|=4)}},Yi=function(e,t,n,r){n!==r&&(t.flags|=4)};var dl="function"==typeof WeakMap?WeakMap:Map;function fl(e,t,n){(n=da(-1,n)).tag=3,n.payload={element:null};var r=t.value;return n.callback=function(){Yl||(Yl=!0,Xl=r),cl(0,t)},n}function pl(e,t,n){(n=da(-1,n)).tag=3;var r=e.type.getDerivedStateFromError;if("function"==typeof r){var o=t.value;n.payload=function(){return cl(0,t),r(o)}}var a=e.stateNode;return null!==a&&"function"==typeof a.componentDidCatch&&(n.callback=function(){"function"!=typeof r&&(null===Kl?Kl=new Set([this]):Kl.add(this),cl(0,t));var e=t.stack;this.componentDidCatch(t.value,{componentStack:null!==e?e:""})}),n}var hl="function"==typeof WeakSet?WeakSet:Set;function ml(e){var t=e.ref;if(null!==t)if("function"==typeof t)try{t(null)}catch(n){zs(e,n)}else t.current=null}function gl(e,t){switch(t.tag){case 0:case 11:case 15:case 22:case 5:case 6:case 4:case 17:return;case 1:if(256&t.flags&&null!==e){var n=e.memoizedProps,r=e.memoizedState;t=(e=t.stateNode).getSnapshotBeforeUpdate(t.elementType===t.type?n:Ko(t.type,n),r),e.__reactInternalSnapshotBeforeUpdate=t}return;case 3:return void(256&t.flags&&Wr(t.stateNode.containerInfo))}throw Error(i(163))}function vl(e,t,n){switch(n.tag){case 0:case 11:case 15:case 22:if(null!==(t=null!==(t=n.updateQueue)?t.lastEffect:null)){e=t=t.next;do{if(3==(3&e.tag)){var r=e.create;e.destroy=r()}e=e.next}while(e!==t)}if(null!==(t=null!==(t=n.updateQueue)?t.lastEffect:null)){e=t=t.next;do{var o=e;r=o.next,0!=(4&(o=o.tag))&&0!=(1&o)&&(Ms(n,e),js(n,e)),e=r}while(e!==t)}return;case 1:return e=n.stateNode,4&n.flags&&(null===t?e.componentDidMount():(r=n.elementType===n.type?t.memoizedProps:Ko(n.type,t.memoizedProps),e.componentDidUpdate(r,t.memoizedState,e.__reactInternalSnapshotBeforeUpdate))),void(null!==(t=n.updateQueue)&&ma(n,t,e));case 3:if(null!==(t=n.updateQueue)){if(e=null,null!==n.child)switch(n.child.tag){case 5:case 1:e=n.child.stateNode}ma(n,t,e)}return;case 5:return e=n.stateNode,void(null===t&&4&n.flags&&Hr(n.type,n.memoizedProps)&&e.focus());case 6:case 4:case 12:case 19:case 17:case 20:case 21:case 23:case 24:return;case 13:return void(null===n.memoizedState&&(n=n.alternate,null!==n&&(n=n.memoizedState,null!==n&&(n=n.dehydrated,null!==n&&_t(n)))))}throw Error(i(163))}function bl(e,t){for(var n=e;;){if(5===n.tag){var r=n.stateNode;if(t)"function"==typeof(r=r.style).setProperty?r.setProperty("display","none","important"):r.display="none";else{r=n.stateNode;var o=n.memoizedProps.style;o=null!=o&&o.hasOwnProperty("display")?o.display:null,r.style.display=xe("display",o)}}else if(6===n.tag)n.stateNode.nodeValue=t?"":n.memoizedProps;else if((23!==n.tag&&24!==n.tag||null===n.memoizedState||n===e)&&null!==n.child){n.child.return=n,n=n.child;continue}if(n===e)break;for(;null===n.sibling;){if(null===n.return||n.return===e)return;n=n.return}n.sibling.return=n.return,n=n.sibling}}function yl(e,t){if(So&&"function"==typeof So.onCommitFiberUnmount)try{So.onCommitFiberUnmount(Eo,t)}catch(a){}switch(t.tag){case 0:case 11:case 14:case 15:case 22:if(null!==(e=t.updateQueue)&&null!==(e=e.lastEffect)){var n=e=e.next;do{var r=n,o=r.destroy;if(r=r.tag,void 0!==o)if(0!=(4&r))Ms(t,n);else{r=t;try{o()}catch(a){zs(r,a)}}n=n.next}while(n!==e)}break;case 1:if(ml(t),"function"==typeof(e=t.stateNode).componentWillUnmount)try{e.props=t.memoizedProps,e.state=t.memoizedState,e.componentWillUnmount()}catch(a){zs(t,a)}break;case 5:ml(t);break;case 4:Sl(e,t)}}function wl(e){e.alternate=null,e.child=null,e.dependencies=null,e.firstEffect=null,e.lastEffect=null,e.memoizedProps=null,e.memoizedState=null,e.pendingProps=null,e.return=null,e.updateQueue=null}function xl(e){return 5===e.tag||3===e.tag||4===e.tag}function _l(e){e:{for(var t=e.return;null!==t;){if(xl(t))break e;t=t.return}throw Error(i(160))}var n=t;switch(t=n.stateNode,n.tag){case 5:var r=!1;break;case 3:case 4:t=t.containerInfo,r=!0;break;default:throw Error(i(161))}16&n.flags&&(be(t,""),n.flags&=-17);e:t:for(n=e;;){for(;null===n.sibling;){if(null===n.return||xl(n.return)){n=null;break e}n=n.return}for(n.sibling.return=n.return,n=n.sibling;5!==n.tag&&6!==n.tag&&18!==n.tag;){if(2&n.flags)continue t;if(null===n.child||4===n.tag)continue t;n.child.return=n,n=n.child}if(!(2&n.flags)){n=n.stateNode;break e}}r?kl(e,n,t):El(e,n,t)}function kl(e,t,n){var r=e.tag,o=5===r||6===r;if(o)e=o?e.stateNode:e.stateNode.instance,t?8===n.nodeType?n.parentNode.insertBefore(e,t):n.insertBefore(e,t):(8===n.nodeType?(t=n.parentNode).insertBefore(e,n):(t=n).appendChild(e),null!=(n=n._reactRootContainer)||null!==t.onclick||(t.onclick=zr));else if(4!==r&&null!==(e=e.child))for(kl(e,t,n),e=e.sibling;null!==e;)kl(e,t,n),e=e.sibling}function El(e,t,n){var r=e.tag,o=5===r||6===r;if(o)e=o?e.stateNode:e.stateNode.instance,t?n.insertBefore(e,t):n.appendChild(e);else if(4!==r&&null!==(e=e.child))for(El(e,t,n),e=e.sibling;null!==e;)El(e,t,n),e=e.sibling}function Sl(e,t){for(var n,r,o=t,a=!1;;){if(!a){a=o.return;e:for(;;){if(null===a)throw Error(i(160));switch(n=a.stateNode,a.tag){case 5:r=!1;break e;case 3:case 4:n=n.containerInfo,r=!0;break e}a=a.return}a=!0}if(5===o.tag||6===o.tag){e:for(var l=e,s=o,u=s;;)if(yl(l,u),null!==u.child&&4!==u.tag)u.child.return=u,u=u.child;else{if(u===s)break e;for(;null===u.sibling;){if(null===u.return||u.return===s)break e;u=u.return}u.sibling.return=u.return,u=u.sibling}r?(l=n,s=o.stateNode,8===l.nodeType?l.parentNode.removeChild(s):l.removeChild(s)):n.removeChild(o.stateNode)}else if(4===o.tag){if(null!==o.child){n=o.stateNode.containerInfo,r=!0,o.child.return=o,o=o.child;continue}}else if(yl(e,o),null!==o.child){o.child.return=o,o=o.child;continue}if(o===t)break;for(;null===o.sibling;){if(null===o.return||o.return===t)return;4===(o=o.return).tag&&(a=!1)}o.sibling.return=o.return,o=o.sibling}}function Cl(e,t){switch(t.tag){case 0:case 11:case 14:case 15:case 22:var n=t.updateQueue;if(null!==(n=null!==n?n.lastEffect:null)){var r=n=n.next;do{3==(3&r.tag)&&(e=r.destroy,r.destroy=void 0,void 0!==e&&e()),r=r.next}while(r!==n)}return;case 1:case 12:case 17:return;case 5:if(null!=(n=t.stateNode)){r=t.memoizedProps;var o=null!==e?e.memoizedProps:r;e=t.type;var a=t.updateQueue;if(t.updateQueue=null,null!==a){for(n[Jr]=r,"input"===e&&"radio"===r.type&&null!=r.name&&te(n,r),Se(e,o),t=Se(e,r),o=0;o<a.length;o+=2){var l=a[o],s=a[o+1];"style"===l?_e(n,s):"dangerouslySetInnerHTML"===l?ve(n,s):"children"===l?be(n,s):w(n,l,s,t)}switch(e){case"input":ne(n,r);break;case"textarea":ue(n,r);break;case"select":e=n._wrapperState.wasMultiple,n._wrapperState.wasMultiple=!!r.multiple,null!=(a=r.value)?ie(n,!!r.multiple,a,!1):e!==!!r.multiple&&(null!=r.defaultValue?ie(n,!!r.multiple,r.defaultValue,!0):ie(n,!!r.multiple,r.multiple?[]:"",!1))}}}return;case 6:if(null===t.stateNode)throw Error(i(162));return void(t.stateNode.nodeValue=t.memoizedProps);case 3:return void((n=t.stateNode).hydrate&&(n.hydrate=!1,_t(n.containerInfo)));case 13:return null!==t.memoizedState&&(ql=Vo(),bl(t.child,!0)),void Tl(t);case 19:return void Tl(t);case 23:case 24:return void bl(t,null!==t.memoizedState)}throw Error(i(163))}function Tl(e){var t=e.updateQueue;if(null!==t){e.updateQueue=null;var n=e.stateNode;null===n&&(n=e.stateNode=new hl),t.forEach((function(t){var r=Us.bind(null,e,t);n.has(t)||(n.add(t),t.then(r,r))}))}}function Ol(e,t){return null!==e&&(null===(e=e.memoizedState)||null!==e.dehydrated)&&(null!==(t=t.memoizedState)&&null===t.dehydrated)}var Dl=Math.ceil,Pl=x.ReactCurrentDispatcher,Nl=x.ReactCurrentOwner,Al=0,Il=null,Ll=null,Rl=0,jl=0,Ml=uo(0),Fl=0,Bl=null,zl=0,$l=0,Ul=0,Hl=0,Vl=null,ql=0,Gl=1/0;function Wl(){Gl=Vo()+500}var Zl,Ql=null,Yl=!1,Xl=null,Kl=null,Jl=!1,es=null,ts=90,ns=[],rs=[],os=null,as=0,is=null,ls=-1,ss=0,us=0,cs=null,ds=!1;function fs(){return 0!=(48&Al)?Vo():-1!==ls?ls:ls=Vo()}function ps(e){if(0==(2&(e=e.mode)))return 1;if(0==(4&e))return 99===qo()?1:2;if(0===ss&&(ss=zl),0!==Xo.transition){0!==us&&(us=null!==Vl?Vl.pendingLanes:0),e=ss;var t=4186112&~us;return 0===(t&=-t)&&(0===(t=(e=4186112&~e)&-e)&&(t=8192)),t}return e=qo(),0!=(4&Al)&&98===e?e=zt(12,ss):e=zt(e=function(e){switch(e){case 99:return 15;case 98:return 10;case 97:case 96:return 8;case 95:return 2;default:return 0}}(e),ss),e}function hs(e,t,n){if(50<as)throw as=0,is=null,Error(i(185));if(null===(e=ms(e,t)))return null;Ht(e,t,n),e===Il&&(Ul|=t,4===Fl&&bs(e,Rl));var r=qo();1===t?0!=(8&Al)&&0==(48&Al)?ys(e):(gs(e,n),0===Al&&(Wl(),Qo())):(0==(4&Al)||98!==r&&99!==r||(null===os?os=new Set([e]):os.add(e)),gs(e,n)),Vl=e}function ms(e,t){e.lanes|=t;var n=e.alternate;for(null!==n&&(n.lanes|=t),n=e,e=e.return;null!==e;)e.childLanes|=t,null!==(n=e.alternate)&&(n.childLanes|=t),n=e,e=e.return;return 3===n.tag?n.stateNode:null}function gs(e,t){for(var n=e.callbackNode,r=e.suspendedLanes,o=e.pingedLanes,a=e.expirationTimes,l=e.pendingLanes;0<l;){var s=31-Vt(l),u=1<<s,c=a[s];if(-1===c){if(0==(u&r)||0!=(u&o)){c=t,Mt(u);var d=jt;a[s]=10<=d?c+250:6<=d?c+5e3:-1}}else c<=t&&(e.expiredLanes|=u);l&=~u}if(r=Ft(e,e===Il?Rl:0),t=jt,0===r)null!==n&&(n!==Fo&&Oo(n),e.callbackNode=null,e.callbackPriority=0);else{if(null!==n){if(e.callbackPriority===t)return;n!==Fo&&Oo(n)}15===t?(n=ys.bind(null,e),null===zo?(zo=[n],$o=To(Io,Yo)):zo.push(n),n=Fo):14===t?n=Zo(99,ys.bind(null,e)):(n=function(e){switch(e){case 15:case 14:return 99;case 13:case 12:case 11:case 10:return 98;case 9:case 8:case 7:case 6:case 4:case 5:return 97;case 3:case 2:case 1:return 95;case 0:return 90;default:throw Error(i(358,e))}}(t),n=Zo(n,vs.bind(null,e))),e.callbackPriority=t,e.callbackNode=n}}function vs(e){if(ls=-1,us=ss=0,0!=(48&Al))throw Error(i(327));var t=e.callbackNode;if(Rs()&&e.callbackNode!==t)return null;var n=Ft(e,e===Il?Rl:0);if(0===n)return null;var r=n,o=Al;Al|=16;var a=Cs();for(Il===e&&Rl===r||(Wl(),Es(e,r));;)try{Ds();break}catch(s){Ss(e,s)}if(ra(),Pl.current=a,Al=o,null!==Ll?r=0:(Il=null,Rl=0,r=Fl),0!=(zl&Ul))Es(e,0);else if(0!==r){if(2===r&&(Al|=64,e.hydrate&&(e.hydrate=!1,Wr(e.containerInfo)),0!==(n=Bt(e))&&(r=Ts(e,n))),1===r)throw t=Bl,Es(e,0),bs(e,n),gs(e,Vo()),t;switch(e.finishedWork=e.current.alternate,e.finishedLanes=n,r){case 0:case 1:throw Error(i(345));case 2:case 5:As(e);break;case 3:if(bs(e,n),(62914560&n)===n&&10<(r=ql+500-Vo())){if(0!==Ft(e,0))break;if(((o=e.suspendedLanes)&n)!==n){fs(),e.pingedLanes|=e.suspendedLanes&o;break}e.timeoutHandle=qr(As.bind(null,e),r);break}As(e);break;case 4:if(bs(e,n),(4186112&n)===n)break;for(r=e.eventTimes,o=-1;0<n;){var l=31-Vt(n);a=1<<l,(l=r[l])>o&&(o=l),n&=~a}if(n=o,10<(n=(120>(n=Vo()-n)?120:480>n?480:1080>n?1080:1920>n?1920:3e3>n?3e3:4320>n?4320:1960*Dl(n/1960))-n)){e.timeoutHandle=qr(As.bind(null,e),n);break}As(e);break;default:throw Error(i(329))}}return gs(e,Vo()),e.callbackNode===t?vs.bind(null,e):null}function bs(e,t){for(t&=~Hl,t&=~Ul,e.suspendedLanes|=t,e.pingedLanes&=~t,e=e.expirationTimes;0<t;){var n=31-Vt(t),r=1<<n;e[n]=-1,t&=~r}}function ys(e){if(0!=(48&Al))throw Error(i(327));if(Rs(),e===Il&&0!=(e.expiredLanes&Rl)){var t=Rl,n=Ts(e,t);0!=(zl&Ul)&&(n=Ts(e,t=Ft(e,t)))}else n=Ts(e,t=Ft(e,0));if(0!==e.tag&&2===n&&(Al|=64,e.hydrate&&(e.hydrate=!1,Wr(e.containerInfo)),0!==(t=Bt(e))&&(n=Ts(e,t))),1===n)throw n=Bl,Es(e,0),bs(e,t),gs(e,Vo()),n;return e.finishedWork=e.current.alternate,e.finishedLanes=t,As(e),gs(e,Vo()),null}function ws(e,t){var n=Al;Al|=1;try{return e(t)}finally{0===(Al=n)&&(Wl(),Qo())}}function xs(e,t){var n=Al;Al&=-2,Al|=8;try{return e(t)}finally{0===(Al=n)&&(Wl(),Qo())}}function _s(e,t){fo(Ml,jl),jl|=t,zl|=t}function ks(){jl=Ml.current,co(Ml)}function Es(e,t){e.finishedWork=null,e.finishedLanes=0;var n=e.timeoutHandle;if(-1!==n&&(e.timeoutHandle=-1,Gr(n)),null!==Ll)for(n=Ll.return;null!==n;){var r=n;switch(r.tag){case 1:null!=(r=r.type.childContextTypes)&&yo();break;case 3:Ra(),co(mo),co(ho),Ya();break;case 5:Ma(r);break;case 4:Ra();break;case 13:case 19:co(Fa);break;case 10:oa(r);break;case 23:case 24:ks()}n=n.return}Il=e,Ll=Gs(e.current,null),Rl=jl=zl=t,Fl=0,Bl=null,Hl=Ul=$l=0}function Ss(e,t){for(;;){var n=Ll;try{if(ra(),Xa.current=Ai,ri){for(var r=ei.memoizedState;null!==r;){var o=r.queue;null!==o&&(o.pending=null),r=r.next}ri=!1}if(Ja=0,ni=ti=ei=null,oi=!1,Nl.current=null,null===n||null===n.return){Fl=1,Bl=t,Ll=null;break}e:{var a=e,i=n.return,l=n,s=t;if(t=Rl,l.flags|=2048,l.firstEffect=l.lastEffect=null,null!==s&&"object"==typeof s&&"function"==typeof s.then){var u=s;if(0==(2&l.mode)){var c=l.alternate;c?(l.updateQueue=c.updateQueue,l.memoizedState=c.memoizedState,l.lanes=c.lanes):(l.updateQueue=null,l.memoizedState=null)}var d=0!=(1&Fa.current),f=i;do{var p;if(p=13===f.tag){var h=f.memoizedState;if(null!==h)p=null!==h.dehydrated;else{var m=f.memoizedProps;p=void 0!==m.fallback&&(!0!==m.unstable_avoidThisFallback||!d)}}if(p){var g=f.updateQueue;if(null===g){var v=new Set;v.add(u),f.updateQueue=v}else g.add(u);if(0==(2&f.mode)){if(f.flags|=64,l.flags|=16384,l.flags&=-2981,1===l.tag)if(null===l.alternate)l.tag=17;else{var b=da(-1,1);b.tag=2,fa(l,b)}l.lanes|=1;break e}s=void 0,l=t;var y=a.pingCache;if(null===y?(y=a.pingCache=new dl,s=new Set,y.set(u,s)):void 0===(s=y.get(u))&&(s=new Set,y.set(u,s)),!s.has(l)){s.add(l);var w=$s.bind(null,a,u,l);u.then(w,w)}f.flags|=4096,f.lanes=t;break e}f=f.return}while(null!==f);s=Error((W(l.type)||"A React component")+" suspended while rendering, but no fallback UI was specified.\n\nAdd a <Suspense fallback=...> component higher in the tree to provide a loading indicator or placeholder to display.")}5!==Fl&&(Fl=2),s=ul(s,l),f=i;do{switch(f.tag){case 3:a=s,f.flags|=4096,t&=-t,f.lanes|=t,pa(f,fl(0,a,t));break e;case 1:a=s;var x=f.type,_=f.stateNode;if(0==(64&f.flags)&&("function"==typeof x.getDerivedStateFromError||null!==_&&"function"==typeof _.componentDidCatch&&(null===Kl||!Kl.has(_)))){f.flags|=4096,t&=-t,f.lanes|=t,pa(f,pl(f,a,t));break e}}f=f.return}while(null!==f)}Ns(n)}catch(k){t=k,Ll===n&&null!==n&&(Ll=n=n.return);continue}break}}function Cs(){var e=Pl.current;return Pl.current=Ai,null===e?Ai:e}function Ts(e,t){var n=Al;Al|=16;var r=Cs();for(Il===e&&Rl===t||Es(e,t);;)try{Os();break}catch(o){Ss(e,o)}if(ra(),Al=n,Pl.current=r,null!==Ll)throw Error(i(261));return Il=null,Rl=0,Fl}function Os(){for(;null!==Ll;)Ps(Ll)}function Ds(){for(;null!==Ll&&!Do();)Ps(Ll)}function Ps(e){var t=Zl(e.alternate,e,jl);e.memoizedProps=e.pendingProps,null===t?Ns(e):Ll=t,Nl.current=null}function Ns(e){var t=e;do{var n=t.alternate;if(e=t.return,0==(2048&t.flags)){if(null!==(n=ll(n,t,jl)))return void(Ll=n);if(24!==(n=t).tag&&23!==n.tag||null===n.memoizedState||0!=(1073741824&jl)||0==(4&n.mode)){for(var r=0,o=n.child;null!==o;)r|=o.lanes|o.childLanes,o=o.sibling;n.childLanes=r}null!==e&&0==(2048&e.flags)&&(null===e.firstEffect&&(e.firstEffect=t.firstEffect),null!==t.lastEffect&&(null!==e.lastEffect&&(e.lastEffect.nextEffect=t.firstEffect),e.lastEffect=t.lastEffect),1<t.flags&&(null!==e.lastEffect?e.lastEffect.nextEffect=t:e.firstEffect=t,e.lastEffect=t))}else{if(null!==(n=sl(t)))return n.flags&=2047,void(Ll=n);null!==e&&(e.firstEffect=e.lastEffect=null,e.flags|=2048)}if(null!==(t=t.sibling))return void(Ll=t);Ll=t=e}while(null!==t);0===Fl&&(Fl=5)}function As(e){var t=qo();return Wo(99,Is.bind(null,e,t)),null}function Is(e,t){do{Rs()}while(null!==es);if(0!=(48&Al))throw Error(i(327));var n=e.finishedWork;if(null===n)return null;if(e.finishedWork=null,e.finishedLanes=0,n===e.current)throw Error(i(177));e.callbackNode=null;var r=n.lanes|n.childLanes,o=r,a=e.pendingLanes&~o;e.pendingLanes=o,e.suspendedLanes=0,e.pingedLanes=0,e.expiredLanes&=o,e.mutableReadLanes&=o,e.entangledLanes&=o,o=e.entanglements;for(var l=e.eventTimes,s=e.expirationTimes;0<a;){var u=31-Vt(a),c=1<<u;o[u]=0,l[u]=-1,s[u]=-1,a&=~c}if(null!==os&&0==(24&r)&&os.has(e)&&os.delete(e),e===Il&&(Ll=Il=null,Rl=0),1<n.flags?null!==n.lastEffect?(n.lastEffect.nextEffect=n,r=n.firstEffect):r=n:r=n.firstEffect,null!==r){if(o=Al,Al|=32,Nl.current=null,$r=Qt,vr(l=gr())){if("selectionStart"in l)s={start:l.selectionStart,end:l.selectionEnd};else e:if(s=(s=l.ownerDocument)&&s.defaultView||window,(c=s.getSelection&&s.getSelection())&&0!==c.rangeCount){s=c.anchorNode,a=c.anchorOffset,u=c.focusNode,c=c.focusOffset;try{s.nodeType,u.nodeType}catch(C){s=null;break e}var d=0,f=-1,p=-1,h=0,m=0,g=l,v=null;t:for(;;){for(var b;g!==s||0!==a&&3!==g.nodeType||(f=d+a),g!==u||0!==c&&3!==g.nodeType||(p=d+c),3===g.nodeType&&(d+=g.nodeValue.length),null!==(b=g.firstChild);)v=g,g=b;for(;;){if(g===l)break t;if(v===s&&++h===a&&(f=d),v===u&&++m===c&&(p=d),null!==(b=g.nextSibling))break;v=(g=v).parentNode}g=b}s=-1===f||-1===p?null:{start:f,end:p}}else s=null;s=s||{start:0,end:0}}else s=null;Ur={focusedElem:l,selectionRange:s},Qt=!1,cs=null,ds=!1,Ql=r;do{try{Ls()}catch(C){if(null===Ql)throw Error(i(330));zs(Ql,C),Ql=Ql.nextEffect}}while(null!==Ql);cs=null,Ql=r;do{try{for(l=e;null!==Ql;){var y=Ql.flags;if(16&y&&be(Ql.stateNode,""),128&y){var w=Ql.alternate;if(null!==w){var x=w.ref;null!==x&&("function"==typeof x?x(null):x.current=null)}}switch(1038&y){case 2:_l(Ql),Ql.flags&=-3;break;case 6:_l(Ql),Ql.flags&=-3,Cl(Ql.alternate,Ql);break;case 1024:Ql.flags&=-1025;break;case 1028:Ql.flags&=-1025,Cl(Ql.alternate,Ql);break;case 4:Cl(Ql.alternate,Ql);break;case 8:Sl(l,s=Ql);var _=s.alternate;wl(s),null!==_&&wl(_)}Ql=Ql.nextEffect}}catch(C){if(null===Ql)throw Error(i(330));zs(Ql,C),Ql=Ql.nextEffect}}while(null!==Ql);if(x=Ur,w=gr(),y=x.focusedElem,l=x.selectionRange,w!==y&&y&&y.ownerDocument&&mr(y.ownerDocument.documentElement,y)){null!==l&&vr(y)&&(w=l.start,void 0===(x=l.end)&&(x=w),"selectionStart"in y?(y.selectionStart=w,y.selectionEnd=Math.min(x,y.value.length)):(x=(w=y.ownerDocument||document)&&w.defaultView||window).getSelection&&(x=x.getSelection(),s=y.textContent.length,_=Math.min(l.start,s),l=void 0===l.end?_:Math.min(l.end,s),!x.extend&&_>l&&(s=l,l=_,_=s),s=hr(y,_),a=hr(y,l),s&&a&&(1!==x.rangeCount||x.anchorNode!==s.node||x.anchorOffset!==s.offset||x.focusNode!==a.node||x.focusOffset!==a.offset)&&((w=w.createRange()).setStart(s.node,s.offset),x.removeAllRanges(),_>l?(x.addRange(w),x.extend(a.node,a.offset)):(w.setEnd(a.node,a.offset),x.addRange(w))))),w=[];for(x=y;x=x.parentNode;)1===x.nodeType&&w.push({element:x,left:x.scrollLeft,top:x.scrollTop});for("function"==typeof y.focus&&y.focus(),y=0;y<w.length;y++)(x=w[y]).element.scrollLeft=x.left,x.element.scrollTop=x.top}Qt=!!$r,Ur=$r=null,e.current=n,Ql=r;do{try{for(y=e;null!==Ql;){var k=Ql.flags;if(36&k&&vl(y,Ql.alternate,Ql),128&k){w=void 0;var E=Ql.ref;if(null!==E){var S=Ql.stateNode;Ql.tag,w=S,"function"==typeof E?E(w):E.current=w}}Ql=Ql.nextEffect}}catch(C){if(null===Ql)throw Error(i(330));zs(Ql,C),Ql=Ql.nextEffect}}while(null!==Ql);Ql=null,Bo(),Al=o}else e.current=n;if(Jl)Jl=!1,es=e,ts=t;else for(Ql=r;null!==Ql;)t=Ql.nextEffect,Ql.nextEffect=null,8&Ql.flags&&((k=Ql).sibling=null,k.stateNode=null),Ql=t;if(0===(r=e.pendingLanes)&&(Kl=null),1===r?e===is?as++:(as=0,is=e):as=0,n=n.stateNode,So&&"function"==typeof So.onCommitFiberRoot)try{So.onCommitFiberRoot(Eo,n,void 0,64==(64&n.current.flags))}catch(C){}if(gs(e,Vo()),Yl)throw Yl=!1,e=Xl,Xl=null,e;return 0!=(8&Al)||Qo(),null}function Ls(){for(;null!==Ql;){var e=Ql.alternate;ds||null===cs||(0!=(8&Ql.flags)?et(Ql,cs)&&(ds=!0):13===Ql.tag&&Ol(e,Ql)&&et(Ql,cs)&&(ds=!0));var t=Ql.flags;0!=(256&t)&&gl(e,Ql),0==(512&t)||Jl||(Jl=!0,Zo(97,(function(){return Rs(),null}))),Ql=Ql.nextEffect}}function Rs(){if(90!==ts){var e=97<ts?97:ts;return ts=90,Wo(e,Fs)}return!1}function js(e,t){ns.push(t,e),Jl||(Jl=!0,Zo(97,(function(){return Rs(),null})))}function Ms(e,t){rs.push(t,e),Jl||(Jl=!0,Zo(97,(function(){return Rs(),null})))}function Fs(){if(null===es)return!1;var e=es;if(es=null,0!=(48&Al))throw Error(i(331));var t=Al;Al|=32;var n=rs;rs=[];for(var r=0;r<n.length;r+=2){var o=n[r],a=n[r+1],l=o.destroy;if(o.destroy=void 0,"function"==typeof l)try{l()}catch(u){if(null===a)throw Error(i(330));zs(a,u)}}for(n=ns,ns=[],r=0;r<n.length;r+=2){o=n[r],a=n[r+1];try{var s=o.create;o.destroy=s()}catch(u){if(null===a)throw Error(i(330));zs(a,u)}}for(s=e.current.firstEffect;null!==s;)e=s.nextEffect,s.nextEffect=null,8&s.flags&&(s.sibling=null,s.stateNode=null),s=e;return Al=t,Qo(),!0}function Bs(e,t,n){fa(e,t=fl(0,t=ul(n,t),1)),t=fs(),null!==(e=ms(e,1))&&(Ht(e,1,t),gs(e,t))}function zs(e,t){if(3===e.tag)Bs(e,e,t);else for(var n=e.return;null!==n;){if(3===n.tag){Bs(n,e,t);break}if(1===n.tag){var r=n.stateNode;if("function"==typeof n.type.getDerivedStateFromError||"function"==typeof r.componentDidCatch&&(null===Kl||!Kl.has(r))){var o=pl(n,e=ul(t,e),1);if(fa(n,o),o=fs(),null!==(n=ms(n,1)))Ht(n,1,o),gs(n,o);else if("function"==typeof r.componentDidCatch&&(null===Kl||!Kl.has(r)))try{r.componentDidCatch(t,e)}catch(a){}break}}n=n.return}}function $s(e,t,n){var r=e.pingCache;null!==r&&r.delete(t),t=fs(),e.pingedLanes|=e.suspendedLanes&n,Il===e&&(Rl&n)===n&&(4===Fl||3===Fl&&(62914560&Rl)===Rl&&500>Vo()-ql?Es(e,0):Hl|=n),gs(e,t)}function Us(e,t){var n=e.stateNode;null!==n&&n.delete(t),0===(t=0)&&(0==(2&(t=e.mode))?t=1:0==(4&t)?t=99===qo()?1:2:(0===ss&&(ss=zl),0===(t=$t(62914560&~ss))&&(t=4194304))),n=fs(),null!==(e=ms(e,t))&&(Ht(e,t,n),gs(e,n))}function Hs(e,t,n,r){this.tag=e,this.key=n,this.sibling=this.child=this.return=this.stateNode=this.type=this.elementType=null,this.index=0,this.ref=null,this.pendingProps=t,this.dependencies=this.memoizedState=this.updateQueue=this.memoizedProps=null,this.mode=r,this.flags=0,this.lastEffect=this.firstEffect=this.nextEffect=null,this.childLanes=this.lanes=0,this.alternate=null}function Vs(e,t,n,r){return new Hs(e,t,n,r)}function qs(e){return!(!(e=e.prototype)||!e.isReactComponent)}function Gs(e,t){var n=e.alternate;return null===n?((n=Vs(e.tag,t,e.key,e.mode)).elementType=e.elementType,n.type=e.type,n.stateNode=e.stateNode,n.alternate=e,e.alternate=n):(n.pendingProps=t,n.type=e.type,n.flags=0,n.nextEffect=null,n.firstEffect=null,n.lastEffect=null),n.childLanes=e.childLanes,n.lanes=e.lanes,n.child=e.child,n.memoizedProps=e.memoizedProps,n.memoizedState=e.memoizedState,n.updateQueue=e.updateQueue,t=e.dependencies,n.dependencies=null===t?null:{lanes:t.lanes,firstContext:t.firstContext},n.sibling=e.sibling,n.index=e.index,n.ref=e.ref,n}function Ws(e,t,n,r,o,a){var l=2;if(r=e,"function"==typeof e)qs(e)&&(l=1);else if("string"==typeof e)l=5;else e:switch(e){case E:return Zs(n.children,o,a,t);case j:l=8,o|=16;break;case S:l=8,o|=1;break;case C:return(e=Vs(12,n,t,8|o)).elementType=C,e.type=C,e.lanes=a,e;case P:return(e=Vs(13,n,t,o)).type=P,e.elementType=P,e.lanes=a,e;case N:return(e=Vs(19,n,t,o)).elementType=N,e.lanes=a,e;case M:return Qs(n,o,a,t);case F:return(e=Vs(24,n,t,o)).elementType=F,e.lanes=a,e;default:if("object"==typeof e&&null!==e)switch(e.$$typeof){case T:l=10;break e;case O:l=9;break e;case D:l=11;break e;case A:l=14;break e;case I:l=16,r=null;break e;case L:l=22;break e}throw Error(i(130,null==e?e:typeof e,""))}return(t=Vs(l,n,t,o)).elementType=e,t.type=r,t.lanes=a,t}function Zs(e,t,n,r){return(e=Vs(7,e,r,t)).lanes=n,e}function Qs(e,t,n,r){return(e=Vs(23,e,r,t)).elementType=M,e.lanes=n,e}function Ys(e,t,n){return(e=Vs(6,e,null,t)).lanes=n,e}function Xs(e,t,n){return(t=Vs(4,null!==e.children?e.children:[],e.key,t)).lanes=n,t.stateNode={containerInfo:e.containerInfo,pendingChildren:null,implementation:e.implementation},t}function Ks(e,t,n){this.tag=t,this.containerInfo=e,this.finishedWork=this.pingCache=this.current=this.pendingChildren=null,this.timeoutHandle=-1,this.pendingContext=this.context=null,this.hydrate=n,this.callbackNode=null,this.callbackPriority=0,this.eventTimes=Ut(0),this.expirationTimes=Ut(-1),this.entangledLanes=this.finishedLanes=this.mutableReadLanes=this.expiredLanes=this.pingedLanes=this.suspendedLanes=this.pendingLanes=0,this.entanglements=Ut(0),this.mutableSourceEagerHydrationData=null}function Js(e,t,n){var r=3<arguments.length&&void 0!==arguments[3]?arguments[3]:null;return{$$typeof:k,key:null==r?null:""+r,children:e,containerInfo:t,implementation:n}}function eu(e,t,n,r){var o=t.current,a=fs(),l=ps(o);e:if(n){t:{if(Ye(n=n._reactInternals)!==n||1!==n.tag)throw Error(i(170));var s=n;do{switch(s.tag){case 3:s=s.stateNode.context;break t;case 1:if(bo(s.type)){s=s.stateNode.__reactInternalMemoizedMergedChildContext;break t}}s=s.return}while(null!==s);throw Error(i(171))}if(1===n.tag){var u=n.type;if(bo(u)){n=xo(n,u,s);break e}}n=s}else n=po;return null===t.context?t.context=n:t.pendingContext=n,(t=da(a,l)).payload={element:e},null!==(r=void 0===r?null:r)&&(t.callback=r),fa(o,t),hs(o,l,a),l}function tu(e){return(e=e.current).child?(e.child.tag,e.child.stateNode):null}function nu(e,t){if(null!==(e=e.memoizedState)&&null!==e.dehydrated){var n=e.retryLane;e.retryLane=0!==n&&n<t?n:t}}function ru(e,t){nu(e,t),(e=e.alternate)&&nu(e,t)}function ou(e,t,n){var r=null!=n&&null!=n.hydrationOptions&&n.hydrationOptions.mutableSources||null;if(n=new Ks(e,t,null!=n&&!0===n.hydrate),t=Vs(3,null,null,2===t?7:1===t?3:0),n.current=t,t.stateNode=n,ua(t),e[eo]=n.current,Ar(8===e.nodeType?e.parentNode:e),r)for(e=0;e<r.length;e++){var o=(t=r[e])._getVersion;o=o(t._source),null==n.mutableSourceEagerHydrationData?n.mutableSourceEagerHydrationData=[t,o]:n.mutableSourceEagerHydrationData.push(t,o)}this._internalRoot=n}function au(e){return!(!e||1!==e.nodeType&&9!==e.nodeType&&11!==e.nodeType&&(8!==e.nodeType||" react-mount-point-unstable "!==e.nodeValue))}function iu(e,t,n,r,o){var a=n._reactRootContainer;if(a){var i=a._internalRoot;if("function"==typeof o){var l=o;o=function(){var e=tu(i);l.call(e)}}eu(t,i,e,o)}else{if(a=n._reactRootContainer=function(e,t){if(t||(t=!(!(t=e?9===e.nodeType?e.documentElement:e.firstChild:null)||1!==t.nodeType||!t.hasAttribute("data-reactroot"))),!t)for(var n;n=e.lastChild;)e.removeChild(n);return new ou(e,0,t?{hydrate:!0}:void 0)}(n,r),i=a._internalRoot,"function"==typeof o){var s=o;o=function(){var e=tu(i);s.call(e)}}xs((function(){eu(t,i,e,o)}))}return tu(i)}function lu(e,t){var n=2<arguments.length&&void 0!==arguments[2]?arguments[2]:null;if(!au(t))throw Error(i(200));return Js(e,t,null,n)}Zl=function(e,t,n){var r=t.lanes;if(null!==e)if(e.memoizedProps!==t.pendingProps||mo.current)Mi=!0;else{if(0==(n&r)){switch(Mi=!1,t.tag){case 3:Wi(t),Za();break;case 5:ja(t);break;case 1:bo(t.type)&&_o(t);break;case 4:La(t,t.stateNode.containerInfo);break;case 10:r=t.memoizedProps.value;var o=t.type._context;fo(Jo,o._currentValue),o._currentValue=r;break;case 13:if(null!==t.memoizedState)return 0!=(n&t.child.childLanes)?Ki(e,t,n):(fo(Fa,1&Fa.current),null!==(t=al(e,t,n))?t.sibling:null);fo(Fa,1&Fa.current);break;case 19:if(r=0!=(n&t.childLanes),0!=(64&e.flags)){if(r)return ol(e,t,n);t.flags|=64}if(null!==(o=t.memoizedState)&&(o.rendering=null,o.tail=null,o.lastEffect=null),fo(Fa,Fa.current),r)break;return null;case 23:case 24:return t.lanes=0,Ui(e,t,n)}return al(e,t,n)}Mi=0!=(16384&e.flags)}else Mi=!1;switch(t.lanes=0,t.tag){case 2:if(r=t.type,null!==e&&(e.alternate=null,t.alternate=null,t.flags|=2),e=t.pendingProps,o=vo(t,ho.current),ia(t,n),o=li(null,t,r,e,o,n),t.flags|=1,"object"==typeof o&&null!==o&&"function"==typeof o.render&&void 0===o.$$typeof){if(t.tag=1,t.memoizedState=null,t.updateQueue=null,bo(r)){var a=!0;_o(t)}else a=!1;t.memoizedState=null!==o.state&&void 0!==o.state?o.state:null,ua(t);var l=r.getDerivedStateFromProps;"function"==typeof l&&va(t,r,l,e),o.updater=ba,t.stateNode=o,o._reactInternals=t,_a(t,r,e,n),t=Gi(null,t,r,!0,a,n)}else t.tag=0,Fi(null,t,o,n),t=t.child;return t;case 16:o=t.elementType;e:{switch(null!==e&&(e.alternate=null,t.alternate=null,t.flags|=2),e=t.pendingProps,o=(a=o._init)(o._payload),t.type=o,a=t.tag=function(e){if("function"==typeof e)return qs(e)?1:0;if(null!=e){if((e=e.$$typeof)===D)return 11;if(e===A)return 14}return 2}(o),e=Ko(o,e),a){case 0:t=Vi(null,t,o,e,n);break e;case 1:t=qi(null,t,o,e,n);break e;case 11:t=Bi(null,t,o,e,n);break e;case 14:t=zi(null,t,o,Ko(o.type,e),r,n);break e}throw Error(i(306,o,""))}return t;case 0:return r=t.type,o=t.pendingProps,Vi(e,t,r,o=t.elementType===r?o:Ko(r,o),n);case 1:return r=t.type,o=t.pendingProps,qi(e,t,r,o=t.elementType===r?o:Ko(r,o),n);case 3:if(Wi(t),r=t.updateQueue,null===e||null===r)throw Error(i(282));if(r=t.pendingProps,o=null!==(o=t.memoizedState)?o.element:null,ca(e,t),ha(t,r,null,n),(r=t.memoizedState.element)===o)Za(),t=al(e,t,n);else{if((a=(o=t.stateNode).hydrate)&&($a=Zr(t.stateNode.containerInfo.firstChild),za=t,a=Ua=!0),a){if(null!=(e=o.mutableSourceEagerHydrationData))for(o=0;o<e.length;o+=2)(a=e[o])._workInProgressVersionPrimary=e[o+1],Qa.push(a);for(n=Oa(t,null,r,n),t.child=n;n;)n.flags=-3&n.flags|1024,n=n.sibling}else Fi(e,t,r,n),Za();t=t.child}return t;case 5:return ja(t),null===e&&qa(t),r=t.type,o=t.pendingProps,a=null!==e?e.memoizedProps:null,l=o.children,Vr(r,o)?l=null:null!==a&&Vr(r,a)&&(t.flags|=16),Hi(e,t),Fi(e,t,l,n),t.child;case 6:return null===e&&qa(t),null;case 13:return Ki(e,t,n);case 4:return La(t,t.stateNode.containerInfo),r=t.pendingProps,null===e?t.child=Ta(t,null,r,n):Fi(e,t,r,n),t.child;case 11:return r=t.type,o=t.pendingProps,Bi(e,t,r,o=t.elementType===r?o:Ko(r,o),n);case 7:return Fi(e,t,t.pendingProps,n),t.child;case 8:case 12:return Fi(e,t,t.pendingProps.children,n),t.child;case 10:e:{r=t.type._context,o=t.pendingProps,l=t.memoizedProps,a=o.value;var s=t.type._context;if(fo(Jo,s._currentValue),s._currentValue=a,null!==l)if(s=l.value,0===(a=cr(s,a)?0:0|("function"==typeof r._calculateChangedBits?r._calculateChangedBits(s,a):1073741823))){if(l.children===o.children&&!mo.current){t=al(e,t,n);break e}}else for(null!==(s=t.child)&&(s.return=t);null!==s;){var u=s.dependencies;if(null!==u){l=s.child;for(var c=u.firstContext;null!==c;){if(c.context===r&&0!=(c.observedBits&a)){1===s.tag&&((c=da(-1,n&-n)).tag=2,fa(s,c)),s.lanes|=n,null!==(c=s.alternate)&&(c.lanes|=n),aa(s.return,n),u.lanes|=n;break}c=c.next}}else l=10===s.tag&&s.type===t.type?null:s.child;if(null!==l)l.return=s;else for(l=s;null!==l;){if(l===t){l=null;break}if(null!==(s=l.sibling)){s.return=l.return,l=s;break}l=l.return}s=l}Fi(e,t,o.children,n),t=t.child}return t;case 9:return o=t.type,r=(a=t.pendingProps).children,ia(t,n),r=r(o=la(o,a.unstable_observedBits)),t.flags|=1,Fi(e,t,r,n),t.child;case 14:return a=Ko(o=t.type,t.pendingProps),zi(e,t,o,a=Ko(o.type,a),r,n);case 15:return $i(e,t,t.type,t.pendingProps,r,n);case 17:return r=t.type,o=t.pendingProps,o=t.elementType===r?o:Ko(r,o),null!==e&&(e.alternate=null,t.alternate=null,t.flags|=2),t.tag=1,bo(r)?(e=!0,_o(t)):e=!1,ia(t,n),wa(t,r,o),_a(t,r,o,n),Gi(null,t,r,!0,e,n);case 19:return ol(e,t,n);case 23:case 24:return Ui(e,t,n)}throw Error(i(156,t.tag))},ou.prototype.render=function(e){eu(e,this._internalRoot,null,null)},ou.prototype.unmount=function(){var e=this._internalRoot,t=e.containerInfo;eu(null,e,null,(function(){t[eo]=null}))},tt=function(e){13===e.tag&&(hs(e,4,fs()),ru(e,4))},nt=function(e){13===e.tag&&(hs(e,67108864,fs()),ru(e,67108864))},rt=function(e){if(13===e.tag){var t=fs(),n=ps(e);hs(e,n,t),ru(e,n)}},ot=function(e,t){return t()},Te=function(e,t,n){switch(t){case"input":if(ne(e,n),t=n.name,"radio"===n.type&&null!=t){for(n=e;n.parentNode;)n=n.parentNode;for(n=n.querySelectorAll("input[name="+JSON.stringify(""+t)+'][type="radio"]'),t=0;t<n.length;t++){var r=n[t];if(r!==e&&r.form===e.form){var o=ao(r);if(!o)throw Error(i(90));X(r),ne(r,o)}}}break;case"textarea":ue(e,n);break;case"select":null!=(t=n.value)&&ie(e,!!n.multiple,t,!1)}},Ie=ws,Le=function(e,t,n,r,o){var a=Al;Al|=4;try{return Wo(98,e.bind(null,t,n,r,o))}finally{0===(Al=a)&&(Wl(),Qo())}},Re=function(){0==(49&Al)&&(function(){if(null!==os){var e=os;os=null,e.forEach((function(e){e.expiredLanes|=24&e.pendingLanes,gs(e,Vo())}))}Qo()}(),Rs())},je=function(e,t){var n=Al;Al|=2;try{return e(t)}finally{0===(Al=n)&&(Wl(),Qo())}};var su={Events:[ro,oo,ao,Ne,Ae,Rs,{current:!1}]},uu={findFiberByHostInstance:no,bundleType:0,version:"17.0.2",rendererPackageName:"react-dom"},cu={bundleType:uu.bundleType,version:uu.version,rendererPackageName:uu.rendererPackageName,rendererConfig:uu.rendererConfig,overrideHookState:null,overrideHookStateDeletePath:null,overrideHookStateRenamePath:null,overrideProps:null,overridePropsDeletePath:null,overridePropsRenamePath:null,setSuspenseHandler:null,scheduleUpdate:null,currentDispatcherRef:x.ReactCurrentDispatcher,findHostInstanceByFiber:function(e){return null===(e=Je(e))?null:e.stateNode},findFiberByHostInstance:uu.findFiberByHostInstance||function(){return null},findHostInstancesForRefresh:null,scheduleRefresh:null,scheduleRoot:null,setRefreshHandler:null,getCurrentFiber:null};if("undefined"!=typeof __REACT_DEVTOOLS_GLOBAL_HOOK__){var du=__REACT_DEVTOOLS_GLOBAL_HOOK__;if(!du.isDisabled&&du.supportsFiber)try{Eo=du.inject(cu),So=du}catch(ge){}}t.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED=su,t.createPortal=lu,t.findDOMNode=function(e){if(null==e)return null;if(1===e.nodeType)return e;var t=e._reactInternals;if(void 0===t){if("function"==typeof e.render)throw Error(i(188));throw Error(i(268,Object.keys(e)))}return e=null===(e=Je(t))?null:e.stateNode},t.flushSync=function(e,t){var n=Al;if(0!=(48&n))return e(t);Al|=1;try{if(e)return Wo(99,e.bind(null,t))}finally{Al=n,Qo()}},t.hydrate=function(e,t,n){if(!au(t))throw Error(i(200));return iu(null,e,t,!0,n)},t.render=function(e,t,n){if(!au(t))throw Error(i(200));return iu(null,e,t,!1,n)},t.unmountComponentAtNode=function(e){if(!au(e))throw Error(i(40));return!!e._reactRootContainer&&(xs((function(){iu(null,null,e,!1,(function(){e._reactRootContainer=null,e[eo]=null}))})),!0)},t.unstable_batchedUpdates=ws,t.unstable_createPortal=function(e,t){return lu(e,t,2<arguments.length&&void 0!==arguments[2]?arguments[2]:null)},t.unstable_renderSubtreeIntoContainer=function(e,t,n,r){if(!au(n))throw Error(i(200));if(null==e||void 0===e._reactInternals)throw Error(i(38));return iu(e,t,n,!1,r)},t.version="17.0.2"},73935:(e,t,n)=>{"use strict";!function e(){if("undefined"!=typeof __REACT_DEVTOOLS_GLOBAL_HOOK__&&"function"==typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE)try{__REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE(e)}catch(t){console.error(t)}}(),e.exports=n(64448)},69590:e=>{var t="undefined"!=typeof Element,n="function"==typeof Map,r="function"==typeof Set,o="function"==typeof ArrayBuffer&&!!ArrayBuffer.isView;function a(e,i){if(e===i)return!0;if(e&&i&&"object"==typeof e&&"object"==typeof i){if(e.constructor!==i.constructor)return!1;var l,s,u,c;if(Array.isArray(e)){if((l=e.length)!=i.length)return!1;for(s=l;0!=s--;)if(!a(e[s],i[s]))return!1;return!0}if(n&&e instanceof Map&&i instanceof Map){if(e.size!==i.size)return!1;for(c=e.entries();!(s=c.next()).done;)if(!i.has(s.value[0]))return!1;for(c=e.entries();!(s=c.next()).done;)if(!a(s.value[1],i.get(s.value[0])))return!1;return!0}if(r&&e instanceof Set&&i instanceof Set){if(e.size!==i.size)return!1;for(c=e.entries();!(s=c.next()).done;)if(!i.has(s.value[0]))return!1;return!0}if(o&&ArrayBuffer.isView(e)&&ArrayBuffer.isView(i)){if((l=e.length)!=i.length)return!1;for(s=l;0!=s--;)if(e[s]!==i[s])return!1;return!0}if(e.constructor===RegExp)return e.source===i.source&&e.flags===i.flags;if(e.valueOf!==Object.prototype.valueOf)return e.valueOf()===i.valueOf();if(e.toString!==Object.prototype.toString)return e.toString()===i.toString();if((l=(u=Object.keys(e)).length)!==Object.keys(i).length)return!1;for(s=l;0!=s--;)if(!Object.prototype.hasOwnProperty.call(i,u[s]))return!1;if(t&&e instanceof Element)return!1;for(s=l;0!=s--;)if(("_owner"!==u[s]&&"__v"!==u[s]&&"__o"!==u[s]||!e.$$typeof)&&!a(e[u[s]],i[u[s]]))return!1;return!0}return e!=e&&i!=i}e.exports=function(e,t){try{return a(e,t)}catch(n){if((n.message||"").match(/stack|recursion/i))return console.warn("react-fast-compare cannot handle circular refs"),!1;throw n}}},70405:(e,t,n)=>{"use strict";n.d(t,{B6:()=>q,ql:()=>J});var r=n(67294),o=n(45697),a=n.n(o),i=n(69590),l=n.n(i),s=n(41143),u=n.n(s),c=n(96774),d=n.n(c);function f(){return f=Object.assign||function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e},f.apply(this,arguments)}function p(e,t){e.prototype=Object.create(t.prototype),e.prototype.constructor=e,h(e,t)}function h(e,t){return h=Object.setPrototypeOf||function(e,t){return e.__proto__=t,e},h(e,t)}function m(e,t){if(null==e)return{};var n,r,o={},a=Object.keys(e);for(r=0;r<a.length;r++)t.indexOf(n=a[r])>=0||(o[n]=e[n]);return o}var g={BASE:"base",BODY:"body",HEAD:"head",HTML:"html",LINK:"link",META:"meta",NOSCRIPT:"noscript",SCRIPT:"script",STYLE:"style",TITLE:"title",FRAGMENT:"Symbol(react.fragment)"},v={rel:["amphtml","canonical","alternate"]},b={type:["application/ld+json"]},y={charset:"",name:["robots","description"],property:["og:type","og:title","og:url","og:image","og:image:alt","og:description","twitter:url","twitter:title","twitter:description","twitter:image","twitter:image:alt","twitter:card","twitter:site"]},w=Object.keys(g).map((function(e){return g[e]})),x={accesskey:"accessKey",charset:"charSet",class:"className",contenteditable:"contentEditable",contextmenu:"contextMenu","http-equiv":"httpEquiv",itemprop:"itemProp",tabindex:"tabIndex"},_=Object.keys(x).reduce((function(e,t){return e[x[t]]=t,e}),{}),k=function(e,t){for(var n=e.length-1;n>=0;n-=1){var r=e[n];if(Object.prototype.hasOwnProperty.call(r,t))return r[t]}return null},E=function(e){var t=k(e,g.TITLE),n=k(e,"titleTemplate");if(Array.isArray(t)&&(t=t.join("")),n&&t)return n.replace(/%s/g,(function(){return t}));var r=k(e,"defaultTitle");return t||r||void 0},S=function(e){return k(e,"onChangeClientState")||function(){}},C=function(e,t){return t.filter((function(t){return void 0!==t[e]})).map((function(t){return t[e]})).reduce((function(e,t){return f({},e,t)}),{})},T=function(e,t){return t.filter((function(e){return void 0!==e[g.BASE]})).map((function(e){return e[g.BASE]})).reverse().reduce((function(t,n){if(!t.length)for(var r=Object.keys(n),o=0;o<r.length;o+=1){var a=r[o].toLowerCase();if(-1!==e.indexOf(a)&&n[a])return t.concat(n)}return t}),[])},O=function(e,t,n){var r={};return n.filter((function(t){return!!Array.isArray(t[e])||(void 0!==t[e]&&console&&"function"==typeof console.warn&&console.warn("Helmet: "+e+' should be of type "Array". Instead found type "'+typeof t[e]+'"'),!1)})).map((function(t){return t[e]})).reverse().reduce((function(e,n){var o={};n.filter((function(e){for(var n,a=Object.keys(e),i=0;i<a.length;i+=1){var l=a[i],s=l.toLowerCase();-1===t.indexOf(s)||"rel"===n&&"canonical"===e[n].toLowerCase()||"rel"===s&&"stylesheet"===e[s].toLowerCase()||(n=s),-1===t.indexOf(l)||"innerHTML"!==l&&"cssText"!==l&&"itemprop"!==l||(n=l)}if(!n||!e[n])return!1;var u=e[n].toLowerCase();return r[n]||(r[n]={}),o[n]||(o[n]={}),!r[n][u]&&(o[n][u]=!0,!0)})).reverse().forEach((function(t){return e.push(t)}));for(var a=Object.keys(o),i=0;i<a.length;i+=1){var l=a[i],s=f({},r[l],o[l]);r[l]=s}return e}),[]).reverse()},D=function(e,t){if(Array.isArray(e)&&e.length)for(var n=0;n<e.length;n+=1)if(e[n][t])return!0;return!1},P=function(e){return Array.isArray(e)?e.join(""):e},N=function(e,t){return Array.isArray(e)?e.reduce((function(e,n){return function(e,t){for(var n=Object.keys(e),r=0;r<n.length;r+=1)if(t[n[r]]&&t[n[r]].includes(e[n[r]]))return!0;return!1}(n,t)?e.priority.push(n):e.default.push(n),e}),{priority:[],default:[]}):{default:e}},A=function(e,t){var n;return f({},e,((n={})[t]=void 0,n))},I=[g.NOSCRIPT,g.SCRIPT,g.STYLE],L=function(e,t){return void 0===t&&(t=!0),!1===t?String(e):String(e).replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""").replace(/'/g,"'")},R=function(e){return Object.keys(e).reduce((function(t,n){var r=void 0!==e[n]?n+'="'+e[n]+'"':""+n;return t?t+" "+r:r}),"")},j=function(e,t){return void 0===t&&(t={}),Object.keys(e).reduce((function(t,n){return t[x[n]||n]=e[n],t}),t)},M=function(e,t){return t.map((function(t,n){var o,a=((o={key:n})["data-rh"]=!0,o);return Object.keys(t).forEach((function(e){var n=x[e]||e;"innerHTML"===n||"cssText"===n?a.dangerouslySetInnerHTML={__html:t.innerHTML||t.cssText}:a[n]=t[e]})),r.createElement(e,a)}))},F=function(e,t,n){switch(e){case g.TITLE:return{toComponent:function(){return n=t.titleAttributes,(o={key:e=t.title})["data-rh"]=!0,a=j(n,o),[r.createElement(g.TITLE,a,e)];var e,n,o,a},toString:function(){return function(e,t,n,r){var o=R(n),a=P(t);return o?"<"+e+' data-rh="true" '+o+">"+L(a,r)+"</"+e+">":"<"+e+' data-rh="true">'+L(a,r)+"</"+e+">"}(e,t.title,t.titleAttributes,n)}};case"bodyAttributes":case"htmlAttributes":return{toComponent:function(){return j(t)},toString:function(){return R(t)}};default:return{toComponent:function(){return M(e,t)},toString:function(){return function(e,t,n){return t.reduce((function(t,r){var o=Object.keys(r).filter((function(e){return!("innerHTML"===e||"cssText"===e)})).reduce((function(e,t){var o=void 0===r[t]?t:t+'="'+L(r[t],n)+'"';return e?e+" "+o:o}),""),a=r.innerHTML||r.cssText||"",i=-1===I.indexOf(e);return t+"<"+e+' data-rh="true" '+o+(i?"/>":">"+a+"</"+e+">")}),"")}(e,t,n)}}}},B=function(e){var t=e.baseTag,n=e.bodyAttributes,r=e.encode,o=e.htmlAttributes,a=e.noscriptTags,i=e.styleTags,l=e.title,s=void 0===l?"":l,u=e.titleAttributes,c=e.linkTags,d=e.metaTags,f=e.scriptTags,p={toComponent:function(){},toString:function(){return""}};if(e.prioritizeSeoTags){var h=function(e){var t=e.linkTags,n=e.scriptTags,r=e.encode,o=N(e.metaTags,y),a=N(t,v),i=N(n,b);return{priorityMethods:{toComponent:function(){return[].concat(M(g.META,o.priority),M(g.LINK,a.priority),M(g.SCRIPT,i.priority))},toString:function(){return F(g.META,o.priority,r)+" "+F(g.LINK,a.priority,r)+" "+F(g.SCRIPT,i.priority,r)}},metaTags:o.default,linkTags:a.default,scriptTags:i.default}}(e);p=h.priorityMethods,c=h.linkTags,d=h.metaTags,f=h.scriptTags}return{priority:p,base:F(g.BASE,t,r),bodyAttributes:F("bodyAttributes",n,r),htmlAttributes:F("htmlAttributes",o,r),link:F(g.LINK,c,r),meta:F(g.META,d,r),noscript:F(g.NOSCRIPT,a,r),script:F(g.SCRIPT,f,r),style:F(g.STYLE,i,r),title:F(g.TITLE,{title:s,titleAttributes:u},r)}},z=[],$=function(e,t){var n=this;void 0===t&&(t="undefined"!=typeof document),this.instances=[],this.value={setHelmet:function(e){n.context.helmet=e},helmetInstances:{get:function(){return n.canUseDOM?z:n.instances},add:function(e){(n.canUseDOM?z:n.instances).push(e)},remove:function(e){var t=(n.canUseDOM?z:n.instances).indexOf(e);(n.canUseDOM?z:n.instances).splice(t,1)}}},this.context=e,this.canUseDOM=t,t||(e.helmet=B({baseTag:[],bodyAttributes:{},encodeSpecialCharacters:!0,htmlAttributes:{},linkTags:[],metaTags:[],noscriptTags:[],scriptTags:[],styleTags:[],title:"",titleAttributes:{}}))},U=r.createContext({}),H=a().shape({setHelmet:a().func,helmetInstances:a().shape({get:a().func,add:a().func,remove:a().func})}),V="undefined"!=typeof document,q=function(e){function t(n){var r;return(r=e.call(this,n)||this).helmetData=new $(r.props.context,t.canUseDOM),r}return p(t,e),t.prototype.render=function(){return r.createElement(U.Provider,{value:this.helmetData.value},this.props.children)},t}(r.Component);q.canUseDOM=V,q.propTypes={context:a().shape({helmet:a().shape()}),children:a().node.isRequired},q.defaultProps={context:{}},q.displayName="HelmetProvider";var G=function(e,t){var n,r=document.head||document.querySelector(g.HEAD),o=r.querySelectorAll(e+"[data-rh]"),a=[].slice.call(o),i=[];return t&&t.length&&t.forEach((function(t){var r=document.createElement(e);for(var o in t)Object.prototype.hasOwnProperty.call(t,o)&&("innerHTML"===o?r.innerHTML=t.innerHTML:"cssText"===o?r.styleSheet?r.styleSheet.cssText=t.cssText:r.appendChild(document.createTextNode(t.cssText)):r.setAttribute(o,void 0===t[o]?"":t[o]));r.setAttribute("data-rh","true"),a.some((function(e,t){return n=t,r.isEqualNode(e)}))?a.splice(n,1):i.push(r)})),a.forEach((function(e){return e.parentNode.removeChild(e)})),i.forEach((function(e){return r.appendChild(e)})),{oldTags:a,newTags:i}},W=function(e,t){var n=document.getElementsByTagName(e)[0];if(n){for(var r=n.getAttribute("data-rh"),o=r?r.split(","):[],a=[].concat(o),i=Object.keys(t),l=0;l<i.length;l+=1){var s=i[l],u=t[s]||"";n.getAttribute(s)!==u&&n.setAttribute(s,u),-1===o.indexOf(s)&&o.push(s);var c=a.indexOf(s);-1!==c&&a.splice(c,1)}for(var d=a.length-1;d>=0;d-=1)n.removeAttribute(a[d]);o.length===a.length?n.removeAttribute("data-rh"):n.getAttribute("data-rh")!==i.join(",")&&n.setAttribute("data-rh",i.join(","))}},Z=function(e,t){var n=e.baseTag,r=e.htmlAttributes,o=e.linkTags,a=e.metaTags,i=e.noscriptTags,l=e.onChangeClientState,s=e.scriptTags,u=e.styleTags,c=e.title,d=e.titleAttributes;W(g.BODY,e.bodyAttributes),W(g.HTML,r),function(e,t){void 0!==e&&document.title!==e&&(document.title=P(e)),W(g.TITLE,t)}(c,d);var f={baseTag:G(g.BASE,n),linkTags:G(g.LINK,o),metaTags:G(g.META,a),noscriptTags:G(g.NOSCRIPT,i),scriptTags:G(g.SCRIPT,s),styleTags:G(g.STYLE,u)},p={},h={};Object.keys(f).forEach((function(e){var t=f[e],n=t.newTags,r=t.oldTags;n.length&&(p[e]=n),r.length&&(h[e]=f[e].oldTags)})),t&&t(),l(e,p,h)},Q=null,Y=function(e){function t(){for(var t,n=arguments.length,r=new Array(n),o=0;o<n;o++)r[o]=arguments[o];return(t=e.call.apply(e,[this].concat(r))||this).rendered=!1,t}p(t,e);var n=t.prototype;return n.shouldComponentUpdate=function(e){return!d()(e,this.props)},n.componentDidUpdate=function(){this.emitChange()},n.componentWillUnmount=function(){this.props.context.helmetInstances.remove(this),this.emitChange()},n.emitChange=function(){var e,t,n=this.props.context,r=n.setHelmet,o=null,a=(e=n.helmetInstances.get().map((function(e){var t=f({},e.props);return delete t.context,t})),{baseTag:T(["href"],e),bodyAttributes:C("bodyAttributes",e),defer:k(e,"defer"),encode:k(e,"encodeSpecialCharacters"),htmlAttributes:C("htmlAttributes",e),linkTags:O(g.LINK,["rel","href"],e),metaTags:O(g.META,["name","charset","http-equiv","property","itemprop"],e),noscriptTags:O(g.NOSCRIPT,["innerHTML"],e),onChangeClientState:S(e),scriptTags:O(g.SCRIPT,["src","innerHTML"],e),styleTags:O(g.STYLE,["cssText"],e),title:E(e),titleAttributes:C("titleAttributes",e),prioritizeSeoTags:D(e,"prioritizeSeoTags")});q.canUseDOM?(t=a,Q&&cancelAnimationFrame(Q),t.defer?Q=requestAnimationFrame((function(){Z(t,(function(){Q=null}))})):(Z(t),Q=null)):B&&(o=B(a)),r(o)},n.init=function(){this.rendered||(this.rendered=!0,this.props.context.helmetInstances.add(this),this.emitChange())},n.render=function(){return this.init(),null},t}(r.Component);Y.propTypes={context:H.isRequired},Y.displayName="HelmetDispatcher";var X=["children"],K=["children"],J=function(e){function t(){return e.apply(this,arguments)||this}p(t,e);var n=t.prototype;return n.shouldComponentUpdate=function(e){return!l()(A(this.props,"helmetData"),A(e,"helmetData"))},n.mapNestedChildrenToProps=function(e,t){if(!t)return null;switch(e.type){case g.SCRIPT:case g.NOSCRIPT:return{innerHTML:t};case g.STYLE:return{cssText:t};default:throw new Error("<"+e.type+" /> elements are self-closing and can not contain children. Refer to our API for more information.")}},n.flattenArrayTypeChildren=function(e){var t,n=e.child,r=e.arrayTypeChildren;return f({},r,((t={})[n.type]=[].concat(r[n.type]||[],[f({},e.newChildProps,this.mapNestedChildrenToProps(n,e.nestedChildren))]),t))},n.mapObjectTypeChildren=function(e){var t,n,r=e.child,o=e.newProps,a=e.newChildProps,i=e.nestedChildren;switch(r.type){case g.TITLE:return f({},o,((t={})[r.type]=i,t.titleAttributes=f({},a),t));case g.BODY:return f({},o,{bodyAttributes:f({},a)});case g.HTML:return f({},o,{htmlAttributes:f({},a)});default:return f({},o,((n={})[r.type]=f({},a),n))}},n.mapArrayTypeChildrenToProps=function(e,t){var n=f({},t);return Object.keys(e).forEach((function(t){var r;n=f({},n,((r={})[t]=e[t],r))})),n},n.warnOnInvalidChildren=function(e,t){return u()(w.some((function(t){return e.type===t})),"function"==typeof e.type?"You may be attempting to nest <Helmet> components within each other, which is not allowed. Refer to our API for more information.":"Only elements types "+w.join(", ")+" are allowed. Helmet does not support rendering <"+e.type+"> elements. Refer to our API for more information."),u()(!t||"string"==typeof t||Array.isArray(t)&&!t.some((function(e){return"string"!=typeof e})),"Helmet expects a string as a child of <"+e.type+">. Did you forget to wrap your children in braces? ( <"+e.type+">{``}</"+e.type+"> ) Refer to our API for more information."),!0},n.mapChildrenToProps=function(e,t){var n=this,o={};return r.Children.forEach(e,(function(e){if(e&&e.props){var r=e.props,a=r.children,i=m(r,X),l=Object.keys(i).reduce((function(e,t){return e[_[t]||t]=i[t],e}),{}),s=e.type;switch("symbol"==typeof s?s=s.toString():n.warnOnInvalidChildren(e,a),s){case g.FRAGMENT:t=n.mapChildrenToProps(a,t);break;case g.LINK:case g.META:case g.NOSCRIPT:case g.SCRIPT:case g.STYLE:o=n.flattenArrayTypeChildren({child:e,arrayTypeChildren:o,newChildProps:l,nestedChildren:a});break;default:t=n.mapObjectTypeChildren({child:e,newProps:t,newChildProps:l,nestedChildren:a})}}})),this.mapArrayTypeChildrenToProps(o,t)},n.render=function(){var e=this.props,t=e.children,n=m(e,K),o=f({},n),a=n.helmetData;return t&&(o=this.mapChildrenToProps(t,o)),!a||a instanceof $||(a=new $(a.context,a.instances)),a?r.createElement(Y,f({},o,{context:a.value,helmetData:void 0})):r.createElement(U.Consumer,null,(function(e){return r.createElement(Y,f({},o,{context:e}))}))},t}(r.Component);J.propTypes={base:a().object,bodyAttributes:a().object,children:a().oneOfType([a().arrayOf(a().node),a().node]),defaultTitle:a().string,defer:a().bool,encodeSpecialCharacters:a().bool,htmlAttributes:a().object,link:a().arrayOf(a().object),meta:a().arrayOf(a().object),noscript:a().arrayOf(a().object),onChangeClientState:a().func,script:a().arrayOf(a().object),style:a().arrayOf(a().object),title:a().string,titleAttributes:a().object,titleTemplate:a().string,prioritizeSeoTags:a().bool,helmetData:a().object},J.defaultProps={defer:!0,encodeSpecialCharacters:!0,prioritizeSeoTags:!1},J.displayName="Helmet"},69921:(e,t)=>{"use strict";var n="function"==typeof Symbol&&Symbol.for,r=n?Symbol.for("react.element"):60103,o=n?Symbol.for("react.portal"):60106,a=n?Symbol.for("react.fragment"):60107,i=n?Symbol.for("react.strict_mode"):60108,l=n?Symbol.for("react.profiler"):60114,s=n?Symbol.for("react.provider"):60109,u=n?Symbol.for("react.context"):60110,c=n?Symbol.for("react.async_mode"):60111,d=n?Symbol.for("react.concurrent_mode"):60111,f=n?Symbol.for("react.forward_ref"):60112,p=n?Symbol.for("react.suspense"):60113,h=n?Symbol.for("react.suspense_list"):60120,m=n?Symbol.for("react.memo"):60115,g=n?Symbol.for("react.lazy"):60116,v=n?Symbol.for("react.block"):60121,b=n?Symbol.for("react.fundamental"):60117,y=n?Symbol.for("react.responder"):60118,w=n?Symbol.for("react.scope"):60119;function x(e){if("object"==typeof e&&null!==e){var t=e.$$typeof;switch(t){case r:switch(e=e.type){case c:case d:case a:case l:case i:case p:return e;default:switch(e=e&&e.$$typeof){case u:case f:case g:case m:case s:return e;default:return t}}case o:return t}}}function _(e){return x(e)===d}t.AsyncMode=c,t.ConcurrentMode=d,t.ContextConsumer=u,t.ContextProvider=s,t.Element=r,t.ForwardRef=f,t.Fragment=a,t.Lazy=g,t.Memo=m,t.Portal=o,t.Profiler=l,t.StrictMode=i,t.Suspense=p,t.isAsyncMode=function(e){return _(e)||x(e)===c},t.isConcurrentMode=_,t.isContextConsumer=function(e){return x(e)===u},t.isContextProvider=function(e){return x(e)===s},t.isElement=function(e){return"object"==typeof e&&null!==e&&e.$$typeof===r},t.isForwardRef=function(e){return x(e)===f},t.isFragment=function(e){return x(e)===a},t.isLazy=function(e){return x(e)===g},t.isMemo=function(e){return x(e)===m},t.isPortal=function(e){return x(e)===o},t.isProfiler=function(e){return x(e)===l},t.isStrictMode=function(e){return x(e)===i},t.isSuspense=function(e){return x(e)===p},t.isValidElementType=function(e){return"string"==typeof e||"function"==typeof e||e===a||e===d||e===l||e===i||e===p||e===h||"object"==typeof e&&null!==e&&(e.$$typeof===g||e.$$typeof===m||e.$$typeof===s||e.$$typeof===u||e.$$typeof===f||e.$$typeof===b||e.$$typeof===y||e.$$typeof===w||e.$$typeof===v)},t.typeOf=x},59864:(e,t,n)=>{"use strict";e.exports=n(69921)},68356:(e,t,n)=>{"use strict";function r(e,t){e.prototype=Object.create(t.prototype),e.prototype.constructor=e,e.__proto__=t}function o(e){if(void 0===e)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return e}function a(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function i(){return i=Object.assign||function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e},i.apply(this,arguments)}var l=n(67294),s=n(45697),u=[],c=[];function d(e){var t=e(),n={loading:!0,loaded:null,error:null};return n.promise=t.then((function(e){return n.loading=!1,n.loaded=e,e})).catch((function(e){throw n.loading=!1,n.error=e,e})),n}function f(e){var t={loading:!1,loaded:{},error:null},n=[];try{Object.keys(e).forEach((function(r){var o=d(e[r]);o.loading?t.loading=!0:(t.loaded[r]=o.loaded,t.error=o.error),n.push(o.promise),o.promise.then((function(e){t.loaded[r]=e})).catch((function(e){t.error=e}))}))}catch(r){t.error=r}return t.promise=Promise.all(n).then((function(e){return t.loading=!1,e})).catch((function(e){throw t.loading=!1,e})),t}function p(e,t){return l.createElement((n=e)&&n.__esModule?n.default:n,t);var n}function h(e,t){var d,f;if(!t.loading)throw new Error("react-loadable requires a `loading` component");var h=i({loader:null,loading:null,delay:200,timeout:null,render:p,webpack:null,modules:null},t),m=null;function g(){return m||(m=e(h.loader)),m.promise}return u.push(g),"function"==typeof h.webpack&&c.push((function(){if((0,h.webpack)().every((function(e){return void 0!==e&&void 0!==n.m[e]})))return g()})),f=d=function(t){function n(n){var r;return a(o(o(r=t.call(this,n)||this)),"retry",(function(){r.setState({error:null,loading:!0,timedOut:!1}),m=e(h.loader),r._loadModule()})),g(),r.state={error:m.error,pastDelay:!1,timedOut:!1,loading:m.loading,loaded:m.loaded},r}r(n,t),n.preload=function(){return g()};var i=n.prototype;return i.UNSAFE_componentWillMount=function(){this._loadModule()},i.componentDidMount=function(){this._mounted=!0},i._loadModule=function(){var e=this;if(this.context.loadable&&Array.isArray(h.modules)&&h.modules.forEach((function(t){e.context.loadable.report(t)})),m.loading){var t=function(t){e._mounted&&e.setState(t)};"number"==typeof h.delay&&(0===h.delay?this.setState({pastDelay:!0}):this._delay=setTimeout((function(){t({pastDelay:!0})}),h.delay)),"number"==typeof h.timeout&&(this._timeout=setTimeout((function(){t({timedOut:!0})}),h.timeout));var n=function(){t({error:m.error,loaded:m.loaded,loading:m.loading}),e._clearTimeouts()};m.promise.then((function(){return n(),null})).catch((function(e){return n(),null}))}},i.componentWillUnmount=function(){this._mounted=!1,this._clearTimeouts()},i._clearTimeouts=function(){clearTimeout(this._delay),clearTimeout(this._timeout)},i.render=function(){return this.state.loading||this.state.error?l.createElement(h.loading,{isLoading:this.state.loading,pastDelay:this.state.pastDelay,timedOut:this.state.timedOut,error:this.state.error,retry:this.retry}):this.state.loaded?h.render(this.state.loaded,this.props):null},n}(l.Component),a(d,"contextTypes",{loadable:s.shape({report:s.func.isRequired})}),f}function m(e){return h(d,e)}m.Map=function(e){if("function"!=typeof e.render)throw new Error("LoadableMap requires a `render(loaded, props)` function");return h(f,e)};var g=function(e){function t(){return e.apply(this,arguments)||this}r(t,e);var n=t.prototype;return n.getChildContext=function(){return{loadable:{report:this.props.report}}},n.render=function(){return l.Children.only(this.props.children)},t}(l.Component);function v(e){for(var t=[];e.length;){var n=e.pop();t.push(n())}return Promise.all(t).then((function(){if(e.length)return v(e)}))}a(g,"propTypes",{report:s.func.isRequired}),a(g,"childContextTypes",{loadable:s.shape({report:s.func.isRequired}).isRequired}),m.Capture=g,m.preloadAll=function(){return new Promise((function(e,t){v(u).then(e,t)}))},m.preloadReady=function(){return new Promise((function(e,t){v(c).then(e,e)}))},e.exports=m},33199:(e,t,n)=>{"use strict";n.r(t),n.d(t,{default:()=>B,hasTranslate3DSupport:()=>h,isTouch:()=>d,make2dTransformValue:()=>f,make3dTransformValue:()=>p});var r=function(e,t){return r=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(e,t){e.__proto__=t}||function(e,t){for(var n in t)Object.prototype.hasOwnProperty.call(t,n)&&(e[n]=t[n])},r(e,t)};function o(e,t){if("function"!=typeof t&&null!==t)throw new TypeError("Class extends value "+String(t)+" is not a constructor or null");function n(){this.constructor=e}r(e,t),e.prototype=null===t?Object.create(t):(n.prototype=t.prototype,new n)}var a=function(){return a=Object.assign||function(e){for(var t,n=1,r=arguments.length;n<r;n++)for(var o in t=arguments[n])Object.prototype.hasOwnProperty.call(t,o)&&(e[o]=t[o]);return e},a.apply(this,arguments)};Object.create;Object.create;var i=n(67294),l="kvfysmfp",s="ufhsfnkm",u=".".concat(l,"{overflow:hidden;touch-action:none}.").concat(s,"{transform-origin: 0 0}"),c="undefined"==typeof window,d=function(){return!c&&("ontouchstart"in window||navigator.maxTouchPoints>0)},f=function(e){var t=e.x,n=e.y,r=e.scale;return"scale(".concat(r,") translate(").concat(t,"px, ").concat(n,"px)")},p=function(e){var t=e.x,n=e.y,r=e.scale;return"scale3d(".concat(r,",").concat(r,", 1) translate3d(").concat(t,"px, ").concat(n,"px, 0)")},h=function(){var e=!c&&window.CSS;return e&&e.supports&&e.supports("transform","translate3d(0,0,0)")},m=Math.min,g=Math.max;function v(e){var t=e.containerDimension,n=e.childDimension,r=e.padding,o=e.centerContained,a=n-t;return a+2*r<=0&&o?[a/2,a/2]:[m(a+r,0)-r,g(0,a+r)]}var b=function(e,t){return t?"".concat(e," ").concat(t):e},y=Math.abs,w=Math.min,x=Math.sqrt,_="undefined"==typeof window,k=!_&&/(Mac)/i.test(navigator.platform),E=function(e){return"drag"===e},S=function(e){return"zoom"===e},C=function(e){return k&&e.ctrlKey},T=function(e){e.stopPropagation(),e.preventDefault()},O=function(e,t){var n=e.x-t.x,r=e.y-t.y;return x(n*n+r*r)},D=function(e,t){var n=O(e[0],e[1]);return O(t[0],t[1])/n},P=function(e){return-Math.cos(e*Math.PI)/2+.5},N=function(e){return{x:e.pageX,y:e.pageY}},A=function(e){return Array.from(e).map(N)},I=function(e,t){return e+t},L=function(e,t,n){return n<e?e:n>t?t:n},R=function(e){return!(e.ctrlKey||e.metaKey)},j=function(){},M={x:0,y:0},F=function(e){function t(){var t=null!==e&&e.apply(this,arguments)||this;return t._prevDragMovePoint=null,t._containerObserver=null,t._fingers=0,t._firstMove=!0,t._initialOffset=a({},M),t._interaction=null,t._isDoubleTap=!1,t._isOffsetsSet=!1,t._lastDragPosition=null,t._lastScale=1,t._lastTouchStart=0,t._lastZoomCenter=null,t._listenMouseMove=!1,t._nthZoom=0,t._offset=a({},M),t._startOffset=a({},M),t._startTouches=null,t._updatePlaned=!1,t._wheelTimeOut=null,t._zoomFactor=1,t._initialZoomFactor=1,t._draggingPoint=a({},M),t._ignoreNextClick=!1,t._containerRef=i.createRef(),t._handleClick=function(e){t._ignoreNextClick&&(t._ignoreNextClick=!1,e.stopPropagation())},t._onResize=function(){var e;(null===(e=t._containerRef)||void 0===e?void 0:e.current)&&(t._updateInitialZoomFactor(),t._setupOffsets(),t._update())},t._handlerOnTouchEnd=t._handlerIfEnable((function(e){t._fingers=e.touches.length,t.props.shouldCancelHandledTouchEndEvents&&(S(t._interaction)||E(t._interaction)&&(t._startOffset.x!==t._offset.x||t._startOffset.y!==t._offset.y))&&T(e),E(t._interaction)&&!t._enoughToDrag()&&t._handleClick(e),t._updateInteraction(e)})),t._handlerOnTouchStart=t._handlerIfEnable((function(e){t._firstMove=!0,t._fingers=e.touches.length,t._detectDoubleTap(e)})),t._handlerOnTouchMove=t._handlerIfEnable((function(e){t._isDoubleTap||(t._collectInertia(e),t._firstMove?(t._updateInteraction(e),t._interaction&&T(e),t._startOffset=a({},t._offset),t._startTouches=A(e.touches)):(S(t._interaction)?t._startTouches&&2===t._startTouches.length&&2===e.touches.length&&t._handleZoom(e,D(t._startTouches,A(e.touches))):E(t._interaction)&&t._handleDrag(e),t._interaction&&(T(e),t._update())),t._firstMove=!1)})),t._handlerWheel=function(e){if(!t.props.shouldInterceptWheel(e)){T(e);var n=e.pageX,r=e.pageY,o=e.deltaY,a=e.deltaMode,i=1;(C(e)||1===a)&&(i=15);var l={touches:[{pageX:n,pageY:r}]},s=t._getOffsetByFirstTouch(l),u=o*i;t._stopAnimation(),t._scaleTo(t._zoomFactor-u/t.props.wheelScaleFactor,s),t._update(),clearTimeout(t._wheelTimeOut),t._wheelTimeOut=setTimeout((function(){return t._sanitize()}),100)}},t._handlers=t.props.isTouch()?[["touchstart",t._handlerOnTouchStart],["touchend",t._handlerOnTouchEnd],["touchmove",t._handlerOnTouchMove]]:[["mousemove",t.simulate(t._handlerOnTouchMove),t.props._document],["mouseup",t.simulate(t._handlerOnTouchEnd),t.props._document],["mousedown",t.simulate(t._handlerOnTouchStart)],["click",t._handleClick],["wheel",t._handlerWheel]],t}return o(t,e),t.prototype._handleDragStart=function(e){this._ignoreNextClick=!0,this.props.onDragStart(),this._stopAnimation(),this._resetInertia(),this._lastDragPosition=null,this._hasInteraction=!0,this._draggingPoint=this._offset,this._handleDrag(e)},t.prototype._handleDrag=function(e){var t=this._getOffsetByFirstTouch(e);this._enoughToDrag()?this._drag(t,this._lastDragPosition):this._virtualDrag(t,this._lastDragPosition),this._offset=this._sanitizeOffset(this._offset),this._lastDragPosition=t},t.prototype._resetInertia=function(){this._velocity=null,this._prevDragMovePoint=null},t.prototype._realizeInertia=function(){var e=this,t=this.props,n=t.inertiaFriction;if(t.inertia&&this._velocity){var r=this._velocity,o=r.x,i=r.y;if(o||i){this._stopAnimation(),this._resetInertia();this._animate((function(){if(i*=n,!(o*=n)&&!i)return e._stopAnimation();var t,r,l=a({},e._offset);if(e._addOffset({x:o,y:i}),e._offset=e._sanitizeOffset(e._offset),t=l,r=e._offset,t.x===r.x&&t.y===r.y)return e._stopAnimation();e._update({isAnimation:!0})}),{duration:9999})}}},t.prototype._collectInertia=function(e){var t=e.touches;if(this.props.inertia){var n,r,o=A(t)[0],a=this._prevDragMovePoint;a&&(this._velocity=(n=o,{x:(r=a).x-n.x,y:r.y-n.y})),this._prevDragMovePoint=o}},t.prototype._handleDragEnd=function(){this.props.onDragEnd(),this._end(),this._realizeInertia()},t.prototype._handleZoomStart=function(){this.props.onZoomStart(),this._stopAnimation(),this._lastScale=1,this._nthZoom=0,this._lastZoomCenter=null,this._hasInteraction=!0},t.prototype._handleZoom=function(e,t){var n,r={x:(n=this._getOffsetTouches(e)).map((function(e){return e.x})).reduce(I,0)/n.length,y:n.map((function(e){return e.y})).reduce(I,0)/n.length},o=t/this._lastScale;this._lastScale=t,this._nthZoom+=1,this._nthZoom>3&&(this._scale(o,r),this._drag(r,this._lastZoomCenter),this.props.enforceBoundsDuringZoom&&(this._offset=this._sanitizeOffset(this._offset))),this._lastZoomCenter=r},t.prototype._handleZoomEnd=function(){this.props.onZoomEnd(),this._end()},t.prototype._handleDoubleTap=function(e){var t=this;if(!this._hasInteraction&&0!==this.props.tapZoomFactor){var n=this.props.doubleTapZoomOutOnMaxScale&&this._zoomFactor===this.props.maxZoom||this.props.doubleTapToggleZoom&&this._zoomFactor>1;this.props.onDoubleTap(),this._ignoreNextClick=!0;var r=this._zoomFactor+this.props.tapZoomFactor,o=this._zoomFactor,a=this._getOffsetByFirstTouch(e);this._isDoubleTap=!0,o>r&&(a=this._getCurrentZoomCenter()),n?this._zoomOutAnimation():this._animate((function(e){t._scaleTo(o+e*(r-o),a)}))}},t.prototype._computeInitialOffset=function(){var e=this._getContainerRect(),t=this._getChildSize(),n=t.width,r=t.height,o=-y(n*this._getInitialZoomFactor()-e.width)/2,a=-y(r*this._getInitialZoomFactor()-e.height)/2;this._initialOffset={x:o,y:a}},t.prototype._resetOffset=function(){this._offset=a({},this._initialOffset)},t.prototype._setupOffsets=function(){this.props.setOffsetsOnce&&this._isOffsetsSet||(this._isOffsetsSet=!0,this._computeInitialOffset(),this._resetOffset())},t.prototype._sanitizeOffset=function(e){var t=this._getContainerRect(),n=this._getChildSize(),r=n.width,o=n.height,a=r*this._getInitialZoomFactor()*this._zoomFactor,i=o*this._getInitialZoomFactor()*this._zoomFactor,l=v({containerDimension:t.width,childDimension:a,padding:this.props.horizontalPadding,centerContained:this.props.centerContained}),s=l[0],u=l[1],c=v({containerDimension:t.height,childDimension:i,padding:this.props.verticalPadding,centerContained:this.props.centerContained}),d=c[0],f=c[1];return{x:L(s,u,e.x),y:L(d,f,e.y)}},t.prototype.alignCenter=function(e){var t=this,n=a({duration:250,animated:!0},e),r=n.x,o=n.y,i=n.scale,l=n.animated,s=n.duration,u=this._zoomFactor,c=a({},this._offset),d=this._getContainerRect(),f={x:d.width/2,y:d.height/2};if(this._zoomFactor=1,this._offset={x:-(f.x-r),y:-(f.y-o)},this._scaleTo(i,f),this._stopAnimation(),!l)return this._update();var p=this._zoomFactor-u,h=this._offset.x-c.x,m=this._offset.y-c.y;this._zoomFactor=u,this._offset=a({},c);this._animate((function(e){var n=c.x+h*e,r=c.y+m*e;t._zoomFactor=u+p*e,t._offset=t._sanitizeOffset({x:n,y:r}),t._update()}),{callback:function(){return t._sanitize()},duration:s})},t.prototype.scaleTo=function(e){var t=this,n=a({duration:250,animated:!0},e),r=n.x,o=n.y,i=n.scale,l=n.animated,s=n.duration,u=this._zoomFactor,c=a({},this._offset);if(this._zoomFactor=1,this._offset={x:0,y:0},this._scaleTo(i,{x:r,y:o}),this._stopAnimation(),!l)return this._update();var d=this._zoomFactor-u,f=this._offset.x-c.x,p=this._offset.y-c.y;this._zoomFactor=u,this._offset=a({},c);this._animate((function(e){var n=c.x+f*e,r=c.y+p*e;t._zoomFactor=u+d*e,t._offset={x:n,y:r},t._update()}),{callback:function(){return t._sanitize()},duration:s})},t.prototype._scaleTo=function(e,t){this._scale(e/this._zoomFactor,t),this._offset=this._sanitizeOffset(this._offset)},t.prototype._scale=function(e,t){e=this._scaleZoomFactor(e),this._addOffset({x:(e-1)*(t.x+this._offset.x),y:(e-1)*(t.y+this._offset.y)}),this.props.onZoomUpdate()},t.prototype._scaleZoomFactor=function(e){var t=this._zoomFactor;return this._zoomFactor*=e,this._zoomFactor=L(this.props.minZoom,this.props.maxZoom,this._zoomFactor),this._zoomFactor/t},t.prototype._canDrag=function(){return this.props.draggableUnZoomed||!((e=this._zoomFactor)>(t=1)-.01&&e<t+.01);var e,t},t.prototype._drag=function(e,t){if(t){var n=-(e.y-t.y),r=-(e.x-t.x);this.props.lockDragAxis?y(r)>y(n)?this._addOffset({x:r,y:0}):this._addOffset({y:n,x:0}):this._addOffset({x:r,y:n}),this.props.onDragUpdate()}},t.prototype._virtualDrag=function(e,t){if(t){var n=-(e.y-t.y),r=-(e.x-t.x);this._draggingPoint={x:r+this._draggingPoint.x,y:n+this._draggingPoint.y}}},t.prototype._addOffset=function(e){var t=this._offset,n=t.x,r=t.y;this._offset={x:n+e.x,y:r+e.y}},t.prototype._sanitize=function(){this._zoomFactor<this.props.zoomOutFactor?(this._resetInertia(),this._zoomOutAnimation()):this._isInsaneOffset()&&this._sanitizeOffsetAnimation()},t.prototype._isInsaneOffset=function(){var e=this._offset,t=this._sanitizeOffset(e);return t.x!==e.x||t.y!==e.y},t.prototype._sanitizeOffsetAnimation=function(){var e=this,t=this._sanitizeOffset(this._offset),n=a({},this._offset);this._animate((function(r){var o=n.x+r*(t.x-n.x),a=n.y+r*(t.y-n.y);e._offset={x:o,y:a},e._update()}))},t.prototype._zoomOutAnimation=function(){var e=this;if(1!==this._zoomFactor){var t=this._zoomFactor,n=this._getCurrentZoomCenter();this._animate((function(r){var o=t+r*(1-t);e._scaleTo(o,n)}))}},t.prototype._getInitialZoomFactor=function(){return this._initialZoomFactor},t.prototype._getCurrentZoomCenter=function(){var e=this._offset,t=e.x,n=e.y,r=t-this._initialOffset.x,o=n-this._initialOffset.y;return{x:-1*t-r/(1/this._zoomFactor-1),y:-1*n-o/(1/this._zoomFactor-1)}},t.prototype._getOffsetByFirstTouch=function(e){return this._getOffsetTouches(e)[0]},t.prototype._getOffsetTouches=function(e){var t=this.props._document,n=t.documentElement,r=t.body,o=this._getContainerRect(),a=o.top,i=o.left,l=n.scrollTop||r.scrollTop,s=n.scrollLeft||r.scrollLeft,u=a+l,c=i+s;return A(e.touches).map((function(e){var t=e.x,n=e.y;return{x:t-c,y:n-u}}))},t.prototype._animate=function(e,t){var n=this,r=(new Date).getTime(),o=a({timeFn:P,callback:function(){},duration:this.props.animationDuration},t),i=o.timeFn,l=o.callback,s=o.duration,u=function(){if(n._inAnimation){var t=(new Date).getTime()-r,o=t/s;t>=s?(e(1),n._stopAnimation(),l(),n._update()):(o=i(o),e(o),n._update({isAnimation:!0}),requestAnimationFrame(u))}};this._inAnimation=!0,requestAnimationFrame(u)},t.prototype._stopAnimation=function(){this._inAnimation=!1},t.prototype._end=function(){this._hasInteraction=!1,this._sanitize(),this._update()},t.prototype._getContainerRect=function(){return this._containerRef.current.getBoundingClientRect()},t.prototype._getChildSize=function(){var e=this._containerRef.current;return function(e){if(e){var t=e.offsetWidth,n=e.offsetHeight;if(t&&n)return{width:t,height:n};var r=getComputedStyle(e),o=parseFloat(r.width),a=parseFloat(r.height);if(a&&o)return{width:o,height:a}}return{width:0,height:0}}(null==e?void 0:e.firstElementChild)},t.prototype._updateInitialZoomFactor=function(){var e=this._getContainerRect(),t=this._getChildSize(),n=e.width/t.width,r=e.height/t.height;this._initialZoomFactor=w(n,r)},t.prototype._bindEvents=function(){var e=this,t=this._containerRef.current;window.ResizeObserver?(this._containerObserver=new ResizeObserver(this._onResize),this._containerObserver.observe(t)):window.addEventListener("resize",this._onResize),this._handlers.forEach((function(e){var n=e[0],r=e[1];(e[2]||t).addEventListener(n,r,!0)})),Array.from(t.querySelectorAll("img")).forEach((function(t){return t.addEventListener("load",e._onResize)}))},t.prototype._unSubscribe=function(){var e=this,t=this._containerRef.current;this._containerObserver&&(this._containerObserver.disconnect(),this._containerObserver=null),window.removeEventListener("resize",this._onResize),this._handlers.forEach((function(e){var n=e[0],r=e[1];(e[2]||t).removeEventListener(n,r,!0)})),Array.from(t.querySelectorAll("img")).forEach((function(t){return t.removeEventListener("load",e._onResize)}))},t.prototype._update=function(e){var t=this;if(!this._updatePlaned){var n=function(){var e=t._getInitialZoomFactor()*t._zoomFactor,n=-t._offset.x/e,r=-t._offset.y/e;t.props.onUpdate({scale:e,x:n,y:r})};if(null==e?void 0:e.isAnimation)return n();this._updatePlaned=!0,requestAnimationFrame((function(){t._updatePlaned=!1,n()}))}},t.prototype._handlerIfEnable=function(e){var t=this;return function(){for(var n=[],r=0;r<arguments.length;r++)n[r]=arguments[r];t.props.enabled&&e.apply(void 0,n)}},t.prototype._setInteraction=function(e,t){var n=this._interaction;n!==e&&(n&&!e&&(S(n)?this._handleZoomEnd():E(n)&&this._handleDragEnd()),S(e)?this._handleZoomStart():E(e)&&this._handleDragStart(t)),this._interaction=e},t.prototype._distanceBetweenNumbers=function(e,t){return e>t?e-t:t-e},t.prototype._enoughToDrag=function(){return this._distanceBetweenNumbers(this._startOffset.x,this._draggingPoint.x)>5||this._distanceBetweenNumbers(this._startOffset.y,this._draggingPoint.y)>5},t.prototype._updateInteraction=function(e){var t=this._fingers;return 2===t?this._setInteraction("zoom",e):1===t&&this._canDrag()?this._setInteraction("drag",e):void this._setInteraction(null,e)},t.prototype._detectDoubleTap=function(e){var t=(new Date).getTime();this._fingers>1&&(this._lastTouchStart=0),t-this._lastTouchStart<300?(T(e),this._handleDoubleTap(e),S(this._interaction)?this._handleZoomEnd():E(this._interaction)&&this._handleDragEnd()):this._isDoubleTap=!1,1===this._fingers&&(this._lastTouchStart=t)},t.prototype.simulate=function(e){var t=this;return function(n){var r=n.pageX,o=n.pageY,a=n.type,i="mouseup"===a;"mousedown"===a&&(n.preventDefault(),t._listenMouseMove=!0),t._listenMouseMove&&(n.touches=i?[]:[{pageX:r,pageY:o}],e(n)),i&&(t._listenMouseMove=!1)}},t.prototype.componentDidMount=function(){this._bindEvents(),this._update()},t.prototype.componentWillUnmount=function(){this._stopAnimation(),this._unSubscribe()},t.prototype.render=function(){var e=this.props,t=e.children,n=e.containerProps,r=i.Children.only(t),o=n||{};return i.createElement(i.Fragment,null,i.createElement("style",null,u),i.createElement("div",a({},o,{ref:this._containerRef,className:b(l,o.className)}),i.cloneElement(r,{className:b(s,r.props.className)})))},t.defaultProps={animationDuration:250,draggableUnZoomed:!0,enforceBoundsDuringZoom:!1,centerContained:!1,enabled:!0,inertia:!0,inertiaFriction:.96,horizontalPadding:0,isTouch:d,lockDragAxis:!1,maxZoom:5,minZoom:.5,onDoubleTap:j,onDragEnd:j,onDragStart:j,onDragUpdate:j,onZoomEnd:j,onZoomStart:j,onZoomUpdate:j,setOffsetsOnce:!1,shouldInterceptWheel:R,shouldCancelHandledTouchEndEvents:!1,tapZoomFactor:1,verticalPadding:0,wheelScaleFactor:1500,zoomOutFactor:1.3,doubleTapZoomOutOnMaxScale:!1,doubleTapToggleZoom:!1,_document:_?null:window.document},t}(i.Component);const B=F},18790:(e,t,n)=>{"use strict";n.d(t,{H:()=>l,f:()=>i});var r=n(16550),o=n(87462),a=n(67294);function i(e,t,n){return void 0===n&&(n=[]),e.some((function(e){var o=e.path?(0,r.LX)(t,e):n.length?n[n.length-1].match:r.F0.computeRootMatch(t);return o&&(n.push({route:e,match:o}),e.routes&&i(e.routes,t,n)),o})),n}function l(e,t,n){return void 0===t&&(t={}),void 0===n&&(n={}),e?a.createElement(r.rs,n,e.map((function(e,n){return a.createElement(r.AW,{key:e.key||n,path:e.path,exact:e.exact,strict:e.strict,render:function(n){return e.render?e.render((0,o.Z)({},n,{},t,{route:e})):a.createElement(e.component,(0,o.Z)({},n,t,{route:e}))}})}))):null}},73727:(e,t,n)=>{"use strict";n.d(t,{OL:()=>y,VK:()=>c,rU:()=>g});var r=n(16550),o=n(75068),a=n(67294),i=n(42358),l=n(87462),s=n(63366),u=n(38776),c=function(e){function t(){for(var t,n=arguments.length,r=new Array(n),o=0;o<n;o++)r[o]=arguments[o];return(t=e.call.apply(e,[this].concat(r))||this).history=(0,i.lX)(t.props),t}return(0,o.Z)(t,e),t.prototype.render=function(){return a.createElement(r.F0,{history:this.history,children:this.props.children})},t}(a.Component);a.Component;var d=function(e,t){return"function"==typeof e?e(t):e},f=function(e,t){return"string"==typeof e?(0,i.ob)(e,null,null,t):e},p=function(e){return e},h=a.forwardRef;void 0===h&&(h=p);var m=h((function(e,t){var n=e.innerRef,r=e.navigate,o=e.onClick,i=(0,s.Z)(e,["innerRef","navigate","onClick"]),u=i.target,c=(0,l.Z)({},i,{onClick:function(e){try{o&&o(e)}catch(t){throw e.preventDefault(),t}e.defaultPrevented||0!==e.button||u&&"_self"!==u||function(e){return!!(e.metaKey||e.altKey||e.ctrlKey||e.shiftKey)}(e)||(e.preventDefault(),r())}});return c.ref=p!==h&&t||n,a.createElement("a",c)}));var g=h((function(e,t){var n=e.component,o=void 0===n?m:n,c=e.replace,g=e.to,v=e.innerRef,b=(0,s.Z)(e,["component","replace","to","innerRef"]);return a.createElement(r.s6.Consumer,null,(function(e){e||(0,u.Z)(!1);var n=e.history,r=f(d(g,e.location),e.location),s=r?n.createHref(r):"",m=(0,l.Z)({},b,{href:s,navigate:function(){var t=d(g,e.location),r=(0,i.Ep)(e.location)===(0,i.Ep)(f(t));(c||r?n.replace:n.push)(t)}});return p!==h?m.ref=t||v:m.innerRef=v,a.createElement(o,m)}))})),v=function(e){return e},b=a.forwardRef;void 0===b&&(b=v);var y=b((function(e,t){var n=e["aria-current"],o=void 0===n?"page":n,i=e.activeClassName,c=void 0===i?"active":i,p=e.activeStyle,h=e.className,m=e.exact,y=e.isActive,w=e.location,x=e.sensitive,_=e.strict,k=e.style,E=e.to,S=e.innerRef,C=(0,s.Z)(e,["aria-current","activeClassName","activeStyle","className","exact","isActive","location","sensitive","strict","style","to","innerRef"]);return a.createElement(r.s6.Consumer,null,(function(e){e||(0,u.Z)(!1);var n=w||e.location,i=f(d(E,n),n),s=i.pathname,T=s&&s.replace(/([.+*?=^!:${}()[\]|/\\])/g,"\\$1"),O=T?(0,r.LX)(n.pathname,{path:T,exact:m,sensitive:x,strict:_}):null,D=!!(y?y(O,n):O),P="function"==typeof h?h(D):h,N="function"==typeof k?k(D):k;D&&(P=function(){for(var e=arguments.length,t=new Array(e),n=0;n<e;n++)t[n]=arguments[n];return t.filter((function(e){return e})).join(" ")}(P,c),N=(0,l.Z)({},N,p));var A=(0,l.Z)({"aria-current":D&&o||null,className:P,style:N,to:i},C);return v!==b?A.ref=t||S:A.innerRef=S,a.createElement(g,A)}))}))},16550:(e,t,n)=>{"use strict";n.d(t,{AW:()=>D,F0:()=>w,LX:()=>O,TH:()=>F,k6:()=>M,l_:()=>S,rs:()=>R,s6:()=>y});var r=n(75068),o=n(67294),a=n(45697),i=n.n(a),l=n(42358),s=n(38776),u=n(87462),c=n(39658),d=n.n(c),f=(n(59864),n(63366)),p=(n(8679),1073741823),h="undefined"!=typeof globalThis?globalThis:"undefined"!=typeof window?window:void 0!==n.g?n.g:{};function m(e){var t=[];return{on:function(e){t.push(e)},off:function(e){t=t.filter((function(t){return t!==e}))},get:function(){return e},set:function(n,r){e=n,t.forEach((function(t){return t(e,r)}))}}}var g=o.createContext||function(e,t){var n,a,l="__create-react-context-"+function(){var e="__global_unique_id__";return h[e]=(h[e]||0)+1}()+"__",s=function(e){function n(){for(var t,n=arguments.length,r=new Array(n),o=0;o<n;o++)r[o]=arguments[o];return(t=e.call.apply(e,[this].concat(r))||this).emitter=m(t.props.value),t}(0,r.Z)(n,e);var o=n.prototype;return o.getChildContext=function(){var e;return(e={})[l]=this.emitter,e},o.componentWillReceiveProps=function(e){if(this.props.value!==e.value){var n,r=this.props.value,o=e.value;((a=r)===(i=o)?0!==a||1/a==1/i:a!=a&&i!=i)?n=0:(n="function"==typeof t?t(r,o):p,0!==(n|=0)&&this.emitter.set(e.value,n))}var a,i},o.render=function(){return this.props.children},n}(o.Component);s.childContextTypes=((n={})[l]=i().object.isRequired,n);var u=function(t){function n(){for(var e,n=arguments.length,r=new Array(n),o=0;o<n;o++)r[o]=arguments[o];return(e=t.call.apply(t,[this].concat(r))||this).observedBits=void 0,e.state={value:e.getValue()},e.onUpdate=function(t,n){0!=((0|e.observedBits)&n)&&e.setState({value:e.getValue()})},e}(0,r.Z)(n,t);var o=n.prototype;return o.componentWillReceiveProps=function(e){var t=e.observedBits;this.observedBits=null==t?p:t},o.componentDidMount=function(){this.context[l]&&this.context[l].on(this.onUpdate);var e=this.props.observedBits;this.observedBits=null==e?p:e},o.componentWillUnmount=function(){this.context[l]&&this.context[l].off(this.onUpdate)},o.getValue=function(){return this.context[l]?this.context[l].get():e},o.render=function(){return(e=this.props.children,Array.isArray(e)?e[0]:e)(this.state.value);var e},n}(o.Component);return u.contextTypes=((a={})[l]=i().object,a),{Provider:s,Consumer:u}},v=function(e){var t=g();return t.displayName=e,t},b=v("Router-History"),y=v("Router"),w=function(e){function t(t){var n;return(n=e.call(this,t)||this).state={location:t.history.location},n._isMounted=!1,n._pendingLocation=null,t.staticContext||(n.unlisten=t.history.listen((function(e){n._pendingLocation=e}))),n}(0,r.Z)(t,e),t.computeRootMatch=function(e){return{path:"/",url:"/",params:{},isExact:"/"===e}};var n=t.prototype;return n.componentDidMount=function(){var e=this;this._isMounted=!0,this.unlisten&&this.unlisten(),this.props.staticContext||(this.unlisten=this.props.history.listen((function(t){e._isMounted&&e.setState({location:t})}))),this._pendingLocation&&this.setState({location:this._pendingLocation})},n.componentWillUnmount=function(){this.unlisten&&(this.unlisten(),this._isMounted=!1,this._pendingLocation=null)},n.render=function(){return o.createElement(y.Provider,{value:{history:this.props.history,location:this.state.location,match:t.computeRootMatch(this.state.location.pathname),staticContext:this.props.staticContext}},o.createElement(b.Provider,{children:this.props.children||null,value:this.props.history}))},t}(o.Component);o.Component;var x=function(e){function t(){return e.apply(this,arguments)||this}(0,r.Z)(t,e);var n=t.prototype;return n.componentDidMount=function(){this.props.onMount&&this.props.onMount.call(this,this)},n.componentDidUpdate=function(e){this.props.onUpdate&&this.props.onUpdate.call(this,this,e)},n.componentWillUnmount=function(){this.props.onUnmount&&this.props.onUnmount.call(this,this)},n.render=function(){return null},t}(o.Component);var _={},k=0;function E(e,t){return void 0===e&&(e="/"),void 0===t&&(t={}),"/"===e?e:function(e){if(_[e])return _[e];var t=d().compile(e);return k<1e4&&(_[e]=t,k++),t}(e)(t,{pretty:!0})}function S(e){var t=e.computedMatch,n=e.to,r=e.push,a=void 0!==r&&r;return o.createElement(y.Consumer,null,(function(e){e||(0,s.Z)(!1);var r=e.history,i=e.staticContext,c=a?r.push:r.replace,d=(0,l.ob)(t?"string"==typeof n?E(n,t.params):(0,u.Z)({},n,{pathname:E(n.pathname,t.params)}):n);return i?(c(d),null):o.createElement(x,{onMount:function(){c(d)},onUpdate:function(e,t){var n=(0,l.ob)(t.to);(0,l.Hp)(n,(0,u.Z)({},d,{key:n.key}))||c(d)},to:n})}))}var C={},T=0;function O(e,t){void 0===t&&(t={}),("string"==typeof t||Array.isArray(t))&&(t={path:t});var n=t,r=n.path,o=n.exact,a=void 0!==o&&o,i=n.strict,l=void 0!==i&&i,s=n.sensitive,u=void 0!==s&&s;return[].concat(r).reduce((function(t,n){if(!n&&""!==n)return null;if(t)return t;var r=function(e,t){var n=""+t.end+t.strict+t.sensitive,r=C[n]||(C[n]={});if(r[e])return r[e];var o=[],a={regexp:d()(e,o,t),keys:o};return T<1e4&&(r[e]=a,T++),a}(n,{end:a,strict:l,sensitive:u}),o=r.regexp,i=r.keys,s=o.exec(e);if(!s)return null;var c=s[0],f=s.slice(1),p=e===c;return a&&!p?null:{path:n,url:"/"===n&&""===c?"/":c,isExact:p,params:i.reduce((function(e,t,n){return e[t.name]=f[n],e}),{})}}),null)}var D=function(e){function t(){return e.apply(this,arguments)||this}return(0,r.Z)(t,e),t.prototype.render=function(){var e=this;return o.createElement(y.Consumer,null,(function(t){t||(0,s.Z)(!1);var n=e.props.location||t.location,r=e.props.computedMatch?e.props.computedMatch:e.props.path?O(n.pathname,e.props):t.match,a=(0,u.Z)({},t,{location:n,match:r}),i=e.props,l=i.children,c=i.component,d=i.render;return Array.isArray(l)&&function(e){return 0===o.Children.count(e)}(l)&&(l=null),o.createElement(y.Provider,{value:a},a.match?l?"function"==typeof l?l(a):l:c?o.createElement(c,a):d?d(a):null:"function"==typeof l?l(a):null)}))},t}(o.Component);function P(e){return"/"===e.charAt(0)?e:"/"+e}function N(e,t){if(!e)return t;var n=P(e);return 0!==t.pathname.indexOf(n)?t:(0,u.Z)({},t,{pathname:t.pathname.substr(n.length)})}function A(e){return"string"==typeof e?e:(0,l.Ep)(e)}function I(e){return function(){(0,s.Z)(!1)}}function L(){}o.Component;var R=function(e){function t(){return e.apply(this,arguments)||this}return(0,r.Z)(t,e),t.prototype.render=function(){var e=this;return o.createElement(y.Consumer,null,(function(t){t||(0,s.Z)(!1);var n,r,a=e.props.location||t.location;return o.Children.forEach(e.props.children,(function(e){if(null==r&&o.isValidElement(e)){n=e;var i=e.props.path||e.props.from;r=i?O(a.pathname,(0,u.Z)({},e.props,{path:i})):t.match}})),r?o.cloneElement(n,{location:a,computedMatch:r}):null}))},t}(o.Component);var j=o.useContext;function M(){return j(b)}function F(){return j(y).location}},76585:e=>{e.exports=Array.isArray||function(e){return"[object Array]"==Object.prototype.toString.call(e)}},39658:(e,t,n)=>{var r=n(76585);e.exports=p,e.exports.parse=a,e.exports.compile=function(e,t){return l(a(e,t),t)},e.exports.tokensToFunction=l,e.exports.tokensToRegExp=f;var o=new RegExp(["(\\\\.)","([\\/.])?(?:(?:\\:(\\w+)(?:\\(((?:\\\\.|[^\\\\()])+)\\))?|\\(((?:\\\\.|[^\\\\()])+)\\))([+*?])?|(\\*))"].join("|"),"g");function a(e,t){for(var n,r=[],a=0,i=0,l="",c=t&&t.delimiter||"/";null!=(n=o.exec(e));){var d=n[0],f=n[1],p=n.index;if(l+=e.slice(i,p),i=p+d.length,f)l+=f[1];else{var h=e[i],m=n[2],g=n[3],v=n[4],b=n[5],y=n[6],w=n[7];l&&(r.push(l),l="");var x=null!=m&&null!=h&&h!==m,_="+"===y||"*"===y,k="?"===y||"*"===y,E=n[2]||c,S=v||b;r.push({name:g||a++,prefix:m||"",delimiter:E,optional:k,repeat:_,partial:x,asterisk:!!w,pattern:S?u(S):w?".*":"[^"+s(E)+"]+?"})}}return i<e.length&&(l+=e.substr(i)),l&&r.push(l),r}function i(e){return encodeURI(e).replace(/[\/?#]/g,(function(e){return"%"+e.charCodeAt(0).toString(16).toUpperCase()}))}function l(e,t){for(var n=new Array(e.length),o=0;o<e.length;o++)"object"==typeof e[o]&&(n[o]=new RegExp("^(?:"+e[o].pattern+")$",d(t)));return function(t,o){for(var a="",l=t||{},s=(o||{}).pretty?i:encodeURIComponent,u=0;u<e.length;u++){var c=e[u];if("string"!=typeof c){var d,f=l[c.name];if(null==f){if(c.optional){c.partial&&(a+=c.prefix);continue}throw new TypeError('Expected "'+c.name+'" to be defined')}if(r(f)){if(!c.repeat)throw new TypeError('Expected "'+c.name+'" to not repeat, but received `'+JSON.stringify(f)+"`");if(0===f.length){if(c.optional)continue;throw new TypeError('Expected "'+c.name+'" to not be empty')}for(var p=0;p<f.length;p++){if(d=s(f[p]),!n[u].test(d))throw new TypeError('Expected all "'+c.name+'" to match "'+c.pattern+'", but received `'+JSON.stringify(d)+"`");a+=(0===p?c.prefix:c.delimiter)+d}}else{if(d=c.asterisk?encodeURI(f).replace(/[?#]/g,(function(e){return"%"+e.charCodeAt(0).toString(16).toUpperCase()})):s(f),!n[u].test(d))throw new TypeError('Expected "'+c.name+'" to match "'+c.pattern+'", but received "'+d+'"');a+=c.prefix+d}}else a+=c}return a}}function s(e){return e.replace(/([.+*?=^!:${}()[\]|\/\\])/g,"\\$1")}function u(e){return e.replace(/([=!:$\/()])/g,"\\$1")}function c(e,t){return e.keys=t,e}function d(e){return e&&e.sensitive?"":"i"}function f(e,t,n){r(t)||(n=t||n,t=[]);for(var o=(n=n||{}).strict,a=!1!==n.end,i="",l=0;l<e.length;l++){var u=e[l];if("string"==typeof u)i+=s(u);else{var f=s(u.prefix),p="(?:"+u.pattern+")";t.push(u),u.repeat&&(p+="(?:"+f+p+")*"),i+=p=u.optional?u.partial?f+"("+p+")?":"(?:"+f+"("+p+"))?":f+"("+p+")"}}var h=s(n.delimiter||"/"),m=i.slice(-h.length)===h;return o||(i=(m?i.slice(0,-h.length):i)+"(?:"+h+"(?=$))?"),i+=a?"$":o&&m?"":"(?="+h+"|$)",c(new RegExp("^"+i,d(n)),t)}function p(e,t,n){return r(t)||(n=t||n,t=[]),n=n||{},e instanceof RegExp?function(e,t){var n=e.source.match(/\((?!\?)/g);if(n)for(var r=0;r<n.length;r++)t.push({name:r,prefix:null,delimiter:null,optional:!1,repeat:!1,partial:!1,asterisk:!1,pattern:null});return c(e,t)}(e,t):r(e)?function(e,t,n){for(var r=[],o=0;o<e.length;o++)r.push(p(e[o],t,n).source);return c(new RegExp("(?:"+r.join("|")+")",d(n)),t)}(e,t,n):function(e,t,n){return f(a(e,n),t,n)}(e,t,n)}},86718:(e,t,n)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0});var r=n(70655).__importDefault(n(45503));t.default=function(e){return!e.prototype?r.default(e):e}},27162:(e,t,n)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.divWrapper=void 0;var r=n(70655),o=r.__importStar(n(67294)),a=r.__importDefault(n(86718)),i=o.createElement,l=function(e,t,n,o){var a;return i(e,t?r.__assign(((a={})[t]=o,a),n):r.__assign(r.__assign({},o),n))};t.divWrapper=function(e,t,n,r){return i("div",null,l(e,t,n,r))};t.default=function(e,t,n){void 0===n&&(n=l);var r=function(o,l,s){void 0===l&&(l=t),void 0===s&&(s=null);var u="string"==typeof o;if(u)return function(e){return r(e,o||t,l)};var c=function(t){return i(e,s,(function(e){return n(o,l,t,e)}))};return u?a.default(c):c};return r}},3:(e,t,n)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0});var r=n(70655).__importDefault(n(95364)),o=function(e){return[e]};t.default=function(e,t){return void 0===t&&(t=o),function(n){return r.default(n,e.apply(void 0,t(n)))}}},96260:(e,t,n)=>{"use strict";var r=n(70655);r.__importDefault(n(95364)).default,r.__importDefault(n(27162)).default,r.__importDefault(n(3)).default},95364:(e,t,n)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0});var r=n(70655),o=n(67294),a=parseInt(o.version.substr(0,o.version.indexOf(".")))>15,i=function(e){return"function"==typeof e};t.default=function(e,t){for(var n=[],l=2;l<arguments.length;l++)n[l-2]=arguments[l];var s=e.render,u=e.children,c=void 0===u?s:u,d=e.component,f=e.comp,p=void 0===f?d:f;return i(c)?c.apply(void 0,r.__spreadArrays([t],n)):p?o.createElement(p,t):c instanceof Array?a?c:o.createElement.apply(void 0,r.__spreadArrays(["div",null],c)):c&&c instanceof Object?"string"==typeof c.type?c:o.cloneElement(c,Object.assign({},c.props,t)):c||null}},45503:(e,t,n)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0});var r=n(70655),o=r.__importStar(n(67294));t.default=function(e){var t=function(t){function n(){return null!==t&&t.apply(this,arguments)||this}return r.__extends(n,t),n.prototype.render=function(){return e(this.props,this.context)},n}(o.Component);return t}},89164:(e,t,n)=>{"use strict";n.r(t),n.d(t,{createBreakpoint:()=>Le,createGlobalState:()=>_n,createMemo:()=>a,createReducer:()=>c,createReducerContext:()=>i,createStateContext:()=>d,ensuredForwardRef:()=>ce,useAsync:()=>m,useAsyncFn:()=>h,useAsyncRetry:()=>g,useAudio:()=>w,useBattery:()=>D,useBeforeUnload:()=>P,useBoolean:()=>I,useClickAway:()=>R,useCookie:()=>F,useCopyToClipboard:()=>$,useCounter:()=>G,useCss:()=>ee,useCustomCompareEffect:()=>te,useDebounce:()=>re,useDeepCompareEffect:()=>oe,useDefault:()=>ae,useDrop:()=>ie,useDropArea:()=>le,useEffectOnce:()=>se,useEnsuredForwardedRef:()=>ue,useError:()=>me,useEvent:()=>he,useFavicon:()=>ge,useFirstMountState:()=>l,useFullscreen:()=>ye,useGeolocation:()=>we,useGetSet:()=>q,useGetSetState:()=>xe,useHarmonicIntervalFn:()=>Ee,useHash:()=>kn,useHover:()=>Ce,useHoverDirty:()=>Te,useIdle:()=>Pe,useIntersection:()=>Ne,useInterval:()=>Ae,useIsomorphicLayoutEffect:()=>X,useKey:()=>Ie,useKeyPress:()=>Re,useKeyPressEvent:()=>je,useLatest:()=>Me,useLifecycles:()=>Fe,useList:()=>Be,useLocalStorage:()=>ze,useLocation:()=>Ve,useLockBodyScroll:()=>Xe,useLogger:()=>Ke,useLongPress:()=>et,useMap:()=>tt,useMeasure:()=>vn,useMedia:()=>nt,useMediaDevices:()=>rt,useMediatedState:()=>ot,useMethods:()=>at,useMotion:()=>lt,useMount:()=>st,useMountedState:()=>p,useMouse:()=>dt,useMouseHovered:()=>pt,useMouseWheel:()=>ht,useMultiStateValidator:()=>pn,useNetworkState:()=>bt,useNumber:()=>yt,useObservable:()=>wt,useOrientation:()=>_t,usePageLeave:()=>kt,usePermission:()=>Et,usePinchZoom:()=>yn,usePrevious:()=>St,usePreviousDistinct:()=>Tt,usePromise:()=>Ot,useQueue:()=>Dt,useRaf:()=>Pt,useRafLoop:()=>Nt,useRafState:()=>ct,useRendersCount:()=>wn,useScratch:()=>Rt,useScroll:()=>jt,useScrollbarWidth:()=>fn,useScrolling:()=>Mt,useSearchParam:()=>It,useSessionStorage:()=>Ft,useSet:()=>xn,useSetState:()=>v,useShallowCompareEffect:()=>$t,useSize:()=>qt,useSlider:()=>Gt,useSpeech:()=>Zt,useStartTyping:()=>Qt,useStateList:()=>Xt,useStateValidator:()=>cn,useStateWithHistory:()=>Yt,useThrottle:()=>Kt,useThrottleFn:()=>Jt,useTimeout:()=>en,useTimeoutFn:()=>ne,useTitle:()=>nn,useToggle:()=>A,useTween:()=>on,useUnmount:()=>ut,useUnmountPromise:()=>an,useUpdate:()=>H,useUpdateEffect:()=>s,useUpsert:()=>ln,useVibrate:()=>sn,useVideo:()=>un,useWindowScroll:()=>hn,useWindowSize:()=>mn});var r=n(67294),o=n.t(r,2);const a=function(e){return function(){for(var t=[],n=0;n<arguments.length;n++)t[n]=arguments[n];return(0,r.useMemo)((function(){return e.apply(void 0,t)}),t)}};const i=function(e,t){var n=(0,r.createContext)(void 0);return[function(){var e=(0,r.useContext)(n);if(null==e)throw new Error("useReducerContext must be used inside a ReducerProvider.");return e},function(o){var a=o.children,i=o.initialState;return function(e,t){return(0,r.createElement)(n.Provider,e,t)}({value:(0,r.useReducer)(e,void 0!==i?i:t)},a)},n]};function l(){var e=(0,r.useRef)(!0);return e.current?(e.current=!1,!0):e.current}const s=function(e,t){var n=l();(0,r.useEffect)((function(){if(!n)return e()}),t)};function u(e){return function(t,n){return e.reduceRight((function(e,n){return n(t)(e)}),n)}}const c=function(){for(var e=[],t=0;t<arguments.length;t++)e[t]=arguments[t];var n=u(e);return function(e,t,o){void 0===o&&(o=function(e){return e});var a=(0,r.useRef)(o(t)),i=(0,r.useState)(a.current)[1],l=(0,r.useCallback)((function(t){return a.current=e(a.current,t),i(a.current),t}),[e]),u=(0,r.useRef)(n({getState:function(){return a.current},dispatch:function(){for(var e=[],t=0;t<arguments.length;t++)e[t]=arguments[t];return u.current.apply(u,e)}},l));return s((function(){u.current=n({getState:function(){return a.current},dispatch:function(){for(var e=[],t=0;t<arguments.length;t++)e[t]=arguments[t];return u.current.apply(u,e)}},l)}),[l]),[a.current,u.current]}};const d=function(e){var t=(0,r.createContext)(void 0);return[function(){var e=(0,r.useContext)(t);if(null==e)throw new Error("useStateContext must be used inside a StateProvider.");return e},function(n){var o=n.children,a=n.initialValue;return function(e,n){return(0,r.createElement)(t.Provider,e,n)}({value:(0,r.useState)(void 0!==a?a:e)},o)},t]};var f=n(70655);function p(){var e=(0,r.useRef)(!1),t=(0,r.useCallback)((function(){return e.current}),[]);return(0,r.useEffect)((function(){return e.current=!0,function(){e.current=!1}}),[]),t}function h(e,t,n){void 0===t&&(t=[]),void 0===n&&(n={loading:!1});var o=(0,r.useRef)(0),a=p(),i=(0,r.useState)(n),l=i[0],s=i[1],u=(0,r.useCallback)((function(){for(var t=[],n=0;n<arguments.length;n++)t[n]=arguments[n];var r=++o.current;return l.loading||s((function(e){return(0,f.__assign)((0,f.__assign)({},e),{loading:!0})})),e.apply(void 0,t).then((function(e){return a()&&r===o.current&&s({value:e,loading:!1}),e}),(function(e){return a()&&r===o.current&&s({error:e,loading:!1}),e}))}),t);return[l,u]}function m(e,t){void 0===t&&(t=[]);var n=h(e,t,{loading:!0}),o=n[0],a=n[1];return(0,r.useEffect)((function(){a()}),[a]),o}const g=function(e,t){void 0===t&&(t=[]);var n=(0,r.useState)(0),o=n[0],a=n[1],i=m(e,(0,f.__spreadArrays)(t,[o])),l=i.loading,s=(0,r.useCallback)((function(){l||a((function(e){return e+1}))}),(0,f.__spreadArrays)(t,[l]));return(0,f.__assign)((0,f.__assign)({},i),{retry:s})};const v=function(e){void 0===e&&(e={});var t=(0,r.useState)(e),n=t[0],o=t[1];return[n,(0,r.useCallback)((function(e){o((function(t){return Object.assign({},t,e instanceof Function?e(t):e)}))}),[])]};function b(e){for(var t=[],n=0;n<e.length;n++)t.push({start:e.start(n),end:e.end(n)});return t}function y(e){return function(t){var n,o;o=r.isValidElement(t)?(n=t).props:t;var a=v({buffered:[],time:0,duration:0,paused:!0,muted:!1,volume:1,playing:!1}),i=a[0],l=a[1],s=(0,r.useRef)(null),u=function(e,t){return function(n){try{t&&t(n)}finally{e&&e(n)}}},c=function(){return l({paused:!1})},d=function(){return l({playing:!0})},p=function(){return l({playing:!1})},h=function(){return l({paused:!0,playing:!1})},m=function(){var e=s.current;e&&l({muted:e.muted,volume:e.volume})},g=function(){var e=s.current;if(e){var t=e.duration,n=e.buffered;l({duration:t,buffered:b(n)})}},y=function(){var e=s.current;e&&l({time:e.currentTime})},w=function(){var e=s.current;e&&l({buffered:b(e.buffered)})};n=n?r.cloneElement(n,(0,f.__assign)((0,f.__assign)({controls:!1},o),{ref:s,onPlay:u(o.onPlay,c),onPlaying:u(o.onPlaying,d),onWaiting:u(o.onWaiting,p),onPause:u(o.onPause,h),onVolumeChange:u(o.onVolumeChange,m),onDurationChange:u(o.onDurationChange,g),onTimeUpdate:u(o.onTimeUpdate,y),onProgress:u(o.onProgress,w)})):r.createElement(e,(0,f.__assign)((0,f.__assign)({controls:!1},o),{ref:s,onPlay:u(o.onPlay,c),onPlaying:u(o.onPlaying,d),onWaiting:u(o.onWaiting,p),onPause:u(o.onPause,h),onVolumeChange:u(o.onVolumeChange,m),onDurationChange:u(o.onDurationChange,g),onTimeUpdate:u(o.onTimeUpdate,y),onProgress:u(o.onProgress,w)}));var x=!1,_={play:function(){var e=s.current;if(e&&!x){var t=e.play();if("object"==typeof t){x=!0;var n=function(){x=!1};t.then(n,n)}return t}},pause:function(){var e=s.current;if(e&&!x)return e.pause()},seek:function(e){var t=s.current;t&&void 0!==i.duration&&(e=Math.min(i.duration,Math.max(0,e)),t.currentTime=e)},volume:function(e){var t=s.current;t&&(e=Math.min(1,Math.max(0,e)),t.volume=e,l({volume:e}))},mute:function(){var e=s.current;e&&(e.muted=!0)},unmute:function(){var e=s.current;e&&(e.muted=!1)}};return(0,r.useEffect)((function(){var e=s.current;e&&(l({volume:e.volume,muted:e.muted,paused:e.paused}),o.autoPlay&&e.paused&&_.play())}),[o.src]),[n,i,_,s]}}const w=y("audio");var x=function(){};function _(e){for(var t=[],n=1;n<arguments.length;n++)t[n-1]=arguments[n];e&&e.addEventListener&&e.addEventListener.apply(e,t)}function k(e){for(var t=[],n=1;n<arguments.length;n++)t[n-1]=arguments[n];e&&e.removeEventListener&&e.removeEventListener.apply(e,t)}var E="undefined"!=typeof window,S="undefined"!=typeof navigator,C=n(38252);const T=n.n(C)();var O=S?navigator:void 0;const D=O&&"function"==typeof O.getBattery?function(){var e=(0,r.useState)({isSupported:!0,fetched:!1}),t=e[0],n=e[1];return(0,r.useEffect)((function(){var e=!0,r=null,o=function(){if(e&&r){var o={isSupported:!0,fetched:!0,level:r.level,charging:r.charging,dischargingTime:r.dischargingTime,chargingTime:r.chargingTime};!T(t,o)&&n(o)}};return O.getBattery().then((function(t){e&&(_(r=t,"chargingchange",o),_(r,"chargingtimechange",o),_(r,"dischargingtimechange",o),_(r,"levelchange",o),o())})),function(){e=!1,r&&(k(r,"chargingchange",o),k(r,"chargingtimechange",o),k(r,"dischargingtimechange",o),k(r,"levelchange",o))}}),[]),t}:function(){return{isSupported:!1}};const P=function(e,t){void 0===e&&(e=!0);var n=(0,r.useCallback)((function(n){if("function"!=typeof e||e())return n.preventDefault(),t&&(n.returnValue=t),t}),[e,t]);(0,r.useEffect)((function(){if(e)return _(window,"beforeunload",n),function(){return k(window,"beforeunload",n)}}),[e,n])};var N=function(e,t){return"boolean"==typeof t?t:!e};const A=function(e){return(0,r.useReducer)(N,e)},I=A;var L=["mousedown","touchstart"];const R=function(e,t,n){void 0===n&&(n=L);var o=(0,r.useRef)(t);(0,r.useEffect)((function(){o.current=t}),[t]),(0,r.useEffect)((function(){for(var t=function(t){var n=e.current;n&&!n.contains(t.target)&&o.current(t)},r=0,a=n;r<a.length;r++){var i=a[r];_(document,i,t)}return function(){for(var e=0,r=n;e<r.length;e++){var o=r[e];k(document,o,t)}}}),[n,e])};var j=n(36808),M=n.n(j);const F=function(e){var t=(0,r.useState)((function(){return M().get(e)||null})),n=t[0],o=t[1];return[n,(0,r.useCallback)((function(t,n){M().set(e,t,n),o(t)}),[e]),(0,r.useCallback)((function(){M().remove(e),o(null)}),[e])]};var B=n(20640),z=n.n(B);const $=function(){var e=p(),t=v({value:void 0,error:void 0,noUserInteraction:!0}),n=t[0],o=t[1];return[n,(0,r.useCallback)((function(t){var n,r;if(e())try{if("string"!=typeof t&&"number"!=typeof t){var a=new Error("Cannot copy typeof "+typeof t+" to clipboard, must be a string");return void o({value:t,error:a,noUserInteraction:!0})}if(""===t){a=new Error("Cannot copy empty string to clipboard.");return void o({value:t,error:a,noUserInteraction:!0})}r=t.toString(),n=z()(r),o({value:r,error:void 0,noUserInteraction:n})}catch(a){o({value:r,error:a,noUserInteraction:n})}}),[])]};var U=function(e){return(e+1)%1e6};function H(){return(0,r.useReducer)(U,0)[1]}function V(e,t){return"function"==typeof e?e.length?e(t):e():e}function q(e){var t=(0,r.useRef)(V(e)),n=H();return(0,r.useMemo)((function(){return[function(){return t.current},function(e){t.current=V(e,t.current),n()}]}),[])}function G(e,t,n){void 0===e&&(e=0),void 0===t&&(t=null),void 0===n&&(n=null);var o=V(e);"number"!=typeof o&&console.error("initialValue has to be a number, got "+typeof e),"number"==typeof n?o=Math.max(o,n):null!==n&&console.error("min has to be a number, got "+typeof n),"number"==typeof t?o=Math.min(o,t):null!==t&&console.error("max has to be a number, got "+typeof t);var a=q(o),i=a[0],l=a[1];return[i(),(0,r.useMemo)((function(){var e=function(e){var r=i(),o=V(e,r);r!==o&&("number"==typeof n&&(o=Math.max(o,n)),"number"==typeof t&&(o=Math.min(o,t)),r!==o&&l(o))};return{get:i,set:e,inc:function(t){void 0===t&&(t=1);var n=V(t,i());"number"!=typeof n&&console.error("delta has to be a number or function returning a number, got "+typeof n),e((function(e){return e+n}))},dec:function(t){void 0===t&&(t=1);var n=V(t,i());"number"!=typeof n&&console.error("delta has to be a number or function returning a number, got "+typeof n),e((function(e){return e-n}))},reset:function(t){void 0===t&&(t=o);var n=V(t,i());"number"!=typeof n&&console.error("value has to be a number or function returning a number, got "+typeof n),o=n,e(n)}}}),[o,n,t])]}var W=n(40818),Z=n(97142),Q=n(52099),Y=n(87749);const X=E?r.useLayoutEffect:r.useEffect;var K=(0,W.U)();(0,Z.I)(K),(0,Q.I)(K);var J=0;const ee=function(e){var t=(0,r.useMemo)((function(){return"react-use-css-"+(J++).toString(36)}),[]),n=(0,r.useMemo)((function(){return new K.VSheet}),[]);return X((function(){var r={};return(0,Y.z)(r,e,"."+t,""),n.diff(r),function(){n.diff({})}})),t};const te=function(e,t,n){var o=(0,r.useRef)(void 0);o.current&&n(t,o.current)||(o.current=t),(0,r.useEffect)(e,o.current)};function ne(e,t){void 0===t&&(t=0);var n=(0,r.useRef)(!1),o=(0,r.useRef)(),a=(0,r.useRef)(e),i=(0,r.useCallback)((function(){return n.current}),[]),l=(0,r.useCallback)((function(){n.current=!1,o.current&&clearTimeout(o.current),o.current=setTimeout((function(){n.current=!0,a.current()}),t)}),[t]),s=(0,r.useCallback)((function(){n.current=null,o.current&&clearTimeout(o.current)}),[]);return(0,r.useEffect)((function(){a.current=e}),[e]),(0,r.useEffect)((function(){return l(),s}),[t]),[i,s,l]}function re(e,t,n){void 0===t&&(t=0),void 0===n&&(n=[]);var o=ne(e,t),a=o[0],i=o[1],l=o[2];return(0,r.useEffect)(l,n),[a,i]}const oe=function(e,t){te(e,t,T)};const ae=function(e,t){var n=(0,r.useState)(t),o=n[0],a=n[1];return null==o?[e,a]:[o,a]};const ie=function(e,t){void 0===e&&(e={}),void 0===t&&(t=[]);var n=e.onFiles,o=e.onText,a=e.onUri,i=(0,r.useState)(!1),l=i[0],s=i[1],u=(0,r.useCallback)(s,[]),c=(0,r.useMemo)((function(){return function(e){return function(t,n){var r=t.getData("text/uri-list");if(r)(e.onUri||x)(r,n);else if(t.files&&t.files.length)(e.onFiles||x)(Array.from(t.files),n);else if(n.clipboardData){var o=n.clipboardData.getData("text");(e.onText||x)(o,n)}}}(e)}),[n,o,a]);return(0,r.useEffect)((function(){var e=function(e){e.preventDefault(),u(!0)},t=function(e){e.preventDefault(),u(!0)},n=function(){u(!1)},r=function(){u(!1)},a=function(e){e.preventDefault(),u(!1),c(e.dataTransfer,e)},i=function(e){c(e.clipboardData,e)};return _(document,"dragover",e),_(document,"dragenter",t),_(document,"dragleave",n),_(document,"dragexit",r),_(document,"drop",a),o&&_(document,"paste",i),function(){k(document,"dragover",e),k(document,"dragenter",t),k(document,"dragleave",n),k(document,"dragexit",r),k(document,"drop",a),k(document,"paste",i)}}),(0,f.__spreadArrays)([c],t)),{over:l}};const le=function(e){void 0===e&&(e={});var t=e.onFiles,n=e.onText,o=e.onUri,a=p(),i=(0,r.useState)(!1),l=i[0],s=i[1],u=(0,r.useMemo)((function(){return function(e,t){return function(n,r){var o=n.getData("text/uri-list");o?(e.onUri||x)(o,r):n.files&&n.files.length?(e.onFiles||x)(Array.from(n.files),r):n.items&&n.items.length&&n.items[0].getAsString((function(n){t&&(e.onText||x)(n,r)}))}}(e,a())}),[t,n,o]),c=(0,r.useMemo)((function(){return function(e,t){return{onDragOver:function(e){e.preventDefault()},onDragEnter:function(e){e.preventDefault(),t(!0)},onDragLeave:function(){t(!1)},onDrop:function(n){n.preventDefault(),n.persist(),t(!1),e(n.dataTransfer,n)},onPaste:function(t){t.persist(),e(t.clipboardData,t)}}}(u,s)}),[u,s]);return[c,{over:l}]};const se=function(e){(0,r.useEffect)(e,[])};function ue(e){var t=(0,r.useRef)(e&&e.current);return(0,r.useEffect)((function(){e&&(e.current=t.current)}),[e]),t}function ce(e){return(0,r.forwardRef)((function(t,n){var r=ue(n);return e(t,r)}))}var de=E?window:null,fe=function(e){return!!e.addEventListener},pe=function(e){return!!e.on};const he=function(e,t,n,o){void 0===n&&(n=de),(0,r.useEffect)((function(){if(t&&n)return fe(n)?_(n,e,t,o):pe(n)&&n.on(e,t,o),function(){fe(n)?k(n,e,t,o):pe(n)&&n.off(e,t,o)}}),[e,t,n,JSON.stringify(o)])};const me=function(){var e=(0,r.useState)(null),t=e[0],n=e[1];return(0,r.useEffect)((function(){if(t)throw t}),[t]),(0,r.useCallback)((function(e){n(e)}),[])};const ge=function(e){(0,r.useEffect)((function(){var t=document.querySelector("link[rel*='icon']")||document.createElement("link");t.type="image/x-icon",t.rel="shortcut icon",t.href=e,document.getElementsByTagName("head")[0].appendChild(t)}),[e])};var ve=n(10577),be=n.n(ve);const ye=function(e,t,n){void 0===n&&(n={});var o=n.video,a=n.onClose,i=void 0===a?x:a,l=(0,r.useState)(t),s=l[0],u=l[1];return X((function(){if(t&&e.current){var n=function(){(null==o?void 0:o.current)&&k(o.current,"webkitendfullscreen",n),i()},r=function(){if(be().isEnabled){var e=be().isFullscreen;u(e),e||i()}};if(be().isEnabled){try{be().request(e.current),u(!0)}catch(l){i(l),u(!1)}be().on("change",r)}else o&&o.current&&o.current.webkitEnterFullscreen?(o.current.webkitEnterFullscreen(),_(o.current,"webkitendfullscreen",n),u(!0)):(i(),u(!1));return function(){if(u(!1),be().isEnabled)try{be().off("change",r),be().exit()}catch(a){}else o&&o.current&&o.current.webkitExitFullscreen&&(k(o.current,"webkitendfullscreen",n),o.current.webkitExitFullscreen())}}}),[t,o,e]),s};const we=function(e){var t,n=(0,r.useState)({loading:!0,accuracy:null,altitude:null,altitudeAccuracy:null,heading:null,latitude:null,longitude:null,speed:null,timestamp:Date.now()}),o=n[0],a=n[1],i=!0,l=function(e){i&&a({loading:!1,accuracy:e.coords.accuracy,altitude:e.coords.altitude,altitudeAccuracy:e.coords.altitudeAccuracy,heading:e.coords.heading,latitude:e.coords.latitude,longitude:e.coords.longitude,speed:e.coords.speed,timestamp:e.timestamp})},s=function(e){return i&&a((function(t){return(0,f.__assign)((0,f.__assign)({},t),{loading:!1,error:e})}))};return(0,r.useEffect)((function(){return navigator.geolocation.getCurrentPosition(l,s,e),t=navigator.geolocation.watchPosition(l,s,e),function(){i=!1,navigator.geolocation.clearWatch(t)}}),[]),o};const xe=function(e){void 0===e&&(e={});var t=H(),n=(0,r.useRef)((0,f.__assign)({},e));return[(0,r.useCallback)((function(){return n.current}),[]),(0,r.useCallback)((function(e){e&&(Object.assign(n.current,e),t())}),[])]};var _e=0,ke={};const Ee=function(e,t){void 0===t&&(t=0);var n=(0,r.useRef)((function(){}));(0,r.useEffect)((function(){n.current=e})),(0,r.useEffect)((function(){if(null!==t){var e=function(e,t){var n,r=_e++;if(ke[t])ke[t].listeners[r]=e;else{var o=setInterval((function(){for(var e,n=ke[t].listeners,r=!1,o=0,a=Object.values(n);o<a.length;o++){var i=a[o];try{i()}catch(l){r=!0,e=l}}if(r)throw e}),t);ke[t]={ms:t,timer:o,listeners:(n={},n[r]=e,n)}}return{bucket:ke[t],id:r}}((function(){return n.current()}),t);return function(){return function(e){var t=e.bucket,n=e.id;delete t.listeners[n];var r=!1;for(var o in t.listeners){r=!0;break}r||(clearInterval(t.timer),delete ke[t.ms])}(e)}}}),[t])};var Se=r.useState;const Ce=function(e){var t,n,o=Se(!1),a=o[0],i=o[1];return"function"==typeof e&&(e=e(a)),[r.cloneElement(e,{onMouseEnter:(n=e.props.onMouseEnter,function(e){(n||x)(e),i(!0)}),onMouseLeave:(t=e.props.onMouseLeave,function(e){(t||x)(e),i(!1)})}),a]};const Te=function(e,t){void 0===t&&(t=!0);var n=(0,r.useState)(!1),o=n[0],a=n[1];return(0,r.useEffect)((function(){var n=function(){return a(!0)},r=function(){return a(!1)};t&&e&&e.current&&(_(e.current,"mouseover",n),_(e.current,"mouseout",r));var o=e.current;return function(){t&&o&&(k(o,"mouseover",n),k(o,"mouseout",r))}}),[t,e]),o};function Oe(e,t,n,r){var o,a=!1,i=0;function l(){o&&clearTimeout(o)}function s(){for(var s=arguments.length,u=new Array(s),c=0;c<s;c++)u[c]=arguments[c];var d=this,f=Date.now()-i;function p(){i=Date.now(),n.apply(d,u)}function h(){o=void 0}a||(r&&!o&&p(),l(),void 0===r&&f>e?p():!0!==t&&(o=setTimeout(r?h:p,void 0===r?e-f:e)))}return"boolean"!=typeof t&&(r=n,n=t,t=void 0),s.cancel=function(){l(),a=!0},s}var De=["mousemove","mousedown","resize","keydown","touchstart","wheel"];const Pe=function(e,t,n){void 0===e&&(e=6e4),void 0===t&&(t=!1),void 0===n&&(n=De);var o=(0,r.useState)(t),a=o[0],i=o[1];return(0,r.useEffect)((function(){for(var t,r=!0,o=a,l=function(e){r&&(o=e,i(e))},s=Oe(50,(function(){o&&l(!1),clearTimeout(t),t=setTimeout((function(){return l(!0)}),e)})),u=function(){document.hidden||s()},c=0;c<n.length;c++)_(window,n[c],s);return _(document,"visibilitychange",u),t=setTimeout((function(){return l(!0)}),e),function(){r=!1;for(var e=0;e<n.length;e++)k(window,n[e],s);k(document,"visibilitychange",u)}}),[e,n]),a};const Ne=function(e,t){var n=(0,r.useState)(null),o=n[0],a=n[1];return(0,r.useEffect)((function(){if(e.current&&"function"==typeof IntersectionObserver){var n=new IntersectionObserver((function(e){a(e[0])}),t);return n.observe(e.current),function(){a(null),n.disconnect()}}return function(){}}),[e.current,t.threshold,t.root,t.rootMargin]),o};const Ae=function(e,t){var n=(0,r.useRef)((function(){}));(0,r.useEffect)((function(){n.current=e})),(0,r.useEffect)((function(){if(null!==t){var e=setInterval((function(){return n.current()}),t||0);return function(){return clearInterval(e)}}}),[t])};const Ie=function(e,t,n,o){void 0===t&&(t=x),void 0===n&&(n={}),void 0===o&&(o=[e]);var a=n.event,i=void 0===a?"keydown":a,l=n.target,s=n.options,u=(0,r.useMemo)((function(){var n,r="function"==typeof(n=e)?n:"string"==typeof n?function(e){return e.key===n}:n?function(){return!0}:function(){return!1};return function(e){if(r(e))return t(e)}}),o);he(i,u,l,s)};const Le=function(e){return void 0===e&&(e={laptopL:1440,laptop:1024,tablet:768}),function(){var t=(0,r.useState)(E?window.innerWidth:0),n=t[0],o=t[1];(0,r.useEffect)((function(){var e=function(){o(window.innerWidth)};return e(),_(window,"resize",e),function(){k(window,"resize",e)}}));var a=(0,r.useMemo)((function(){return Object.entries(e).sort((function(e,t){return e[1]>=t[1]?1:-1}))}),[e]),i=a.reduce((function(e,t){var r=t[0],o=t[1];return n>=o?r:e}),a[0][0]);return i}};const Re=function(e){var t=(0,r.useState)([!1,null]),n=t[0],o=t[1];return Ie(e,(function(e){return o([!0,e])}),{event:"keydown"},[n]),Ie(e,(function(e){return o([!1,e])}),{event:"keyup"},[n]),n};const je=function(e,t,n,r){void 0===r&&(r=Re);var o=r(e),a=o[0],i=o[1];s((function(){!a&&n?n(i):a&&t&&t(i)}),[a])};const Me=function(e){var t=(0,r.useRef)(e);return t.current=e,t};const Fe=function(e,t){(0,r.useEffect)((function(){return e&&e(),function(){t&&t()}}),[])};const Be=function(e){void 0===e&&(e=[]);var t=(0,r.useRef)(V(e)),n=H(),o=(0,r.useMemo)((function(){var r={set:function(e){t.current=V(e,t.current),n()},push:function(){for(var e=[],t=0;t<arguments.length;t++)e[t]=arguments[t];e.length&&o.set((function(t){return t.concat(e)}))},updateAt:function(e,t){o.set((function(n){var r=n.slice();return r[e]=t,r}))},insertAt:function(e,t){o.set((function(n){var r=n.slice();return e>r.length?r[e]=t:r.splice(e,0,t),r}))},update:function(e,t){o.set((function(n){return n.map((function(n){return e(n,t)?t:n}))}))},updateFirst:function(e,n){var r=t.current.findIndex((function(t){return e(t,n)}));r>=0&&o.updateAt(r,n)},upsert:function(e,n){var r=t.current.findIndex((function(t){return e(t,n)}));r>=0?o.updateAt(r,n):o.push(n)},sort:function(e){o.set((function(t){return t.slice().sort(e)}))},filter:function(e,t){o.set((function(n){return n.slice().filter(e,t)}))},removeAt:function(e){o.set((function(t){var n=t.slice();return n.splice(e,1),n}))},clear:function(){o.set([])},reset:function(){o.set(V(e).slice())}};return r.remove=r.removeAt,r}),[]);return[t.current,o]};const ze=function(e,t,n){if(!E)return[t,x,x];if(!e)throw new Error("useLocalStorage key may not be falsy");var o=n?n.raw?function(e){return e}:n.deserializer:JSON.parse,a=(0,r.useRef)((function(e){try{var r=n?n.raw?String:n.serializer:JSON.stringify,a=localStorage.getItem(e);return null!==a?o(a):(t&&localStorage.setItem(e,r(t)),t)}catch(i){return t}})),i=(0,r.useState)((function(){return a.current(e)})),l=i[0],s=i[1];(0,r.useLayoutEffect)((function(){return s(a.current(e))}),[e]);var u=(0,r.useCallback)((function(t){try{var r="function"==typeof t?t(l):t;if(void 0===r)return;var a=void 0;a=n?n.raw?"string"==typeof r?r:JSON.stringify(r):n.serializer?n.serializer(r):JSON.stringify(r):JSON.stringify(r),localStorage.setItem(e,a),s(o(a))}catch(i){}}),[e,s]),c=(0,r.useCallback)((function(){try{localStorage.removeItem(e),s(void 0)}catch(i){}}),[e,s]);return[l,u,c]};var $e=function(e){var t=window.history,n=t[e];t[e]=function(t){var r=n.apply(this,arguments),o=new Event(e.toLowerCase());return o.state=t,window.dispatchEvent(o),r}};E&&($e("pushState"),$e("replaceState"));var Ue=function(e){var t=window.history,n=t.state,r=t.length,o=window.location;return{trigger:e,state:n,length:r,hash:o.hash,host:o.host,hostname:o.hostname,href:o.href,origin:o.origin,pathname:o.pathname,port:o.port,protocol:o.protocol,search:o.search}},He="function"==typeof Event;const Ve=E&&He?function(){var e=(0,r.useState)(Ue("load")),t=e[0],n=e[1];return(0,r.useEffect)((function(){var e=function(){return n(Ue("popstate"))},t=function(){return n(Ue("pushstate"))},r=function(){return n(Ue("replacestate"))};return _(window,"popstate",e),_(window,"pushstate",t),_(window,"replacestate",r),function(){k(window,"popstate",e),k(window,"pushstate",t),k(window,"replacestate",r)}}),[]),t}:function(){return{trigger:"load",length:1}};function qe(e){if(!e)return null;if("BODY"===e.tagName)return e;if("IFRAME"===e.tagName){var t=e.contentDocument;return t?t.body:null}return e.offsetParent?qe(e.offsetParent):null}function Ge(e){var t=e||window.event;return t.touches.length>1||(t.preventDefault&&t.preventDefault(),!1)}var We=E&&window.navigator&&window.navigator.platform&&/iP(ad|hone|od)/.test(window.navigator.platform),Ze=new Map,Qe="object"==typeof document?document:void 0,Ye=!1;const Xe=Qe?function(e,t){void 0===e&&(e=!0);var n=(0,r.useRef)(Qe.body);t=t||n;var o=function(e){var t=Ze.get(e);t&&(1===t.counter?(Ze.delete(e),We?(e.ontouchmove=null,Ye&&(k(document,"touchmove",Ge),Ye=!1)):e.style.overflow=t.initialOverflow):Ze.set(e,{counter:t.counter-1,initialOverflow:t.initialOverflow}))};(0,r.useEffect)((function(){var n=qe(t.current);n&&(e?function(e){var t=Ze.get(e);t?Ze.set(e,{counter:t.counter+1,initialOverflow:t.initialOverflow}):(Ze.set(e,{counter:1,initialOverflow:e.style.overflow}),We?Ye||(_(document,"touchmove",Ge,{passive:!1}),Ye=!0):e.style.overflow="hidden")}(n):o(n))}),[e,t.current]),(0,r.useEffect)((function(){var e=qe(t.current);if(e)return function(){o(e)}}),[])}:function(e,t){void 0===e&&(e=!0)};const Ke=function(e){for(var t=[],n=1;n<arguments.length;n++)t[n-1]=arguments[n];se((function(){return console.log.apply(console,(0,f.__spreadArrays)([e+" mounted"],t)),function(){return console.log(e+" unmounted")}})),s((function(){console.log.apply(console,(0,f.__spreadArrays)([e+" updated"],t))}))};var Je=function(e){(function(e){return"touches"in e})(e)&&e.touches.length<2&&e.preventDefault&&e.preventDefault()};const et=function(e,t){var n=void 0===t?{}:t,o=n.isPreventDefault,a=void 0===o||o,i=n.delay,l=void 0===i?300:i,s=(0,r.useRef)(),u=(0,r.useRef)(),c=(0,r.useCallback)((function(t){a&&t.target&&(_(t.target,"touchend",Je,{passive:!1}),u.current=t.target),s.current=setTimeout((function(){return e(t)}),l)}),[e,l,a]),d=(0,r.useCallback)((function(){s.current&&clearTimeout(s.current),a&&u.current&&k(u.current,"touchend",Je)}),[a]);return{onMouseDown:function(e){return c(e)},onTouchStart:function(e){return c(e)},onMouseUp:d,onMouseLeave:d,onTouchEnd:d}};const tt=function(e){void 0===e&&(e={});var t=(0,r.useState)(e),n=t[0],o=t[1],a=(0,r.useMemo)((function(){return{set:function(e,t){o((function(n){var r;return(0,f.__assign)((0,f.__assign)({},n),((r={})[e]=t,r))}))},setAll:function(e){o(e)},remove:function(e){o((function(t){var n=t,r=e;n[r];return(0,f.__rest)(n,["symbol"==typeof r?r:r+""])}))},reset:function(){return o(e)}}}),[o]),i=(0,f.__assign)({get:(0,r.useCallback)((function(e){return n[e]}),[n])},a);return[n,i]};const nt=function(e,t){var n=(0,r.useState)(function(e,t){return void 0!==t?t:!!E&&window.matchMedia(e).matches}(e,t)),o=n[0],a=n[1];return(0,r.useEffect)((function(){var t=!0,n=window.matchMedia(e),r=function(){t&&a(!!n.matches)};return n.addListener(r),a(n.matches),function(){t=!1,n.removeListener(r)}}),[e]),o};const rt=S&&navigator.mediaDevices?function(){var e=(0,r.useState)({}),t=e[0],n=e[1];return(0,r.useEffect)((function(){var e=!0,t=function(){navigator.mediaDevices.enumerateDevices().then((function(t){e&&n({devices:t.map((function(e){return{deviceId:e.deviceId,groupId:e.groupId,kind:e.kind,label:e.label}}))})})).catch(x)};return _(navigator.mediaDevices,"devicechange",t),t(),function(){e=!1,k(navigator.mediaDevices,"devicechange",t)}}),[]),t}:function(){return{}};function ot(e,t){var n=(0,r.useRef)(e),o=(0,r.useState)(t),a=o[0],i=o[1];return[a,(0,r.useCallback)((function(e){2===n.current.length?n.current(e,i):i(n.current(e))}),[a])]}const at=function(e,t){var n=(0,r.useMemo)((function(){return function(t,n){var r;return(r=e(t))[n.type].apply(r,n.payload)}}),[e]),o=(0,r.useReducer)(n,t),a=o[0],i=o[1],l=(0,r.useMemo)((function(){return Object.keys(e(t)).reduce((function(e,t){return e[t]=function(){for(var e=[],n=0;n<arguments.length;n++)e[n]=arguments[n];return i({type:t,payload:e})},e}),{})}),[e,t]);return[a,l]};var it={acceleration:{x:null,y:null,z:null},accelerationIncludingGravity:{x:null,y:null,z:null},rotationRate:{alpha:null,beta:null,gamma:null},interval:16};const lt=function(e){void 0===e&&(e=it);var t=(0,r.useState)(e),n=t[0],o=t[1];return(0,r.useEffect)((function(){var e=function(e){var t=e.acceleration,n=e.accelerationIncludingGravity,r=e.rotationRate,a=e.interval;o({acceleration:{x:t.x,y:t.y,z:t.z},accelerationIncludingGravity:{x:n.x,y:n.y,z:n.z},rotationRate:{alpha:r.alpha,beta:r.beta,gamma:r.gamma},interval:a})};return _(window,"devicemotion",e),function(){k(window,"devicemotion",e)}}),[]),n};const st=function(e){se((function(){e()}))};const ut=function(e){var t=(0,r.useRef)(e);t.current=e,se((function(){return function(){return t.current()}}))};const ct=function(e){var t=(0,r.useRef)(0),n=(0,r.useState)(e),o=n[0],a=n[1],i=(0,r.useCallback)((function(e){cancelAnimationFrame(t.current),t.current=requestAnimationFrame((function(){a(e)}))}),[]);return ut((function(){cancelAnimationFrame(t.current)})),[o,i]};const dt=function(e){var t=ct({docX:0,docY:0,posX:0,posY:0,elX:0,elY:0,elH:0,elW:0}),n=t[0],o=t[1];return(0,r.useEffect)((function(){var t=function(t){if(e&&e.current){var n=e.current.getBoundingClientRect(),r=n.left,a=n.top,i=n.width,l=n.height,s=r+window.pageXOffset,u=a+window.pageYOffset,c=t.pageX-s,d=t.pageY-u;o({docX:t.pageX,docY:t.pageY,posX:s,posY:u,elX:c,elY:d,elH:l,elW:i})}};return _(document,"mousemove",t),function(){k(document,"mousemove",t)}}),[e]),n};var ft={current:null};const pt=function(e,t){void 0===t&&(t={});var n=!!t.whenHovered,r=!!t.bound,o=Te(e,n),a=dt(n&&!o?ft:e);return r&&(a.elX=Math.max(0,Math.min(a.elX,a.elW)),a.elY=Math.max(0,Math.min(a.elY,a.elH))),a},ht=function(){var e=(0,r.useState)(0),t=e[0],n=e[1];return(0,r.useEffect)((function(){var e=function(e){n(e.deltaY+t)};return _(window,"wheel",e,!1),function(){return k(window,"wheel",e)}})),t};var mt=S?navigator:void 0,gt=mt&&(mt.connection||mt.mozConnection||mt.webkitConnection);function vt(e){var t=null==mt?void 0:mt.onLine,n=null==e?void 0:e.online;return{online:t,previous:n,since:t!==n?new Date:null==e?void 0:e.since,downlink:null==gt?void 0:gt.downlink,downlinkMax:null==gt?void 0:gt.downlinkMax,effectiveType:null==gt?void 0:gt.effectiveType,rtt:null==gt?void 0:gt.rtt,saveData:null==gt?void 0:gt.saveData,type:null==gt?void 0:gt.type}}function bt(e){var t=(0,r.useState)(null!=e?e:vt),n=t[0],o=t[1];return(0,r.useEffect)((function(){var e=function(){o(vt)};return _(window,"online",e,{passive:!0}),_(window,"offline",e,{passive:!0}),gt&&_(gt,"change",e,{passive:!0}),function(){k(window,"online",e),k(window,"offline",e),gt&&k(gt,"change",e)}}),[]),n}const yt=G;const wt=function(e,t){var n=(0,r.useState)(t),o=n[0],a=n[1];return X((function(){var t=e.subscribe(a);return function(){return t.unsubscribe()}}),[e]),o};var xt={angle:0,type:"landscape-primary"};const _t=function(e){void 0===e&&(e=xt);var t=(0,r.useState)(e),n=t[0],o=t[1];return(0,r.useEffect)((function(){var t=window.screen,n=!0,r=function(){if(n){var r=t.orientation;if(r){var a=r.angle,i=r.type;o({angle:a,type:i})}else void 0!==window.orientation?o({angle:"number"==typeof window.orientation?window.orientation:0,type:""}):o(e)}};return _(window,"orientationchange",r),r(),function(){n=!1,k(window,"orientationchange",r)}}),[]),n};const kt=function(e,t){void 0===t&&(t=[]),(0,r.useEffect)((function(){if(e){var t=function(t){var n=(t=t||window.event).relatedTarget||t.toElement;n&&"HTML"!==n.nodeName||e()};return _(document,"mouseout",t),function(){k(document,"mouseout",t)}}}),t)};const Et=function(e){var t=(0,r.useState)(""),n=t[0],o=t[1];return(0,r.useEffect)((function(){var t=!0,n=null,r=function(){t&&o((function(){var e;return null!==(e=null==n?void 0:n.state)&&void 0!==e?e:""}))};return navigator.permissions.query(e).then((function(e){_(n=e,"change",r),r()})).catch(x),function(){n&&k(n,"change",r),t=!1,n=null}}),[e]),n};function St(e){var t=(0,r.useRef)();return(0,r.useEffect)((function(){t.current=e})),t.current}var Ct=function(e,t){return e===t};function Tt(e,t){void 0===t&&(t=Ct);var n=(0,r.useRef)(),o=(0,r.useRef)(e);return l()||t(o.current,e)||(n.current=o.current,o.current=e),n.current}const Ot=function(){var e=p();return(0,r.useCallback)((function(t){return new Promise((function(n,r){t.then((function(t){e()&&n(t)}),(function(t){e()&&r(t)}))}))}),[])};const Dt=function(e){void 0===e&&(e=[]);var t=(0,r.useState)(e),n=t[0],o=t[1];return{add:function(e){o((function(t){return(0,f.__spreadArrays)(t,[e])}))},remove:function(){var e;return o((function(t){var n=t[0],r=t.slice(1);return e=n,r})),e},get first(){return n[0]},get last(){return n[n.length-1]},get size(){return n.length}}};const Pt=function(e,t){void 0===e&&(e=1e12),void 0===t&&(t=0);var n=(0,r.useState)(0),o=n[0],a=n[1];return X((function(){var n,r,o,i=function(){var t=Math.min(1,(Date.now()-o)/e);a(t),l()},l=function(){n=requestAnimationFrame(i)},s=setTimeout((function(){r=setTimeout((function(){cancelAnimationFrame(n),a(1)}),e),o=Date.now(),l()}),t);return function(){clearTimeout(r),clearTimeout(s),cancelAnimationFrame(n)}}),[e,t]),o};function Nt(e,t){void 0===t&&(t=!0);var n=(0,r.useRef)(null),o=(0,r.useRef)(!1),a=(0,r.useRef)(e);a.current=e;var i=(0,r.useCallback)((function(e){o.current&&(a.current(e),n.current=requestAnimationFrame(i))}),[]),l=(0,r.useMemo)((function(){return[function(){o.current&&(o.current=!1,n.current&&cancelAnimationFrame(n.current))},function(){o.current||(o.current=!0,n.current=requestAnimationFrame(i))},function(){return o.current}]}),[]);return(0,r.useEffect)((function(){return t&&l[1](),l[0]}),[]),l}var At=function(e,t){return new URLSearchParams(e).get(t)};const It=E?function(e){var t=window.location,n=(0,r.useState)((function(){return At(t.search,e)})),o=n[0],a=n[1];return(0,r.useEffect)((function(){var n=function(){a(At(t.search,e))};return _(window,"popstate",n),_(window,"pushstate",n),_(window,"replacestate",n),function(){k(window,"popstate",n),k(window,"pushstate",n),k(window,"replacestate",n)}}),[]),o}:function(){return null};n(96260);var Lt=function(e){void 0===e&&(e={});var t=e.disabled,n=Me(e),o=(0,r.useState)({isScratching:!1}),a=o[0],i=o[1],l=(0,r.useRef)(a),s=(0,r.useRef)(!1),u=(0,r.useRef)(null),c=(0,r.useState)(null),d=c[0],p=c[1];return(0,r.useEffect)((function(){if(!t&&d){var e,r,o=function(e,t){cancelAnimationFrame(u.current),u.current=requestAnimationFrame((function(){var r=d.getBoundingClientRect(),o=r.left,a=r.top,s=o+window.scrollX,u=a+window.scrollY,c=e-s,p=t-u;i((function(e){var t=(0,f.__assign)((0,f.__assign)({},e),{dx:c-(e.x||0),dy:p-(e.y||0),end:Date.now(),isScratching:!0});return l.current=t,(n.current.onScratch||x)(t),t}))}))},a=function(e){o(e.pageX,e.pageY)},c=function(e){o(e.changedTouches[0].pageX,e.changedTouches[0].pageY)},p=function(){s.current&&(s.current=!1,l.current=(0,f.__assign)((0,f.__assign)({},l.current),{isScratching:!1}),(n.current.onScratchEnd||x)(l.current),i({isScratching:!1}),k(window,"mousemove",a),k(window,"touchmove",c),k(window,"mouseup",e),k(window,"touchend",r))};e=p,r=p;var h=function(t,o){if(s.current){var u=d.getBoundingClientRect(),f=u.left,p=u.top,h=f+window.scrollX,m=p+window.scrollY,g=t-h,v=o-m,b=Date.now(),y={isScratching:!0,start:b,end:b,docX:t,docY:o,x:g,y:v,dx:0,dy:0,elH:d.offsetHeight,elW:d.offsetWidth,elX:h,elY:m};l.current=y,(n.current.onScratchStart||x)(y),i(y),_(window,"mousemove",a),_(window,"touchmove",c),_(window,"mouseup",e),_(window,"touchend",r)}},m=function(e){s.current=!0,h(e.pageX,e.pageY)},g=function(e){s.current=!0,h(e.changedTouches[0].pageX,e.changedTouches[0].pageY)};return _(d,"mousedown",m),_(d,"touchstart",g),function(){k(d,"mousedown",m),k(d,"touchstart",g),k(window,"mousemove",a),k(window,"touchmove",c),k(window,"mouseup",e),k(window,"touchend",r),u.current&&cancelAnimationFrame(u.current),u.current=null,s.current=!1,l.current={isScratching:!1},i(l.current)}}}),[d,t,n]),[p,a]};const Rt=Lt;const jt=function(e){var t=ct({x:0,y:0}),n=t[0],o=t[1];return(0,r.useEffect)((function(){var t=function(){e.current&&o({x:e.current.scrollLeft,y:e.current.scrollTop})};return e.current&&_(e.current,"scroll",t,{capture:!1,passive:!0}),function(){e.current&&k(e.current,"scroll",t)}}),[e]),n};const Mt=function(e){var t=(0,r.useState)(!1),n=t[0],o=t[1];return(0,r.useEffect)((function(){if(e.current){var t,n=function(){o(!0),clearTimeout(t),t=setTimeout((function(){o(!1)}),150)};return _(e.current,"scroll",n,!1),function(){e.current&&k(e.current,"scroll",n,!1)}}return function(){}}),[e]),n};const Ft=function(e,t,n){if(!E)return[t,function(){}];var o=(0,r.useState)((function(){try{var r=sessionStorage.getItem(e);return"string"!=typeof r?(sessionStorage.setItem(e,n?String(t):JSON.stringify(t)),t):n?r:JSON.parse(r||"null")}catch(o){return t}})),a=o[0],i=o[1];return(0,r.useEffect)((function(){try{var t=n?String(a):JSON.stringify(a);sessionStorage.setItem(e,t)}catch(o){}})),[a,i]};var Bt=n(99376),zt=function(e,t){return e.every((function(e,n){return(0,Bt.D)(e,t[n])}))};const $t=function(e,t){te(e,t,zt)};var Ut=r.useState,Ht=r.useEffect,Vt=r.useRef;const qt=function(e,t){var n=void 0===t?{}:t,a=n.width,i=void 0===a?1/0:a,l=n.height,s=void 0===l?1/0:l;if(!E)return["function"==typeof e?e({width:i,height:s}):e,{width:i,height:s}];var u=Ut({width:i,height:s}),c=u[0],d=u[1];"function"==typeof e&&(e=e(c));var p=e.props.style||{},h=Vt(null),m=null,g=function(){var e=h.current,t=e?{width:e.offsetWidth,height:e.offsetHeight}:{width:i,height:s};d(t)},v=function(e){_(e,"resize",g),setTimeout(g,35)};return Ht((function(){var e=h.current;if(e){if(e.contentWindow)m=e.contentWindow,v(m);else{var t=function(){_(e,"load",t),m=e.contentWindow,v(m)};k(e,"load",t)}return function(){m&&m.removeEventListener&&k(m,"resize",g)}}}),[]),p.position="relative",[r.cloneElement.apply(o,(0,f.__spreadArrays)([e,{style:p}],(0,f.__spreadArrays)([r.createElement("iframe",{ref:h,style:{background:"transparent",border:"none",height:"100%",left:0,position:"absolute",top:0,width:"100%",zIndex:-1}})],r.Children.toArray(e.props.children)))),c]};const Gt=function(e,t){void 0===t&&(t={});var n=p(),o=(0,r.useRef)(!1),a=(0,r.useRef)(0),i=(0,r.useRef)(0),l=v({isSliding:!1,value:0}),s=l[0],u=l[1];return a.current=s.value,(0,r.useEffect)((function(){if(E){var r=void 0===t.styles||t.styles,l=void 0!==t.reverse&&t.reverse;e.current&&r&&(e.current.style.userSelect="none");var s=function(){!o.current&&n()&&((t.onScrubStart||x)(),o.current=!0,u({isSliding:!0}),m())},c=function(){o.current&&n()&&((t.onScrubStop||x)(a.current),o.current=!1,u({isSliding:!1}),g())},d=function(e){s(),f(e)},f=t.vertical?function(e){return v(e.clientY)}:function(e){return v(e.clientX)},p=function(e){s(),h(e)},h=t.vertical?function(e){return v(e.changedTouches[0].clientY)}:function(e){return v(e.changedTouches[0].clientX)},m=function(){_(document,"mousemove",f),_(document,"mouseup",c),_(document,"touchmove",h),_(document,"touchend",c)},g=function(){k(document,"mousemove",f),k(document,"mouseup",c),k(document,"touchmove",h),k(document,"touchend",c)},v=function(r){cancelAnimationFrame(i.current),i.current=requestAnimationFrame((function(){if(n()&&e.current){var o=e.current.getBoundingClientRect(),a=t.vertical?o.top:o.left,i=t.vertical?o.height:o.width;if(!i)return;var s=(r-a)/i;s>1?s=1:s<0&&(s=0),l&&(s=1-s),u({value:s}),(t.onScrub||x)(s)}}))};return _(e.current,"mousedown",d),_(e.current,"touchstart",p),function(){k(e.current,"mousedown",d),k(e.current,"touchstart",p)}}}),[e,t.vertical]),s};var Wt;!function(e){e[e.init=0]="init",e[e.play=1]="play",e[e.pause=2]="pause",e[e.end=3]="end"}(Wt||(Wt={}));const Zt=function(e,t){var n=(0,r.useRef)(!1),o=(0,r.useState)((function(){var e=t.voice||{},n=e.lang,r=void 0===n?"default":n,o=e.name,a=void 0===o?"":o;return{isPlaying:!1,status:Wt[Wt.init],lang:t.lang||"default",voiceInfo:{lang:r,name:a},rate:t.rate||1,pitch:t.pitch||1,volume:t.volume||1}})),a=o[0],i=o[1],l=(0,r.useCallback)((function(){n.current&&i((function(e){return(0,f.__assign)((0,f.__assign)({},e),{isPlaying:!0,status:Wt[Wt.play]})}))}),[]),s=(0,r.useCallback)((function(){n.current&&i((function(e){return(0,f.__assign)((0,f.__assign)({},e),{isPlaying:!1,status:Wt[Wt.pause]})}))}),[]),u=(0,r.useCallback)((function(){n.current&&i((function(e){return(0,f.__assign)((0,f.__assign)({},e),{isPlaying:!1,status:Wt[Wt.end]})}))}),[]);return(0,r.useEffect)((function(){n.current=!0;var r=new SpeechSynthesisUtterance(e);return t.lang&&(r.lang=t.lang),t.voice&&(r.voice=t.voice),r.rate=t.rate||1,r.pitch=t.pitch||1,r.volume=t.volume||1,r.onstart=l,r.onpause=s,r.onresume=l,r.onend=u,window.speechSynthesis.speak(r),function(){n.current=!1}}),[]),a};const Qt=function(e){X((function(){var t=function(t){var n,r,o,a,i;!function(){var e=document.activeElement,t=document.body;if(!e)return!1;if(e===t)return!1;switch(e.tagName){case"INPUT":case"TEXTAREA":return!0}return e.hasAttribute("contenteditable")}()&&(r=(n=t).keyCode,o=n.metaKey,a=n.ctrlKey,i=n.altKey,!(o||a||i)&&(r>=48&&r<=57||r>=65&&r<=90))&&e(t)};return _(document,"keydown",t),function(){k(document,"keydown",t)}}),[])};function Yt(e,t,n){if(void 0===t&&(t=10),t<1)throw new Error("Capacity has to be greater than 1, got '"+t+"'");var o=l(),a=(0,r.useState)(e),i=a[0],s=a[1],u=(0,r.useRef)(null!=n?n:[]),c=(0,r.useRef)(0);return o&&(u.current.length?(u.current[u.current.length-1]!==e&&u.current.push(e),u.current.length>t&&(u.current=u.current.slice(u.current.length-t))):u.current.push(e),c.current=u.current.length&&u.current.length-1),[i,(0,r.useCallback)((function(e){s((function(n){return(e=V(e,n))!==n&&(c.current<u.current.length-1&&(u.current=u.current.slice(0,c.current+1)),c.current=u.current.push(e)-1,u.current.length>t&&(u.current=u.current.slice(u.current.length-t))),e}))}),[i,t]),(0,r.useMemo)((function(){return{history:u.current,position:c.current,capacity:t,back:function(e){void 0===e&&(e=1),c.current&&s((function(){return c.current-=Math.min(e,c.current),u.current[c.current]}))},forward:function(e){void 0===e&&(e=1),c.current!==u.current.length-1&&s((function(){return c.current=Math.min(c.current+e,u.current.length-1),u.current[c.current]}))},go:function(e){e!==c.current&&s((function(){return c.current=e<0?Math.max(u.current.length+e,0):Math.min(u.current.length-1,e),u.current[c.current]}))}}}),[i])]}function Xt(e){void 0===e&&(e=[]);var t=p(),n=H(),o=(0,r.useRef)(0);s((function(){e.length<=o.current&&(o.current=e.length-1,n())}),[e.length]);var a=(0,r.useMemo)((function(){return{next:function(){return a.setStateAt(o.current+1)},prev:function(){return a.setStateAt(o.current-1)},setStateAt:function(r){t()&&e.length&&r!==o.current&&(o.current=r>=0?r%e.length:e.length+r%e.length,n())},setState:function(r){if(t()){var a=e.length?e.indexOf(r):-1;if(-1===a)throw new Error("State '"+r+"' is not a valid state (does not exist in state list)");o.current=a,n()}}}}),[e]);return(0,f.__assign)({state:e[o.current],currentIndex:o.current},a)}const Kt=function(e,t){void 0===t&&(t=200);var n=(0,r.useState)(e),o=n[0],a=n[1],i=(0,r.useRef)(),l=(0,r.useRef)(null),s=(0,r.useRef)(0);return(0,r.useEffect)((function(){if(i.current)l.current=e,s.current=!0;else{a(e);var n=function(){s.current?(s.current=!1,a(l.current),i.current=setTimeout(n,t)):i.current=void 0};i.current=setTimeout(n,t)}}),[e]),ut((function(){i.current&&clearTimeout(i.current)})),o};const Jt=function(e,t,n){void 0===t&&(t=200);var o=(0,r.useState)(null),a=o[0],i=o[1],l=(0,r.useRef)(),s=(0,r.useRef)();return(0,r.useEffect)((function(){if(l.current)s.current=n;else{i(e.apply(void 0,n));var r=function(){s.current?(i(e.apply(void 0,s.current)),s.current=void 0,l.current=setTimeout(r,t)):l.current=void 0};l.current=setTimeout(r,t)}}),n),ut((function(){l.current&&clearTimeout(l.current)})),a};function en(e){return void 0===e&&(e=0),ne(H(),e)}var tn={restoreOnUnmount:!1};const nn="undefined"!=typeof document?function(e,t){void 0===t&&(t=tn);var n=(0,r.useRef)(document.title);document.title!==e&&(document.title=e),(0,r.useEffect)((function(){return t&&t.restoreOnUnmount?function(){document.title=n.current}:void 0}),[])}:function(e){};var rn=n(75534);const on=function(e,t,n){return void 0===e&&(e="inCirc"),void 0===t&&(t=200),void 0===n&&(n=0),(0,rn.U[e])(Pt(t,n))};const an=function(){var e=(0,r.useRef)(!1);return se((function(){return function(){e.current=!0}})),(0,r.useMemo)((function(){return function(t,n){return new Promise((function(r,o){t.then((function(t){e.current||r(t)}),(function(t){e.current?n?n(t):console.error("useUnmountPromise",t):o(t)}))}))}}),[])};function ln(e,t){void 0===t&&(t=[]);var n=Be(t),r=n[0],o=n[1];return[r,(0,f.__assign)((0,f.__assign)({},o),{upsert:function(t){o.upsert(e,t)}})]}const sn=S&&"vibrate"in navigator?function(e,t,n){void 0===e&&(e=!0),void 0===t&&(t=[1e3,1e3]),void 0===n&&(n=!0),(0,r.useEffect)((function(){var r;if(e&&(navigator.vibrate(t),n)){var o=t instanceof Array?t.reduce((function(e,t){return e+t})):t;r=setInterval((function(){navigator.vibrate(t)}),o)}return function(){e&&(navigator.vibrate(0),n&&clearInterval(r))}}),[e])}:x;const un=y("video");function cn(e,t,n){void 0===n&&(n=[void 0]);var o=(0,r.useRef)(t),a=(0,r.useRef)(e);o.current=t,a.current=e;var i=(0,r.useState)(n),l=i[0],s=i[1],u=(0,r.useCallback)((function(){o.current.length>=2?o.current(a.current,s):s(o.current(a.current))}),[s]);return(0,r.useEffect)((function(){u()}),[e]),[l,u]}var dn=function(e){if("undefined"==typeof document)return 0;if(document.body&&(!document.readyState||"loading"!==document.readyState)){if(!0!==e&&"number"==typeof dn.__cache)return dn.__cache;var t=document.createElement("div"),n=t.style;n.display="block",n.position="absolute",n.width="100px",n.height="100px",n.left="-999px",n.top="-999px",n.overflow="scroll",document.body.insertBefore(t,null);var r=t.clientWidth;if(0!==r)return dn.__cache=100-r,document.body.removeChild(t),dn.__cache;document.body.removeChild(t)}};function fn(){var e=(0,r.useState)(dn()),t=e[0],n=e[1];return(0,r.useEffect)((function(){if(void 0===t){var e=requestAnimationFrame((function(){n(dn())}));return function(){return cancelAnimationFrame(e)}}}),[]),t}function pn(e,t,n){if(void 0===n&&(n=[void 0]),"object"!=typeof e)throw new Error("states expected to be an object or array, got "+typeof e);var o=(0,r.useRef)(t),a=(0,r.useRef)(e);o.current=t,a.current=e;var i=(0,r.useState)(n),l=i[0],s=i[1],u=(0,r.useCallback)((function(){o.current.length>=2?o.current(a.current,s):s(o.current(a.current))}),[s]);return(0,r.useEffect)((function(){u()}),Object.values(e)),[l,u]}const hn=function(){var e=ct((function(){return{x:E?window.pageXOffset:0,y:E?window.pageYOffset:0}})),t=e[0],n=e[1];return(0,r.useEffect)((function(){var e=function(){n((function(e){var t=window.pageXOffset,n=window.pageYOffset;return e.x!==t||e.y!==n?{x:t,y:n}:e}))};return e(),_(window,"scroll",e,{capture:!1,passive:!0}),function(){k(window,"scroll",e)}}),[]),t};const mn=function(e,t){void 0===e&&(e=1/0),void 0===t&&(t=1/0);var n=ct({width:E?window.innerWidth:e,height:E?window.innerHeight:t}),o=n[0],a=n[1];return(0,r.useEffect)((function(){if(E){var e=function(){a({width:window.innerWidth,height:window.innerHeight})};return _(window,"resize",e),function(){k(window,"resize",e)}}}),[]),o};var gn={x:0,y:0,width:0,height:0,top:0,left:0,bottom:0,right:0};const vn=E&&void 0!==window.ResizeObserver?function(){var e=(0,r.useState)(null),t=e[0],n=e[1],o=(0,r.useState)(gn),a=o[0],i=o[1],l=(0,r.useMemo)((function(){return new window.ResizeObserver((function(e){if(e[0]){var t=e[0].contentRect,n=t.x,r=t.y,o=t.width,a=t.height,l=t.top,s=t.left,u=t.bottom,c=t.right;i({x:n,y:r,width:o,height:a,top:l,left:s,bottom:u,right:c})}}))}),[]);return X((function(){if(t)return l.observe(t),function(){l.disconnect()}}),[t]),[n,a]}:function(){return[x,gn]};var bn;!function(e){e.ZOOMING_IN="ZOOMING_IN",e.ZOOMING_OUT="ZOOMING_OUT"}(bn||(bn={}));const yn=function(e){var t=(0,r.useMemo)((function(){return{evCache:[],prevDiff:-1}}),[e.current]),n=(0,r.useState)(),o=n[0],a=n[1],i=function(e){for(var n=0;n<t.evCache.length;n++)if(e.pointerId==t.evCache[n].pointerId){t.evCache[n]=e;break}if(2==t.evCache.length){var r=Math.abs(t.evCache[0].clientX-t.evCache[1].clientX);t.prevDiff>0&&(r>t.prevDiff&&a([bn.ZOOMING_IN,r]),r<t.prevDiff&&a([bn.ZOOMING_OUT,r])),t.prevDiff=r}},l=function(e){t.evCache.push(e)},s=function(e){u(e),t.evCache.length<2&&(t.prevDiff=-1)},u=function(e){for(var n=0;n<t.evCache.length;n++)if(t.evCache[n].pointerId==e.pointerId){t.evCache.splice(n,1);break}};return(0,r.useEffect)((function(){(null==e?void 0:e.current)&&(e.current.onpointerdown=l,e.current.onpointermove=i,e.current.onpointerup=s,e.current.onpointercancel=s,e.current.onpointerout=s,e.current.onpointerleave=s)}),[null==e?void 0:e.current]),o?{zoomingState:o[0],pinchState:o[1]}:{zoomingState:null,pinchState:0}};function wn(){return++(0,r.useRef)(0).current}const xn=function(e){void 0===e&&(e=new Set);var t=(0,r.useState)(e),n=t[0],o=t[1],a=(0,r.useMemo)((function(){return{add:function(e){return o((function(t){return new Set((0,f.__spreadArrays)(Array.from(t),[e]))}))},remove:function(e){return o((function(t){return new Set(Array.from(t).filter((function(t){return t!==e})))}))},toggle:function(e){return o((function(t){return t.has(e)?new Set(Array.from(t).filter((function(t){return t!==e}))):new Set((0,f.__spreadArrays)(Array.from(t),[e]))}))},reset:function(){return o(e)}}}),[o]),i=(0,f.__assign)({has:(0,r.useCallback)((function(e){return n.has(e)}),[n])},a);return[n,i]};function _n(e){var t={state:e instanceof Function?e():e,setState:function(e){t.state=V(e,t.state),t.setters.forEach((function(e){return e(t.state)}))},setters:[]};return function(){var e=(0,r.useState)(t.state),n=e[0],o=e[1];return se((function(){return function(){t.setters=t.setters.filter((function(e){return e!==o}))}})),X((function(){t.setters.includes(o)||t.setters.push(o)})),[n,t.setState]}}var kn=function(){var e=(0,r.useState)((function(){return window.location.hash})),t=e[0],n=e[1],o=(0,r.useCallback)((function(){n(window.location.hash)}),[]);Fe((function(){_(window,"hashchange",o)}),(function(){k(window,"hashchange",o)}));var a=(0,r.useCallback)((function(e){e!==t&&(window.location.hash=e)}),[t]);return[t,a]}},72408:(e,t,n)=>{"use strict";var r=n(27418),o=60103,a=60106;t.Fragment=60107,t.StrictMode=60108,t.Profiler=60114;var i=60109,l=60110,s=60112;t.Suspense=60113;var u=60115,c=60116;if("function"==typeof Symbol&&Symbol.for){var d=Symbol.for;o=d("react.element"),a=d("react.portal"),t.Fragment=d("react.fragment"),t.StrictMode=d("react.strict_mode"),t.Profiler=d("react.profiler"),i=d("react.provider"),l=d("react.context"),s=d("react.forward_ref"),t.Suspense=d("react.suspense"),u=d("react.memo"),c=d("react.lazy")}var f="function"==typeof Symbol&&Symbol.iterator;function p(e){for(var t="https://reactjs.org/docs/error-decoder.html?invariant="+e,n=1;n<arguments.length;n++)t+="&args[]="+encodeURIComponent(arguments[n]);return"Minified React error #"+e+"; visit "+t+" for the full message or use the non-minified dev environment for full errors and additional helpful warnings."}var h={isMounted:function(){return!1},enqueueForceUpdate:function(){},enqueueReplaceState:function(){},enqueueSetState:function(){}},m={};function g(e,t,n){this.props=e,this.context=t,this.refs=m,this.updater=n||h}function v(){}function b(e,t,n){this.props=e,this.context=t,this.refs=m,this.updater=n||h}g.prototype.isReactComponent={},g.prototype.setState=function(e,t){if("object"!=typeof e&&"function"!=typeof e&&null!=e)throw Error(p(85));this.updater.enqueueSetState(this,e,t,"setState")},g.prototype.forceUpdate=function(e){this.updater.enqueueForceUpdate(this,e,"forceUpdate")},v.prototype=g.prototype;var y=b.prototype=new v;y.constructor=b,r(y,g.prototype),y.isPureReactComponent=!0;var w={current:null},x=Object.prototype.hasOwnProperty,_={key:!0,ref:!0,__self:!0,__source:!0};function k(e,t,n){var r,a={},i=null,l=null;if(null!=t)for(r in void 0!==t.ref&&(l=t.ref),void 0!==t.key&&(i=""+t.key),t)x.call(t,r)&&!_.hasOwnProperty(r)&&(a[r]=t[r]);var s=arguments.length-2;if(1===s)a.children=n;else if(1<s){for(var u=Array(s),c=0;c<s;c++)u[c]=arguments[c+2];a.children=u}if(e&&e.defaultProps)for(r in s=e.defaultProps)void 0===a[r]&&(a[r]=s[r]);return{$$typeof:o,type:e,key:i,ref:l,props:a,_owner:w.current}}function E(e){return"object"==typeof e&&null!==e&&e.$$typeof===o}var S=/\/+/g;function C(e,t){return"object"==typeof e&&null!==e&&null!=e.key?function(e){var t={"=":"=0",":":"=2"};return"$"+e.replace(/[=:]/g,(function(e){return t[e]}))}(""+e.key):t.toString(36)}function T(e,t,n,r,i){var l=typeof e;"undefined"!==l&&"boolean"!==l||(e=null);var s=!1;if(null===e)s=!0;else switch(l){case"string":case"number":s=!0;break;case"object":switch(e.$$typeof){case o:case a:s=!0}}if(s)return i=i(s=e),e=""===r?"."+C(s,0):r,Array.isArray(i)?(n="",null!=e&&(n=e.replace(S,"$&/")+"/"),T(i,t,n,"",(function(e){return e}))):null!=i&&(E(i)&&(i=function(e,t){return{$$typeof:o,type:e.type,key:t,ref:e.ref,props:e.props,_owner:e._owner}}(i,n+(!i.key||s&&s.key===i.key?"":(""+i.key).replace(S,"$&/")+"/")+e)),t.push(i)),1;if(s=0,r=""===r?".":r+":",Array.isArray(e))for(var u=0;u<e.length;u++){var c=r+C(l=e[u],u);s+=T(l,t,n,c,i)}else if(c=function(e){return null===e||"object"!=typeof e?null:"function"==typeof(e=f&&e[f]||e["@@iterator"])?e:null}(e),"function"==typeof c)for(e=c.call(e),u=0;!(l=e.next()).done;)s+=T(l=l.value,t,n,c=r+C(l,u++),i);else if("object"===l)throw t=""+e,Error(p(31,"[object Object]"===t?"object with keys {"+Object.keys(e).join(", ")+"}":t));return s}function O(e,t,n){if(null==e)return e;var r=[],o=0;return T(e,r,"","",(function(e){return t.call(n,e,o++)})),r}function D(e){if(-1===e._status){var t=e._result;t=t(),e._status=0,e._result=t,t.then((function(t){0===e._status&&(t=t.default,e._status=1,e._result=t)}),(function(t){0===e._status&&(e._status=2,e._result=t)}))}if(1===e._status)return e._result;throw e._result}var P={current:null};function N(){var e=P.current;if(null===e)throw Error(p(321));return e}var A={ReactCurrentDispatcher:P,ReactCurrentBatchConfig:{transition:0},ReactCurrentOwner:w,IsSomeRendererActing:{current:!1},assign:r};t.Children={map:O,forEach:function(e,t,n){O(e,(function(){t.apply(this,arguments)}),n)},count:function(e){var t=0;return O(e,(function(){t++})),t},toArray:function(e){return O(e,(function(e){return e}))||[]},only:function(e){if(!E(e))throw Error(p(143));return e}},t.Component=g,t.PureComponent=b,t.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED=A,t.cloneElement=function(e,t,n){if(null==e)throw Error(p(267,e));var a=r({},e.props),i=e.key,l=e.ref,s=e._owner;if(null!=t){if(void 0!==t.ref&&(l=t.ref,s=w.current),void 0!==t.key&&(i=""+t.key),e.type&&e.type.defaultProps)var u=e.type.defaultProps;for(c in t)x.call(t,c)&&!_.hasOwnProperty(c)&&(a[c]=void 0===t[c]&&void 0!==u?u[c]:t[c])}var c=arguments.length-2;if(1===c)a.children=n;else if(1<c){u=Array(c);for(var d=0;d<c;d++)u[d]=arguments[d+2];a.children=u}return{$$typeof:o,type:e.type,key:i,ref:l,props:a,_owner:s}},t.createContext=function(e,t){return void 0===t&&(t=null),(e={$$typeof:l,_calculateChangedBits:t,_currentValue:e,_currentValue2:e,_threadCount:0,Provider:null,Consumer:null}).Provider={$$typeof:i,_context:e},e.Consumer=e},t.createElement=k,t.createFactory=function(e){var t=k.bind(null,e);return t.type=e,t},t.createRef=function(){return{current:null}},t.forwardRef=function(e){return{$$typeof:s,render:e}},t.isValidElement=E,t.lazy=function(e){return{$$typeof:c,_payload:{_status:-1,_result:e},_init:D}},t.memo=function(e,t){return{$$typeof:u,type:e,compare:void 0===t?null:t}},t.useCallback=function(e,t){return N().useCallback(e,t)},t.useContext=function(e,t){return N().useContext(e,t)},t.useDebugValue=function(){},t.useEffect=function(e,t){return N().useEffect(e,t)},t.useImperativeHandle=function(e,t,n){return N().useImperativeHandle(e,t,n)},t.useLayoutEffect=function(e,t){return N().useLayoutEffect(e,t)},t.useMemo=function(e,t){return N().useMemo(e,t)},t.useReducer=function(e,t,n){return N().useReducer(e,t,n)},t.useRef=function(e){return N().useRef(e)},t.useState=function(e){return N().useState(e)},t.version="17.0.2"},67294:(e,t,n)=>{"use strict";e.exports=n(72408)},60053:(e,t)=>{"use strict";var n,r,o,a;if("object"==typeof performance&&"function"==typeof performance.now){var i=performance;t.unstable_now=function(){return i.now()}}else{var l=Date,s=l.now();t.unstable_now=function(){return l.now()-s}}if("undefined"==typeof window||"function"!=typeof MessageChannel){var u=null,c=null,d=function(){if(null!==u)try{var e=t.unstable_now();u(!0,e),u=null}catch(n){throw setTimeout(d,0),n}};n=function(e){null!==u?setTimeout(n,0,e):(u=e,setTimeout(d,0))},r=function(e,t){c=setTimeout(e,t)},o=function(){clearTimeout(c)},t.unstable_shouldYield=function(){return!1},a=t.unstable_forceFrameRate=function(){}}else{var f=window.setTimeout,p=window.clearTimeout;if("undefined"!=typeof console){var h=window.cancelAnimationFrame;"function"!=typeof window.requestAnimationFrame&&console.error("This browser doesn't support requestAnimationFrame. Make sure that you load a polyfill in older browsers. https://reactjs.org/link/react-polyfills"),"function"!=typeof h&&console.error("This browser doesn't support cancelAnimationFrame. Make sure that you load a polyfill in older browsers. https://reactjs.org/link/react-polyfills")}var m=!1,g=null,v=-1,b=5,y=0;t.unstable_shouldYield=function(){return t.unstable_now()>=y},a=function(){},t.unstable_forceFrameRate=function(e){0>e||125<e?console.error("forceFrameRate takes a positive int between 0 and 125, forcing frame rates higher than 125 fps is not supported"):b=0<e?Math.floor(1e3/e):5};var w=new MessageChannel,x=w.port2;w.port1.onmessage=function(){if(null!==g){var e=t.unstable_now();y=e+b;try{g(!0,e)?x.postMessage(null):(m=!1,g=null)}catch(n){throw x.postMessage(null),n}}else m=!1},n=function(e){g=e,m||(m=!0,x.postMessage(null))},r=function(e,n){v=f((function(){e(t.unstable_now())}),n)},o=function(){p(v),v=-1}}function _(e,t){var n=e.length;e.push(t);e:for(;;){var r=n-1>>>1,o=e[r];if(!(void 0!==o&&0<S(o,t)))break e;e[r]=t,e[n]=o,n=r}}function k(e){return void 0===(e=e[0])?null:e}function E(e){var t=e[0];if(void 0!==t){var n=e.pop();if(n!==t){e[0]=n;e:for(var r=0,o=e.length;r<o;){var a=2*(r+1)-1,i=e[a],l=a+1,s=e[l];if(void 0!==i&&0>S(i,n))void 0!==s&&0>S(s,i)?(e[r]=s,e[l]=n,r=l):(e[r]=i,e[a]=n,r=a);else{if(!(void 0!==s&&0>S(s,n)))break e;e[r]=s,e[l]=n,r=l}}}return t}return null}function S(e,t){var n=e.sortIndex-t.sortIndex;return 0!==n?n:e.id-t.id}var C=[],T=[],O=1,D=null,P=3,N=!1,A=!1,I=!1;function L(e){for(var t=k(T);null!==t;){if(null===t.callback)E(T);else{if(!(t.startTime<=e))break;E(T),t.sortIndex=t.expirationTime,_(C,t)}t=k(T)}}function R(e){if(I=!1,L(e),!A)if(null!==k(C))A=!0,n(j);else{var t=k(T);null!==t&&r(R,t.startTime-e)}}function j(e,n){A=!1,I&&(I=!1,o()),N=!0;var a=P;try{for(L(n),D=k(C);null!==D&&(!(D.expirationTime>n)||e&&!t.unstable_shouldYield());){var i=D.callback;if("function"==typeof i){D.callback=null,P=D.priorityLevel;var l=i(D.expirationTime<=n);n=t.unstable_now(),"function"==typeof l?D.callback=l:D===k(C)&&E(C),L(n)}else E(C);D=k(C)}if(null!==D)var s=!0;else{var u=k(T);null!==u&&r(R,u.startTime-n),s=!1}return s}finally{D=null,P=a,N=!1}}var M=a;t.unstable_IdlePriority=5,t.unstable_ImmediatePriority=1,t.unstable_LowPriority=4,t.unstable_NormalPriority=3,t.unstable_Profiling=null,t.unstable_UserBlockingPriority=2,t.unstable_cancelCallback=function(e){e.callback=null},t.unstable_continueExecution=function(){A||N||(A=!0,n(j))},t.unstable_getCurrentPriorityLevel=function(){return P},t.unstable_getFirstCallbackNode=function(){return k(C)},t.unstable_next=function(e){switch(P){case 1:case 2:case 3:var t=3;break;default:t=P}var n=P;P=t;try{return e()}finally{P=n}},t.unstable_pauseExecution=function(){},t.unstable_requestPaint=M,t.unstable_runWithPriority=function(e,t){switch(e){case 1:case 2:case 3:case 4:case 5:break;default:e=3}var n=P;P=e;try{return t()}finally{P=n}},t.unstable_scheduleCallback=function(e,a,i){var l=t.unstable_now();switch("object"==typeof i&&null!==i?i="number"==typeof(i=i.delay)&&0<i?l+i:l:i=l,e){case 1:var s=-1;break;case 2:s=250;break;case 5:s=1073741823;break;case 4:s=1e4;break;default:s=5e3}return e={id:O++,callback:a,priorityLevel:e,startTime:i,expirationTime:s=i+s,sortIndex:-1},i>l?(e.sortIndex=i,_(T,e),null===k(C)&&e===k(T)&&(I?o():I=!0,r(R,i-l))):(e.sortIndex=s,_(C,e),A||N||(A=!0,n(j))),e},t.unstable_wrapCallback=function(e){var t=P;return function(){var n=P;P=t;try{return e.apply(this,arguments)}finally{P=n}}}},63840:(e,t,n)=>{"use strict";e.exports=n(60053)},10577:e=>{!function(){"use strict";var t="undefined"!=typeof window&&void 0!==window.document?window.document:{},n=e.exports,r=function(){for(var e,n=[["requestFullscreen","exitFullscreen","fullscreenElement","fullscreenEnabled","fullscreenchange","fullscreenerror"],["webkitRequestFullscreen","webkitExitFullscreen","webkitFullscreenElement","webkitFullscreenEnabled","webkitfullscreenchange","webkitfullscreenerror"],["webkitRequestFullScreen","webkitCancelFullScreen","webkitCurrentFullScreenElement","webkitCancelFullScreen","webkitfullscreenchange","webkitfullscreenerror"],["mozRequestFullScreen","mozCancelFullScreen","mozFullScreenElement","mozFullScreenEnabled","mozfullscreenchange","mozfullscreenerror"],["msRequestFullscreen","msExitFullscreen","msFullscreenElement","msFullscreenEnabled","MSFullscreenChange","MSFullscreenError"]],r=0,o=n.length,a={};r<o;r++)if((e=n[r])&&e[1]in t){for(r=0;r<e.length;r++)a[n[0][r]]=e[r];return a}return!1}(),o={change:r.fullscreenchange,error:r.fullscreenerror},a={request:function(e,n){return new Promise(function(o,a){var i=function(){this.off("change",i),o()}.bind(this);this.on("change",i);var l=(e=e||t.documentElement)[r.requestFullscreen](n);l instanceof Promise&&l.then(i).catch(a)}.bind(this))},exit:function(){return new Promise(function(e,n){if(this.isFullscreen){var o=function(){this.off("change",o),e()}.bind(this);this.on("change",o);var a=t[r.exitFullscreen]();a instanceof Promise&&a.then(o).catch(n)}else e()}.bind(this))},toggle:function(e,t){return this.isFullscreen?this.exit():this.request(e,t)},onchange:function(e){this.on("change",e)},onerror:function(e){this.on("error",e)},on:function(e,n){var r=o[e];r&&t.addEventListener(r,n,!1)},off:function(e,n){var r=o[e];r&&t.removeEventListener(r,n,!1)},raw:r};r?(Object.defineProperties(a,{isFullscreen:{get:function(){return Boolean(t[r.fullscreenElement])}},element:{enumerable:!0,get:function(){return t[r.fullscreenElement]}},isEnabled:{enumerable:!0,get:function(){return Boolean(t[r.fullscreenEnabled])}}}),n?e.exports=a:window.screenfull=a):n?e.exports={isEnabled:!1}:window.screenfull={isEnabled:!1}}()},96774:e=>{e.exports=function(e,t,n,r){var o=n?n.call(r,e,t):void 0;if(void 0!==o)return!!o;if(e===t)return!0;if("object"!=typeof e||!e||"object"!=typeof t||!t)return!1;var a=Object.keys(e),i=Object.keys(t);if(a.length!==i.length)return!1;for(var l=Object.prototype.hasOwnProperty.bind(t),s=0;s<a.length;s++){var u=a[s];if(!l(u))return!1;var c=e[u],d=t[u];if(!1===(o=n?n.call(r,c,d,u):void 0)||void 0===o&&c!==d)return!1}return!0}},11742:e=>{e.exports=function(){var e=document.getSelection();if(!e.rangeCount)return function(){};for(var t=document.activeElement,n=[],r=0;r<e.rangeCount;r++)n.push(e.getRangeAt(r));switch(t.tagName.toUpperCase()){case"INPUT":case"TEXTAREA":t.blur();break;default:t=null}return e.removeAllRanges(),function(){"Caret"===e.type&&e.removeAllRanges(),e.rangeCount||n.forEach((function(t){e.addRange(t)})),t&&t.focus()}}},75534:(e,t)=>{"use strict";t.U={linear:function(e){return e},quadratic:function(e){return e*(-e*e*e+4*e*e-6*e+4)},cubic:function(e){return e*(4*e*e-9*e+6)},elastic:function(e){return e*(33*e*e*e*e-106*e*e*e+126*e*e-67*e+15)},inQuad:function(e){return e*e},outQuad:function(e){return e*(2-e)},inOutQuad:function(e){return e<.5?2*e*e:(4-2*e)*e-1},inCubic:function(e){return e*e*e},outCubic:function(e){return--e*e*e+1},inOutCubic:function(e){return e<.5?4*e*e*e:(e-1)*(2*e-2)*(2*e-2)+1},inQuart:function(e){return e*e*e*e},outQuart:function(e){return 1- --e*e*e*e},inOutQuart:function(e){return e<.5?8*e*e*e*e:1-8*--e*e*e*e},inQuint:function(e){return e*e*e*e*e},outQuint:function(e){return 1+--e*e*e*e*e},inOutQuint:function(e){return e<.5?16*e*e*e*e*e:1+16*--e*e*e*e*e},inSine:function(e){return 1-Math.cos(e*(Math.PI/2))},outSine:function(e){return Math.sin(e*(Math.PI/2))},inOutSine:function(e){return-(Math.cos(Math.PI*e)-1)/2},inExpo:function(e){return Math.pow(2,10*(e-1))},outExpo:function(e){return 1-Math.pow(2,-10*e)},inOutExpo:function(e){return(e/=.5)<1?Math.pow(2,10*(e-1))/2:(e--,(2-Math.pow(2,-10*e))/2)},inCirc:function(e){return 1-Math.sqrt(1-e*e)},outCirc:function(e){return Math.sqrt(1-(e-=1)*e)},inOutCirc:function(e){return(e/=.5)<1?-(Math.sqrt(1-e*e)-1)/2:(e-=2,(Math.sqrt(1-e*e)+1)/2)}}},70655:(e,t,n)=>{"use strict";n.r(t),n.d(t,{__assign:()=>a,__asyncDelegator:()=>x,__asyncGenerator:()=>w,__asyncValues:()=>_,__await:()=>y,__awaiter:()=>c,__classPrivateFieldGet:()=>T,__classPrivateFieldIn:()=>D,__classPrivateFieldSet:()=>O,__createBinding:()=>f,__decorate:()=>l,__exportStar:()=>p,__extends:()=>o,__generator:()=>d,__importDefault:()=>C,__importStar:()=>S,__makeTemplateObject:()=>k,__metadata:()=>u,__param:()=>s,__read:()=>m,__rest:()=>i,__spread:()=>g,__spreadArray:()=>b,__spreadArrays:()=>v,__values:()=>h});var r=function(e,t){return r=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(e,t){e.__proto__=t}||function(e,t){for(var n in t)Object.prototype.hasOwnProperty.call(t,n)&&(e[n]=t[n])},r(e,t)};function o(e,t){if("function"!=typeof t&&null!==t)throw new TypeError("Class extends value "+String(t)+" is not a constructor or null");function n(){this.constructor=e}r(e,t),e.prototype=null===t?Object.create(t):(n.prototype=t.prototype,new n)}var a=function(){return a=Object.assign||function(e){for(var t,n=1,r=arguments.length;n<r;n++)for(var o in t=arguments[n])Object.prototype.hasOwnProperty.call(t,o)&&(e[o]=t[o]);return e},a.apply(this,arguments)};function i(e,t){var n={};for(var r in e)Object.prototype.hasOwnProperty.call(e,r)&&t.indexOf(r)<0&&(n[r]=e[r]);if(null!=e&&"function"==typeof Object.getOwnPropertySymbols){var o=0;for(r=Object.getOwnPropertySymbols(e);o<r.length;o++)t.indexOf(r[o])<0&&Object.prototype.propertyIsEnumerable.call(e,r[o])&&(n[r[o]]=e[r[o]])}return n}function l(e,t,n,r){var o,a=arguments.length,i=a<3?t:null===r?r=Object.getOwnPropertyDescriptor(t,n):r;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)i=Reflect.decorate(e,t,n,r);else for(var l=e.length-1;l>=0;l--)(o=e[l])&&(i=(a<3?o(i):a>3?o(t,n,i):o(t,n))||i);return a>3&&i&&Object.defineProperty(t,n,i),i}function s(e,t){return function(n,r){t(n,r,e)}}function u(e,t){if("object"==typeof Reflect&&"function"==typeof Reflect.metadata)return Reflect.metadata(e,t)}function c(e,t,n,r){return new(n||(n=Promise))((function(o,a){function i(e){try{s(r.next(e))}catch(t){a(t)}}function l(e){try{s(r.throw(e))}catch(t){a(t)}}function s(e){var t;e.done?o(e.value):(t=e.value,t instanceof n?t:new n((function(e){e(t)}))).then(i,l)}s((r=r.apply(e,t||[])).next())}))}function d(e,t){var n,r,o,a,i={label:0,sent:function(){if(1&o[0])throw o[1];return o[1]},trys:[],ops:[]};return a={next:l(0),throw:l(1),return:l(2)},"function"==typeof Symbol&&(a[Symbol.iterator]=function(){return this}),a;function l(a){return function(l){return function(a){if(n)throw new TypeError("Generator is already executing.");for(;i;)try{if(n=1,r&&(o=2&a[0]?r.return:a[0]?r.throw||((o=r.return)&&o.call(r),0):r.next)&&!(o=o.call(r,a[1])).done)return o;switch(r=0,o&&(a=[2&a[0],o.value]),a[0]){case 0:case 1:o=a;break;case 4:return i.label++,{value:a[1],done:!1};case 5:i.label++,r=a[1],a=[0];continue;case 7:a=i.ops.pop(),i.trys.pop();continue;default:if(!(o=i.trys,(o=o.length>0&&o[o.length-1])||6!==a[0]&&2!==a[0])){i=0;continue}if(3===a[0]&&(!o||a[1]>o[0]&&a[1]<o[3])){i.label=a[1];break}if(6===a[0]&&i.label<o[1]){i.label=o[1],o=a;break}if(o&&i.label<o[2]){i.label=o[2],i.ops.push(a);break}o[2]&&i.ops.pop(),i.trys.pop();continue}a=t.call(e,i)}catch(l){a=[6,l],r=0}finally{n=o=0}if(5&a[0])throw a[1];return{value:a[0]?a[1]:void 0,done:!0}}([a,l])}}}var f=Object.create?function(e,t,n,r){void 0===r&&(r=n);var o=Object.getOwnPropertyDescriptor(t,n);o&&!("get"in o?!t.__esModule:o.writable||o.configurable)||(o={enumerable:!0,get:function(){return t[n]}}),Object.defineProperty(e,r,o)}:function(e,t,n,r){void 0===r&&(r=n),e[r]=t[n]};function p(e,t){for(var n in e)"default"===n||Object.prototype.hasOwnProperty.call(t,n)||f(t,e,n)}function h(e){var t="function"==typeof Symbol&&Symbol.iterator,n=t&&e[t],r=0;if(n)return n.call(e);if(e&&"number"==typeof e.length)return{next:function(){return e&&r>=e.length&&(e=void 0),{value:e&&e[r++],done:!e}}};throw new TypeError(t?"Object is not iterable.":"Symbol.iterator is not defined.")}function m(e,t){var n="function"==typeof Symbol&&e[Symbol.iterator];if(!n)return e;var r,o,a=n.call(e),i=[];try{for(;(void 0===t||t-- >0)&&!(r=a.next()).done;)i.push(r.value)}catch(l){o={error:l}}finally{try{r&&!r.done&&(n=a.return)&&n.call(a)}finally{if(o)throw o.error}}return i}function g(){for(var e=[],t=0;t<arguments.length;t++)e=e.concat(m(arguments[t]));return e}function v(){for(var e=0,t=0,n=arguments.length;t<n;t++)e+=arguments[t].length;var r=Array(e),o=0;for(t=0;t<n;t++)for(var a=arguments[t],i=0,l=a.length;i<l;i++,o++)r[o]=a[i];return r}function b(e,t,n){if(n||2===arguments.length)for(var r,o=0,a=t.length;o<a;o++)!r&&o in t||(r||(r=Array.prototype.slice.call(t,0,o)),r[o]=t[o]);return e.concat(r||Array.prototype.slice.call(t))}function y(e){return this instanceof y?(this.v=e,this):new y(e)}function w(e,t,n){if(!Symbol.asyncIterator)throw new TypeError("Symbol.asyncIterator is not defined.");var r,o=n.apply(e,t||[]),a=[];return r={},i("next"),i("throw"),i("return"),r[Symbol.asyncIterator]=function(){return this},r;function i(e){o[e]&&(r[e]=function(t){return new Promise((function(n,r){a.push([e,t,n,r])>1||l(e,t)}))})}function l(e,t){try{(n=o[e](t)).value instanceof y?Promise.resolve(n.value.v).then(s,u):c(a[0][2],n)}catch(r){c(a[0][3],r)}var n}function s(e){l("next",e)}function u(e){l("throw",e)}function c(e,t){e(t),a.shift(),a.length&&l(a[0][0],a[0][1])}}function x(e){var t,n;return t={},r("next"),r("throw",(function(e){throw e})),r("return"),t[Symbol.iterator]=function(){return this},t;function r(r,o){t[r]=e[r]?function(t){return(n=!n)?{value:y(e[r](t)),done:"return"===r}:o?o(t):t}:o}}function _(e){if(!Symbol.asyncIterator)throw new TypeError("Symbol.asyncIterator is not defined.");var t,n=e[Symbol.asyncIterator];return n?n.call(e):(e=h(e),t={},r("next"),r("throw"),r("return"),t[Symbol.asyncIterator]=function(){return this},t);function r(n){t[n]=e[n]&&function(t){return new Promise((function(r,o){(function(e,t,n,r){Promise.resolve(r).then((function(t){e({value:t,done:n})}),t)})(r,o,(t=e[n](t)).done,t.value)}))}}}function k(e,t){return Object.defineProperty?Object.defineProperty(e,"raw",{value:t}):e.raw=t,e}var E=Object.create?function(e,t){Object.defineProperty(e,"default",{enumerable:!0,value:t})}:function(e,t){e.default=t};function S(e){if(e&&e.__esModule)return e;var t={};if(null!=e)for(var n in e)"default"!==n&&Object.prototype.hasOwnProperty.call(e,n)&&f(t,e,n);return E(t,e),t}function C(e){return e&&e.__esModule?e:{default:e}}function T(e,t,n,r){if("a"===n&&!r)throw new TypeError("Private accessor was defined without a getter");if("function"==typeof t?e!==t||!r:!t.has(e))throw new TypeError("Cannot read private member from an object whose class did not declare it");return"m"===n?r:"a"===n?r.call(e):r?r.value:t.get(e)}function O(e,t,n,r,o){if("m"===r)throw new TypeError("Private method is not writable");if("a"===r&&!o)throw new TypeError("Private accessor was defined without a setter");if("function"==typeof t?e!==t||!o:!t.has(e))throw new TypeError("Cannot write private member to an object whose class did not declare it");return"a"===r?o.call(e,n):o?o.value=n:t.set(e,n),n}function D(e,t){if(null===t||"object"!=typeof t&&"function"!=typeof t)throw new TypeError("Cannot use 'in' operator on non-object");return"function"==typeof e?t===e:e.has(t)}},53250:(e,t,n)=>{"use strict";var r=n(67294);var o="function"==typeof Object.is?Object.is:function(e,t){return e===t&&(0!==e||1/e==1/t)||e!=e&&t!=t},a=r.useState,i=r.useEffect,l=r.useLayoutEffect,s=r.useDebugValue;function u(e){var t=e.getSnapshot;e=e.value;try{var n=t();return!o(e,n)}catch(r){return!0}}var c="undefined"==typeof window||void 0===window.document||void 0===window.document.createElement?function(e,t){return t()}:function(e,t){var n=t(),r=a({inst:{value:n,getSnapshot:t}}),o=r[0].inst,c=r[1];return l((function(){o.value=n,o.getSnapshot=t,u(o)&&c({inst:o})}),[e,n,t]),i((function(){return u(o)&&c({inst:o}),e((function(){u(o)&&c({inst:o})}))}),[e]),s(n),n};t.useSyncExternalStore=void 0!==r.useSyncExternalStore?r.useSyncExternalStore:c},61688:(e,t,n)=>{"use strict";e.exports=n(53250)},36809:(e,t,n)=>{"use strict";n.d(t,{Z:()=>r});const r={title:"Vac Research",url:"https://vac.dev",baseUrl:"/",markdown:{mermaid:!0},i18n:{defaultLocale:"en",locales:["en"],path:"i18n",localeConfigs:{}},presets:[["@acid-info/logos-docusaurus-preset",{businessUnit:"VacResearch",theme:{name:"default",options:{customCss:["/home/jenkins/workspace/website/vac.dev/src/css/custom.scss"]}},docs:{id:"Docs",breadcrumbs:!1,routeBasePath:"/",sidebarPath:"docs/sidebars.js",remarkPlugins:[null],rehypePlugins:[null]},og:{},generated:{jobList:{jobBoard:"vac"}}}]],plugins:[["@docusaurus/plugin-content-blog",{id:"blog",routeBasePath:"/rlog",path:"rlog",blogTitle:"Research Blog",blogSidebarCount:0,authorsMapPath:"authors.yml",remarkPlugins:[null],rehypePlugins:[null]}],["@docusaurus/plugin-client-redirects",{redirects:[{from:"/research",to:"/rlog"}]}],["@acid-info/docusaurus-og",{path:"_og",imageRenderers:{}}]],themeConfig:{docs:{sidebar:{hideable:!0,autoCollapseCategories:!1},versionPersistence:"localStorage"},metadata:[{name:"description",content:"Vac - Communication, Privacy, Etc."},{name:"image",content:"theme/image/preview-image.png"}],colorMode:{disableSwitch:!1,defaultMode:"dark",respectPrefersColorScheme:!0},navbar:{title:"",logo:{alt:"Vac Research",src:"theme/image/logo.svg",height:26},hideOnScroll:!0,items:[{type:"search",position:"left"},{label:"About Vac",to:"/",activeBaseRegex:"^/$",position:"left"},{label:"Community",to:"/community",activeBasePath:"community",position:"left"},{label:"Research Blog",to:"/rlog",activeBasePath:"rlog",position:"left"},{label:"Join Us",to:"/join-us",activeBasePath:"join-us",position:"left"}]},footer:{logo:{alt:"Vac Research",src:"theme/image/logo.svg",href:"/",width:22},links:[{items:[{label:"Twitter",href:"https://twitter.com/vacp2p"},{label:"Discord",href:"https://discord.gg/PQFdubGt6d"},{label:"Github",href:"https://github.com/vacp2p"}],title:null},{items:[{label:"Work With Us",href:"https://jobs.status.im/"},{label:"Terms & Conditions",to:"/terms"},{href:"/privacy-policy",label:"Privacy Policy"},{href:"/security",label:"Security"}],title:null},{title:"shared:Research",items:[{href:"https://vac.dev",label:"VacP2P"},{href:"https://afaik.institute",label:"AFAIK"}]},{title:"shared:Infrastructure",items:[{href:"https://waku.org/",label:"Waku"},{href:"https://nimbus.team/",label:"Nimbus"},{href:"https://codex.storage",label:"Codex"},{href:"https://nomos.tech",label:"Nomos"}]},{title:"shared:Creative Studio",items:[{href:"https://acid.info",label:"Acid.info"}]},{title:"shared:Movement",items:[{href:"https://logos.co",label:"Logos"}]},{title:"shared:User-facing products",items:[{href:"https://status.im",label:"Status"},{href:"https://keycard.tech",label:"Keycard"}]}],copyright:"Vac Research \xa9 2024<br/>All rights reserved.",style:"light"},prism:{theme:{plain:{color:"#000000",backgroundColor:"rgba(var(--lsd-surface-secondary), 0.08)"},styles:[{types:["comment"],style:{color:"rgb(0, 128, 0)"}},{types:["builtin"],style:{color:"rgb(0, 112, 193)"}},{types:["number","variable","inserted"],style:{color:"rgb(9, 134, 88)"}},{types:["operator"],style:{color:"rgb(0, 0, 0)"}},{types:["constant","char"],style:{color:"rgb(129, 31, 63)"}},{types:["tag"],style:{color:"rgb(128, 0, 0)"}},{types:["attr-name"],style:{color:"rgb(255, 0, 0)"}},{types:["deleted","string"],style:{color:"rgb(163, 21, 21)"}},{types:["changed","punctuation"],style:{color:"rgb(4, 81, 165)"}},{types:["function","keyword"],style:{color:"rgb(0, 0, 255)"}},{types:["class-name"],style:{color:"rgb(38, 127, 153)"}}]},darkTheme:{plain:{color:"#F8F8F2",backgroundColor:"rgba(var(--lsd-surface-secondary), 0.08)"},styles:[{types:["prolog","constant","builtin"],style:{color:"rgb(189, 147, 249)"}},{types:["inserted","function"],style:{color:"rgb(80, 250, 123)"}},{types:["deleted"],style:{color:"rgb(255, 85, 85)"}},{types:["changed"],style:{color:"rgb(255, 184, 108)"}},{types:["punctuation","symbol"],style:{color:"rgb(248, 248, 242)"}},{types:["string","char","tag","selector"],style:{color:"rgb(255, 121, 198)"}},{types:["keyword","variable"],style:{color:"rgb(189, 147, 249)",fontStyle:"italic"}},{types:["comment"],style:{color:"rgb(98, 114, 164)"}},{types:["attr-name"],style:{color:"rgb(241, 250, 140)"}}]},additionalLanguages:[],magicComments:[{className:"theme-code-block-highlighted-line",line:"highlight-next-line",block:{start:"highlight-start",end:"highlight-end"}}]},tableOfContents:{minHeadingLevel:2,maxHeadingLevel:3},mermaid:{theme:{dark:"dark",light:"default"},options:{}}},stylesheets:[{href:"https://cdn.jsdelivr.net/npm/katex@0.13.24/dist/katex.min.css",type:"text/css",integrity:"sha384-odtC+0UGzzFL/6PNoE8rX/SPcQDXBJ+uRepguP4QkPCm2LBxH3FA3y+fKSiJ+AmM",crossorigin:"anonymous"}],baseUrlIssueBanner:!0,onBrokenLinks:"warn",onBrokenMarkdownLinks:"warn",onDuplicateRoutes:"warn",staticDirectories:["static","/home/jenkins/workspace/website/vac.dev/node_modules/@acid-info/logos-docusaurus-preset/static/common","/home/jenkins/workspace/website/vac.dev/node_modules/@acid-info/logos-docusaurus-preset/static/VacResearch","/home/jenkins/workspace/website/vac.dev/node_modules/@acid-info/logos-docusaurus-theme/lib/client/static/"],customFields:{businessUnits:"VacResearch","logos-docusaurus-theme":{customCss:["/home/jenkins/workspace/website/vac.dev/src/css/custom.scss"],docs:{},id:"default"}},themes:[],scripts:[],headTags:[],clientModules:[],tagline:"Vac - Communication, Privacy, Etc.",titleDelimiter:"|",noIndex:!1,favicon:"theme/image/favicon.ico"}},87462:(e,t,n)=>{"use strict";function r(){return r=Object.assign?Object.assign.bind():function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e},r.apply(this,arguments)}n.d(t,{Z:()=>r})},75068:(e,t,n)=>{"use strict";function r(e,t){return r=Object.setPrototypeOf?Object.setPrototypeOf.bind():function(e,t){return e.__proto__=t,e},r(e,t)}function o(e,t){e.prototype=Object.create(t.prototype),e.prototype.constructor=e,r(e,t)}n.d(t,{Z:()=>o})},63366:(e,t,n)=>{"use strict";function r(e,t){if(null==e)return{};var n,r,o={},a=Object.keys(e);for(r=0;r<a.length;r++)n=a[r],t.indexOf(n)>=0||(o[n]=e[n]);return o}n.d(t,{Z:()=>r})},27563:(e,t,n)=>{"use strict";n.d(t,{Ab:()=>i,Fr:()=>l,G$:()=>a,JM:()=>d,K$:()=>u,MS:()=>r,h5:()=>s,lK:()=>c,uj:()=>o});var r="-ms-",o="-moz-",a="-webkit-",i="comm",l="rule",s="decl",u="@import",c="@keyframes",d="@layer"},92190:(e,t,n)=>{"use strict";n.d(t,{MY:()=>i});var r=n(27563),o=n(26686),a=n(46411);function i(e){return(0,a.cE)(l("",null,null,null,[""],e=(0,a.un)(e),0,[0],e))}function l(e,t,n,r,i,d,f,p,h){for(var m=0,g=0,v=f,b=0,y=0,w=0,x=1,_=1,k=1,E=0,S="",C=i,T=d,O=r,D=S;_;)switch(w=E,E=(0,a.lp)()){case 40:if(108!=w&&58==(0,o.uO)(D,v-1)){-1!=(0,o.Cw)(D+=(0,o.gx)((0,a.iF)(E),"&","&\f"),"&\f")&&(k=-1);break}case 34:case 39:case 91:D+=(0,a.iF)(E);break;case 9:case 10:case 13:case 32:D+=(0,a.Qb)(w);break;case 92:D+=(0,a.kq)((0,a.Ud)()-1,7);continue;case 47:switch((0,a.fj)()){case 42:case 47:(0,o.R3)(u((0,a.q6)((0,a.lp)(),(0,a.Ud)()),t,n),h);break;default:D+="/"}break;case 123*x:p[m++]=(0,o.to)(D)*k;case 125*x:case 59:case 0:switch(E){case 0:case 125:_=0;case 59+g:-1==k&&(D=(0,o.gx)(D,/\f/g,"")),y>0&&(0,o.to)(D)-v&&(0,o.R3)(y>32?c(D+";",r,n,v-1):c((0,o.gx)(D," ","")+";",r,n,v-2),h);break;case 59:D+=";";default:if((0,o.R3)(O=s(D,t,n,m,g,i,p,S,C=[],T=[],v),d),123===E)if(0===g)l(D,t,O,O,C,d,v,p,T);else switch(99===b&&110===(0,o.uO)(D,3)?100:b){case 100:case 108:case 109:case 115:l(e,O,O,r&&(0,o.R3)(s(e,O,O,0,0,i,p,S,i,C=[],v),T),i,T,v,p,r?C:T);break;default:l(D,O,O,O,[""],T,0,p,T)}}m=g=y=0,x=k=1,S=D="",v=f;break;case 58:v=1+(0,o.to)(D),y=w;default:if(x<1)if(123==E)--x;else if(125==E&&0==x++&&125==(0,a.mp)())continue;switch(D+=(0,o.Dp)(E),E*x){case 38:k=g>0?1:(D+="\f",-1);break;case 44:p[m++]=((0,o.to)(D)-1)*k,k=1;break;case 64:45===(0,a.fj)()&&(D+=(0,a.iF)((0,a.lp)())),b=(0,a.fj)(),g=v=(0,o.to)(S=D+=(0,a.QU)((0,a.Ud)())),E++;break;case 45:45===w&&2==(0,o.to)(D)&&(x=0)}}return d}function s(e,t,n,i,l,s,u,c,d,f,p){for(var h=l-1,m=0===l?s:[""],g=(0,o.Ei)(m),v=0,b=0,y=0;v<i;++v)for(var w=0,x=(0,o.tb)(e,h+1,h=(0,o.Wn)(b=u[v])),_=e;w<g;++w)(_=(0,o.fy)(b>0?m[w]+" "+x:(0,o.gx)(x,/&\f/g,m[w])))&&(d[y++]=_);return(0,a.dH)(e,t,n,0===l?r.Fr:c,d,f,p)}function u(e,t,n){return(0,a.dH)(e,t,n,r.Ab,(0,o.Dp)((0,a.Tb)()),(0,o.tb)(e,2,-2),0)}function c(e,t,n,i){return(0,a.dH)(e,t,n,r.h5,(0,o.tb)(e,0,i),(0,o.tb)(e,i+1,-1),i)}},20211:(e,t,n)=>{"use strict";n.d(t,{P:()=>i,q:()=>a});var r=n(27563),o=n(26686);function a(e,t){for(var n="",r=(0,o.Ei)(e),a=0;a<r;a++)n+=t(e[a],a,e,t)||"";return n}function i(e,t,n,i){switch(e.type){case r.JM:if(e.children.length)break;case r.K$:case r.h5:return e.return=e.return||e.value;case r.Ab:return"";case r.lK:return e.return=e.value+"{"+a(e.children,i)+"}";case r.Fr:e.value=e.props.join(",")}return(0,o.to)(n=a(e.children,i))?e.return=e.value+"{"+n+"}":""}},46411:(e,t,n)=>{"use strict";n.d(t,{FK:()=>l,JG:()=>d,QU:()=>C,Qb:()=>_,Tb:()=>f,Ud:()=>g,cE:()=>w,dH:()=>c,fj:()=>m,iF:()=>x,kq:()=>k,lp:()=>h,mp:()=>p,q6:()=>S,r:()=>b,tP:()=>v,un:()=>y});var r=n(26686),o=1,a=1,i=0,l=0,s=0,u="";function c(e,t,n,r,i,l,s){return{value:e,root:t,parent:n,type:r,props:i,children:l,line:o,column:a,length:s,return:""}}function d(e,t){return(0,r.f0)(c("",null,null,"",null,null,0),e,{length:-e.length},t)}function f(){return s}function p(){return s=l>0?(0,r.uO)(u,--l):0,a--,10===s&&(a=1,o--),s}function h(){return s=l<i?(0,r.uO)(u,l++):0,a++,10===s&&(a=1,o++),s}function m(){return(0,r.uO)(u,l)}function g(){return l}function v(e,t){return(0,r.tb)(u,e,t)}function b(e){switch(e){case 0:case 9:case 10:case 13:case 32:return 5;case 33:case 43:case 44:case 47:case 62:case 64:case 126:case 59:case 123:case 125:return 4;case 58:return 3;case 34:case 39:case 40:case 91:return 2;case 41:case 93:return 1}return 0}function y(e){return o=a=1,i=(0,r.to)(u=e),l=0,[]}function w(e){return u="",e}function x(e){return(0,r.fy)(v(l-1,E(91===e?e+2:40===e?e+1:e)))}function _(e){for(;(s=m())&&s<33;)h();return b(e)>2||b(s)>3?"":" "}function k(e,t){for(;--t&&h()&&!(s<48||s>102||s>57&&s<65||s>70&&s<97););return v(e,g()+(t<6&&32==m()&&32==h()))}function E(e){for(;h();)switch(s){case e:return l;case 34:case 39:34!==e&&39!==e&&E(s);break;case 40:41===e&&E(e);break;case 92:h()}return l}function S(e,t){for(;h()&&e+s!==57&&(e+s!==84||47!==m()););return"/*"+v(t,l-1)+"*"+(0,r.Dp)(47===e?e:h())}function C(e){for(;!b(m());)h();return v(e,l)}},26686:(e,t,n)=>{"use strict";n.d(t,{$e:()=>g,Cw:()=>c,Dp:()=>o,EQ:()=>s,Ei:()=>h,R3:()=>m,Wn:()=>r,f0:()=>a,fy:()=>l,gx:()=>u,tb:()=>f,to:()=>p,uO:()=>d,vp:()=>i});var r=Math.abs,o=String.fromCharCode,a=Object.assign;function i(e,t){return 45^d(e,0)?(((t<<2^d(e,0))<<2^d(e,1))<<2^d(e,2))<<2^d(e,3):0}function l(e){return e.trim()}function s(e,t){return(e=t.exec(e))?e[0]:e}function u(e,t,n){return e.replace(t,n)}function c(e,t){return e.indexOf(t)}function d(e,t){return 0|e.charCodeAt(t)}function f(e,t,n){return e.slice(t,n)}function p(e){return e.length}function h(e){return e.length}function m(e,t){return t.push(e),e}function g(e,t){return e.map(t).join("")}},38776:(e,t,n)=>{"use strict";n.d(t,{Z:()=>o});var r="Invariant failed";function o(e,t){if(!e)throw new Error(r)}},57529:e=>{"use strict";e.exports={}},16887:e=>{"use strict";e.exports=JSON.parse('{"/rlog-a65":{"__comp":"a6aa9e1f","__context":{"plugin":"1e4c069f"},"sidebar":"95b96bb9","items":[{"content":"2e8c87b8"},{"content":"cbf8cf19"},{"content":"feda84cd"},{"content":"2858c6ff"},{"content":"fdd3b45a"},{"content":"382fdf29"},{"content":"39f27fb8"},{"content":"84dd0cf8"},{"content":"38dc9501"},{"content":"544f54cc"}],"metadata":"124805df"},"/rlog/archive-242":{"__comp":"9e4087bc","__context":{"plugin":"1e4c069f"},"archive":"99c49682"},"/rlog/building-privacy-protecting-infrastructure-b52":{"__comp":"ccc49370","__context":{"plugin":"1e4c069f"},"sidebar":"95b96bb9","content":"e22c7a04"},"/rlog/device-pairing-in-js-waku-and-go-waku-6e6":{"__comp":"ccc49370","__context":{"plugin":"1e4c069f"},"sidebar":"95b96bb9","content":"67b45d3c"},"/rlog/dns-based-discovery-f9b":{"__comp":"ccc49370","__context":{"plugin":"1e4c069f"},"sidebar":"95b96bb9","content":"15a93281"},"/rlog/ethics-surveillance-tech-872":{"__comp":"ccc49370","__context":{"plugin":"1e4c069f"},"sidebar":"95b96bb9","content":"7b019678"},"/rlog/feasibility-discv5-2c3":{"__comp":"ccc49370","__context":{"plugin":"1e4c069f"},"sidebar":"95b96bb9","content":"f7ba2fd8"},"/rlog/feasibility-semaphore-rate-limiting-zksnarks-cff":{"__comp":"ccc49370","__context":{"plugin":"1e4c069f"},"sidebar":"95b96bb9","content":"96524732"},"/rlog/fixing-whisper-with-waku-4ec":{"__comp":"ccc49370","__context":{"plugin":"1e4c069f"},"sidebar":"95b96bb9","content":"2056d17e"},"/rlog/future-of-waku-network-100":{"__comp":"ccc49370","__context":{"plugin":"1e4c069f"},"sidebar":"95b96bb9","content":"91ce8bda"},"/rlog/GossipSub Improvements-4fc":{"__comp":"ccc49370","__context":{"plugin":"1e4c069f"},"sidebar":"95b96bb9","content":"bd3d84fb"},"/rlog/introducing-nwaku-9eb":{"__comp":"ccc49370","__context":{"plugin":"1e4c069f"},"sidebar":"95b96bb9","content":"9e34dc04"},"/rlog/kademlia-to-discv5-2d3":{"__comp":"ccc49370","__context":{"plugin":"1e4c069f"},"sidebar":"95b96bb9","content":"f40b13b8"},"/rlog/membership-with-bloom-filters-and-cuckoo-filters-b1b":{"__comp":"ccc49370","__context":{"plugin":"1e4c069f"},"sidebar":"95b96bb9","content":"7b0e1478"},"/rlog/Nescience-A-zkVM-leveraging-hiding-properties-605":{"__comp":"ccc49370","__context":{"plugin":"1e4c069f"},"sidebar":"95b96bb9","content":"3b467599"},"/rlog/Nescience-state-separation-architecture-72d":{"__comp":"ccc49370","__context":{"plugin":"1e4c069f"},"sidebar":"95b96bb9","content":"18a94246"},"/rlog/p2p-data-sync-for-mobile-8e8":{"__comp":"ccc49370","__context":{"plugin":"1e4c069f"},"sidebar":"95b96bb9","content":"e954d700"},"/rlog/page/2-9df":{"__comp":"a6aa9e1f","__context":{"plugin":"1e4c069f"},"sidebar":"95b96bb9","items":[{"content":"6facda94"},{"content":"7d3f2fdb"},{"content":"ec8fd1ee"},{"content":"13a255f1"},{"content":"c8894de3"},{"content":"0d54ff0d"},{"content":"f643ab5d"},{"content":"18961ce6"},{"content":"9fb2a6b1"},{"content":"3f64d9a3"}],"metadata":"cde6c892"},"/rlog/page/3-dbe":{"__comp":"a6aa9e1f","__context":{"plugin":"1e4c069f"},"sidebar":"95b96bb9","items":[{"content":"c2965f87"},{"content":"74c00f84"},{"content":"6f6bcf93"},{"content":"6abf00de"},{"content":"83575890"},{"content":"84f8336a"},{"content":"7af80316"},{"content":"3f082616"},{"content":"158719ed"},{"content":"6f1f8c5f"}],"metadata":"8c1443cc"},"/rlog/page/4-7f7":{"__comp":"a6aa9e1f","__context":{"plugin":"1e4c069f"},"sidebar":"95b96bb9","items":[{"content":"db970d56"},{"content":"4a8210e4"},{"content":"c7770090"},{"content":"2d6b2291"}],"metadata":"2ef0cd56"},"/rlog/presenting-js-waku-380":{"__comp":"ccc49370","__context":{"plugin":"1e4c069f"},"sidebar":"95b96bb9","content":"12da0170"},"/rlog/remote-log-5c3":{"__comp":"ccc49370","__context":{"plugin":"1e4c069f"},"sidebar":"95b96bb9","content":"f1787e6d"},"/rlog/rln-anonymous-dos-prevention-535":{"__comp":"ccc49370","__context":{"plugin":"1e4c069f"},"sidebar":"95b96bb9","content":"8779ed83"},"/rlog/rln-light-verifiers-657":{"__comp":"ccc49370","__context":{"plugin":"1e4c069f"},"sidebar":"95b96bb9","content":"a71c3513"},"/rlog/rln-relay-2b7":{"__comp":"ccc49370","__context":{"plugin":"1e4c069f"},"sidebar":"95b96bb9","content":"29ae586d"},"/rlog/rln-v3-f91":{"__comp":"ccc49370","__context":{"plugin":"1e4c069f"},"sidebar":"95b96bb9","content":"db40b3a8"},"/rlog/vac-overview-13b":{"__comp":"ccc49370","__context":{"plugin":"1e4c069f"},"sidebar":"95b96bb9","content":"5a7c4f09"},"/rlog/waku-for-all-8f7":{"__comp":"ccc49370","__context":{"plugin":"1e4c069f"},"sidebar":"95b96bb9","content":"191d05a9"},"/rlog/waku-update-7bc":{"__comp":"ccc49370","__context":{"plugin":"1e4c069f"},"sidebar":"95b96bb9","content":"d0c5fcac"},"/rlog/waku-v1-v2-bandwidth-comparison-a00":{"__comp":"ccc49370","__context":{"plugin":"1e4c069f"},"sidebar":"95b96bb9","content":"b0a36ee8"},"/rlog/waku-v2-ethereum-coscup-f86":{"__comp":"ccc49370","__context":{"plugin":"1e4c069f"},"sidebar":"95b96bb9","content":"f3c329e5"},"/rlog/waku-v2-ethereum-messaging-d5b":{"__comp":"ccc49370","__context":{"plugin":"1e4c069f"},"sidebar":"95b96bb9","content":"9e396004"},"/rlog/waku-v2-plan-943":{"__comp":"ccc49370","__context":{"plugin":"1e4c069f"},"sidebar":"95b96bb9","content":"3ec022cb"},"/rlog/waku-v2-update-73e":{"__comp":"ccc49370","__context":{"plugin":"1e4c069f"},"sidebar":"95b96bb9","content":"384035e2"},"/rlog/wakuv2-apd-f04":{"__comp":"ccc49370","__context":{"plugin":"1e4c069f"},"sidebar":"95b96bb9","content":"99f69f8e"},"/rlog/wakuv2-noise-6d7":{"__comp":"ccc49370","__context":{"plugin":"1e4c069f"},"sidebar":"95b96bb9","content":"1e7f5ce0"},"/rlog/wakuv2-relay-anon-dc8":{"__comp":"ccc49370","__context":{"plugin":"1e4c069f"},"sidebar":"95b96bb9","content":"b6f6cb50"},"/rlog/wechat-replacement-need-4e9":{"__comp":"ccc49370","__context":{"plugin":"1e4c069f"},"sidebar":"95b96bb9","content":"e6b418ad"},"/rlog/zkVM-explorations-337":{"__comp":"ccc49370","__context":{"plugin":"1e4c069f"},"sidebar":"95b96bb9","content":"b8fd8041"},"/-4d6":{"__comp":"1be78505","__context":{"plugin":"bfd2a918"},"versionMetadata":"1f3523a7"},"/-d22":{"__comp":"17896441","content":"c377a04b"},"/community-051":{"__comp":"17896441","content":"2c2dd814"},"/contribute-00f":{"__comp":"17896441","content":"4ba7e5a3"},"/deepresearch-40e":{"__comp":"17896441","content":"4f94ff0f"},"/join-us-63f":{"__comp":"17896441","content":"a413eb42"},"/media-895":{"__comp":"17896441","content":"8e79cc52"},"/principles-ef3":{"__comp":"17896441","content":"f8d84f88"},"/privacy-policy-4cd":{"__comp":"17896441","content":"8c5da4da"},"/publications-be1":{"__comp":"17896441","content":"0b46e8e7"},"/rfcprocess-d12":{"__comp":"17896441","content":"8161b354"},"/security-2fb":{"__comp":"17896441","content":"db32d859"},"/terms-37d":{"__comp":"17896441","content":"500a151f"},"/vips-fef":{"__comp":"17896441","content":"3f781295"},"/vsus-e2a":{"__comp":"17896441","content":"ad3e391a"}}')}},e=>{e.O(0,[532],(()=>{return t=3364,e(e.s=t);var t}));e.O()}]); \ No newline at end of file diff --git a/assets/js/runtime~main.556fa6f5.js b/assets/js/runtime~main.556fa6f5.js deleted file mode 100644 index 885ab6e9..00000000 --- a/assets/js/runtime~main.556fa6f5.js +++ /dev/null @@ -1 +0,0 @@ -(()=>{"use strict";var e,d,f,a,c,b={},t={};function r(e){var d=t[e];if(void 0!==d)return d.exports;var f=t[e]={id:e,loaded:!1,exports:{}};return b[e].call(f.exports,f,f.exports,r),f.loaded=!0,f.exports}r.m=b,r.c=t,e=[],r.O=(d,f,a,c)=>{if(!f){var b=1/0;for(i=0;i<e.length;i++){f=e[i][0],a=e[i][1],c=e[i][2];for(var t=!0,o=0;o<f.length;o++)(!1&c||b>=c)&&Object.keys(r.O).every((e=>r.O[e](f[o])))?f.splice(o--,1):(t=!1,c<b&&(b=c));if(t){e.splice(i--,1);var n=a();void 0!==n&&(d=n)}}return d}c=c||0;for(var i=e.length;i>0&&e[i-1][2]>c;i--)e[i]=e[i-1];e[i]=[f,a,c]},r.n=e=>{var d=e&&e.__esModule?()=>e.default:()=>e;return r.d(d,{a:d}),d},f=Object.getPrototypeOf?e=>Object.getPrototypeOf(e):e=>e.__proto__,r.t=function(e,a){if(1&a&&(e=this(e)),8&a)return e;if("object"==typeof e&&e){if(4&a&&e.__esModule)return e;if(16&a&&"function"==typeof e.then)return e}var c=Object.create(null);r.r(c);var b={};d=d||[null,f({}),f([]),f(f)];for(var t=2&a&&e;"object"==typeof t&&!~d.indexOf(t);t=f(t))Object.getOwnPropertyNames(t).forEach((d=>b[d]=()=>e[d]));return b.default=()=>e,r.d(c,b),c},r.d=(e,d)=>{for(var f in d)r.o(d,f)&&!r.o(e,f)&&Object.defineProperty(e,f,{enumerable:!0,get:d[f]})},r.f={},r.e=e=>Promise.all(Object.keys(r.f).reduce(((d,f)=>(r.f[f](e,d),d)),[])),r.u=e=>"assets/js/"+({14:"191d05a9",242:"6f6bcf93",305:"384035e2",689:"bfd2a918",819:"2056d17e",865:"99f69f8e",959:"4a8210e4",1016:"feda84cd",1158:"29ae586d",1221:"db970d56",1327:"b6f6cb50",1525:"83575890",1569:"4f94ff0f",1599:"3f781295",1618:"b0a36ee8",1742:"84f8336a",1750:"e22c7a04",1869:"c8894de3",1923:"8c5da4da",1969:"cde6c892",2206:"124805df",2223:"f1787e6d",2276:"ad3e391a",2282:"3f64d9a3",2585:"2e8c87b8",2594:"15a93281",2614:"e6b418ad",2702:"c7770090",2819:"3f082616",2982:"96524732",3089:"a6aa9e1f",3171:"39f27fb8",3228:"f7ba2fd8",3231:"cbf8cf19",3274:"8e79cc52",3415:"13a255f1",3561:"95b96bb9",3607:"3ec022cb",3608:"9e4087bc",3854:"7b019678",3877:"7b0e1478",4046:"f643ab5d",4248:"0d54ff0d",4441:"38dc9501",4545:"500a151f",4588:"b8fd8041",4633:"f3c329e5",4733:"f8d84f88",4763:"158719ed",4991:"c2965f87",5025:"6abf00de",5035:"2c2dd814",5077:"382fdf29",5089:"db40b3a8",5302:"8c1443cc",5328:"9e396004",5387:"0b46e8e7",5417:"5a7c4f09",5524:"2d6b2291",5543:"18a94246",5601:"3b467599",5705:"544f54cc",6103:"ccc49370",6125:"6facda94",6149:"84dd0cf8",6297:"1e7f5ce0",6424:"1e4c069f",6653:"db32d859",6676:"74c00f84",6807:"99c49682",6971:"c377a04b",7070:"ec8fd1ee",7120:"e954d700",7467:"91ce8bda",7495:"6f1f8c5f",7562:"8779ed83",7604:"2858c6ff",7746:"bd3d84fb",7791:"a71c3513",7846:"f40b13b8",7918:"17896441",7969:"7d3f2fdb",7972:"2ef0cd56",7975:"18961ce6",8056:"12da0170",8161:"67b45d3c",8381:"9fb2a6b1",8398:"8161b354",8581:"fdd3b45a",8648:"1f3523a7",8761:"7af80316",9313:"d0c5fcac",9514:"1be78505",9735:"4ba7e5a3",9834:"a413eb42",9924:"9e34dc04"}[e]||e)+"."+{14:"66a5572c",219:"95266e50",242:"a5b260a7",305:"a2ae9e74",689:"7c418579",819:"17ab72a1",865:"db06b1bc",959:"e03c2c3e",1016:"192fc8d5",1158:"43dc6d1e",1221:"2e8af086",1327:"be8f5f8a",1525:"d2fb685d",1569:"225b3397",1599:"9ff2a1c6",1618:"acf34ec0",1742:"ae0ca484",1750:"76b4eeb3",1755:"1940342d",1869:"2879f364",1923:"685c10b2",1969:"4f12a213",2206:"efc495a4",2223:"5de71105",2276:"b9a2f709",2282:"98888d12",2585:"756e51d5",2594:"32702a53",2614:"bb67fb39",2702:"156d228f",2819:"3483b2d9",2982:"9d34232f",3089:"1ba90efa",3171:"6828597e",3228:"16e1379c",3231:"81bdca4f",3274:"55b53923",3415:"eeb2e4ba",3561:"4149cdd0",3607:"30efd6ee",3608:"da8266f8",3854:"c2807219",3877:"48ff094c",4046:"aecf4dbc",4248:"b508d506",4441:"7ada98a5",4545:"50c37ed8",4588:"7e4da9c9",4633:"307d6307",4733:"3ca46756",4763:"3c6b3396",4991:"f1bf87c0",5025:"54330503",5035:"f4da87ca",5077:"fd7bbc15",5089:"46fb11a3",5253:"a56d7493",5302:"f0369ef8",5328:"0b7c31f9",5387:"64cdc00f",5417:"418f63c6",5524:"4c7453ec",5543:"db90dfd6",5601:"9aa43a76",5705:"3294a6c5",6103:"e69e3332",6125:"c662c386",6149:"1026aeae",6297:"02b3da0f",6316:"40c713ba",6424:"7b918630",6653:"d430742d",6676:"89ccce3e",6807:"49525b7c",6971:"01e70aa4",7070:"0cebc1f4",7120:"03a8d5ee",7467:"f051f36a",7495:"58fc6f07",7562:"99f069ef",7604:"0dcb04b6",7724:"88bcb85f",7746:"41abb0be",7791:"0bc3e732",7846:"adeed3fd",7918:"4d3bb07c",7969:"422b0438",7972:"e591aa00",7975:"2d53c0b3",8056:"40efcc2d",8161:"b5eedc5b",8381:"3a473605",8398:"ec2956a6",8581:"999f5f0c",8648:"6f837535",8761:"98408c76",9313:"bad2fbf5",9481:"7b0f0e1a",9487:"d7c2aac6",9514:"f08cfc6c",9735:"e119e8dd",9834:"4fd28c32",9924:"7a809e1c"}[e]+".js",r.miniCssF=e=>{},r.g=function(){if("object"==typeof globalThis)return globalThis;try{return this||new Function("return this")()}catch(e){if("object"==typeof window)return window}}(),r.o=(e,d)=>Object.prototype.hasOwnProperty.call(e,d),a={},c="vac-dev:",r.l=(e,d,f,b)=>{if(a[e])a[e].push(d);else{var t,o;if(void 0!==f)for(var n=document.getElementsByTagName("script"),i=0;i<n.length;i++){var l=n[i];if(l.getAttribute("src")==e||l.getAttribute("data-webpack")==c+f){t=l;break}}t||(o=!0,(t=document.createElement("script")).charset="utf-8",t.timeout=120,r.nc&&t.setAttribute("nonce",r.nc),t.setAttribute("data-webpack",c+f),t.src=e),a[e]=[d];var u=(d,f)=>{t.onerror=t.onload=null,clearTimeout(s);var c=a[e];if(delete a[e],t.parentNode&&t.parentNode.removeChild(t),c&&c.forEach((e=>e(f))),d)return d(f)},s=setTimeout(u.bind(null,void 0,{type:"timeout",target:t}),12e4);t.onerror=u.bind(null,t.onerror),t.onload=u.bind(null,t.onload),o&&document.head.appendChild(t)}},r.r=e=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},r.nmd=e=>(e.paths=[],e.children||(e.children=[]),e),r.p="/",r.gca=function(e){return e={17896441:"7918",83575890:"1525",96524732:"2982","191d05a9":"14","6f6bcf93":"242","384035e2":"305",bfd2a918:"689","2056d17e":"819","99f69f8e":"865","4a8210e4":"959",feda84cd:"1016","29ae586d":"1158",db970d56:"1221",b6f6cb50:"1327","4f94ff0f":"1569","3f781295":"1599",b0a36ee8:"1618","84f8336a":"1742",e22c7a04:"1750",c8894de3:"1869","8c5da4da":"1923",cde6c892:"1969","124805df":"2206",f1787e6d:"2223",ad3e391a:"2276","3f64d9a3":"2282","2e8c87b8":"2585","15a93281":"2594",e6b418ad:"2614",c7770090:"2702","3f082616":"2819",a6aa9e1f:"3089","39f27fb8":"3171",f7ba2fd8:"3228",cbf8cf19:"3231","8e79cc52":"3274","13a255f1":"3415","95b96bb9":"3561","3ec022cb":"3607","9e4087bc":"3608","7b019678":"3854","7b0e1478":"3877",f643ab5d:"4046","0d54ff0d":"4248","38dc9501":"4441","500a151f":"4545",b8fd8041:"4588",f3c329e5:"4633",f8d84f88:"4733","158719ed":"4763",c2965f87:"4991","6abf00de":"5025","2c2dd814":"5035","382fdf29":"5077",db40b3a8:"5089","8c1443cc":"5302","9e396004":"5328","0b46e8e7":"5387","5a7c4f09":"5417","2d6b2291":"5524","18a94246":"5543","3b467599":"5601","544f54cc":"5705",ccc49370:"6103","6facda94":"6125","84dd0cf8":"6149","1e7f5ce0":"6297","1e4c069f":"6424",db32d859:"6653","74c00f84":"6676","99c49682":"6807",c377a04b:"6971",ec8fd1ee:"7070",e954d700:"7120","91ce8bda":"7467","6f1f8c5f":"7495","8779ed83":"7562","2858c6ff":"7604",bd3d84fb:"7746",a71c3513:"7791",f40b13b8:"7846","7d3f2fdb":"7969","2ef0cd56":"7972","18961ce6":"7975","12da0170":"8056","67b45d3c":"8161","9fb2a6b1":"8381","8161b354":"8398",fdd3b45a:"8581","1f3523a7":"8648","7af80316":"8761",d0c5fcac:"9313","1be78505":"9514","4ba7e5a3":"9735",a413eb42:"9834","9e34dc04":"9924"}[e]||e,r.p+r.u(e)},(()=>{var e={1303:0,532:0};r.f.j=(d,f)=>{var a=r.o(e,d)?e[d]:void 0;if(0!==a)if(a)f.push(a[2]);else if(/^(1303|532)$/.test(d))e[d]=0;else{var c=new Promise(((f,c)=>a=e[d]=[f,c]));f.push(a[2]=c);var b=r.p+r.u(d),t=new Error;r.l(b,(f=>{if(r.o(e,d)&&(0!==(a=e[d])&&(e[d]=void 0),a)){var c=f&&("load"===f.type?"missing":f.type),b=f&&f.target&&f.target.src;t.message="Loading chunk "+d+" failed.\n("+c+": "+b+")",t.name="ChunkLoadError",t.type=c,t.request=b,a[1](t)}}),"chunk-"+d,d)}},r.O.j=d=>0===e[d];var d=(d,f)=>{var a,c,b=f[0],t=f[1],o=f[2],n=0;if(b.some((d=>0!==e[d]))){for(a in t)r.o(t,a)&&(r.m[a]=t[a]);if(o)var i=o(r)}for(d&&d(f);n<b.length;n++)c=b[n],r.o(e,c)&&e[c]&&e[c][0](),e[c]=0;return r.O(i)},f=self.webpackChunkvac_dev=self.webpackChunkvac_dev||[];f.forEach(d.bind(null,0)),f.push=d.bind(null,f.push.bind(f))})()})(); \ No newline at end of file diff --git a/assets/js/runtime~main.a9103199.js b/assets/js/runtime~main.a9103199.js new file mode 100644 index 00000000..ee728a36 --- /dev/null +++ b/assets/js/runtime~main.a9103199.js @@ -0,0 +1 @@ +(()=>{"use strict";var e,f,d,a,c,b={},t={};function r(e){var f=t[e];if(void 0!==f)return f.exports;var d=t[e]={id:e,loaded:!1,exports:{}};return b[e].call(d.exports,d,d.exports,r),d.loaded=!0,d.exports}r.m=b,r.c=t,e=[],r.O=(f,d,a,c)=>{if(!d){var b=1/0;for(i=0;i<e.length;i++){d=e[i][0],a=e[i][1],c=e[i][2];for(var t=!0,o=0;o<d.length;o++)(!1&c||b>=c)&&Object.keys(r.O).every((e=>r.O[e](d[o])))?d.splice(o--,1):(t=!1,c<b&&(b=c));if(t){e.splice(i--,1);var n=a();void 0!==n&&(f=n)}}return f}c=c||0;for(var i=e.length;i>0&&e[i-1][2]>c;i--)e[i]=e[i-1];e[i]=[d,a,c]},r.n=e=>{var f=e&&e.__esModule?()=>e.default:()=>e;return r.d(f,{a:f}),f},d=Object.getPrototypeOf?e=>Object.getPrototypeOf(e):e=>e.__proto__,r.t=function(e,a){if(1&a&&(e=this(e)),8&a)return e;if("object"==typeof e&&e){if(4&a&&e.__esModule)return e;if(16&a&&"function"==typeof e.then)return e}var c=Object.create(null);r.r(c);var b={};f=f||[null,d({}),d([]),d(d)];for(var t=2&a&&e;"object"==typeof t&&!~f.indexOf(t);t=d(t))Object.getOwnPropertyNames(t).forEach((f=>b[f]=()=>e[f]));return b.default=()=>e,r.d(c,b),c},r.d=(e,f)=>{for(var d in f)r.o(f,d)&&!r.o(e,d)&&Object.defineProperty(e,d,{enumerable:!0,get:f[d]})},r.f={},r.e=e=>Promise.all(Object.keys(r.f).reduce(((f,d)=>(r.f[d](e,f),f)),[])),r.u=e=>"assets/js/"+({14:"191d05a9",242:"6f6bcf93",305:"384035e2",689:"bfd2a918",819:"2056d17e",865:"99f69f8e",959:"4a8210e4",1016:"feda84cd",1033:"d758c4b4",1158:"29ae586d",1221:"db970d56",1327:"b6f6cb50",1525:"83575890",1569:"4f94ff0f",1599:"3f781295",1618:"b0a36ee8",1742:"84f8336a",1750:"e22c7a04",1773:"93541fc5",1869:"c8894de3",1923:"8c5da4da",1969:"cde6c892",2206:"124805df",2223:"f1787e6d",2276:"ad3e391a",2282:"3f64d9a3",2585:"2e8c87b8",2594:"15a93281",2614:"e6b418ad",2702:"c7770090",2819:"3f082616",2982:"96524732",3089:"a6aa9e1f",3171:"39f27fb8",3228:"f7ba2fd8",3231:"cbf8cf19",3274:"8e79cc52",3415:"13a255f1",3561:"95b96bb9",3607:"3ec022cb",3608:"9e4087bc",3854:"7b019678",3877:"7b0e1478",4046:"f643ab5d",4248:"0d54ff0d",4441:"38dc9501",4545:"500a151f",4588:"b8fd8041",4633:"f3c329e5",4733:"f8d84f88",4763:"158719ed",4991:"c2965f87",5025:"6abf00de",5035:"2c2dd814",5077:"382fdf29",5089:"db40b3a8",5302:"8c1443cc",5328:"9e396004",5387:"0b46e8e7",5417:"5a7c4f09",5524:"2d6b2291",5543:"18a94246",5601:"3b467599",5705:"544f54cc",6103:"ccc49370",6125:"6facda94",6149:"84dd0cf8",6297:"1e7f5ce0",6424:"1e4c069f",6653:"db32d859",6676:"74c00f84",6807:"99c49682",6971:"c377a04b",7070:"ec8fd1ee",7120:"e954d700",7467:"91ce8bda",7495:"6f1f8c5f",7562:"8779ed83",7604:"2858c6ff",7746:"bd3d84fb",7791:"a71c3513",7846:"f40b13b8",7918:"17896441",7969:"7d3f2fdb",7972:"2ef0cd56",7975:"18961ce6",8056:"12da0170",8161:"67b45d3c",8381:"9fb2a6b1",8398:"8161b354",8581:"fdd3b45a",8648:"1f3523a7",8761:"7af80316",9313:"d0c5fcac",9514:"1be78505",9735:"4ba7e5a3",9834:"a413eb42",9924:"9e34dc04"}[e]||e)+"."+{14:"66a5572c",219:"95266e50",242:"a5b260a7",305:"a2ae9e74",689:"7c418579",819:"17ab72a1",865:"db06b1bc",959:"e03c2c3e",1016:"192fc8d5",1033:"2e4cb6f0",1158:"43dc6d1e",1221:"2e8af086",1327:"be8f5f8a",1525:"d2fb685d",1569:"225b3397",1599:"9ff2a1c6",1618:"acf34ec0",1742:"ae0ca484",1750:"76b4eeb3",1755:"1940342d",1773:"91b83c51",1869:"2879f364",1923:"685c10b2",1969:"9503586d",2206:"b9daba0d",2223:"5de71105",2276:"b9a2f709",2282:"98888d12",2585:"666a61ea",2594:"32702a53",2614:"bb67fb39",2702:"156d228f",2819:"3483b2d9",2982:"9d34232f",3089:"1ba90efa",3171:"6828597e",3228:"16e1379c",3231:"81bdca4f",3274:"55b53923",3415:"eeb2e4ba",3561:"4149cdd0",3607:"30efd6ee",3608:"da8266f8",3854:"c2807219",3877:"48ff094c",4046:"aecf4dbc",4248:"b508d506",4441:"7ada98a5",4545:"50c37ed8",4588:"0f505322",4633:"307d6307",4733:"3ca46756",4763:"3c6b3396",4991:"f1bf87c0",5025:"54330503",5035:"f4da87ca",5077:"fd7bbc15",5089:"46fb11a3",5253:"a56d7493",5302:"db36718a",5328:"0b7c31f9",5387:"64cdc00f",5417:"418f63c6",5524:"4c7453ec",5543:"db90dfd6",5601:"9aa43a76",5705:"3294a6c5",6103:"e69e3332",6125:"c662c386",6149:"1026aeae",6297:"02b3da0f",6316:"40c713ba",6424:"7b918630",6653:"d430742d",6676:"89ccce3e",6807:"9b6f6dd4",6971:"01e70aa4",7070:"0cebc1f4",7120:"03a8d5ee",7467:"f051f36a",7495:"58fc6f07",7562:"99f069ef",7604:"0dcb04b6",7724:"88bcb85f",7746:"41abb0be",7791:"0bc3e732",7846:"adeed3fd",7918:"4d3bb07c",7969:"422b0438",7972:"924206af",7975:"2d53c0b3",8056:"40efcc2d",8161:"b5eedc5b",8381:"3a473605",8398:"ec2956a6",8581:"999f5f0c",8648:"6f837535",8761:"98408c76",9313:"bad2fbf5",9481:"7b0f0e1a",9487:"d7c2aac6",9514:"f08cfc6c",9735:"e119e8dd",9834:"cbda4164",9924:"7a809e1c"}[e]+".js",r.miniCssF=e=>{},r.g=function(){if("object"==typeof globalThis)return globalThis;try{return this||new Function("return this")()}catch(e){if("object"==typeof window)return window}}(),r.o=(e,f)=>Object.prototype.hasOwnProperty.call(e,f),a={},c="vac-dev:",r.l=(e,f,d,b)=>{if(a[e])a[e].push(f);else{var t,o;if(void 0!==d)for(var n=document.getElementsByTagName("script"),i=0;i<n.length;i++){var l=n[i];if(l.getAttribute("src")==e||l.getAttribute("data-webpack")==c+d){t=l;break}}t||(o=!0,(t=document.createElement("script")).charset="utf-8",t.timeout=120,r.nc&&t.setAttribute("nonce",r.nc),t.setAttribute("data-webpack",c+d),t.src=e),a[e]=[f];var u=(f,d)=>{t.onerror=t.onload=null,clearTimeout(s);var c=a[e];if(delete a[e],t.parentNode&&t.parentNode.removeChild(t),c&&c.forEach((e=>e(d))),f)return f(d)},s=setTimeout(u.bind(null,void 0,{type:"timeout",target:t}),12e4);t.onerror=u.bind(null,t.onerror),t.onload=u.bind(null,t.onload),o&&document.head.appendChild(t)}},r.r=e=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},r.nmd=e=>(e.paths=[],e.children||(e.children=[]),e),r.p="/",r.gca=function(e){return e={17896441:"7918",83575890:"1525",96524732:"2982","191d05a9":"14","6f6bcf93":"242","384035e2":"305",bfd2a918:"689","2056d17e":"819","99f69f8e":"865","4a8210e4":"959",feda84cd:"1016",d758c4b4:"1033","29ae586d":"1158",db970d56:"1221",b6f6cb50:"1327","4f94ff0f":"1569","3f781295":"1599",b0a36ee8:"1618","84f8336a":"1742",e22c7a04:"1750","93541fc5":"1773",c8894de3:"1869","8c5da4da":"1923",cde6c892:"1969","124805df":"2206",f1787e6d:"2223",ad3e391a:"2276","3f64d9a3":"2282","2e8c87b8":"2585","15a93281":"2594",e6b418ad:"2614",c7770090:"2702","3f082616":"2819",a6aa9e1f:"3089","39f27fb8":"3171",f7ba2fd8:"3228",cbf8cf19:"3231","8e79cc52":"3274","13a255f1":"3415","95b96bb9":"3561","3ec022cb":"3607","9e4087bc":"3608","7b019678":"3854","7b0e1478":"3877",f643ab5d:"4046","0d54ff0d":"4248","38dc9501":"4441","500a151f":"4545",b8fd8041:"4588",f3c329e5:"4633",f8d84f88:"4733","158719ed":"4763",c2965f87:"4991","6abf00de":"5025","2c2dd814":"5035","382fdf29":"5077",db40b3a8:"5089","8c1443cc":"5302","9e396004":"5328","0b46e8e7":"5387","5a7c4f09":"5417","2d6b2291":"5524","18a94246":"5543","3b467599":"5601","544f54cc":"5705",ccc49370:"6103","6facda94":"6125","84dd0cf8":"6149","1e7f5ce0":"6297","1e4c069f":"6424",db32d859:"6653","74c00f84":"6676","99c49682":"6807",c377a04b:"6971",ec8fd1ee:"7070",e954d700:"7120","91ce8bda":"7467","6f1f8c5f":"7495","8779ed83":"7562","2858c6ff":"7604",bd3d84fb:"7746",a71c3513:"7791",f40b13b8:"7846","7d3f2fdb":"7969","2ef0cd56":"7972","18961ce6":"7975","12da0170":"8056","67b45d3c":"8161","9fb2a6b1":"8381","8161b354":"8398",fdd3b45a:"8581","1f3523a7":"8648","7af80316":"8761",d0c5fcac:"9313","1be78505":"9514","4ba7e5a3":"9735",a413eb42:"9834","9e34dc04":"9924"}[e]||e,r.p+r.u(e)},(()=>{var e={1303:0,532:0};r.f.j=(f,d)=>{var a=r.o(e,f)?e[f]:void 0;if(0!==a)if(a)d.push(a[2]);else if(/^(1303|532)$/.test(f))e[f]=0;else{var c=new Promise(((d,c)=>a=e[f]=[d,c]));d.push(a[2]=c);var b=r.p+r.u(f),t=new Error;r.l(b,(d=>{if(r.o(e,f)&&(0!==(a=e[f])&&(e[f]=void 0),a)){var c=d&&("load"===d.type?"missing":d.type),b=d&&d.target&&d.target.src;t.message="Loading chunk "+f+" failed.\n("+c+": "+b+")",t.name="ChunkLoadError",t.type=c,t.request=b,a[1](t)}}),"chunk-"+f,f)}},r.O.j=f=>0===e[f];var f=(f,d)=>{var a,c,b=d[0],t=d[1],o=d[2],n=0;if(b.some((f=>0!==e[f]))){for(a in t)r.o(t,a)&&(r.m[a]=t[a]);if(o)var i=o(r)}for(f&&f(d);n<b.length;n++)c=b[n],r.o(e,c)&&e[c]&&e[c][0](),e[c]=0;return r.O(i)},d=self.webpackChunkvac_dev=self.webpackChunkvac_dev||[];d.forEach(f.bind(null,0)),d.push=f.bind(null,d.push.bind(d))})()})(); \ No newline at end of file diff --git a/build.json b/build.json index 4e64addf..9a8c6067 100644 --- a/build.json +++ b/build.json @@ -1,15 +1,15 @@ { - "timestamp": "2024-08-27T15:37:29Z", + "timestamp": "2024-09-30T15:58:27Z", "git": { - "commit": "253ede81ea727e1071f55adf41e554ce87ca05e6", + "commit": "9119b798a6382d32517c779804a80c30da3a3963", "branch": "origin/master", "url": "git@github.com:vacp2p/vac.dev.git" }, "build": { - "id": "4340", - "number": "4340", + "id": "4341", + "number": "4341", "name": "website/vac.dev", - "slave": "linux-02", - "url": "https://ci.infra.status.im/job/website/job/vac.dev/4340/" + "slave": "linux-01", + "url": "https://ci.infra.status.im/job/website/job/vac.dev/4341/" } } \ No newline at end of file diff --git a/community/index.html b/community/index.html index 66e3f92c..7ec26d97 100644 --- a/community/index.html +++ b/community/index.html @@ -10,8 +10,8 @@ <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/katex@0.13.24/dist/katex.min.css" integrity="sha384-odtC+0UGzzFL/6PNoE8rX/SPcQDXBJ+uRepguP4QkPCm2LBxH3FA3y+fKSiJ+AmM" crossorigin="anonymous"><link rel="stylesheet" href="/assets/css/styles.08d697e6.css"> -<link rel="preload" href="/assets/js/runtime~main.556fa6f5.js" as="script"> -<link rel="preload" href="/assets/js/main.ffc20c94.js" as="script"> +<link rel="preload" href="/assets/js/runtime~main.a9103199.js" as="script"> +<link rel="preload" href="/assets/js/main.5454aec3.js" as="script"> <meta property="og:image" content="https://vac.dev/_og/2c73972e891926e787c283280001cad7293ae28e.png"><meta name="twitter:image" content="https://vac.dev/_og/2c73972e891926e787c283280001cad7293ae28e.png"></head> <body class="navigation-with-keyboard"> <script>!function(){function e(e){document.documentElement.setAttribute("data-theme",e)}var t=function(){var e=null;try{e=new URLSearchParams(window.location.search).get("docusaurus-theme")}catch(e){}return e}()||function(){var e=null;try{e=localStorage.getItem("theme")}catch(e){}return e}();null!==t?e(t):window.matchMedia("(prefers-color-scheme: dark)").matches?e("dark"):window.matchMedia("(prefers-color-scheme: light)").matches?e("light"):e("dark")}()</script><div id="__docusaurus"> @@ -20,7 +20,7 @@ ) .lsd-dropdown__trigger:hover .lsd-dropdown__option-label,.lsd-dropdown:not(.lsd-dropdown--disabled):not( .lsd-dropdown--error ) .lsd-dropdown__trigger:focus .lsd-dropdown__option-label{-webkit-text-decoration:underline;text-decoration:underline;}.lsd-dropdown__label{display:block;}.lsd-dropdown__button-container{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-box-pack:justify;-webkit-justify-content:space-between;justify-content:space-between;}.lsd-dropdown__trigger{width:100%;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:row;-ms-flex-direction:row;flex-direction:row;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:justify;-webkit-justify-content:space-between;justify-content:space-between;border:none;cursor:pointer;background:none;}.lsd-dropdown__trigger:focus{outline:none;}.lsd-dropdown__option-label{cursor:inherit;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;}.lsd-dropdown__icons{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:row;-ms-flex-direction:row;flex-direction:row;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:center;-ms-flex-pack:center;-webkit-justify-content:center;justify-content:center;gap:8px;}.lsd-dropdown__icon{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;}.lsd-dropdown__supporting-text{margin:6px 14px;}.lsd-dropdown--error .lsd-dropdown__option-label{-webkit-text-decoration:line-through;text-decoration:line-through;}.lsd-dropdown--disabled{opacity:0.34;cursor:initial;}.lsd-dropdown--large{width:208px;}.lsd-dropdown--large.lsd-dropdown--error{width:230px;}.lsd-dropdown--large .lsd-dropdown__label{margin:0 0 6px 18px;}.lsd-dropdown--large .lsd-dropdown__button-container{height:40px;}.lsd-dropdown--large .lsd-dropdown__trigger{padding:10px 0px 10px 18px;}.lsd-dropdown--large .lsd-dropdown__icons{padding:0px 14px;}.lsd-dropdown--medium{width:188px;}.lsd-dropdown--medium.lsd-dropdown--error{width:210px;}.lsd-dropdown--medium .lsd-dropdown__label{margin:0 0 6px 14px;}.lsd-dropdown--medium .lsd-dropdown__button-container{height:32px;}.lsd-dropdown--medium .lsd-dropdown__trigger{padding:6px 0px 6px 14px;}.lsd-dropdown--medium .lsd-dropdown__icons{padding:0px 12px;}.lsd-dropdown--small{width:164px;}.lsd-dropdown--small.lsd-dropdown--error{width:186px;}.lsd-dropdown--small .lsd-dropdown__label{margin:0 0 6px 12px;}.lsd-dropdown--small .lsd-dropdown__button-container{height:28px;}.lsd-dropdown--small .lsd-dropdown__trigger{padding:6px 0px 6px 12px;}.lsd-dropdown--small .lsd-dropdown__icons{padding:0px 10px;}.lsd-dropdown--outlined .lsd-dropdown__button-container{border:1px solid rgb(var(--lsd-border-primary));}.lsd-dropdown--underlined .lsd-dropdown__button-container{border:1px solid transparent;border-bottom:1px solid rgb(var(--lsd-border-primary));}</style><style data-emotion="css-global w2g5fy">.lsd-dropdown-item{width:100%;box-sizing:border-box;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:row;-ms-flex-direction:row;flex-direction:row;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;border:1px solid rgb(var(--lsd-border-primary));}.lsd-dropdown-item:not(.lsd-dropdown-item--disabled){cursor:pointer;}.lsd-dropdown-item:not(.lsd-dropdown-item--disabled):hover,.lsd-dropdown-item:not(.lsd-dropdown-item--disabled):focus{outline:none;}.lsd-dropdown-item:not(.lsd-dropdown-item--disabled):hover .lsd-dropdown-item__label,.lsd-dropdown-item:not(.lsd-dropdown-item--disabled):focus .lsd-dropdown-item__label{-webkit-text-decoration:underline;text-decoration:underline;}.lsd-dropdown-item__label{display:block;overflow:hidden;white-space:nowrap;text-overflow:ellipsis;}.lsd-dropdown-item--disabled{opacity:0.34;}.lsd-dropdown-item__icon{margin-right:18px;-webkit-flex-shrink:0;-ms-flex-negative:0;flex-shrink:0;}.lsd-dropdown-item--small{padding:5px 9px;height:28px;}.lsd-dropdown-item--medium{padding:5px 11px;height:32px;}.lsd-dropdown-item--large{padding:5px 13px;height:40px;}</style><style data-emotion="css-global ww9kgc">.lsd-breadcrumb__list{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:row;-ms-flex-direction:row;flex-direction:row;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;list-style-type:none;margin:0;padding:0;}.lsd-breadcrumb--disabled .lsd-breadcrumb__list{opacity:0.34;cursor:initial;pointer-events:none;}.lsd-breadcrumb__dropdown-menu{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column;overflow:auto;border:1px solid rgb(var(--lsd-border-primary));margin-top:10px;position:absolute;width:auto!important;}.lsd-breadcrumb__dropdown-menu>li{cursor:pointer;}.lsd-breadcrumb__dropdown-menu>li:not(:last-child){border-bottom:1px solid rgb(var(--lsd-border-primary));}.lsd-breadcrumb__dropdown-menu>li:hover,.lsd-breadcrumb__dropdown-menu>li:focus{-webkit-text-decoration:underline;text-decoration:underline;text-decoration-color:rgb(var(--lsd-border-primary));}.lsd-breadcrumb__dropdown-menu li>a{width:164px;padding:5px 11px;}</style><style data-emotion="css-global 4gvini">.lsd-breadcrumb-item{list-style-type:none;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;}.lsd-breadcrumb__list>li:not(:last-child)::after{display:inline-block;margin-inline:12px;content:'/';}.lsd-breadcrumb-item__link{-webkit-text-decoration:none;text-decoration:none;cursor:pointer;}.lsd-breadcrumb-item--outlined{padding:3px 11px;border:1px solid rgb(var(--lsd-border-primary));}.lsd-breadcrumb:not(.lsd-breadcrumb--disabled) .lsd-breadcrumb-item__link:hover,.lsd-breadcrumb:not(.lsd-breadcrumb--disabled) .lsd-breadcrumb-item__link:focus{-webkit-text-decoration:underline;text-decoration:underline;text-decoration-color:rgb(var(--lsd-border-primary));}</style><style data-emotion="css-global 1cwg3oc">.lsd-card{box-sizing:border-box;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column;}.lsd-card>.lsd-card-header{margin-bottom:-1px;}</style><style data-emotion="css-global v7d76i">.lsd-card-header{box-sizing:border-box;padding:10px 18px;text-align:center;border:1px solid rgb(var(--lsd-border-primary));}.lsd-card-header__title{overflow:hidden;word-break:break-all;}.lsd-card-header--large{padding:10px 18px;}.lsd-card-header--medium{padding:6px 14px;}.lsd-card-header--small{padding:6px 12px;}</style><style data-emotion="css-global 1txgafh">.lsd-card-body{box-sizing:border-box;padding:14px 22px;border:1px solid rgb(var(--lsd-border-primary));}</style><style data-emotion="css-global kzy52c">.lsd-tag{width:-webkit-fit-content;width:-moz-fit-content;width:fit-content;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:row;-ms-flex-direction:row;flex-direction:row;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:center;-ms-flex-pack:center;-webkit-justify-content:center;justify-content:center;box-sizing:border-box;border:1px solid rgb(var(--lsd-icon-primary));}.lsd-tag:hover,.lsd-tag:focus{-webkit-text-decoration:underline;text-decoration:underline;cursor:pointer;}.lsd-badge--large{padding:3px 11px;gap:12px;height:28px;}.lsd-badge--small{padding:3px 7px;gap:8px;height:24px;}.lsd-tag--filled{background-color:rgb(var(--lsd-icon-primary));}.lsd-tag--filled .lsd-tag__label{color:rgb(var(--lsd-text-secondary));}.lsd-tag--filled svg{--lsd-icon-primary:var(--lsd-icon-secondary);}.lsd-tag--outlined{color:rgb(var(--lsd-text-primary));}.lsd-tag--disabled{opacity:0.3;cursor:initial;pointer-events:none;}</style><style data-emotion="css-global 4wy0ub">.lsd-text-field{box-sizing:border-box;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column;}.lsd-text-field__input-container{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:justify;-webkit-justify-content:space-between;justify-content:space-between;}.lsd-text-field--disabled{opacity:0.34;}.lsd-text-field__input{border:none;outline:none;font-size:14px;color:rgb(var(--lsd-text-primary));background:none;width:100%;}.lsd-text-field__input:hover{outline:none;}.lsd-text-field__input::-webkit-input-placeholder{color:rgb(var(--lsd-text-primary));opacity:0.3;}.lsd-text-field__input::-moz-placeholder{color:rgb(var(--lsd-text-primary));opacity:0.3;}.lsd-text-field__input:-ms-input-placeholder{color:rgb(var(--lsd-text-primary));opacity:0.3;}.lsd-text-field__input::placeholder{color:rgb(var(--lsd-text-primary));opacity:0.3;}.lsd-text-field--error .lsd-text-field__input{-webkit-text-decoration:line-through;text-decoration:line-through;}.lsd-text-field__supporting-text{width:-webkit-fit-content;width:-moz-fit-content;width:fit-content;}.lsd-text-field--large{width:208px;}.lsd-text-field--large>*{padding:10px 14px 10px 18px;}.lsd-text-field--medium{width:188px;}.lsd-text-field--medium>*{padding:6px 12px 6px 14px;}.lsd-text-field--small{width:164px;}.lsd-text-field--small>*{padding:6px 10px 6px 12px;}.lsd-text-field__label{padding-top:0;padding-bottom:6px;}.lsd-text-field__supporting-text{padding-bottom:0;padding-top:6px;}.lsd-text-field--outlined .lsd-text-field__input-container{border:1px solid rgb(var(--lsd-border-primary));}.lsd-text-field--underlined .lsd-text-field__input-container{border:1px solid transparent;border-bottom:1px solid rgb(var(--lsd-border-primary));}.lsd-text-field__clear-button{padding:0;width:auto;height:auto;margin:0;border:0;}</style><style data-emotion="css-global uhig7c">.lsd-checkbox{position:relative;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:row;-ms-flex-direction:row;flex-direction:row;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;}.lsd-checkbox__input{opacity:0;position:absolute;left:0;top:0;padding:0;margin:0;width:100%;height:100%;}.lsd-checkbox:not(.lsd-checkbox--disabled):hover,.lsd-checkbox:not(.lsd-checkbox--disabled).lsd-checkbox--focused{-webkit-text-decoration:underline;text-decoration:underline;}.lsd-checkbox:not(.lsd-checkbox--disabled) .lsd-checkbox__input{cursor:pointer;}.lsd-checkbox--disabled{opacity:0.34;}.lsd-checkbox__label{margin-left:18px;}.lsd-checkbox--large .lsd-checkbox__label{margin-left:18px;}.lsd-checkbox--medium .lsd-checkbox__label{margin-left:14px;}.lsd-checkbox--small .lsd-checkbox__label{margin-left:12px;}</style><style data-emotion="css-global txommo">.lsd-autocomplete{box-sizing:border-box;}.lsd-autocomplete__label{display:block;}.lsd-autocomplete__input-container{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-box-pack:justify;-webkit-justify-content:space-between;justify-content:space-between;}.lsd-autocomplete--disabled{opacity:0.34;}.lsd-autocomplete__input{border:none;outline:none;font-size:14px;color:rgb(var(--lsd-text-primary));background:none;width:100%;}.lsd-autocomplete__input:hover{outline:none;}.lsd-autocomplete__input::-webkit-input-placeholder{color:rgb(var(--lsd-text-primary));opacity:0.3;}.lsd-autocomplete__input::-moz-placeholder{color:rgb(var(--lsd-text-primary));opacity:0.3;}.lsd-autocomplete__input:-ms-input-placeholder{color:rgb(var(--lsd-text-primary));opacity:0.3;}.lsd-autocomplete__input::placeholder{color:rgb(var(--lsd-text-primary));opacity:0.3;}.lsd-autocomplete__icon{cursor:pointer;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;}.lsd-autocomplete--error{-webkit-text-decoration:line-through;text-decoration:line-through;}.lsd-autocomplete--large{width:208px;}.lsd-autocomplete--large .lsd-autocomplete__label{margin:0 0 6px 18px;}.lsd-autocomplete--large .lsd-autocomplete__input-container{height:40px;}.lsd-autocomplete--large .lsd-autocomplete__input{padding:9px 17px;}.lsd-autocomplete--large .lsd-autocomplete__icon{padding:12px 13px;}.lsd-autocomplete--medium{width:188px;}.lsd-autocomplete--medium .lsd-autocomplete__label{margin:0 0 6px 14px;}.lsd-autocomplete--medium .lsd-autocomplete__input-container{height:32px;}.lsd-autocomplete--medium .lsd-autocomplete__input{padding:5px 13px;}.lsd-autocomplete--medium .lsd-autocomplete__icon{padding:8px 11px;}.lsd-autocomplete--small{width:164px;}.lsd-autocomplete--small .lsd-autocomplete__label{margin:0 0 6px 12px;}.lsd-autocomplete--small .lsd-autocomplete__input-container{height:28px;}.lsd-autocomplete--small .lsd-autocomplete__input{padding:5px 11px;}.lsd-autocomplete--small .lsd-autocomplete__icon{padding:6px 9px;}.lsd-autocomplete--outlined .lsd-autocomplete__input-container{border:1px solid rgb(var(--lsd-border-primary));}.lsd-autocomplete--underlined .lsd-autocomplete__input-container{border:1px solid transparent;border-bottom:1px solid rgb(var(--lsd-border-primary));}.lsd-autocomplete__dropdown-item-placeholder{opacity:0.5;white-space:pre;}</style><style data-emotion="css-global quxxm6">.lsd-quote{color:rgb(var(--lsd-text-primary));white-space:pre-wrap;}.lsd-quote--indented-inline{border-left:1px solid rgb(var(--lsd-border-primary));padding:4px 8px 4px 28px;}.lsd-quote--parentheses{padding:0px;text-align:center;}.lsd-quote--parentheses::before{content:'***';}.lsd-quote--parentheses::after{content:'***';}</style><style data-emotion="css-global a49t4h">.lsd-collapse{box-sizing:border-box;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column;}.lsd-collapse--open .lsd-collapse__content{border-top:1px solid transparent;}.lsd-collapse__content{border:1px solid rgb(var(--lsd-border-primary));}</style><style data-emotion="css-global 12ppw0q">.lsd-collapse-header{box-sizing:border-box;}.lsd-collapse-header:not(.lsd-collapse-header--disabled) .lsd-collapse-header__trigger:hover .lsd-collapse-header__label{-webkit-text-decoration:underline;text-decoration:underline;}.lsd-collapse-header__trigger{width:100%;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:row;-ms-flex-direction:row;flex-direction:row;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:justify;-webkit-justify-content:space-between;justify-content:space-between;cursor:pointer;background:none;border:1px solid rgb(var(--lsd-border-primary));}.lsd-collapse-header__trigger:focus{outline:none;}.lsd-collapse-header__label{cursor:inherit;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;margin:auto;}.lsd-collapse-header__icons{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:row;-ms-flex-direction:row;flex-direction:row;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:end;-ms-flex-pack:end;-webkit-justify-content:flex-end;justify-content:flex-end;}.lsd-collapse-header__icon{margin-right:8px;}.lsd-collapse-header--disabled .lsd-collapse-header__trigger{opacity:0.34;cursor:initial;}.lsd-collapse-header--large .lsd-collapse-header__trigger{width:299px;height:40px;padding:9px 17px;}.lsd-collapse-header--medium .lsd-collapse-header__trigger{width:270px;height:32px;padding:5px 13px;}.lsd-collapse-header--small .lsd-collapse-header__trigger{width:235px;height:28px;padding:5px 11px;}</style><style data-emotion="css-global dixc0i">.lsd-checkbox-group{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column;gap:6px;width:-webkit-fit-content;width:-moz-fit-content;width:fit-content;}.lsd-checkbox-group__label{margin-bottom:6px;}</style><style data-emotion="css-global q2n2hz">.lsd-badge{width:-webkit-fit-content;width:-moz-fit-content;width:fit-content;box-sizing:border-box;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:row;-ms-flex-direction:row;flex-direction:row;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:center;-ms-flex-pack:center;-webkit-justify-content:center;justify-content:center;border:1px solid rgb(var(--lsd-icon-primary));border-radius:20px;}.lsd-badge:hover,.lsd-badge:focus{-webkit-text-decoration:underline;text-decoration:underline;cursor:pointer;}.lsd-badge--large{padding:3px 11px;gap:12px;height:28px;}.lsd-badge--small{padding:3px 7px;gap:8px;height:24px;}.lsd-badge--filled{background-color:rgb(var(--lsd-icon-primary));}.lsd-badge--filled .lsd-badge__label{color:rgb(var(--lsd-text-secondary));}.lsd-badge--filled svg{--lsd-icon-primary:var(--lsd-icon-secondary);}.lsd-badge--outlined{color:rgb(var(--lsd-text-primary));}.lsd-badge--disabled{opacity:0.3;cursor:initial;pointer-events:none;}</style><style data-emotion="css-global rlst54">.lsd-radio-button{position:relative;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:row;-ms-flex-direction:row;flex-direction:row;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;}.lsd-radio-button__input{opacity:0;position:absolute;left:0;top:0;padding:0;margin:0;width:100%;height:100%;}.lsd-radio-button:not(.lsd-radio-button--disabled):hover{-webkit-text-decoration:underline;text-decoration:underline;}.lsd-radio-button:not(.lsd-radio-button--disabled) .lsd-radio-button__input{cursor:pointer;}.lsd-radio-button--disabled{opacity:0.34;}.lsd-radio-button__label{margin-left:18px;}.lsd-radio-button--large .lsd-radio-button__label{margin-left:18px;}.lsd-radio-button--medium .lsd-radio-button__label{margin-left:14px;}.lsd-radio-button--small .lsd-radio-button__label{margin-left:12px;}</style><style data-emotion="css-global mo7h6o">.lsd-radio-button-group{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column;gap:6px;width:-webkit-fit-content;width:-moz-fit-content;width:fit-content;}.lsd-radio-button-group__label{margin-bottom:6px;}</style><style data-emotion="css-global amncrr">.lsd-table{box-sizing:border-box;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column;}.lsd-table>.lsd-table-header{margin-bottom:-1px;}</style><style data-emotion="css-global 1fkbozr">.lsd-table-header{box-sizing:border-box;border:1px solid rgb(var(--lsd-border-primary));}</style><style data-emotion="css-global 1fb1r54">.lsd-table-body table{border-collapse:collapse;text-align:center;table-layout:fixed;width:100%;height:auto;}.lsd-table-body table tr:first-of-type td label:has(input[type='radio']){display:none;}.lsd-table-body__toolbar{box-sizing:border-box;padding:10px;border:1px solid rgb(var(--lsd-border-primary));border-bottom:none;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-box-pack:justify;-webkit-justify-content:space-between;justify-content:space-between;}</style><style data-emotion="css-global 607rj8">.lsd-table-item{border:1px solid rgb(var(--lsd-border-primary));}.lsd-table-item:has(> label){width:40px;}.lsd-table-item:has(> label) input{position:relative;width:14px;height:14px;margin:auto;}.lsd-table-item:has(> label) span{margin-left:14px!important;}.lsd-table-item--large{padding:10px;}.lsd-table-item--medium{padding:6px 8px;}.lsd-table-item--small{padding:6px;}</style><style data-emotion="css-global 1vlh57l">.lsd-table-row{-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;}</style><style data-emotion="css-global 1fw5y3v">.lsd-number-input{width:auto;box-sizing:border-box;}.lsd-number-input__main-container:hover{-webkit-text-decoration:underline;text-decoration:underline;}.lsd-number-input--error .lsd-number-input__main-container{-webkit-text-decoration:line-through;text-decoration:line-through;}.lsd-number-input__label{display:block;}.lsd-number-input__plus-minus-icons{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-shrink:0;-ms-flex-negative:0;flex-shrink:0;}.lsd-number-input__input-container{box-sizing:border-box;border:1px solid rgb(var(--lsd-border-primary));border-left:0px;border-right:0px;}.lsd-number-input__error-icon{cursor:pointer;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;padding:10px 8px;}.lsd-number-input__input-container{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:justify;-webkit-justify-content:space-between;justify-content:space-between;}.lsd-number-input--disabled{opacity:0.34;}.lsd-number-input__main-container{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;}.lsd-number-input__input{border:none;outline:none;font-size:14px;color:rgb(var(--lsd-text-primary));background:none;text-align:center;padding:0 4px;}.lsd-number-input__input::-webkit-inner-spin-button{display:none;-webkit-appearance:none;}.lsd-number-input__input:hover{outline:none;}.lsd-number-input__supporting-text{position:absolute;}.lsd-number-input--large .lsd-number-input__label{margin:0 0 6px 18px;}.lsd-number-input--large .lsd-number-input__input-container{height:40px;}.lsd-number-input--large .lsd-number-input__input{width:62px;}.lsd-number-input--large .lsd-number-input__plus-minus-icons{height:40px;width:40px;}.lsd-number-input--large .lsd-number-input__supporting-text{margin:6px 18px 0 18px;}.lsd-number-input--medium .lsd-number-input__label{margin:0 0 6px 14px;}.lsd-number-input--medium .lsd-number-input__input-container{height:32px;}.lsd-number-input--medium .lsd-number-input__input{width:58px;}.lsd-number-input--medium .lsd-number-input__plus-minus-icons{height:32px;width:32px;}.lsd-number-input--medium .lsd-number-input__supporting-text{margin:6px 14px 0 14px;}.lsd-number-input--small .lsd-number-input__label{margin:0 0 6px 12px;}.lsd-number-input--small .lsd-number-input__input-container{height:28px;}.lsd-number-input--small .lsd-number-input__input{width:50px;}.lsd-number-input--small .lsd-number-input__plus-minus-icons{height:28px;width:28px;}.lsd-number-input--small .lsd-number-input__supporting-text{margin:6px 12px 0 12px;}</style><style data-emotion="css-global 12rmo7o">.lsd-modal{box-sizing:border-box;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column;position:fixed;top:0;left:0;right:0;bottom:0;background-color:rgba(0, 0, 0, 0.5);display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-box-pack:center;-ms-flex-pack:center;-webkit-justify-content:center;justify-content:center;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;z-index:9999;}.lsd-modal__container{position:relative;background:rgb(var(--lsd-surface-primary));padding:20px;max-width:90%;box-sizing:border-box;border:1px solid rgb(var(--lsd-border-primary));}.lsd-modal__header{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-box-pack:justify;-webkit-justify-content:space-between;justify-content:space-between;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;}.lsd-modal__close-icon{position:absolute;top:8px;right:8px;cursor:pointer;}.lsd-modal__title-and-subtitle-container{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column;}.lsd-modal--large .lsd-modal__container{min-width:960px;}.lsd-modal--medium .lsd-modal__container{min-width:768px;}.lsd-modal--small .lsd-modal__container{min-width:614px;}.lsd-modal--extra-small .lsd-modal__container{min-width:490px;}</style><style data-emotion="css-global 1k7gzc">.lsd-modal-footer{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;}</style><style data-emotion="css-global 1b9t8so">.lsd-modal-body{margin:18px 0;}</style><style data-emotion="css-global dyud2a">.lsd-date-picker{width:-webkit-fit-content;width:-moz-fit-content;width:fit-content;}.lsd-date-picker__calendar{border-top:none!important;}.lsd-date-picker--large .lsd-date-field--large{width:318px;}.lsd-date-picker--medium .lsd-date-field--medium{width:290px;}.lsd-date-picker--small .lsd-date-field--small{width:262px;}</style><style data-emotion="css-global olq3nk">.lsd-date-field{width:auto;box-sizing:border-box;}.lsd-date-field__label{display:block;}.lsd-date-field__input-container__icon{position:absolute;right:0;cursor:pointer;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;background-color:rgb(var(--lsd-surface-primary));}.lsd-date-field__input-container__icon:focus{background:blue;background-color:pink;border:1px solid rgb(var(--lsd-border-primary));}.lsd-date-field__input-container__no-icon{position:absolute;right:0;background-color:rgb(var(--lsd-surface-primary));padding:12px;}.lsd-date-field--outlined{border:1px solid rgb(var(--lsd-border-primary));}.lsd-date-field--underlined{border-bottom:1px solid rgb(var(--lsd-border-primary));}.lsd-date-field__input-container{position:relative;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:justify;-webkit-justify-content:space-between;justify-content:space-between;}.lsd-date-field--disabled{opacity:0.34;}.lsd-date-field__input-container__input{border:none;outline:none;font-size:14px;color:rgb(var(--lsd-text-primary));background:none;width:100%;opacity:0.4;-webkit-transition:opacity 0.2s ease-in-out;transition:opacity 0.2s ease-in-out;}.lsd-date-field__input-container__input::-webkit-inner-spin-button,.lsd-date-field__input-container__input::-webkit-calendar-picker-indicator{display:none;-webkit-appearance:none;}.lsd-date-field__input-container__input:hover{outline:none;}.lsd-date-field__supporting-text{position:absolute;}.lsd-date-field--large{width:208px;}.lsd-date-field--large .lsd-date-field__label{margin:0 0 6px 18px;}.lsd-date-field--large .lsd-date-field__input-container{height:40px;}.lsd-date-field--large .lsd-date-field__input-container__input{padding:9px 0px 9px 17px;}.lsd-date-field--large .lsd-date-field__input-container__icon{padding:12px 13px;}.lsd-date-field--large .lsd-date-field__supporting-text{margin:6px 18px 0 18px;}.lsd-date-field--medium{width:188px;}.lsd-date-field--medium .lsd-date-field__label{margin:0 0 6px 14px;}.lsd-date-field--medium .lsd-date-field__input-container{height:32px;}.lsd-date-field--medium .lsd-date-field__input-container__input{padding:5px 11px 5px 13px;}.lsd-date-field--medium .lsd-date-field__input-container__icon{padding:8px 11px;}.lsd-date-field--medium .lsd-date-field__supporting-text{margin:6px 14px 0 14px;}.lsd-date-field--small{width:164px;}.lsd-date-field--small .lsd-date-field__label{margin:0 0 6px 12px;}.lsd-date-field--small .lsd-date-field__input-container{height:28px;}.lsd-date-field--small .lsd-date-field__input-container__input{padding:5px 9px 5px 11px;font-size:12px;}.lsd-date-field--small .lsd-date-field__input-container__icon{padding:6px 9px;}.lsd-date-field--small .lsd-date-field__supporting-text{margin:6px 12px 0 12px;}.lsd-date-field__input-container__input:invalid,.lsd-date-field__input-container__input--filled{color:rgb(var(--lsd-border-primary));opacity:1;}.lsd-date-field--error .lsd-date-field__input-container__input::-webkit-datetime-edit-year-field,.lsd-date-field--error .lsd-date-field__input-container__input::-webkit-datetime-edit-month-field,.lsd-date-field--error .lsd-date-field__input-container__input::-webkit-datetime-edit-day-field{-webkit-text-decoration:line-through;text-decoration:line-through;}@supports not selector(::-webkit-datetime-edit-day-field){.lsd-date-field--error .lsd-date-field__input-container__input{-webkit-text-decoration:line-through;text-decoration:line-through;}}</style><style data-emotion="css-global 1gjtao4">.lsd-calendar{border:1px solid rgb(var(--lsd-border-primary));visibility:hidden;position:absolute!important;top:0;left:0;opacity:0;visibility:hidden;margin:0;padding:0;box-sizing:border-box;background:rgb(var(--lsd-surface-primary));-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;}.lsd-calendar-container{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column;padding:8px;}.lsd-calendar--open{opacity:1;visibility:visible;}.lsd-calendar-header{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-box-pack:center;-ms-flex-pack:center;-webkit-justify-content:center;justify-content:center;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;height:32px;margin-bottom:8px;}.lsd-calendar__week_day{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-box-pack:center;-ms-flex-pack:center;-webkit-justify-content:center;justify-content:center;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;aspect-ratio:1/1;margin-bottom:4px;}.lsd-calendar__change-year{position:relative;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-box-pack:center;-ms-flex-pack:center;-webkit-justify-content:center;justify-content:center;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;padding:2px 0xp 2px 8px;gap:6px;border:1px solid transparent;}.lsd-calendar__change-year--active .lsd-calendar__year-and-icon{border:1px solid rgb(var(--lsd-border-primary));}.lsd-calendar__change-year-icon-container{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-box-pack:center;-ms-flex-pack:center;-webkit-justify-content:center;justify-content:center;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;cursor:pointer;border:none;}.lsd-calendar-month{margin-right:8px;}.lsd-calendar__month-and-year{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:center;-ms-flex-pack:center;-webkit-justify-content:center;justify-content:center;}.lsd-calendar-day__container{cursor:pointer;background:transparent;position:relative;box-sizing:border-box;border:1px solid transparent;}.lsd-calendar-day{aspect-ratio:1/1;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-box-pack:center;-ms-flex-pack:center;-webkit-justify-content:center;justify-content:center;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;}.lsd-calendar-day:hover{cursor:pointer;-webkit-text-decoration:underline;text-decoration:underline;text-decoration-color:rgb(var(--lsd-border-primary));}.lsd-calendar-day label:hover{cursor:pointer;}.lsd-calendar-day--selected{border:1px solid rgb(var(--lsd-border-primary));}.lsd-calendar-day--disabled{opacity:0.3;cursor:default;}.lsd-calendar-day__today_indicator{position:absolute;left:50%;-webkit-transform:translateX(-50%);-moz-transform:translateX(-50%);-ms-transform:translateX(-50%);transform:translateX(-50%);bottom:2px;}.lsd-calendar--disabled{pointer-events:none;border:1px solid rgba(var(--lsd-border-primary), 0.3);}.lsd-calendar--disabled label{opacity:0.3;}.lsd-calendar--disabled .lsd-calendar__button{opacity:0.3;}.lsd-calendar--disabled .lsd-calendar-day--selected{opacity:0.3;}.lsd-calendar__button{border:1px solid rgb(var(--lsd-border-primary));cursor:pointer;background:transparent;width:32px;height:32px;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:center;-ms-flex-pack:center;-webkit-justify-content:center;justify-content:center;position:absolute;}.lsd-calendar__next-month-button{top:8px;right:8px;}.lsd-calendar__previous-month-button{top:8px;left:8px;}.lsd-calendar-day--border-left{border-left:1px double rgb(var(--lsd-border-primary));}.lsd-calendar-day--border-right{border-right:1px double rgb(var(--lsd-border-primary));}.lsd-calendar-day--border-left-and-right{border-left:1px double rgb(var(--lsd-border-primary));border-right:1px double rgb(var(--lsd-border-primary));}.lsd-calendar-day--border-top-and-bottom{border-top:1px double rgb(var(--lsd-border-primary));border-bottom:1px double rgb(var(--lsd-border-primary));}.lsd-calendar__month-table{border-collapse:collapse;}.lsd-calendar__year-dropdown{box-sizing:border-box;position:absolute;top:100%;left:0;max-height:200px;overflow-y:auto;width:100%;border:1px solid rgb(var(--lsd-border-primary));border-top:none;z-index:1;}.lsd-calendar__year-dropdown .lsd-calendar-year{border-bottom:1px solid rgb(var(--lsd-border-primary));}.lsd-calendar__year-dropdown--hidden{visibility:hidden;}.lsd-calendar-year{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;cursor:pointer;-webkit-transition:background-color 0.2s;transition:background-color 0.2s;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;background:rgb(var(--lsd-surface-primary));}.lsd-calendar-year:hover{-webkit-text-decoration:underline;text-decoration:underline;}.lsd-calendar__year-and-icon{border:1px solid rgb(var(--lsd-border-primary));}.lsd-calendar--large .lsd-calendar-year{padding:6px 0px 6px 14px;}.lsd-calendar--large .lsd-calendar__change-year-icon-container{width:32px;}.lsd-calendar--medium .lsd-calendar-year{padding:6px 0px 6px 12px;}.lsd-calendar--medium .lsd-calendar__change-year-icon-container{width:28px;}.lsd-calendar--small .lsd-calendar-year{padding:6px 0px 6px 12px;}.lsd-calendar--small .lsd-calendar__change-year-icon-container{width:28px;}</style><style data-emotion="css-global dlrd7d">.lsd-toast{box-sizing:border-box;display:-webkit-inline-box;display:-webkit-inline-flex;display:-ms-inline-flexbox;display:inline-flex;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;background:rgb(var(--lsd-surface-primary));border:1px solid rgb(var(--lsd-border-primary));padding:8px;height:-webkit-fit-content;height:-moz-fit-content;height:fit-content;}.lsd-toast__inline-button-container{-webkit-flex-shrink:0;-ms-flex-negative:0;flex-shrink:0;}.lsd-toast__column-button-container{margin-top:18px;margin-bottom:6px;}.lsd-toast__inline-container{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:justify;-webkit-justify-content:space-between;justify-content:space-between;-webkit-box-flex:1;-webkit-flex-grow:1;-ms-flex-positive:1;flex-grow:1;}.lsd-toast__column-container{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column;-webkit-box-pack:justify;-webkit-justify-content:space-between;justify-content:space-between;}.lsd-toast__text-container{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column;color:rgb(var(--lsd-text-secondary));padding-left:12px;}.lsd-toast__title{position:relative;}.lsd-toast__information{margin-top:4px;}.lsd-toast__button-container{min-height:28px;min-width:60px;width:-webkit-fit-content;width:-moz-fit-content;width:fit-content;padding:0px 12px;}.lsd-toast__close-button{margin-bottom:auto;-webkit-flex-shrink:0;-ms-flex-negative:0;flex-shrink:0;height:28px;width:28px;margin-left:auto;}.lsd-toast__column-icon-container{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-box-pack:center;-ms-flex-pack:center;-webkit-justify-content:center;justify-content:center;margin-bottom:auto;position:relative;top:4px;padding-left:4px;}.lsd-toast__inline-icon-container{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:center;-ms-flex-pack:center;-webkit-justify-content:center;justify-content:center;padding-left:4px;}.lsd-toast__icon{position:relative;}.lsd-toast--large{width:364px;}.lsd-toast--medium{width:336px;}.lsd-toast--small{width:296px;}.lsd-toast--small .lsd-toast__icon{top:0px;}</style><style data-emotion="css-global 5wlfwk">.lsd-toast-provider__toast-container{position:fixed;-webkit-transition:all 230ms cubic-bezier(0.21, 1.02, 0.73, 1);transition:all 230ms cubic-bezier(0.21, 1.02, 0.73, 1);z-index:9999;}.lsd-toast-provider__toast--top-left,.lsd-toast-provider__toast--top-center,.lsd-toast-provider__toast--top-right{top:0;}.lsd-toast-provider__toast--bottom-left,.lsd-toast-provider__toast--bottom-center,.lsd-toast-provider__toast--bottom-right{bottom:0;}.lsd-toast-provider__toast--top-center,.lsd-toast-provider__toast--bottom-center{left:50%;}.lsd-toast-provider__toast--top-right,.lsd-toast-provider__toast--bottom-right{right:0;}</style><style data-emotion="css-global 9yw6e1">.lsd-button-group{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:row;-ms-flex-direction:row;flex-direction:row;}.lsd-button-group >*:not(:last-child).lsd-button--outlined,.lsd-button-group >*:not(:last-child) .lsd-button--outlined{border-right:none;}</style><style data-emotion="css-global 17u9w7w">.lsd-date-range-picker{box-sizing:border-box;}.lsd-date-range-picker .lsd-date-field--outlined{border:none;}.lsd-date-range-picker .lsd-date-field__input-container__icon{padding:8px;}.lsd-date-range-picker__label{display:block;}.lsd-date-range-picker__input-container{box-sizing:border-box;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;border:1px solid transparent;}.lsd-date-picker__calendar{border-top:none!important;}.lsd-date-picker__calendar .lsd-tooltip-base__arrow-tip{-webkit-transition:left 0.2s ease-in-out;transition:left 0.2s ease-in-out;}.lsd-date-range-picker--calendar-open .lsd-date-range-picker__input-container{border-bottom:1px solid rgb(var(--lsd-border-primary));}.lsd-date-range-picker__icon{cursor:pointer;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:center;-ms-flex-pack:center;-webkit-justify-content:center;justify-content:center;-webkit-box-flex:1;-webkit-flex-grow:1;-ms-flex-positive:1;flex-grow:1;padding:0 10px;}.lsd-date-range-picker--disabled{opacity:0.3;}.lsd-date-range-picker__supporting-text{position:absolute;}.lsd-date-range-picker--large{width:318px;}.lsd-date-range-picker--large .lsd-date-field--large{width:156px;}.lsd-date-range-picker--large .lsd-date-field__input-container__input{padding-right:0;}.lsd-date-range-picker--large .lsd-date-field__input-container__icon{padding:11px 12px;}.lsd-date-range-picker--large .lsd-date-range-picker__label{margin:0 0 6px 18px;}.lsd-date-range-picker--large .lsd-date-range-picker__input-container{height:40px;}.lsd-date-range-picker--large .lsd-date-range-picker__supporting-text{margin:6px 18px 0 18px;}.lsd-date-range-picker--medium{width:290px;}.lsd-date-range-picker--medium .lsd-date-field--medium{width:142px;}.lsd-date-range-picker--medium .lsd-date-field__input-container__input{padding-right:0;}.lsd-date-range-picker--medium .lsd-date-field__input-container__icon{padding:7px 8px;}.lsd-date-range-picker--medium .lsd-date-range-picker__label{margin:0 0 6px 14px;}.lsd-date-range-picker--medium .lsd-date-range-picker__input-container{height:32px;}.lsd-date-range-picker--medium .lsd-date-range-picker__supporting-text{margin:6px 14px 0 14px;}.lsd-date-range-picker--small{width:262px;}.lsd-date-range-picker--small .lsd-date-field--small{width:128px;}.lsd-date-range-picker--small .lsd-date-field__input-container__input{padding-right:0;}.lsd-date-range-picker--small .lsd-date-field__input-container__icon{padding:5px 7px;}.lsd-date-range-picker--small .lsd-date-range-picker__label{margin:0 0 6px 12px;}.lsd-date-range-picker--small .lsd-date-range-picker__input-container{height:28px;}.lsd-date-range-picker--small .lsd-date-range-picker__supporting-text{margin:6px 12px 0 12px;}.lsd-date-range-picker__separator{margin-left:3px;width:1px;height:100%;}.lsd-date-range-picker__separator{border-left:1px solid transparent;}.lsd-date-range-picker--outlined{border:1px solid rgb(var(--lsd-border-primary));}.lsd-date-range-picker--outlined .lsd-date-range-picker__separator{border-left:1px solid rgb(var(--lsd-border-primary));}</style><style data-emotion="css-global 19d282h">.lsd-tooltip-base{border:1px solid rgb(var(--lsd-border-primary));position:relative;}.lsd-tooltip-base__arrow-tip{border:1px solid rgb(var(--lsd-border-primary));position:absolute;background:rgb(var(--lsd-surface-primary));}.lsd-tooltip-base__content{background:rgb(var(--lsd-surface-primary));width:100%;height:100%;position:relative;z-index:1;}</style><style data-emotion="css-global 1o77wkp">[data-theme=dark]{--lsd-display1-fontSize:5.5rem;--lsd-display1-fontWeight:normal;--lsd-display1-lineHeight:6rem;--lsd-display2-fontSize:4rem;--lsd-display2-fontWeight:normal;--lsd-display2-lineHeight:4.5rem;--lsd-display3-fontSize:3.5rem;--lsd-display3-fontWeight:normal;--lsd-display3-lineHeight:4rem;--lsd-display4-fontSize:3rem;--lsd-display4-fontWeight:normal;--lsd-display4-lineHeight:3.5rem;--lsd-h1-fontSize:2.5rem;--lsd-h1-fontWeight:normal;--lsd-h1-lineHeight:3rem;--lsd-h2-fontSize:2rem;--lsd-h2-fontWeight:normal;--lsd-h2-lineHeight:2.5rem;--lsd-h3-fontSize:1.75rem;--lsd-h3-fontWeight:normal;--lsd-h3-lineHeight:2.25rem;--lsd-h4-fontSize:1.5rem;--lsd-h4-fontWeight:normal;--lsd-h4-lineHeight:2rem;--lsd-h5-fontSize:1.25rem;--lsd-h5-fontWeight:normal;--lsd-h5-lineHeight:1.75rem;--lsd-h6-fontSize:1rem;--lsd-h6-fontWeight:normal;--lsd-h6-lineHeight:1.5rem;--lsd-subtitle1-fontSize:1.125rem;--lsd-subtitle1-fontWeight:normal;--lsd-subtitle1-lineHeight:1.5rem;--lsd-subtitle2-fontSize:1rem;--lsd-subtitle2-fontWeight:normal;--lsd-subtitle2-lineHeight:1.5rem;--lsd-subtitle3-fontSize:0.875rem;--lsd-subtitle3-fontWeight:normal;--lsd-subtitle3-lineHeight:1.25rem;--lsd-subtitle4-fontSize:0.75rem;--lsd-subtitle4-fontWeight:normal;--lsd-subtitle4-lineHeight:1rem;--lsd-body1-fontSize:1rem;--lsd-body1-fontWeight:normal;--lsd-body1-lineHeight:1.5rem;--lsd-body2-fontSize:0.875rem;--lsd-body2-fontWeight:normal;--lsd-body2-lineHeight:1.25rem;--lsd-body3-fontSize:0.75rem;--lsd-body3-fontWeight:normal;--lsd-body3-lineHeight:1rem;--lsd-label1-fontSize:0.875rem;--lsd-label1-fontWeight:normal;--lsd-label1-lineHeight:1.25rem;--lsd-label2-fontSize:0.75rem;--lsd-label2-fontWeight:normal;--lsd-label2-lineHeight:1rem;--lsd-typography-generic-font-family:sans-serif;--lsd-theme-primary:255,255,255;--lsd-theme-secondary:0,0,0;--lsd-surface-primary:0,0,0;--lsd-surface-secondary:255,255,255;--lsd-border-primary:255,255,255;--lsd-border-secondary:0,0,0;--lsd-icon-primary:255,255,255;--lsd-icon-secondary:0,0,0;--lsd-text-primary:255,255,255;--lsd-text-secondary:0,0,0;--lsd-text-tertiary:255,255,255,0.34;--lsd-spacing-4:4px;--lsd-spacing-8:8px;--lsd-spacing-16:16px;--lsd-spacing-24:24px;--lsd-spacing-32:32px;--lsd-spacing-40:40px;--lsd-spacing-64:64px;--lsd-spacing-80:80px;--lsd-spacing-96:96px;--lsd-spacing-120:120px;}</style><style data-emotion="css-global yon3n1">[data-theme=light]{--lsd-display1-fontSize:5.5rem;--lsd-display1-fontWeight:normal;--lsd-display1-lineHeight:6rem;--lsd-display2-fontSize:4rem;--lsd-display2-fontWeight:normal;--lsd-display2-lineHeight:4.5rem;--lsd-display3-fontSize:3.5rem;--lsd-display3-fontWeight:normal;--lsd-display3-lineHeight:4rem;--lsd-display4-fontSize:3rem;--lsd-display4-fontWeight:normal;--lsd-display4-lineHeight:3.5rem;--lsd-h1-fontSize:2.5rem;--lsd-h1-fontWeight:normal;--lsd-h1-lineHeight:3rem;--lsd-h2-fontSize:2rem;--lsd-h2-fontWeight:normal;--lsd-h2-lineHeight:2.5rem;--lsd-h3-fontSize:1.75rem;--lsd-h3-fontWeight:normal;--lsd-h3-lineHeight:2.25rem;--lsd-h4-fontSize:1.5rem;--lsd-h4-fontWeight:normal;--lsd-h4-lineHeight:2rem;--lsd-h5-fontSize:1.25rem;--lsd-h5-fontWeight:normal;--lsd-h5-lineHeight:1.75rem;--lsd-h6-fontSize:1rem;--lsd-h6-fontWeight:normal;--lsd-h6-lineHeight:1.5rem;--lsd-subtitle1-fontSize:1.125rem;--lsd-subtitle1-fontWeight:normal;--lsd-subtitle1-lineHeight:1.5rem;--lsd-subtitle2-fontSize:1rem;--lsd-subtitle2-fontWeight:normal;--lsd-subtitle2-lineHeight:1.5rem;--lsd-subtitle3-fontSize:0.875rem;--lsd-subtitle3-fontWeight:normal;--lsd-subtitle3-lineHeight:1.25rem;--lsd-subtitle4-fontSize:0.75rem;--lsd-subtitle4-fontWeight:normal;--lsd-subtitle4-lineHeight:1rem;--lsd-body1-fontSize:1rem;--lsd-body1-fontWeight:normal;--lsd-body1-lineHeight:1.5rem;--lsd-body2-fontSize:0.875rem;--lsd-body2-fontWeight:normal;--lsd-body2-lineHeight:1.25rem;--lsd-body3-fontSize:0.75rem;--lsd-body3-fontWeight:normal;--lsd-body3-lineHeight:1rem;--lsd-label1-fontSize:0.875rem;--lsd-label1-fontWeight:normal;--lsd-label1-lineHeight:1.25rem;--lsd-label2-fontSize:0.75rem;--lsd-label2-fontWeight:normal;--lsd-label2-lineHeight:1rem;--lsd-typography-generic-font-family:sans-serif;--lsd-theme-primary:0,0,0;--lsd-theme-secondary:255,255,255;--lsd-surface-primary:255,255,255;--lsd-surface-secondary:0,0,0;--lsd-border-primary:0,0,0;--lsd-border-secondary:255,255,255;--lsd-icon-primary:0,0,0;--lsd-icon-secondary:255,255,255;--lsd-text-primary:0,0,0;--lsd-text-secondary:255,255,255;--lsd-text-tertiary:0,0,0,0.34;--lsd-spacing-4:4px;--lsd-spacing-8:8px;--lsd-spacing-16:16px;--lsd-spacing-24:24px;--lsd-spacing-32:32px;--lsd-spacing-40:40px;--lsd-spacing-64:64px;--lsd-spacing-80:80px;--lsd-spacing-96:96px;--lsd-spacing-120:120px;}</style><div class="root_QACb"><div role="region" aria-label="Skip to main content"><a class="skipToContent_fXgn" href="#__docusaurus_skipToContent_fallback">Skip to main content</a></div><nav aria-label="Main" class="navbar navbar--fixed-top navbarHideable_OoEf"><div class="navbar__inner"><div class="navbar__left"><a class="navbar__brand" href="/"><div class="navbar__logo"><img src="/theme/image/logo.svg" alt="Vac Research" class="themedImage_ToTc themedImage--light_HNdA" height="26"><img src="/theme/image/logo.svg" alt="Vac Research" class="themedImage_ToTc themedImage--dark_i4oU" height="26"></div><b class="navbar__title text--truncate"></b></a></div><div class="navbar__left-items"><a class="navbar__item navbar__link" href="/"><div class="lsd-typography lsd-typography--body2 linkContent__x3v">About Vac</div></a><a aria-current="page" class="navbar__item navbar__link navbar__link--active" href="/community"><div class="lsd-typography lsd-typography--body2 linkContent__x3v">Community</div></a><a class="navbar__item navbar__link" href="/rlog"><div class="lsd-typography lsd-typography--body2 linkContent__x3v">Research Blog</div></a><a class="navbar__item navbar__link" href="/join-us"><div class="lsd-typography lsd-typography--body2 linkContent__x3v">Join Us</div></a></div><div class="navbar__right-items"><div class="iconButtonGroup_ktNv lsd-icon-button-group lsd-icon-button-group--medium lsd-icon-button-group--outlined"><button class="clean-btn toggle_K23S colorModeToggle_GSaI navbar__color-mode-toggle toggleButtonDisabled_AAS_ lsd-icon-button lsd-icon-button--medium lsd-icon-button--outlined lsd-icon-button--disabled" type="button" title="Switch between dark and light mode (currently dark mode)" aria-label="Switch between dark and light mode (currently dark mode)" aria-live="polite"><svg viewBox="0 0 24 24" width="24" height="24" class="lightToggleIcon_K4TL"><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"></path></svg><svg viewBox="0 0 24 24" width="24" height="24" class="darkToggleIcon_lKkA"><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"></path></svg></button><button aria-label="Toggle navigation bar" aria-expanded="false" class="navbar__toggle clean-btn" type="button"><svg width="30" height="30" viewBox="0 0 30 30" aria-hidden="true"><path stroke="currentColor" stroke-linecap="round" stroke-miterlimit="10" stroke-width="2" d="M4 7h22M4 15h22M4 23h22"></path></svg></button></div></div></div><div role="presentation" class="navbar-sidebar__backdrop"></div></nav><div id="__docusaurus_skipToContent_fallback" class="main-wrapper mainWrapper_z2l0 docsWrapper_BCFX"><button aria-label="Scroll back to top" class="clean-btn theme-back-to-top-button backToTopButton_sjWU" type="button"></button><div class="docPage__5DB"><main class="docMainContainer_gTbr docMainContainerEnhanced_Uz_u"><div class="container padding-top--md padding-bottom--lg"><div class="row docItemGrid_SzoZ"><div class="docItemCol_F52z"><div class="docItemContainer_hrrU"><article><div class="theme-doc-markdown markdown"><h1>Join the community</h1><div class="mdx-box" style="--mdx-box-top-xs:0px;--mdx-box-top-sm:0px;--mdx-box-top-md:0px;--mdx-box-top-lg:0px;--mdx-box-top-xl:0px;--mdx-box-bottom-xs:24px;--mdx-box-bottom-sm:24px;--mdx-box-bottom-md:24px;--mdx-box-bottom-lg:24px;--mdx-box-bottom-xl:24px">Join the Vac Community!<br><br>Keep up to date with our latest research by connecting with us on our communities channels.</div><div class="mdx-box" style="padding-bottom:0;--mdx-box-top-xs:32px;--mdx-box-top-sm:32px;--mdx-box-top-md:32px;--mdx-box-top-lg:32px;--mdx-box-top-xl:32px;--mdx-box-bottom-xs:56px;--mdx-box-bottom-sm:56px;--mdx-box-bottom-md:56px;--mdx-box-bottom-lg:56px;--mdx-box-bottom-xl:56px"><style data-emotion="css 108cbff">.css-108cbff{width:100%;}.css-108cbff .mdx-grid__scroll{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;}.css-108cbff .mdx-grid__content{display:grid;gap:var(--grid-gap);grid-template-columns:repeat(var(--grid-cols), minmax(0, 1fr));overflow:hidden;}.css-108cbff .mdx-grid__actions{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:row;-ms-flex-direction:row;flex-direction:row;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;gap:1rem;}.css-108cbff .mdx-grid__actions>*{margin-bottom:3rem;}@media (min-width: 0px){.css-108cbff{--grid-cols:1;--grid-gap:1rem;}.css-108cbff .mdx-grid__scroll{display:none;}.css-108cbff .mdx-grid__content{display:grid;-webkit-box-flex-wrap:unset;-webkit-flex-wrap:unset;-ms-flex-wrap:unset;flex-wrap:unset;overflow-x:unset;overflow-y:unset;scroll-snap-type:unset;}}@media (min-width: 768px){.css-108cbff{--grid-cols:2;}.css-108cbff .mdx-grid__scroll{display:none;}.css-108cbff .mdx-grid__content{display:grid;-webkit-box-flex-wrap:unset;-webkit-flex-wrap:unset;-ms-flex-wrap:unset;flex-wrap:unset;overflow-x:unset;overflow-y:unset;scroll-snap-type:unset;}}</style><div class="mdx-grid css-108cbff"><div class="mdx-grid__actions"><div class="mdx-grid__scroll mdx-scroll-buttons"><div color="primary" class="lsd-icon-button-group lsd-icon-button-group--small lsd-icon-button-group--outlined"><button class="mdx-scroll-buttons__button lsd-icon-button lsd-icon-button--small lsd-icon-button--outlined"><svg width="14" height="14" viewBox="0 0 14 14" fill="none" xmlns="http://www.w3.org/2000/svg" class="lsd-icon lsd-icon--small lsd-icon--filled"><path d="M9.16137 4.3225L8.33887 3.5L4.83887 7L8.33887 10.5L9.16137 9.6775L6.4897 7L9.16137 4.3225Z" fill="black"></path></svg></button><button class="mdx-scroll-buttons__button lsd-icon-button lsd-icon-button--small lsd-icon-button--outlined"><svg width="14" height="14" viewBox="0 0 14 14" fill="none" xmlns="http://www.w3.org/2000/svg" class="lsd-icon lsd-icon--small lsd-icon--filled"><path d="M5.66137 3.5L4.83887 4.3225L7.51053 7L4.83887 9.6775L5.66137 10.5L9.16137 7L5.66137 3.5Z" fill="black"></path></svg></button></div></div></div><div class="mdx-grid__content hidden-scrollbar"><style data-emotion="css kdcjnh">@media (min-width: 0px){.css-kdcjnh{grid-column:span 1;-webkit-flex-basis:calc(100% / var(--grid-cols) * 1);-ms-flex-preferred-size:calc(100% / var(--grid-cols) * 1);flex-basis:calc(100% / var(--grid-cols) * 1);}}</style><div class="css-kdcjnh"><a target="_blank" href="https://twitter.com/vacp2p" class="mdx-social-card"><div class="mdx-social-card__row"><img src="/icons/x-black.svg" alt="social card logo" class="themedImage_ToTc themedImage--light_HNdA mdx-social-card__logo"><img src="/icons/x-white.svg" alt="social card logo" class="themedImage_ToTc themedImage--dark_i4oU mdx-social-card__logo"><div class="icon_S7Kx m_thRi mdx-social-card__external-link"><svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg" role="img"><path fill-rule="evenodd" clip-rule="evenodd" d="M11.192 4H3.428V2.857h9.715v9.715H12V4.808l-8.167 8.168-.809-.808L11.192 4Z" fill="#fff"></path></svg></div></div><span class="lsd-typography lsd-typography--body1 mdx-social-card__description">Follow us on X</span></a></div><div class="css-kdcjnh"><a target="_blank" href="https://discord.com/invite/PQFdubGt6d" class="mdx-social-card"><div class="mdx-social-card__row"><img src="/icons/discord-black.svg" alt="social card logo" class="themedImage_ToTc themedImage--light_HNdA mdx-social-card__logo"><img src="/icons/discord-white.svg" alt="social card logo" class="themedImage_ToTc themedImage--dark_i4oU mdx-social-card__logo"><div class="icon_S7Kx m_thRi mdx-social-card__external-link"><svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg" role="img"><path fill-rule="evenodd" clip-rule="evenodd" d="M11.192 4H3.428V2.857h9.715v9.715H12V4.808l-8.167 8.168-.809-.808L11.192 4Z" fill="#fff"></path></svg></div></div><span class="lsd-typography lsd-typography--body1 mdx-social-card__description">Join the community on Discord</span></a></div><div class="css-kdcjnh"><a target="_blank" href="https://forum.vac.dev/" class="mdx-social-card"><div class="mdx-social-card__row"><img src="/theme/image/logo.svg" alt="social card logo" class="themedImage_ToTc themedImage--light_HNdA mdx-social-card__logo"><img src="/theme/image/logo.svg" alt="social card logo" class="themedImage_ToTc themedImage--dark_i4oU mdx-social-card__logo"><div class="icon_S7Kx m_thRi mdx-social-card__external-link"><svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg" role="img"><path fill-rule="evenodd" clip-rule="evenodd" d="M11.192 4H3.428V2.857h9.715v9.715H12V4.808l-8.167 8.168-.809-.808L11.192 4Z" fill="#fff"></path></svg></div></div><span class="lsd-typography lsd-typography--body1 mdx-social-card__description">Share your thoughts on the latest research on the Vac research forum</span></a></div></div></div></div></div></article><nav class="pagination-nav docusaurus-mt-lg" aria-label="Docs pages"></nav></div></div><div class="gap1_XuuQ"></div></div></div></main></div></div><footer class="footer"><div class="container container-fluid firstRow_ar1q"><div class="footer__bottom text--center"><div class="margin-bottom--sm"><a class="footerLogoLink_BH7S" href="/"><img src="/theme/image/logo.svg" alt="Vac Research" class="themedImage_ToTc themedImage--light_HNdA footer__logo" width="22"><img src="/theme/image/logo.svg" alt="Vac Research" class="themedImage_ToTc themedImage--dark_i4oU footer__logo" width="22"></a></div><div class="footer__copyright">Vac Research © 2024<br>All rights reserved.</div></div><div class="row footer__links"><div class="col footer__col"><div class="footer__title"></div><ul class="footer__items clean-list"><li class="footer__item"><a href="https://twitter.com/vacp2p" target="_blank" rel="noopener noreferrer" class="footer__link-item">Twitter<svg width="13.5" height="13.5" aria-hidden="true" viewBox="0 0 24 24" class="iconExternalLink_nPIU"><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"></path></svg></a></li><li class="footer__item"><a href="https://discord.gg/PQFdubGt6d" target="_blank" rel="noopener noreferrer" class="footer__link-item">Discord<svg width="13.5" height="13.5" aria-hidden="true" viewBox="0 0 24 24" class="iconExternalLink_nPIU"><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"></path></svg></a></li><li class="footer__item"><a href="https://github.com/vacp2p" target="_blank" rel="noopener noreferrer" class="footer__link-item">Github<svg width="13.5" height="13.5" aria-hidden="true" viewBox="0 0 24 24" class="iconExternalLink_nPIU"><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"></path></svg></a></li></ul></div><div class="col footer__col"><div class="footer__title"></div><ul class="footer__items clean-list"><li class="footer__item"><a href="https://jobs.status.im/" target="_blank" rel="noopener noreferrer" class="footer__link-item">Work With Us<svg width="13.5" height="13.5" aria-hidden="true" viewBox="0 0 24 24" class="iconExternalLink_nPIU"><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"></path></svg></a></li><li class="footer__item"><a class="footer__link-item" href="/terms">Terms & Conditions</a></li><li class="footer__item"><a class="footer__link-item" href="/privacy-policy">Privacy Policy</a></li><li class="footer__item"><a class="footer__link-item" href="/security">Security</a></li></ul></div></div></div><div class="secondRow__ww3"><div class="footer__bottom text--center">Logos Collective</div><div class="row footer__links"><div class="col footer__col"><div class="footer__title">Research</div><ul class="footer__items clean-list"><li class="footer__item"><a href="https://vac.dev" target="_blank" rel="noopener noreferrer" class="footer__link-item">VacP2P<svg width="13.5" height="13.5" aria-hidden="true" viewBox="0 0 24 24" class="iconExternalLink_nPIU"><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"></path></svg></a></li><li class="footer__item"><a href="https://afaik.institute" target="_blank" rel="noopener noreferrer" class="footer__link-item">AFAIK<svg width="13.5" height="13.5" aria-hidden="true" viewBox="0 0 24 24" class="iconExternalLink_nPIU"><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"></path></svg></a></li></ul></div><div class="col footer__col"><div class="footer__title">Infrastructure</div><ul class="footer__items clean-list"><li class="footer__item"><a href="https://waku.org/" target="_blank" rel="noopener noreferrer" class="footer__link-item">Waku<svg width="13.5" height="13.5" aria-hidden="true" viewBox="0 0 24 24" class="iconExternalLink_nPIU"><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"></path></svg></a></li><li class="footer__item"><a href="https://nimbus.team/" target="_blank" rel="noopener noreferrer" class="footer__link-item">Nimbus<svg width="13.5" height="13.5" aria-hidden="true" viewBox="0 0 24 24" class="iconExternalLink_nPIU"><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"></path></svg></a></li><li class="footer__item"><a href="https://codex.storage" target="_blank" rel="noopener noreferrer" class="footer__link-item">Codex<svg width="13.5" height="13.5" aria-hidden="true" viewBox="0 0 24 24" class="iconExternalLink_nPIU"><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"></path></svg></a></li><li class="footer__item"><a href="https://nomos.tech" target="_blank" rel="noopener noreferrer" class="footer__link-item">Nomos<svg width="13.5" height="13.5" aria-hidden="true" viewBox="0 0 24 24" class="iconExternalLink_nPIU"><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"></path></svg></a></li></ul></div><div class="col footer__col"><div class="footer__title">Creative Studio</div><ul class="footer__items clean-list"><li class="footer__item"><a href="https://acid.info" target="_blank" rel="noopener noreferrer" class="footer__link-item">Acid.info<svg width="13.5" height="13.5" aria-hidden="true" viewBox="0 0 24 24" class="iconExternalLink_nPIU"><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"></path></svg></a></li></ul></div><div class="col footer__col"><div class="footer__title">Movement</div><ul class="footer__items clean-list"><li class="footer__item"><a href="https://logos.co" target="_blank" rel="noopener noreferrer" class="footer__link-item">Logos<svg width="13.5" height="13.5" aria-hidden="true" viewBox="0 0 24 24" class="iconExternalLink_nPIU"><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"></path></svg></a></li></ul></div><div class="col footer__col"><div class="footer__title">User-facing products</div><ul class="footer__items clean-list"><li class="footer__item"><a href="https://status.im" target="_blank" rel="noopener noreferrer" class="footer__link-item">Status<svg width="13.5" height="13.5" aria-hidden="true" viewBox="0 0 24 24" class="iconExternalLink_nPIU"><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"></path></svg></a></li><li class="footer__item"><a href="https://keycard.tech" target="_blank" rel="noopener noreferrer" class="footer__link-item">Keycard<svg width="13.5" height="13.5" aria-hidden="true" viewBox="0 0 24 24" class="iconExternalLink_nPIU"><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"></path></svg></a></li></ul></div></div></div><button class="backToTop_wDfN lsd-button lsd-button--small lsd-button--outlined"><span class="lsd-typography lsd-typography--label2 lsd-button__text">Back to top ↑</span></button></footer></div></div> -<script src="/assets/js/runtime~main.556fa6f5.js"></script> -<script src="/assets/js/main.ffc20c94.js"></script> +<script src="/assets/js/runtime~main.a9103199.js"></script> +<script src="/assets/js/main.5454aec3.js"></script> </body> </html> \ No newline at end of file diff --git a/contribute/index.html b/contribute/index.html index d3cdefd2..d2149752 100644 --- a/contribute/index.html +++ b/contribute/index.html @@ -10,8 +10,8 @@ <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/katex@0.13.24/dist/katex.min.css" integrity="sha384-odtC+0UGzzFL/6PNoE8rX/SPcQDXBJ+uRepguP4QkPCm2LBxH3FA3y+fKSiJ+AmM" crossorigin="anonymous"><link rel="stylesheet" href="/assets/css/styles.08d697e6.css"> -<link rel="preload" href="/assets/js/runtime~main.556fa6f5.js" as="script"> -<link rel="preload" href="/assets/js/main.ffc20c94.js" as="script"> +<link rel="preload" href="/assets/js/runtime~main.a9103199.js" as="script"> +<link rel="preload" href="/assets/js/main.5454aec3.js" as="script"> <meta property="og:image" content="https://vac.dev/_og/d032ccad5031ebf425b65e61e61953ee7c3a4877.png"><meta name="twitter:image" content="https://vac.dev/_og/d032ccad5031ebf425b65e61e61953ee7c3a4877.png"></head> <body class="navigation-with-keyboard"> <script>!function(){function e(e){document.documentElement.setAttribute("data-theme",e)}var t=function(){var e=null;try{e=new URLSearchParams(window.location.search).get("docusaurus-theme")}catch(e){}return e}()||function(){var e=null;try{e=localStorage.getItem("theme")}catch(e){}return e}();null!==t?e(t):window.matchMedia("(prefers-color-scheme: dark)").matches?e("dark"):window.matchMedia("(prefers-color-scheme: light)").matches?e("light"):e("dark")}()</script><div id="__docusaurus"> @@ -23,7 +23,7 @@ <a href="https://discord.gg/PQFdubGt6d" target="_blank" rel="noopener noreferrer">joining our Discord</a>, <a href="https://forum.vac.dev/" target="_blank" rel="noopener noreferrer">opening a thread in our forum</a>, or <a href="https://github.com/vacp2p" target="_blank" rel="noopener noreferrer">opening issues / PRs on GitHub</a>.</p><p>Also, see our <a href="https://jobs.status.im/?search=Vac" target="_blank" rel="noopener noreferrer">current job openings</a>.</p><h2 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="what-to-contribute">What to Contribute<a href="#what-to-contribute" class="hash-link" aria-label="Direct link to What to Contribute" title="Direct link to What to Contribute">​</a></h2><p>We are interested in both research and code contributions.</p><p>For code contributions, see our "good first issue" lists for various Vac-related code bases:</p><ul><li><a href="https://github.com/vacp2p/nim-libp2p" target="_blank" rel="noopener noreferrer">nim-libp2p</a></li><li><a href="https://github.com/vacp2p/zerokit/labels/good%20first%20issue" target="_blank" rel="noopener noreferrer">zerokit</a></li><li><a href="https://github.com/vacp2p/stealth-address-kit" target="_blank" rel="noopener noreferrer">stealth-address-kit</a></li></ul></div></article><nav class="pagination-nav docusaurus-mt-lg" aria-label="Docs pages"><a class="pagination-nav__link pagination-nav__link--prev" href="/principles"><div class="icon_S7Kx m_thRi"><svg width="14" height="14" viewBox="0 0 14 14" fill="none" xmlns="http://www.w3.org/2000/svg" role="img"><path d="M11.667 6.417h-7.1l3.261-3.261L7 2.333 2.333 7 7 11.667l.823-.823-3.255-3.26h7.099V6.417Z" fill="#fff"></path></svg></div><span class="lsd-typography lsd-typography--body2 pagination-nav__label">Principles</span></a></nav></div></div><div class="gap1_XuuQ"></div></div></div></main></div></div><footer class="footer"><div class="container container-fluid firstRow_ar1q"><div class="footer__bottom text--center"><div class="margin-bottom--sm"><a class="footerLogoLink_BH7S" href="/"><img src="/theme/image/logo.svg" alt="Vac Research" class="themedImage_ToTc themedImage--light_HNdA footer__logo" width="22"><img src="/theme/image/logo.svg" alt="Vac Research" class="themedImage_ToTc themedImage--dark_i4oU footer__logo" width="22"></a></div><div class="footer__copyright">Vac Research © 2024<br>All rights reserved.</div></div><div class="row footer__links"><div class="col footer__col"><div class="footer__title"></div><ul class="footer__items clean-list"><li class="footer__item"><a href="https://twitter.com/vacp2p" target="_blank" rel="noopener noreferrer" class="footer__link-item">Twitter<svg width="13.5" height="13.5" aria-hidden="true" viewBox="0 0 24 24" class="iconExternalLink_nPIU"><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"></path></svg></a></li><li class="footer__item"><a href="https://discord.gg/PQFdubGt6d" target="_blank" rel="noopener noreferrer" class="footer__link-item">Discord<svg width="13.5" height="13.5" aria-hidden="true" viewBox="0 0 24 24" class="iconExternalLink_nPIU"><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"></path></svg></a></li><li class="footer__item"><a href="https://github.com/vacp2p" target="_blank" rel="noopener noreferrer" class="footer__link-item">Github<svg width="13.5" height="13.5" aria-hidden="true" viewBox="0 0 24 24" class="iconExternalLink_nPIU"><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"></path></svg></a></li></ul></div><div class="col footer__col"><div class="footer__title"></div><ul class="footer__items clean-list"><li class="footer__item"><a href="https://jobs.status.im/" target="_blank" rel="noopener noreferrer" class="footer__link-item">Work With Us<svg width="13.5" height="13.5" aria-hidden="true" viewBox="0 0 24 24" class="iconExternalLink_nPIU"><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"></path></svg></a></li><li class="footer__item"><a class="footer__link-item" href="/terms">Terms & Conditions</a></li><li class="footer__item"><a class="footer__link-item" href="/privacy-policy">Privacy Policy</a></li><li class="footer__item"><a class="footer__link-item" href="/security">Security</a></li></ul></div></div></div><div class="secondRow__ww3"><div class="footer__bottom text--center">Logos Collective</div><div class="row footer__links"><div class="col footer__col"><div class="footer__title">Research</div><ul class="footer__items clean-list"><li class="footer__item"><a href="https://vac.dev" target="_blank" rel="noopener noreferrer" class="footer__link-item">VacP2P<svg width="13.5" height="13.5" aria-hidden="true" viewBox="0 0 24 24" class="iconExternalLink_nPIU"><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"></path></svg></a></li><li class="footer__item"><a href="https://afaik.institute" target="_blank" rel="noopener noreferrer" class="footer__link-item">AFAIK<svg width="13.5" height="13.5" aria-hidden="true" viewBox="0 0 24 24" class="iconExternalLink_nPIU"><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"></path></svg></a></li></ul></div><div class="col footer__col"><div class="footer__title">Infrastructure</div><ul class="footer__items clean-list"><li class="footer__item"><a href="https://waku.org/" target="_blank" rel="noopener noreferrer" class="footer__link-item">Waku<svg width="13.5" height="13.5" aria-hidden="true" viewBox="0 0 24 24" class="iconExternalLink_nPIU"><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"></path></svg></a></li><li class="footer__item"><a href="https://nimbus.team/" target="_blank" rel="noopener noreferrer" class="footer__link-item">Nimbus<svg width="13.5" height="13.5" aria-hidden="true" viewBox="0 0 24 24" class="iconExternalLink_nPIU"><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"></path></svg></a></li><li class="footer__item"><a href="https://codex.storage" target="_blank" rel="noopener noreferrer" class="footer__link-item">Codex<svg width="13.5" height="13.5" aria-hidden="true" viewBox="0 0 24 24" class="iconExternalLink_nPIU"><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"></path></svg></a></li><li class="footer__item"><a href="https://nomos.tech" target="_blank" rel="noopener noreferrer" class="footer__link-item">Nomos<svg width="13.5" height="13.5" aria-hidden="true" viewBox="0 0 24 24" class="iconExternalLink_nPIU"><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"></path></svg></a></li></ul></div><div class="col footer__col"><div class="footer__title">Creative Studio</div><ul class="footer__items clean-list"><li class="footer__item"><a href="https://acid.info" target="_blank" rel="noopener noreferrer" class="footer__link-item">Acid.info<svg width="13.5" height="13.5" aria-hidden="true" viewBox="0 0 24 24" class="iconExternalLink_nPIU"><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"></path></svg></a></li></ul></div><div class="col footer__col"><div class="footer__title">Movement</div><ul class="footer__items clean-list"><li class="footer__item"><a href="https://logos.co" target="_blank" rel="noopener noreferrer" class="footer__link-item">Logos<svg width="13.5" height="13.5" aria-hidden="true" viewBox="0 0 24 24" class="iconExternalLink_nPIU"><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"></path></svg></a></li></ul></div><div class="col footer__col"><div class="footer__title">User-facing products</div><ul class="footer__items clean-list"><li class="footer__item"><a href="https://status.im" target="_blank" rel="noopener noreferrer" class="footer__link-item">Status<svg width="13.5" height="13.5" aria-hidden="true" viewBox="0 0 24 24" class="iconExternalLink_nPIU"><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"></path></svg></a></li><li class="footer__item"><a href="https://keycard.tech" target="_blank" rel="noopener noreferrer" class="footer__link-item">Keycard<svg width="13.5" height="13.5" aria-hidden="true" viewBox="0 0 24 24" class="iconExternalLink_nPIU"><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"></path></svg></a></li></ul></div></div></div><button class="backToTop_wDfN lsd-button lsd-button--small lsd-button--outlined"><span class="lsd-typography lsd-typography--label2 lsd-button__text">Back to top ↑</span></button></footer></div></div> -<script src="/assets/js/runtime~main.556fa6f5.js"></script> -<script src="/assets/js/main.ffc20c94.js"></script> +<script src="/assets/js/runtime~main.a9103199.js"></script> +<script src="/assets/js/main.5454aec3.js"></script> </body> </html> \ No newline at end of file diff --git a/deepresearch/index.html b/deepresearch/index.html index 157bdd97..91c25050 100644 --- a/deepresearch/index.html +++ b/deepresearch/index.html @@ -10,8 +10,8 @@ <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/katex@0.13.24/dist/katex.min.css" integrity="sha384-odtC+0UGzzFL/6PNoE8rX/SPcQDXBJ+uRepguP4QkPCm2LBxH3FA3y+fKSiJ+AmM" crossorigin="anonymous"><link rel="stylesheet" href="/assets/css/styles.08d697e6.css"> -<link rel="preload" href="/assets/js/runtime~main.556fa6f5.js" as="script"> -<link rel="preload" href="/assets/js/main.ffc20c94.js" as="script"> +<link rel="preload" href="/assets/js/runtime~main.a9103199.js" as="script"> +<link rel="preload" href="/assets/js/main.5454aec3.js" as="script"> <meta property="og:image" content="https://vac.dev/_og/a4aefb44f64684374ea3602d23a82f182822abca.png"><meta name="twitter:image" content="https://vac.dev/_og/a4aefb44f64684374ea3602d23a82f182822abca.png"></head> <body class="navigation-with-keyboard"> <script>!function(){function e(e){document.documentElement.setAttribute("data-theme",e)}var t=function(){var e=null;try{e=new URLSearchParams(window.location.search).get("docusaurus-theme")}catch(e){}return e}()||function(){var e=null;try{e=localStorage.getItem("theme")}catch(e){}return e}();null!==t?e(t):window.matchMedia("(prefers-color-scheme: dark)").matches?e("dark"):window.matchMedia("(prefers-color-scheme: light)").matches?e("light"):e("dark")}()</script><div id="__docusaurus"> @@ -30,7 +30,7 @@ By advancing the field of ZK, Vac Deep Research strengthens the foundation for s The team explores ways to enhance the performance, efficiency, and reliability of the libp2p gossipsub protocol. By conducting in-depth research and proposing improvements, Vac Deep Research aims to optimise information sharing and communication within decentralised networks, contributing to the overall robustness and scalability of the P2P layers of IFT projects.</p><h2 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="anonymisation-networks">Anonymisation Networks<a href="#anonymisation-networks" class="hash-link" aria-label="Direct link to Anonymisation Networks" title="Direct link to Anonymisation Networks">​</a></h2><p>Vac also researches anonymisation networks, with the main goal of a libp2p gossipsub anonymisation layer with pluggable project-specific components.</p></div></article><nav class="pagination-nav docusaurus-mt-lg" aria-label="Docs pages"><a class="pagination-nav__link pagination-nav__link--prev" href="/vsus"><div class="icon_S7Kx m_thRi"><svg width="14" height="14" viewBox="0 0 14 14" fill="none" xmlns="http://www.w3.org/2000/svg" role="img"><path d="M11.667 6.417h-7.1l3.261-3.261L7 2.333 2.333 7 7 11.667l.823-.823-3.255-3.26h7.099V6.417Z" fill="#fff"></path></svg></div><span class="lsd-typography lsd-typography--body2 pagination-nav__label">R&D Service Units</span></a><a class="pagination-nav__link pagination-nav__link--next" href="/vips"><span class="lsd-typography lsd-typography--body2 pagination-nav__label">Incubator Projects</span><div class="icon_S7Kx m_thRi"><svg width="14" height="14" viewBox="0 0 14 14" fill="none" xmlns="http://www.w3.org/2000/svg" role="img"><path d="m7 2.333-.823.823 3.255 3.26H2.333v1.167h7.1l-3.256 3.261.823.823L11.667 7 7 2.333Z" fill="#fff"></path></svg></div></a></nav></div></div><div class="gap1_XuuQ"></div></div></div></main></div></div><footer class="footer"><div class="container container-fluid firstRow_ar1q"><div class="footer__bottom text--center"><div class="margin-bottom--sm"><a class="footerLogoLink_BH7S" href="/"><img src="/theme/image/logo.svg" alt="Vac Research" class="themedImage_ToTc themedImage--light_HNdA footer__logo" width="22"><img src="/theme/image/logo.svg" alt="Vac Research" class="themedImage_ToTc themedImage--dark_i4oU footer__logo" width="22"></a></div><div class="footer__copyright">Vac Research © 2024<br>All rights reserved.</div></div><div class="row footer__links"><div class="col footer__col"><div class="footer__title"></div><ul class="footer__items clean-list"><li class="footer__item"><a href="https://twitter.com/vacp2p" target="_blank" rel="noopener noreferrer" class="footer__link-item">Twitter<svg width="13.5" height="13.5" aria-hidden="true" viewBox="0 0 24 24" class="iconExternalLink_nPIU"><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"></path></svg></a></li><li class="footer__item"><a href="https://discord.gg/PQFdubGt6d" target="_blank" rel="noopener noreferrer" class="footer__link-item">Discord<svg width="13.5" height="13.5" aria-hidden="true" viewBox="0 0 24 24" class="iconExternalLink_nPIU"><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"></path></svg></a></li><li class="footer__item"><a href="https://github.com/vacp2p" target="_blank" rel="noopener noreferrer" class="footer__link-item">Github<svg width="13.5" height="13.5" aria-hidden="true" viewBox="0 0 24 24" class="iconExternalLink_nPIU"><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"></path></svg></a></li></ul></div><div class="col footer__col"><div class="footer__title"></div><ul class="footer__items clean-list"><li class="footer__item"><a href="https://jobs.status.im/" target="_blank" rel="noopener noreferrer" class="footer__link-item">Work With Us<svg width="13.5" height="13.5" aria-hidden="true" viewBox="0 0 24 24" class="iconExternalLink_nPIU"><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"></path></svg></a></li><li class="footer__item"><a class="footer__link-item" href="/terms">Terms & Conditions</a></li><li class="footer__item"><a class="footer__link-item" href="/privacy-policy">Privacy Policy</a></li><li class="footer__item"><a class="footer__link-item" href="/security">Security</a></li></ul></div></div></div><div class="secondRow__ww3"><div class="footer__bottom text--center">Logos Collective</div><div class="row footer__links"><div class="col footer__col"><div class="footer__title">Research</div><ul class="footer__items clean-list"><li class="footer__item"><a href="https://vac.dev" target="_blank" rel="noopener noreferrer" class="footer__link-item">VacP2P<svg width="13.5" height="13.5" aria-hidden="true" viewBox="0 0 24 24" class="iconExternalLink_nPIU"><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"></path></svg></a></li><li class="footer__item"><a href="https://afaik.institute" target="_blank" rel="noopener noreferrer" class="footer__link-item">AFAIK<svg width="13.5" height="13.5" aria-hidden="true" viewBox="0 0 24 24" class="iconExternalLink_nPIU"><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"></path></svg></a></li></ul></div><div class="col footer__col"><div class="footer__title">Infrastructure</div><ul class="footer__items clean-list"><li class="footer__item"><a href="https://waku.org/" target="_blank" rel="noopener noreferrer" class="footer__link-item">Waku<svg width="13.5" height="13.5" aria-hidden="true" viewBox="0 0 24 24" class="iconExternalLink_nPIU"><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"></path></svg></a></li><li class="footer__item"><a href="https://nimbus.team/" target="_blank" rel="noopener noreferrer" class="footer__link-item">Nimbus<svg width="13.5" height="13.5" aria-hidden="true" viewBox="0 0 24 24" class="iconExternalLink_nPIU"><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"></path></svg></a></li><li class="footer__item"><a href="https://codex.storage" target="_blank" rel="noopener noreferrer" class="footer__link-item">Codex<svg width="13.5" height="13.5" aria-hidden="true" viewBox="0 0 24 24" class="iconExternalLink_nPIU"><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"></path></svg></a></li><li class="footer__item"><a href="https://nomos.tech" target="_blank" rel="noopener noreferrer" class="footer__link-item">Nomos<svg width="13.5" height="13.5" aria-hidden="true" viewBox="0 0 24 24" class="iconExternalLink_nPIU"><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"></path></svg></a></li></ul></div><div class="col footer__col"><div class="footer__title">Creative Studio</div><ul class="footer__items clean-list"><li class="footer__item"><a href="https://acid.info" target="_blank" rel="noopener noreferrer" class="footer__link-item">Acid.info<svg width="13.5" height="13.5" aria-hidden="true" viewBox="0 0 24 24" class="iconExternalLink_nPIU"><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"></path></svg></a></li></ul></div><div class="col footer__col"><div class="footer__title">Movement</div><ul class="footer__items clean-list"><li class="footer__item"><a href="https://logos.co" target="_blank" rel="noopener noreferrer" class="footer__link-item">Logos<svg width="13.5" height="13.5" aria-hidden="true" viewBox="0 0 24 24" class="iconExternalLink_nPIU"><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"></path></svg></a></li></ul></div><div class="col footer__col"><div class="footer__title">User-facing products</div><ul class="footer__items clean-list"><li class="footer__item"><a href="https://status.im" target="_blank" rel="noopener noreferrer" class="footer__link-item">Status<svg width="13.5" height="13.5" aria-hidden="true" viewBox="0 0 24 24" class="iconExternalLink_nPIU"><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"></path></svg></a></li><li class="footer__item"><a href="https://keycard.tech" target="_blank" rel="noopener noreferrer" class="footer__link-item">Keycard<svg width="13.5" height="13.5" aria-hidden="true" viewBox="0 0 24 24" class="iconExternalLink_nPIU"><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"></path></svg></a></li></ul></div></div></div><button class="backToTop_wDfN lsd-button lsd-button--small lsd-button--outlined"><span class="lsd-typography lsd-typography--label2 lsd-button__text">Back to top ↑</span></button></footer></div></div> -<script src="/assets/js/runtime~main.556fa6f5.js"></script> -<script src="/assets/js/main.ffc20c94.js"></script> +<script src="/assets/js/runtime~main.a9103199.js"></script> +<script src="/assets/js/main.5454aec3.js"></script> </body> </html> \ No newline at end of file diff --git a/generated/jobs.json b/generated/jobs.json index 7e9a2c48..e90e90ce 100644 --- a/generated/jobs.json +++ b/generated/jobs.json @@ -1 +1 @@ -{"departments":[{"id":87842,"name":"App","parent_id":43806,"child_ids":[87847,87852,87850,87848,45530,87849],"jobs":[]},{"id":54504,"name":"Brand Design Studio","parent_id":null,"child_ids":[],"jobs":[]},{"id":45532,"name":"Business Development","parent_id":null,"child_ids":[],"jobs":[]},{"id":87841,"name":"Codex","parent_id":43806,"child_ids":[],"jobs":[]},{"id":84549,"name":"Communications","parent_id":null,"child_ids":[],"jobs":[]},{"id":45531,"name":"Design","parent_id":null,"child_ids":[],"jobs":[]},{"id":87847,"name":"Desktop","parent_id":87842,"child_ids":[],"jobs":[]},{"id":87852,"name":"Documentation","parent_id":87842,"child_ids":[],"jobs":[]},{"id":45547,"name":"Engineering ","parent_id":null,"child_ids":[],"jobs":[]},{"id":49925,"name":"Finance","parent_id":87845,"child_ids":[],"jobs":[]},{"id":87854,"name":"Infrastructure","parent_id":43806,"child_ids":[],"jobs":[]},{"id":87853,"name":"Insights","parent_id":87845,"child_ids":[],"jobs":[]},{"id":87850,"name":"Keycard","parent_id":87842,"child_ids":[],"jobs":[]},{"id":145838,"name":"Leadership","parent_id":null,"child_ids":[],"jobs":[]},{"id":74156,"name":"Legal","parent_id":87845,"child_ids":[],"jobs":[]},{"id":91698,"name":"Logos","parent_id":null,"child_ids":[],"jobs":[]},{"id":43807,"name":"Marketing","parent_id":null,"child_ids":[],"jobs":[]},{"id":87848,"name":"Mobile","parent_id":87842,"child_ids":[],"jobs":[]},{"id":87843,"name":"Nimbus","parent_id":43806,"child_ids":[],"jobs":[]},{"id":144866,"name":"Nomos","parent_id":43806,"child_ids":[],"jobs":[]},{"id":45548,"name":"People Operations","parent_id":87845,"child_ids":[],"jobs":[]},{"id":45530,"name":"Product Design","parent_id":87842,"child_ids":[],"jobs":[]},{"id":90941,"name":"Program Management","parent_id":null,"child_ids":[],"jobs":[]},{"id":43806,"name":"Research & Development","parent_id":null,"child_ids":[87842,87841,87854,87843,144866,87846,87981,87847,87852,87850,87848,45530,87849],"jobs":[]},{"id":87851,"name":"Security","parent_id":87845,"child_ids":[],"jobs":[]},{"id":87845,"name":"Services","parent_id":null,"child_ids":[49925,87853,74156,45548,87851],"jobs":[]},{"id":91697,"name":"Status App ","parent_id":null,"child_ids":[],"jobs":[]},{"id":216509,"name":"Status Network","parent_id":null,"child_ids":[],"jobs":[]},{"id":54783,"name":"Technical Writing ","parent_id":null,"child_ids":[],"jobs":[]},{"id":87846,"name":"Vac","parent_id":43806,"child_ids":[],"jobs":[{"absolute_url":"https://boards.greenhouse.io/vac/jobs/5671819","data_compliance":[{"type":"gdpr","requires_consent":false,"requires_processing_consent":false,"requires_retention_consent":false,"retention_period":null}],"internal_job_id":2778364,"location":{"name":"Remote (Worldwide)"},"metadata":null,"id":5671819,"updated_at":"2024-04-29T11:27:14-04:00","requisition_id":"BACK-1205","title":"Libp2p Networking Engineer"},{"absolute_url":"https://boards.greenhouse.io/vac/jobs/5700917","data_compliance":[{"type":"gdpr","requires_consent":false,"requires_processing_consent":false,"requires_retention_consent":false,"retention_period":null}],"internal_job_id":2785448,"location":{"name":"Remote (Worldwide)"},"metadata":null,"id":5700917,"updated_at":"2024-07-30T12:42:59-04:00","requisition_id":"BACK-1330","title":"Software Developer in Test (Low Level Programming)"},{"absolute_url":"https://boards.greenhouse.io/vac/jobs/5543925","data_compliance":[{"type":"gdpr","requires_consent":false,"requires_processing_consent":false,"requires_retention_consent":false,"retention_period":null}],"internal_job_id":2735796,"location":{"name":"Remote (Worldwide)"},"metadata":null,"id":5543925,"updated_at":"2024-04-29T11:27:14-04:00","requisition_id":"Back-1245","title":"Zero Knowledge Research Engineer (ACZ)"},{"absolute_url":"https://boards.greenhouse.io/vac/jobs/5453093","data_compliance":[{"type":"gdpr","requires_consent":false,"requires_processing_consent":false,"requires_retention_consent":false,"retention_period":null}],"internal_job_id":2331302,"location":{"name":"Remote (Worldwide)"},"metadata":null,"id":5453093,"updated_at":"2024-04-29T11:27:14-04:00","requisition_id":"PROV-ZKE-1","title":"Zero Knowledge Researcher (Nescience) "}]},{"id":87981,"name":"Waku","parent_id":43806,"child_ids":[],"jobs":[]},{"id":87849,"name":"Web","parent_id":87842,"child_ids":[],"jobs":[]},{"id":0,"name":"No Department","parent_id":null,"child_ids":[],"jobs":[]}]} \ No newline at end of file +{"departments":[{"id":87842,"name":"App","parent_id":43806,"child_ids":[87847,87852,87850,87848,45530,87849],"jobs":[]},{"id":54504,"name":"Brand Design Studio","parent_id":null,"child_ids":[],"jobs":[]},{"id":45532,"name":"Business Development","parent_id":null,"child_ids":[],"jobs":[]},{"id":87841,"name":"Codex","parent_id":43806,"child_ids":[],"jobs":[]},{"id":84549,"name":"Communications","parent_id":null,"child_ids":[],"jobs":[]},{"id":45531,"name":"Design","parent_id":null,"child_ids":[],"jobs":[]},{"id":87847,"name":"Desktop","parent_id":87842,"child_ids":[],"jobs":[]},{"id":87852,"name":"Documentation","parent_id":87842,"child_ids":[],"jobs":[]},{"id":45547,"name":"Engineering ","parent_id":null,"child_ids":[],"jobs":[]},{"id":49925,"name":"Finance","parent_id":87845,"child_ids":[],"jobs":[]},{"id":87854,"name":"Infrastructure","parent_id":43806,"child_ids":[],"jobs":[]},{"id":87853,"name":"Insights","parent_id":87845,"child_ids":[],"jobs":[]},{"id":87850,"name":"Keycard","parent_id":87842,"child_ids":[],"jobs":[]},{"id":145838,"name":"Leadership","parent_id":null,"child_ids":[],"jobs":[]},{"id":74156,"name":"Legal","parent_id":87845,"child_ids":[],"jobs":[]},{"id":91698,"name":"Logos","parent_id":null,"child_ids":[],"jobs":[]},{"id":43807,"name":"Marketing","parent_id":null,"child_ids":[],"jobs":[]},{"id":87848,"name":"Mobile","parent_id":87842,"child_ids":[],"jobs":[]},{"id":87843,"name":"Nimbus","parent_id":43806,"child_ids":[],"jobs":[]},{"id":144866,"name":"Nomos","parent_id":43806,"child_ids":[],"jobs":[]},{"id":45548,"name":"People Operations","parent_id":87845,"child_ids":[],"jobs":[]},{"id":45530,"name":"Product Design","parent_id":87842,"child_ids":[],"jobs":[]},{"id":90941,"name":"Program Management","parent_id":null,"child_ids":[],"jobs":[]},{"id":43806,"name":"Research & Development","parent_id":null,"child_ids":[87842,87841,87854,87843,144866,87846,87981,87847,87852,87850,87848,45530,87849],"jobs":[]},{"id":87851,"name":"Security","parent_id":87845,"child_ids":[],"jobs":[]},{"id":87845,"name":"Services","parent_id":null,"child_ids":[49925,87853,74156,45548,87851],"jobs":[]},{"id":91697,"name":"Status App ","parent_id":null,"child_ids":[],"jobs":[]},{"id":216509,"name":"Status Network","parent_id":null,"child_ids":[],"jobs":[]},{"id":54783,"name":"Technical Writing ","parent_id":null,"child_ids":[],"jobs":[]},{"id":87846,"name":"Vac","parent_id":43806,"child_ids":[],"jobs":[{"absolute_url":"https://boards.greenhouse.io/vac/jobs/6258104","data_compliance":[{"type":"gdpr","requires_consent":false,"requires_processing_consent":false,"requires_retention_consent":false,"retention_period":null}],"internal_job_id":2964440,"location":{"name":"Remote (Worldwide)"},"metadata":null,"id":6258104,"updated_at":"2024-09-17T08:45:19-04:00","requisition_id":"BACK-1469","title":"Networking Engineer P2P "},{"absolute_url":"https://boards.greenhouse.io/vac/jobs/5543925","data_compliance":[{"type":"gdpr","requires_consent":false,"requires_processing_consent":false,"requires_retention_consent":false,"retention_period":null}],"internal_job_id":2735796,"location":{"name":"Remote (Worldwide)"},"metadata":null,"id":5543925,"updated_at":"2024-04-29T11:27:14-04:00","requisition_id":"Back-1245","title":"Zero Knowledge Research Engineer (ACZ)"},{"absolute_url":"https://boards.greenhouse.io/vac/jobs/5453093","data_compliance":[{"type":"gdpr","requires_consent":false,"requires_processing_consent":false,"requires_retention_consent":false,"retention_period":null}],"internal_job_id":2331302,"location":{"name":"Remote (Worldwide)"},"metadata":null,"id":5453093,"updated_at":"2024-04-29T11:27:14-04:00","requisition_id":"PROV-ZKE-1","title":"Zero Knowledge Researcher (Nescience) "}]},{"id":87981,"name":"Waku","parent_id":43806,"child_ids":[],"jobs":[]},{"id":87849,"name":"Web","parent_id":87842,"child_ids":[],"jobs":[]},{"id":0,"name":"No Department","parent_id":null,"child_ids":[],"jobs":[]}]} \ No newline at end of file diff --git a/img/zkvmtest/alloc11.png b/img/zkvmtest/alloc11.png new file mode 100644 index 00000000..3dd7008f Binary files /dev/null and b/img/zkvmtest/alloc11.png differ diff --git a/img/zkvmtest/alloc12.png b/img/zkvmtest/alloc12.png new file mode 100644 index 00000000..d33eb297 Binary files /dev/null and b/img/zkvmtest/alloc12.png differ diff --git a/img/zkvmtest/alloc21.png b/img/zkvmtest/alloc21.png new file mode 100644 index 00000000..a358adff Binary files /dev/null and b/img/zkvmtest/alloc21.png differ diff --git a/img/zkvmtest/alloc22.png b/img/zkvmtest/alloc22.png new file mode 100644 index 00000000..f0535595 Binary files /dev/null and b/img/zkvmtest/alloc22.png differ diff --git a/img/zkvmtest/alloc31.png b/img/zkvmtest/alloc31.png new file mode 100644 index 00000000..3e0f4e2d Binary files /dev/null and b/img/zkvmtest/alloc31.png differ diff --git a/img/zkvmtest/alloc32.png b/img/zkvmtest/alloc32.png new file mode 100644 index 00000000..9e6ad048 Binary files /dev/null and b/img/zkvmtest/alloc32.png differ diff --git a/img/zkvmtest/alloc41.png b/img/zkvmtest/alloc41.png new file mode 100644 index 00000000..986a619c Binary files /dev/null and b/img/zkvmtest/alloc41.png differ diff --git a/img/zkvmtest/alloc42.png b/img/zkvmtest/alloc42.png new file mode 100644 index 00000000..0471a329 Binary files /dev/null and b/img/zkvmtest/alloc42.png differ diff --git a/img/zkvmtest/alloc51.png b/img/zkvmtest/alloc51.png new file mode 100644 index 00000000..ebe24560 Binary files /dev/null and b/img/zkvmtest/alloc51.png differ diff --git a/img/zkvmtest/alloc52.png b/img/zkvmtest/alloc52.png new file mode 100644 index 00000000..4ac1b951 Binary files /dev/null and b/img/zkvmtest/alloc52.png differ diff --git a/img/zkvmtest/consumed11.png b/img/zkvmtest/consumed11.png new file mode 100644 index 00000000..fd07d240 Binary files /dev/null and b/img/zkvmtest/consumed11.png differ diff --git a/img/zkvmtest/consumed12.png b/img/zkvmtest/consumed12.png new file mode 100644 index 00000000..efc76f3d Binary files /dev/null and b/img/zkvmtest/consumed12.png differ diff --git a/img/zkvmtest/consumed21.png b/img/zkvmtest/consumed21.png new file mode 100644 index 00000000..f8f3241b Binary files /dev/null and b/img/zkvmtest/consumed21.png differ diff --git a/img/zkvmtest/consumed22.png b/img/zkvmtest/consumed22.png new file mode 100644 index 00000000..455f1e4c Binary files /dev/null and b/img/zkvmtest/consumed22.png differ diff --git a/img/zkvmtest/consumed31.png b/img/zkvmtest/consumed31.png new file mode 100644 index 00000000..2394f924 Binary files /dev/null and b/img/zkvmtest/consumed31.png differ diff --git a/img/zkvmtest/consumed32.png b/img/zkvmtest/consumed32.png new file mode 100644 index 00000000..756dff57 Binary files /dev/null and b/img/zkvmtest/consumed32.png differ diff --git a/img/zkvmtest/consumed41.png b/img/zkvmtest/consumed41.png new file mode 100644 index 00000000..1ca4a8c7 Binary files /dev/null and b/img/zkvmtest/consumed41.png differ diff --git a/img/zkvmtest/consumed42.png b/img/zkvmtest/consumed42.png new file mode 100644 index 00000000..591368da Binary files /dev/null and b/img/zkvmtest/consumed42.png differ diff --git a/img/zkvmtest/consumed51.png b/img/zkvmtest/consumed51.png new file mode 100644 index 00000000..a43e073a Binary files /dev/null and b/img/zkvmtest/consumed51.png differ diff --git a/img/zkvmtest/consumed52.png b/img/zkvmtest/consumed52.png new file mode 100644 index 00000000..c0d94996 Binary files /dev/null and b/img/zkvmtest/consumed52.png differ diff --git a/img/zkvmtest/general11.png b/img/zkvmtest/general11.png new file mode 100644 index 00000000..2ae5f575 Binary files /dev/null and b/img/zkvmtest/general11.png differ diff --git a/img/zkvmtest/general12.png b/img/zkvmtest/general12.png new file mode 100644 index 00000000..af9a9a50 Binary files /dev/null and b/img/zkvmtest/general12.png differ diff --git a/img/zkvmtest/general21.png b/img/zkvmtest/general21.png new file mode 100644 index 00000000..3fbdcaa6 Binary files /dev/null and b/img/zkvmtest/general21.png differ diff --git a/img/zkvmtest/general22.png b/img/zkvmtest/general22.png new file mode 100644 index 00000000..ba135132 Binary files /dev/null and b/img/zkvmtest/general22.png differ diff --git a/img/zkvmtest/general31.png b/img/zkvmtest/general31.png new file mode 100644 index 00000000..b7f59cc0 Binary files /dev/null and b/img/zkvmtest/general31.png differ diff --git a/img/zkvmtest/general32.png b/img/zkvmtest/general32.png new file mode 100644 index 00000000..f9e7a1e2 Binary files /dev/null and b/img/zkvmtest/general32.png differ diff --git a/img/zkvmtest/general41.png b/img/zkvmtest/general41.png new file mode 100644 index 00000000..99aab98b Binary files /dev/null and b/img/zkvmtest/general41.png differ diff --git a/img/zkvmtest/general42.png b/img/zkvmtest/general42.png new file mode 100644 index 00000000..cc8e6ae0 Binary files /dev/null and b/img/zkvmtest/general42.png differ diff --git a/img/zkvmtest/general51.png b/img/zkvmtest/general51.png new file mode 100644 index 00000000..c436a627 Binary files /dev/null and b/img/zkvmtest/general51.png differ diff --git a/img/zkvmtest/general52.png b/img/zkvmtest/general52.png new file mode 100644 index 00000000..584c8cb7 Binary files /dev/null and b/img/zkvmtest/general52.png differ diff --git a/img/zkvmtest/sizes11.png b/img/zkvmtest/sizes11.png new file mode 100644 index 00000000..cb5877d0 Binary files /dev/null and b/img/zkvmtest/sizes11.png differ diff --git a/img/zkvmtest/sizes12.png b/img/zkvmtest/sizes12.png new file mode 100644 index 00000000..a6d6ca32 Binary files /dev/null and b/img/zkvmtest/sizes12.png differ diff --git a/img/zkvmtest/sizes21.png b/img/zkvmtest/sizes21.png new file mode 100644 index 00000000..c254a4a4 Binary files /dev/null and b/img/zkvmtest/sizes21.png differ diff --git a/img/zkvmtest/sizes22.png b/img/zkvmtest/sizes22.png new file mode 100644 index 00000000..8d78c54b Binary files /dev/null and b/img/zkvmtest/sizes22.png differ diff --git a/img/zkvmtest/sizes31.png b/img/zkvmtest/sizes31.png new file mode 100644 index 00000000..9caf4499 Binary files /dev/null and b/img/zkvmtest/sizes31.png differ diff --git a/img/zkvmtest/sizes32.png b/img/zkvmtest/sizes32.png new file mode 100644 index 00000000..d00d5178 Binary files /dev/null and b/img/zkvmtest/sizes32.png differ diff --git a/img/zkvmtest/sizes41.png b/img/zkvmtest/sizes41.png new file mode 100644 index 00000000..7a61f8bb Binary files /dev/null and b/img/zkvmtest/sizes41.png differ diff --git a/img/zkvmtest/sizes42.png b/img/zkvmtest/sizes42.png new file mode 100644 index 00000000..1040a3ec Binary files /dev/null and b/img/zkvmtest/sizes42.png differ diff --git a/img/zkvmtest/sizes51.png b/img/zkvmtest/sizes51.png new file mode 100644 index 00000000..9cf9f5d8 Binary files /dev/null and b/img/zkvmtest/sizes51.png differ diff --git a/img/zkvmtest/sizes52.png b/img/zkvmtest/sizes52.png new file mode 100644 index 00000000..7b405c8d Binary files /dev/null and b/img/zkvmtest/sizes52.png differ diff --git a/img/zkvmtest/tempalloc11.png b/img/zkvmtest/tempalloc11.png new file mode 100644 index 00000000..922773bf Binary files /dev/null and b/img/zkvmtest/tempalloc11.png differ diff --git a/img/zkvmtest/tempalloc12.png b/img/zkvmtest/tempalloc12.png new file mode 100644 index 00000000..81f68417 Binary files /dev/null and b/img/zkvmtest/tempalloc12.png differ diff --git a/img/zkvmtest/tempalloc21.png b/img/zkvmtest/tempalloc21.png new file mode 100644 index 00000000..2e07c549 Binary files /dev/null and b/img/zkvmtest/tempalloc21.png differ diff --git a/img/zkvmtest/tempalloc22.png b/img/zkvmtest/tempalloc22.png new file mode 100644 index 00000000..457e819e Binary files /dev/null and b/img/zkvmtest/tempalloc22.png differ diff --git a/img/zkvmtest/tempalloc31.png b/img/zkvmtest/tempalloc31.png new file mode 100644 index 00000000..1fe0d83b Binary files /dev/null and b/img/zkvmtest/tempalloc31.png differ diff --git a/img/zkvmtest/tempalloc32.png b/img/zkvmtest/tempalloc32.png new file mode 100644 index 00000000..60c61440 Binary files /dev/null and b/img/zkvmtest/tempalloc32.png differ diff --git a/img/zkvmtest/tempalloc41.png b/img/zkvmtest/tempalloc41.png new file mode 100644 index 00000000..8d37bf33 Binary files /dev/null and b/img/zkvmtest/tempalloc41.png differ diff --git a/img/zkvmtest/tempalloc42.png b/img/zkvmtest/tempalloc42.png new file mode 100644 index 00000000..fb96b2af Binary files /dev/null and b/img/zkvmtest/tempalloc42.png differ diff --git a/img/zkvmtest/tempalloc51.png b/img/zkvmtest/tempalloc51.png new file mode 100644 index 00000000..b9cfd264 Binary files /dev/null and b/img/zkvmtest/tempalloc51.png differ diff --git a/img/zkvmtest/tempalloc52.png b/img/zkvmtest/tempalloc52.png new file mode 100644 index 00000000..cf022f4e Binary files /dev/null and b/img/zkvmtest/tempalloc52.png differ diff --git a/index.html b/index.html index f6d58b2e..13021945 100644 --- a/index.html +++ b/index.html @@ -10,8 +10,8 @@ <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/katex@0.13.24/dist/katex.min.css" integrity="sha384-odtC+0UGzzFL/6PNoE8rX/SPcQDXBJ+uRepguP4QkPCm2LBxH3FA3y+fKSiJ+AmM" crossorigin="anonymous"><link rel="stylesheet" href="/assets/css/styles.08d697e6.css"> -<link rel="preload" href="/assets/js/runtime~main.556fa6f5.js" as="script"> -<link rel="preload" href="/assets/js/main.ffc20c94.js" as="script"> +<link rel="preload" href="/assets/js/runtime~main.a9103199.js" as="script"> +<link rel="preload" href="/assets/js/main.5454aec3.js" as="script"> <meta property="og:image" content="https://vac.dev/_og/e86d6f5bc629b967df32771853364224240610e4.png"><meta name="twitter:image" content="https://vac.dev/_og/e86d6f5bc629b967df32771853364224240610e4.png"></head> <body class="navigation-with-keyboard"> <script>!function(){function e(e){document.documentElement.setAttribute("data-theme",e)}var t=function(){var e=null;try{e=new URLSearchParams(window.location.search).get("docusaurus-theme")}catch(e){}return e}()||function(){var e=null;try{e=localStorage.getItem("theme")}catch(e){}return e}();null!==t?e(t):window.matchMedia("(prefers-color-scheme: dark)").matches?e("dark"):window.matchMedia("(prefers-color-scheme: light)").matches?e("light"):e("dark")}()</script><div id="__docusaurus"> @@ -23,7 +23,7 @@ Vac comprises <a href="/vsus">R&D Service Units</a>, <a href="/deepresearch">Deep Research</a>, and <a href="/vips">Incubator Projects</a>. We do applied research based on which we build protocols, libraries, <a href="https://rfc.vac.dev/" target="_blank" rel="noopener noreferrer">specifications</a>, and publications. As custodians of these protocols, our aim is to adhere to <a href="/principles">a set of principles</a> that ensure their alignment with our core values and objectives.</p></div></article><nav class="pagination-nav docusaurus-mt-lg" aria-label="Docs pages"><a class="pagination-nav__link pagination-nav__link--next" href="/vsus"><span class="lsd-typography lsd-typography--body2 pagination-nav__label">R&D Service Units</span><div class="icon_S7Kx m_thRi"><svg width="14" height="14" viewBox="0 0 14 14" fill="none" xmlns="http://www.w3.org/2000/svg" role="img"><path d="m7 2.333-.823.823 3.255 3.26H2.333v1.167h7.1l-3.256 3.261.823.823L11.667 7 7 2.333Z" fill="#fff"></path></svg></div></a></nav></div></div><div class="gap1_XuuQ"></div></div></div></main></div></div><footer class="footer"><div class="container container-fluid firstRow_ar1q"><div class="footer__bottom text--center"><div class="margin-bottom--sm"><a class="footerLogoLink_BH7S" href="/"><img src="/theme/image/logo.svg" alt="Vac Research" class="themedImage_ToTc themedImage--light_HNdA footer__logo" width="22"><img src="/theme/image/logo.svg" alt="Vac Research" class="themedImage_ToTc themedImage--dark_i4oU footer__logo" width="22"></a></div><div class="footer__copyright">Vac Research © 2024<br>All rights reserved.</div></div><div class="row footer__links"><div class="col footer__col"><div class="footer__title"></div><ul class="footer__items clean-list"><li class="footer__item"><a href="https://twitter.com/vacp2p" target="_blank" rel="noopener noreferrer" class="footer__link-item">Twitter<svg width="13.5" height="13.5" aria-hidden="true" viewBox="0 0 24 24" class="iconExternalLink_nPIU"><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"></path></svg></a></li><li class="footer__item"><a href="https://discord.gg/PQFdubGt6d" target="_blank" rel="noopener noreferrer" class="footer__link-item">Discord<svg width="13.5" height="13.5" aria-hidden="true" viewBox="0 0 24 24" class="iconExternalLink_nPIU"><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"></path></svg></a></li><li class="footer__item"><a href="https://github.com/vacp2p" target="_blank" rel="noopener noreferrer" class="footer__link-item">Github<svg width="13.5" height="13.5" aria-hidden="true" viewBox="0 0 24 24" class="iconExternalLink_nPIU"><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"></path></svg></a></li></ul></div><div class="col footer__col"><div class="footer__title"></div><ul class="footer__items clean-list"><li class="footer__item"><a href="https://jobs.status.im/" target="_blank" rel="noopener noreferrer" class="footer__link-item">Work With Us<svg width="13.5" height="13.5" aria-hidden="true" viewBox="0 0 24 24" class="iconExternalLink_nPIU"><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"></path></svg></a></li><li class="footer__item"><a class="footer__link-item" href="/terms">Terms & Conditions</a></li><li class="footer__item"><a class="footer__link-item" href="/privacy-policy">Privacy Policy</a></li><li class="footer__item"><a class="footer__link-item" href="/security">Security</a></li></ul></div></div></div><div class="secondRow__ww3"><div class="footer__bottom text--center">Logos Collective</div><div class="row footer__links"><div class="col footer__col"><div class="footer__title">Research</div><ul class="footer__items clean-list"><li class="footer__item"><a href="https://vac.dev" target="_blank" rel="noopener noreferrer" class="footer__link-item">VacP2P<svg width="13.5" height="13.5" aria-hidden="true" viewBox="0 0 24 24" class="iconExternalLink_nPIU"><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"></path></svg></a></li><li class="footer__item"><a href="https://afaik.institute" target="_blank" rel="noopener noreferrer" class="footer__link-item">AFAIK<svg width="13.5" height="13.5" aria-hidden="true" viewBox="0 0 24 24" class="iconExternalLink_nPIU"><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"></path></svg></a></li></ul></div><div class="col footer__col"><div class="footer__title">Infrastructure</div><ul class="footer__items clean-list"><li class="footer__item"><a href="https://waku.org/" target="_blank" rel="noopener noreferrer" class="footer__link-item">Waku<svg width="13.5" height="13.5" aria-hidden="true" viewBox="0 0 24 24" class="iconExternalLink_nPIU"><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"></path></svg></a></li><li class="footer__item"><a href="https://nimbus.team/" target="_blank" rel="noopener noreferrer" class="footer__link-item">Nimbus<svg width="13.5" height="13.5" aria-hidden="true" viewBox="0 0 24 24" class="iconExternalLink_nPIU"><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"></path></svg></a></li><li class="footer__item"><a href="https://codex.storage" target="_blank" rel="noopener noreferrer" class="footer__link-item">Codex<svg width="13.5" height="13.5" aria-hidden="true" viewBox="0 0 24 24" class="iconExternalLink_nPIU"><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"></path></svg></a></li><li class="footer__item"><a href="https://nomos.tech" target="_blank" rel="noopener noreferrer" class="footer__link-item">Nomos<svg width="13.5" height="13.5" aria-hidden="true" viewBox="0 0 24 24" class="iconExternalLink_nPIU"><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"></path></svg></a></li></ul></div><div class="col footer__col"><div class="footer__title">Creative Studio</div><ul class="footer__items clean-list"><li class="footer__item"><a href="https://acid.info" target="_blank" rel="noopener noreferrer" class="footer__link-item">Acid.info<svg width="13.5" height="13.5" aria-hidden="true" viewBox="0 0 24 24" class="iconExternalLink_nPIU"><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"></path></svg></a></li></ul></div><div class="col footer__col"><div class="footer__title">Movement</div><ul class="footer__items clean-list"><li class="footer__item"><a href="https://logos.co" target="_blank" rel="noopener noreferrer" class="footer__link-item">Logos<svg width="13.5" height="13.5" aria-hidden="true" viewBox="0 0 24 24" class="iconExternalLink_nPIU"><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"></path></svg></a></li></ul></div><div class="col footer__col"><div class="footer__title">User-facing products</div><ul class="footer__items clean-list"><li class="footer__item"><a href="https://status.im" target="_blank" rel="noopener noreferrer" class="footer__link-item">Status<svg width="13.5" height="13.5" aria-hidden="true" viewBox="0 0 24 24" class="iconExternalLink_nPIU"><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"></path></svg></a></li><li class="footer__item"><a href="https://keycard.tech" target="_blank" rel="noopener noreferrer" class="footer__link-item">Keycard<svg width="13.5" height="13.5" aria-hidden="true" viewBox="0 0 24 24" class="iconExternalLink_nPIU"><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"></path></svg></a></li></ul></div></div></div><button class="backToTop_wDfN lsd-button lsd-button--small lsd-button--outlined"><span class="lsd-typography lsd-typography--label2 lsd-button__text">Back to top ↑</span></button></footer></div></div> -<script src="/assets/js/runtime~main.556fa6f5.js"></script> -<script src="/assets/js/main.ffc20c94.js"></script> +<script src="/assets/js/runtime~main.a9103199.js"></script> +<script src="/assets/js/main.5454aec3.js"></script> </body> </html> \ No newline at end of file diff --git a/join-us/index.html b/join-us/index.html index aa7914f9..48874ec9 100644 --- a/join-us/index.html +++ b/join-us/index.html @@ -10,8 +10,8 @@ <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/katex@0.13.24/dist/katex.min.css" integrity="sha384-odtC+0UGzzFL/6PNoE8rX/SPcQDXBJ+uRepguP4QkPCm2LBxH3FA3y+fKSiJ+AmM" crossorigin="anonymous"><link rel="stylesheet" href="/assets/css/styles.08d697e6.css"> -<link rel="preload" href="/assets/js/runtime~main.556fa6f5.js" as="script"> -<link rel="preload" href="/assets/js/main.ffc20c94.js" as="script"> +<link rel="preload" href="/assets/js/runtime~main.a9103199.js" as="script"> +<link rel="preload" href="/assets/js/main.5454aec3.js" as="script"> <meta property="og:image" content="https://vac.dev/_og/b0ee154cd20300127a1fd8ca6f9e8d0bc06bb522.png"><meta name="twitter:image" content="https://vac.dev/_og/b0ee154cd20300127a1fd8ca6f9e8d0bc06bb522.png"></head> <body class="navigation-with-keyboard"> <script>!function(){function e(e){document.documentElement.setAttribute("data-theme",e)}var t=function(){var e=null;try{e=new URLSearchParams(window.location.search).get("docusaurus-theme")}catch(e){}return e}()||function(){var e=null;try{e=localStorage.getItem("theme")}catch(e){}return e}();null!==t?e(t):window.matchMedia("(prefers-color-scheme: dark)").matches?e("dark"):window.matchMedia("(prefers-color-scheme: light)").matches?e("light"):e("dark")}()</script><div id="__docusaurus"> @@ -19,8 +19,8 @@ .lsd-dropdown--error ) .lsd-dropdown__trigger:hover .lsd-dropdown__option-label,.lsd-dropdown:not(.lsd-dropdown--disabled):not( .lsd-dropdown--error - ) .lsd-dropdown__trigger:focus .lsd-dropdown__option-label{-webkit-text-decoration:underline;text-decoration:underline;}.lsd-dropdown__label{display:block;}.lsd-dropdown__button-container{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-box-pack:justify;-webkit-justify-content:space-between;justify-content:space-between;}.lsd-dropdown__trigger{width:100%;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:row;-ms-flex-direction:row;flex-direction:row;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:justify;-webkit-justify-content:space-between;justify-content:space-between;border:none;cursor:pointer;background:none;}.lsd-dropdown__trigger:focus{outline:none;}.lsd-dropdown__option-label{cursor:inherit;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;}.lsd-dropdown__icons{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:row;-ms-flex-direction:row;flex-direction:row;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:center;-ms-flex-pack:center;-webkit-justify-content:center;justify-content:center;gap:8px;}.lsd-dropdown__icon{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;}.lsd-dropdown__supporting-text{margin:6px 14px;}.lsd-dropdown--error .lsd-dropdown__option-label{-webkit-text-decoration:line-through;text-decoration:line-through;}.lsd-dropdown--disabled{opacity:0.34;cursor:initial;}.lsd-dropdown--large{width:208px;}.lsd-dropdown--large.lsd-dropdown--error{width:230px;}.lsd-dropdown--large .lsd-dropdown__label{margin:0 0 6px 18px;}.lsd-dropdown--large .lsd-dropdown__button-container{height:40px;}.lsd-dropdown--large .lsd-dropdown__trigger{padding:10px 0px 10px 18px;}.lsd-dropdown--large .lsd-dropdown__icons{padding:0px 14px;}.lsd-dropdown--medium{width:188px;}.lsd-dropdown--medium.lsd-dropdown--error{width:210px;}.lsd-dropdown--medium .lsd-dropdown__label{margin:0 0 6px 14px;}.lsd-dropdown--medium .lsd-dropdown__button-container{height:32px;}.lsd-dropdown--medium .lsd-dropdown__trigger{padding:6px 0px 6px 14px;}.lsd-dropdown--medium .lsd-dropdown__icons{padding:0px 12px;}.lsd-dropdown--small{width:164px;}.lsd-dropdown--small.lsd-dropdown--error{width:186px;}.lsd-dropdown--small .lsd-dropdown__label{margin:0 0 6px 12px;}.lsd-dropdown--small .lsd-dropdown__button-container{height:28px;}.lsd-dropdown--small .lsd-dropdown__trigger{padding:6px 0px 6px 12px;}.lsd-dropdown--small .lsd-dropdown__icons{padding:0px 10px;}.lsd-dropdown--outlined .lsd-dropdown__button-container{border:1px solid rgb(var(--lsd-border-primary));}.lsd-dropdown--underlined .lsd-dropdown__button-container{border:1px solid transparent;border-bottom:1px solid rgb(var(--lsd-border-primary));}</style><style data-emotion="css-global w2g5fy">.lsd-dropdown-item{width:100%;box-sizing:border-box;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:row;-ms-flex-direction:row;flex-direction:row;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;border:1px solid rgb(var(--lsd-border-primary));}.lsd-dropdown-item:not(.lsd-dropdown-item--disabled){cursor:pointer;}.lsd-dropdown-item:not(.lsd-dropdown-item--disabled):hover,.lsd-dropdown-item:not(.lsd-dropdown-item--disabled):focus{outline:none;}.lsd-dropdown-item:not(.lsd-dropdown-item--disabled):hover .lsd-dropdown-item__label,.lsd-dropdown-item:not(.lsd-dropdown-item--disabled):focus .lsd-dropdown-item__label{-webkit-text-decoration:underline;text-decoration:underline;}.lsd-dropdown-item__label{display:block;overflow:hidden;white-space:nowrap;text-overflow:ellipsis;}.lsd-dropdown-item--disabled{opacity:0.34;}.lsd-dropdown-item__icon{margin-right:18px;-webkit-flex-shrink:0;-ms-flex-negative:0;flex-shrink:0;}.lsd-dropdown-item--small{padding:5px 9px;height:28px;}.lsd-dropdown-item--medium{padding:5px 11px;height:32px;}.lsd-dropdown-item--large{padding:5px 13px;height:40px;}</style><style data-emotion="css-global ww9kgc">.lsd-breadcrumb__list{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:row;-ms-flex-direction:row;flex-direction:row;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;list-style-type:none;margin:0;padding:0;}.lsd-breadcrumb--disabled .lsd-breadcrumb__list{opacity:0.34;cursor:initial;pointer-events:none;}.lsd-breadcrumb__dropdown-menu{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column;overflow:auto;border:1px solid rgb(var(--lsd-border-primary));margin-top:10px;position:absolute;width:auto!important;}.lsd-breadcrumb__dropdown-menu>li{cursor:pointer;}.lsd-breadcrumb__dropdown-menu>li:not(:last-child){border-bottom:1px solid rgb(var(--lsd-border-primary));}.lsd-breadcrumb__dropdown-menu>li:hover,.lsd-breadcrumb__dropdown-menu>li:focus{-webkit-text-decoration:underline;text-decoration:underline;text-decoration-color:rgb(var(--lsd-border-primary));}.lsd-breadcrumb__dropdown-menu li>a{width:164px;padding:5px 11px;}</style><style data-emotion="css-global 4gvini">.lsd-breadcrumb-item{list-style-type:none;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;}.lsd-breadcrumb__list>li:not(:last-child)::after{display:inline-block;margin-inline:12px;content:'/';}.lsd-breadcrumb-item__link{-webkit-text-decoration:none;text-decoration:none;cursor:pointer;}.lsd-breadcrumb-item--outlined{padding:3px 11px;border:1px solid rgb(var(--lsd-border-primary));}.lsd-breadcrumb:not(.lsd-breadcrumb--disabled) .lsd-breadcrumb-item__link:hover,.lsd-breadcrumb:not(.lsd-breadcrumb--disabled) .lsd-breadcrumb-item__link:focus{-webkit-text-decoration:underline;text-decoration:underline;text-decoration-color:rgb(var(--lsd-border-primary));}</style><style data-emotion="css-global 1cwg3oc">.lsd-card{box-sizing:border-box;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column;}.lsd-card>.lsd-card-header{margin-bottom:-1px;}</style><style data-emotion="css-global v7d76i">.lsd-card-header{box-sizing:border-box;padding:10px 18px;text-align:center;border:1px solid rgb(var(--lsd-border-primary));}.lsd-card-header__title{overflow:hidden;word-break:break-all;}.lsd-card-header--large{padding:10px 18px;}.lsd-card-header--medium{padding:6px 14px;}.lsd-card-header--small{padding:6px 12px;}</style><style data-emotion="css-global 1txgafh">.lsd-card-body{box-sizing:border-box;padding:14px 22px;border:1px solid rgb(var(--lsd-border-primary));}</style><style data-emotion="css-global kzy52c">.lsd-tag{width:-webkit-fit-content;width:-moz-fit-content;width:fit-content;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:row;-ms-flex-direction:row;flex-direction:row;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:center;-ms-flex-pack:center;-webkit-justify-content:center;justify-content:center;box-sizing:border-box;border:1px solid rgb(var(--lsd-icon-primary));}.lsd-tag:hover,.lsd-tag:focus{-webkit-text-decoration:underline;text-decoration:underline;cursor:pointer;}.lsd-badge--large{padding:3px 11px;gap:12px;height:28px;}.lsd-badge--small{padding:3px 7px;gap:8px;height:24px;}.lsd-tag--filled{background-color:rgb(var(--lsd-icon-primary));}.lsd-tag--filled .lsd-tag__label{color:rgb(var(--lsd-text-secondary));}.lsd-tag--filled svg{--lsd-icon-primary:var(--lsd-icon-secondary);}.lsd-tag--outlined{color:rgb(var(--lsd-text-primary));}.lsd-tag--disabled{opacity:0.3;cursor:initial;pointer-events:none;}</style><style data-emotion="css-global 4wy0ub">.lsd-text-field{box-sizing:border-box;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column;}.lsd-text-field__input-container{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:justify;-webkit-justify-content:space-between;justify-content:space-between;}.lsd-text-field--disabled{opacity:0.34;}.lsd-text-field__input{border:none;outline:none;font-size:14px;color:rgb(var(--lsd-text-primary));background:none;width:100%;}.lsd-text-field__input:hover{outline:none;}.lsd-text-field__input::-webkit-input-placeholder{color:rgb(var(--lsd-text-primary));opacity:0.3;}.lsd-text-field__input::-moz-placeholder{color:rgb(var(--lsd-text-primary));opacity:0.3;}.lsd-text-field__input:-ms-input-placeholder{color:rgb(var(--lsd-text-primary));opacity:0.3;}.lsd-text-field__input::placeholder{color:rgb(var(--lsd-text-primary));opacity:0.3;}.lsd-text-field--error .lsd-text-field__input{-webkit-text-decoration:line-through;text-decoration:line-through;}.lsd-text-field__supporting-text{width:-webkit-fit-content;width:-moz-fit-content;width:fit-content;}.lsd-text-field--large{width:208px;}.lsd-text-field--large>*{padding:10px 14px 10px 18px;}.lsd-text-field--medium{width:188px;}.lsd-text-field--medium>*{padding:6px 12px 6px 14px;}.lsd-text-field--small{width:164px;}.lsd-text-field--small>*{padding:6px 10px 6px 12px;}.lsd-text-field__label{padding-top:0;padding-bottom:6px;}.lsd-text-field__supporting-text{padding-bottom:0;padding-top:6px;}.lsd-text-field--outlined .lsd-text-field__input-container{border:1px solid rgb(var(--lsd-border-primary));}.lsd-text-field--underlined .lsd-text-field__input-container{border:1px solid transparent;border-bottom:1px solid rgb(var(--lsd-border-primary));}.lsd-text-field__clear-button{padding:0;width:auto;height:auto;margin:0;border:0;}</style><style data-emotion="css-global uhig7c">.lsd-checkbox{position:relative;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:row;-ms-flex-direction:row;flex-direction:row;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;}.lsd-checkbox__input{opacity:0;position:absolute;left:0;top:0;padding:0;margin:0;width:100%;height:100%;}.lsd-checkbox:not(.lsd-checkbox--disabled):hover,.lsd-checkbox:not(.lsd-checkbox--disabled).lsd-checkbox--focused{-webkit-text-decoration:underline;text-decoration:underline;}.lsd-checkbox:not(.lsd-checkbox--disabled) .lsd-checkbox__input{cursor:pointer;}.lsd-checkbox--disabled{opacity:0.34;}.lsd-checkbox__label{margin-left:18px;}.lsd-checkbox--large .lsd-checkbox__label{margin-left:18px;}.lsd-checkbox--medium .lsd-checkbox__label{margin-left:14px;}.lsd-checkbox--small .lsd-checkbox__label{margin-left:12px;}</style><style data-emotion="css-global txommo">.lsd-autocomplete{box-sizing:border-box;}.lsd-autocomplete__label{display:block;}.lsd-autocomplete__input-container{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-box-pack:justify;-webkit-justify-content:space-between;justify-content:space-between;}.lsd-autocomplete--disabled{opacity:0.34;}.lsd-autocomplete__input{border:none;outline:none;font-size:14px;color:rgb(var(--lsd-text-primary));background:none;width:100%;}.lsd-autocomplete__input:hover{outline:none;}.lsd-autocomplete__input::-webkit-input-placeholder{color:rgb(var(--lsd-text-primary));opacity:0.3;}.lsd-autocomplete__input::-moz-placeholder{color:rgb(var(--lsd-text-primary));opacity:0.3;}.lsd-autocomplete__input:-ms-input-placeholder{color:rgb(var(--lsd-text-primary));opacity:0.3;}.lsd-autocomplete__input::placeholder{color:rgb(var(--lsd-text-primary));opacity:0.3;}.lsd-autocomplete__icon{cursor:pointer;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;}.lsd-autocomplete--error{-webkit-text-decoration:line-through;text-decoration:line-through;}.lsd-autocomplete--large{width:208px;}.lsd-autocomplete--large .lsd-autocomplete__label{margin:0 0 6px 18px;}.lsd-autocomplete--large .lsd-autocomplete__input-container{height:40px;}.lsd-autocomplete--large .lsd-autocomplete__input{padding:9px 17px;}.lsd-autocomplete--large .lsd-autocomplete__icon{padding:12px 13px;}.lsd-autocomplete--medium{width:188px;}.lsd-autocomplete--medium .lsd-autocomplete__label{margin:0 0 6px 14px;}.lsd-autocomplete--medium .lsd-autocomplete__input-container{height:32px;}.lsd-autocomplete--medium .lsd-autocomplete__input{padding:5px 13px;}.lsd-autocomplete--medium .lsd-autocomplete__icon{padding:8px 11px;}.lsd-autocomplete--small{width:164px;}.lsd-autocomplete--small .lsd-autocomplete__label{margin:0 0 6px 12px;}.lsd-autocomplete--small .lsd-autocomplete__input-container{height:28px;}.lsd-autocomplete--small .lsd-autocomplete__input{padding:5px 11px;}.lsd-autocomplete--small .lsd-autocomplete__icon{padding:6px 9px;}.lsd-autocomplete--outlined .lsd-autocomplete__input-container{border:1px solid rgb(var(--lsd-border-primary));}.lsd-autocomplete--underlined .lsd-autocomplete__input-container{border:1px solid transparent;border-bottom:1px solid rgb(var(--lsd-border-primary));}.lsd-autocomplete__dropdown-item-placeholder{opacity:0.5;white-space:pre;}</style><style data-emotion="css-global quxxm6">.lsd-quote{color:rgb(var(--lsd-text-primary));white-space:pre-wrap;}.lsd-quote--indented-inline{border-left:1px solid rgb(var(--lsd-border-primary));padding:4px 8px 4px 28px;}.lsd-quote--parentheses{padding:0px;text-align:center;}.lsd-quote--parentheses::before{content:'***';}.lsd-quote--parentheses::after{content:'***';}</style><style data-emotion="css-global a49t4h">.lsd-collapse{box-sizing:border-box;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column;}.lsd-collapse--open .lsd-collapse__content{border-top:1px solid transparent;}.lsd-collapse__content{border:1px solid rgb(var(--lsd-border-primary));}</style><style data-emotion="css-global 12ppw0q">.lsd-collapse-header{box-sizing:border-box;}.lsd-collapse-header:not(.lsd-collapse-header--disabled) .lsd-collapse-header__trigger:hover .lsd-collapse-header__label{-webkit-text-decoration:underline;text-decoration:underline;}.lsd-collapse-header__trigger{width:100%;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:row;-ms-flex-direction:row;flex-direction:row;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:justify;-webkit-justify-content:space-between;justify-content:space-between;cursor:pointer;background:none;border:1px solid rgb(var(--lsd-border-primary));}.lsd-collapse-header__trigger:focus{outline:none;}.lsd-collapse-header__label{cursor:inherit;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;margin:auto;}.lsd-collapse-header__icons{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:row;-ms-flex-direction:row;flex-direction:row;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:end;-ms-flex-pack:end;-webkit-justify-content:flex-end;justify-content:flex-end;}.lsd-collapse-header__icon{margin-right:8px;}.lsd-collapse-header--disabled .lsd-collapse-header__trigger{opacity:0.34;cursor:initial;}.lsd-collapse-header--large .lsd-collapse-header__trigger{width:299px;height:40px;padding:9px 17px;}.lsd-collapse-header--medium .lsd-collapse-header__trigger{width:270px;height:32px;padding:5px 13px;}.lsd-collapse-header--small .lsd-collapse-header__trigger{width:235px;height:28px;padding:5px 11px;}</style><style data-emotion="css-global dixc0i">.lsd-checkbox-group{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column;gap:6px;width:-webkit-fit-content;width:-moz-fit-content;width:fit-content;}.lsd-checkbox-group__label{margin-bottom:6px;}</style><style data-emotion="css-global q2n2hz">.lsd-badge{width:-webkit-fit-content;width:-moz-fit-content;width:fit-content;box-sizing:border-box;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:row;-ms-flex-direction:row;flex-direction:row;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:center;-ms-flex-pack:center;-webkit-justify-content:center;justify-content:center;border:1px solid rgb(var(--lsd-icon-primary));border-radius:20px;}.lsd-badge:hover,.lsd-badge:focus{-webkit-text-decoration:underline;text-decoration:underline;cursor:pointer;}.lsd-badge--large{padding:3px 11px;gap:12px;height:28px;}.lsd-badge--small{padding:3px 7px;gap:8px;height:24px;}.lsd-badge--filled{background-color:rgb(var(--lsd-icon-primary));}.lsd-badge--filled .lsd-badge__label{color:rgb(var(--lsd-text-secondary));}.lsd-badge--filled svg{--lsd-icon-primary:var(--lsd-icon-secondary);}.lsd-badge--outlined{color:rgb(var(--lsd-text-primary));}.lsd-badge--disabled{opacity:0.3;cursor:initial;pointer-events:none;}</style><style data-emotion="css-global rlst54">.lsd-radio-button{position:relative;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:row;-ms-flex-direction:row;flex-direction:row;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;}.lsd-radio-button__input{opacity:0;position:absolute;left:0;top:0;padding:0;margin:0;width:100%;height:100%;}.lsd-radio-button:not(.lsd-radio-button--disabled):hover{-webkit-text-decoration:underline;text-decoration:underline;}.lsd-radio-button:not(.lsd-radio-button--disabled) .lsd-radio-button__input{cursor:pointer;}.lsd-radio-button--disabled{opacity:0.34;}.lsd-radio-button__label{margin-left:18px;}.lsd-radio-button--large .lsd-radio-button__label{margin-left:18px;}.lsd-radio-button--medium .lsd-radio-button__label{margin-left:14px;}.lsd-radio-button--small .lsd-radio-button__label{margin-left:12px;}</style><style data-emotion="css-global mo7h6o">.lsd-radio-button-group{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column;gap:6px;width:-webkit-fit-content;width:-moz-fit-content;width:fit-content;}.lsd-radio-button-group__label{margin-bottom:6px;}</style><style data-emotion="css-global amncrr">.lsd-table{box-sizing:border-box;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column;}.lsd-table>.lsd-table-header{margin-bottom:-1px;}</style><style data-emotion="css-global 1fkbozr">.lsd-table-header{box-sizing:border-box;border:1px solid rgb(var(--lsd-border-primary));}</style><style data-emotion="css-global 1fb1r54">.lsd-table-body table{border-collapse:collapse;text-align:center;table-layout:fixed;width:100%;height:auto;}.lsd-table-body table tr:first-of-type td label:has(input[type='radio']){display:none;}.lsd-table-body__toolbar{box-sizing:border-box;padding:10px;border:1px solid rgb(var(--lsd-border-primary));border-bottom:none;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-box-pack:justify;-webkit-justify-content:space-between;justify-content:space-between;}</style><style data-emotion="css-global 607rj8">.lsd-table-item{border:1px solid rgb(var(--lsd-border-primary));}.lsd-table-item:has(> label){width:40px;}.lsd-table-item:has(> label) input{position:relative;width:14px;height:14px;margin:auto;}.lsd-table-item:has(> label) span{margin-left:14px!important;}.lsd-table-item--large{padding:10px;}.lsd-table-item--medium{padding:6px 8px;}.lsd-table-item--small{padding:6px;}</style><style data-emotion="css-global 1vlh57l">.lsd-table-row{-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;}</style><style data-emotion="css-global 1fw5y3v">.lsd-number-input{width:auto;box-sizing:border-box;}.lsd-number-input__main-container:hover{-webkit-text-decoration:underline;text-decoration:underline;}.lsd-number-input--error .lsd-number-input__main-container{-webkit-text-decoration:line-through;text-decoration:line-through;}.lsd-number-input__label{display:block;}.lsd-number-input__plus-minus-icons{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-shrink:0;-ms-flex-negative:0;flex-shrink:0;}.lsd-number-input__input-container{box-sizing:border-box;border:1px solid rgb(var(--lsd-border-primary));border-left:0px;border-right:0px;}.lsd-number-input__error-icon{cursor:pointer;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;padding:10px 8px;}.lsd-number-input__input-container{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:justify;-webkit-justify-content:space-between;justify-content:space-between;}.lsd-number-input--disabled{opacity:0.34;}.lsd-number-input__main-container{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;}.lsd-number-input__input{border:none;outline:none;font-size:14px;color:rgb(var(--lsd-text-primary));background:none;text-align:center;padding:0 4px;}.lsd-number-input__input::-webkit-inner-spin-button{display:none;-webkit-appearance:none;}.lsd-number-input__input:hover{outline:none;}.lsd-number-input__supporting-text{position:absolute;}.lsd-number-input--large .lsd-number-input__label{margin:0 0 6px 18px;}.lsd-number-input--large .lsd-number-input__input-container{height:40px;}.lsd-number-input--large .lsd-number-input__input{width:62px;}.lsd-number-input--large .lsd-number-input__plus-minus-icons{height:40px;width:40px;}.lsd-number-input--large .lsd-number-input__supporting-text{margin:6px 18px 0 18px;}.lsd-number-input--medium .lsd-number-input__label{margin:0 0 6px 14px;}.lsd-number-input--medium .lsd-number-input__input-container{height:32px;}.lsd-number-input--medium .lsd-number-input__input{width:58px;}.lsd-number-input--medium .lsd-number-input__plus-minus-icons{height:32px;width:32px;}.lsd-number-input--medium .lsd-number-input__supporting-text{margin:6px 14px 0 14px;}.lsd-number-input--small .lsd-number-input__label{margin:0 0 6px 12px;}.lsd-number-input--small .lsd-number-input__input-container{height:28px;}.lsd-number-input--small .lsd-number-input__input{width:50px;}.lsd-number-input--small .lsd-number-input__plus-minus-icons{height:28px;width:28px;}.lsd-number-input--small .lsd-number-input__supporting-text{margin:6px 12px 0 12px;}</style><style data-emotion="css-global 12rmo7o">.lsd-modal{box-sizing:border-box;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column;position:fixed;top:0;left:0;right:0;bottom:0;background-color:rgba(0, 0, 0, 0.5);display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-box-pack:center;-ms-flex-pack:center;-webkit-justify-content:center;justify-content:center;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;z-index:9999;}.lsd-modal__container{position:relative;background:rgb(var(--lsd-surface-primary));padding:20px;max-width:90%;box-sizing:border-box;border:1px solid rgb(var(--lsd-border-primary));}.lsd-modal__header{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-box-pack:justify;-webkit-justify-content:space-between;justify-content:space-between;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;}.lsd-modal__close-icon{position:absolute;top:8px;right:8px;cursor:pointer;}.lsd-modal__title-and-subtitle-container{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column;}.lsd-modal--large .lsd-modal__container{min-width:960px;}.lsd-modal--medium .lsd-modal__container{min-width:768px;}.lsd-modal--small .lsd-modal__container{min-width:614px;}.lsd-modal--extra-small .lsd-modal__container{min-width:490px;}</style><style data-emotion="css-global 1k7gzc">.lsd-modal-footer{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;}</style><style data-emotion="css-global 1b9t8so">.lsd-modal-body{margin:18px 0;}</style><style data-emotion="css-global dyud2a">.lsd-date-picker{width:-webkit-fit-content;width:-moz-fit-content;width:fit-content;}.lsd-date-picker__calendar{border-top:none!important;}.lsd-date-picker--large .lsd-date-field--large{width:318px;}.lsd-date-picker--medium .lsd-date-field--medium{width:290px;}.lsd-date-picker--small .lsd-date-field--small{width:262px;}</style><style data-emotion="css-global olq3nk">.lsd-date-field{width:auto;box-sizing:border-box;}.lsd-date-field__label{display:block;}.lsd-date-field__input-container__icon{position:absolute;right:0;cursor:pointer;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;background-color:rgb(var(--lsd-surface-primary));}.lsd-date-field__input-container__icon:focus{background:blue;background-color:pink;border:1px solid rgb(var(--lsd-border-primary));}.lsd-date-field__input-container__no-icon{position:absolute;right:0;background-color:rgb(var(--lsd-surface-primary));padding:12px;}.lsd-date-field--outlined{border:1px solid rgb(var(--lsd-border-primary));}.lsd-date-field--underlined{border-bottom:1px solid rgb(var(--lsd-border-primary));}.lsd-date-field__input-container{position:relative;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:justify;-webkit-justify-content:space-between;justify-content:space-between;}.lsd-date-field--disabled{opacity:0.34;}.lsd-date-field__input-container__input{border:none;outline:none;font-size:14px;color:rgb(var(--lsd-text-primary));background:none;width:100%;opacity:0.4;-webkit-transition:opacity 0.2s ease-in-out;transition:opacity 0.2s ease-in-out;}.lsd-date-field__input-container__input::-webkit-inner-spin-button,.lsd-date-field__input-container__input::-webkit-calendar-picker-indicator{display:none;-webkit-appearance:none;}.lsd-date-field__input-container__input:hover{outline:none;}.lsd-date-field__supporting-text{position:absolute;}.lsd-date-field--large{width:208px;}.lsd-date-field--large .lsd-date-field__label{margin:0 0 6px 18px;}.lsd-date-field--large .lsd-date-field__input-container{height:40px;}.lsd-date-field--large .lsd-date-field__input-container__input{padding:9px 0px 9px 17px;}.lsd-date-field--large .lsd-date-field__input-container__icon{padding:12px 13px;}.lsd-date-field--large .lsd-date-field__supporting-text{margin:6px 18px 0 18px;}.lsd-date-field--medium{width:188px;}.lsd-date-field--medium .lsd-date-field__label{margin:0 0 6px 14px;}.lsd-date-field--medium .lsd-date-field__input-container{height:32px;}.lsd-date-field--medium .lsd-date-field__input-container__input{padding:5px 11px 5px 13px;}.lsd-date-field--medium .lsd-date-field__input-container__icon{padding:8px 11px;}.lsd-date-field--medium .lsd-date-field__supporting-text{margin:6px 14px 0 14px;}.lsd-date-field--small{width:164px;}.lsd-date-field--small .lsd-date-field__label{margin:0 0 6px 12px;}.lsd-date-field--small .lsd-date-field__input-container{height:28px;}.lsd-date-field--small .lsd-date-field__input-container__input{padding:5px 9px 5px 11px;font-size:12px;}.lsd-date-field--small .lsd-date-field__input-container__icon{padding:6px 9px;}.lsd-date-field--small .lsd-date-field__supporting-text{margin:6px 12px 0 12px;}.lsd-date-field__input-container__input:invalid,.lsd-date-field__input-container__input--filled{color:rgb(var(--lsd-border-primary));opacity:1;}.lsd-date-field--error .lsd-date-field__input-container__input::-webkit-datetime-edit-year-field,.lsd-date-field--error .lsd-date-field__input-container__input::-webkit-datetime-edit-month-field,.lsd-date-field--error .lsd-date-field__input-container__input::-webkit-datetime-edit-day-field{-webkit-text-decoration:line-through;text-decoration:line-through;}@supports not selector(::-webkit-datetime-edit-day-field){.lsd-date-field--error .lsd-date-field__input-container__input{-webkit-text-decoration:line-through;text-decoration:line-through;}}</style><style data-emotion="css-global 1gjtao4">.lsd-calendar{border:1px solid rgb(var(--lsd-border-primary));visibility:hidden;position:absolute!important;top:0;left:0;opacity:0;visibility:hidden;margin:0;padding:0;box-sizing:border-box;background:rgb(var(--lsd-surface-primary));-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;}.lsd-calendar-container{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column;padding:8px;}.lsd-calendar--open{opacity:1;visibility:visible;}.lsd-calendar-header{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-box-pack:center;-ms-flex-pack:center;-webkit-justify-content:center;justify-content:center;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;height:32px;margin-bottom:8px;}.lsd-calendar__week_day{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-box-pack:center;-ms-flex-pack:center;-webkit-justify-content:center;justify-content:center;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;aspect-ratio:1/1;margin-bottom:4px;}.lsd-calendar__change-year{position:relative;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-box-pack:center;-ms-flex-pack:center;-webkit-justify-content:center;justify-content:center;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;padding:2px 0xp 2px 8px;gap:6px;border:1px solid transparent;}.lsd-calendar__change-year--active .lsd-calendar__year-and-icon{border:1px solid rgb(var(--lsd-border-primary));}.lsd-calendar__change-year-icon-container{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-box-pack:center;-ms-flex-pack:center;-webkit-justify-content:center;justify-content:center;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;cursor:pointer;border:none;}.lsd-calendar-month{margin-right:8px;}.lsd-calendar__month-and-year{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:center;-ms-flex-pack:center;-webkit-justify-content:center;justify-content:center;}.lsd-calendar-day__container{cursor:pointer;background:transparent;position:relative;box-sizing:border-box;border:1px solid transparent;}.lsd-calendar-day{aspect-ratio:1/1;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-box-pack:center;-ms-flex-pack:center;-webkit-justify-content:center;justify-content:center;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;}.lsd-calendar-day:hover{cursor:pointer;-webkit-text-decoration:underline;text-decoration:underline;text-decoration-color:rgb(var(--lsd-border-primary));}.lsd-calendar-day label:hover{cursor:pointer;}.lsd-calendar-day--selected{border:1px solid rgb(var(--lsd-border-primary));}.lsd-calendar-day--disabled{opacity:0.3;cursor:default;}.lsd-calendar-day__today_indicator{position:absolute;left:50%;-webkit-transform:translateX(-50%);-moz-transform:translateX(-50%);-ms-transform:translateX(-50%);transform:translateX(-50%);bottom:2px;}.lsd-calendar--disabled{pointer-events:none;border:1px solid rgba(var(--lsd-border-primary), 0.3);}.lsd-calendar--disabled label{opacity:0.3;}.lsd-calendar--disabled .lsd-calendar__button{opacity:0.3;}.lsd-calendar--disabled .lsd-calendar-day--selected{opacity:0.3;}.lsd-calendar__button{border:1px solid rgb(var(--lsd-border-primary));cursor:pointer;background:transparent;width:32px;height:32px;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:center;-ms-flex-pack:center;-webkit-justify-content:center;justify-content:center;position:absolute;}.lsd-calendar__next-month-button{top:8px;right:8px;}.lsd-calendar__previous-month-button{top:8px;left:8px;}.lsd-calendar-day--border-left{border-left:1px double rgb(var(--lsd-border-primary));}.lsd-calendar-day--border-right{border-right:1px double rgb(var(--lsd-border-primary));}.lsd-calendar-day--border-left-and-right{border-left:1px double rgb(var(--lsd-border-primary));border-right:1px double rgb(var(--lsd-border-primary));}.lsd-calendar-day--border-top-and-bottom{border-top:1px double rgb(var(--lsd-border-primary));border-bottom:1px double rgb(var(--lsd-border-primary));}.lsd-calendar__month-table{border-collapse:collapse;}.lsd-calendar__year-dropdown{box-sizing:border-box;position:absolute;top:100%;left:0;max-height:200px;overflow-y:auto;width:100%;border:1px solid rgb(var(--lsd-border-primary));border-top:none;z-index:1;}.lsd-calendar__year-dropdown .lsd-calendar-year{border-bottom:1px solid rgb(var(--lsd-border-primary));}.lsd-calendar__year-dropdown--hidden{visibility:hidden;}.lsd-calendar-year{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;cursor:pointer;-webkit-transition:background-color 0.2s;transition:background-color 0.2s;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;background:rgb(var(--lsd-surface-primary));}.lsd-calendar-year:hover{-webkit-text-decoration:underline;text-decoration:underline;}.lsd-calendar__year-and-icon{border:1px solid rgb(var(--lsd-border-primary));}.lsd-calendar--large .lsd-calendar-year{padding:6px 0px 6px 14px;}.lsd-calendar--large .lsd-calendar__change-year-icon-container{width:32px;}.lsd-calendar--medium .lsd-calendar-year{padding:6px 0px 6px 12px;}.lsd-calendar--medium .lsd-calendar__change-year-icon-container{width:28px;}.lsd-calendar--small .lsd-calendar-year{padding:6px 0px 6px 12px;}.lsd-calendar--small .lsd-calendar__change-year-icon-container{width:28px;}</style><style data-emotion="css-global dlrd7d">.lsd-toast{box-sizing:border-box;display:-webkit-inline-box;display:-webkit-inline-flex;display:-ms-inline-flexbox;display:inline-flex;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;background:rgb(var(--lsd-surface-primary));border:1px solid rgb(var(--lsd-border-primary));padding:8px;height:-webkit-fit-content;height:-moz-fit-content;height:fit-content;}.lsd-toast__inline-button-container{-webkit-flex-shrink:0;-ms-flex-negative:0;flex-shrink:0;}.lsd-toast__column-button-container{margin-top:18px;margin-bottom:6px;}.lsd-toast__inline-container{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:justify;-webkit-justify-content:space-between;justify-content:space-between;-webkit-box-flex:1;-webkit-flex-grow:1;-ms-flex-positive:1;flex-grow:1;}.lsd-toast__column-container{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column;-webkit-box-pack:justify;-webkit-justify-content:space-between;justify-content:space-between;}.lsd-toast__text-container{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column;color:rgb(var(--lsd-text-secondary));padding-left:12px;}.lsd-toast__title{position:relative;}.lsd-toast__information{margin-top:4px;}.lsd-toast__button-container{min-height:28px;min-width:60px;width:-webkit-fit-content;width:-moz-fit-content;width:fit-content;padding:0px 12px;}.lsd-toast__close-button{margin-bottom:auto;-webkit-flex-shrink:0;-ms-flex-negative:0;flex-shrink:0;height:28px;width:28px;margin-left:auto;}.lsd-toast__column-icon-container{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-box-pack:center;-ms-flex-pack:center;-webkit-justify-content:center;justify-content:center;margin-bottom:auto;position:relative;top:4px;padding-left:4px;}.lsd-toast__inline-icon-container{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:center;-ms-flex-pack:center;-webkit-justify-content:center;justify-content:center;padding-left:4px;}.lsd-toast__icon{position:relative;}.lsd-toast--large{width:364px;}.lsd-toast--medium{width:336px;}.lsd-toast--small{width:296px;}.lsd-toast--small .lsd-toast__icon{top:0px;}</style><style data-emotion="css-global 5wlfwk">.lsd-toast-provider__toast-container{position:fixed;-webkit-transition:all 230ms cubic-bezier(0.21, 1.02, 0.73, 1);transition:all 230ms cubic-bezier(0.21, 1.02, 0.73, 1);z-index:9999;}.lsd-toast-provider__toast--top-left,.lsd-toast-provider__toast--top-center,.lsd-toast-provider__toast--top-right{top:0;}.lsd-toast-provider__toast--bottom-left,.lsd-toast-provider__toast--bottom-center,.lsd-toast-provider__toast--bottom-right{bottom:0;}.lsd-toast-provider__toast--top-center,.lsd-toast-provider__toast--bottom-center{left:50%;}.lsd-toast-provider__toast--top-right,.lsd-toast-provider__toast--bottom-right{right:0;}</style><style data-emotion="css-global 9yw6e1">.lsd-button-group{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:row;-ms-flex-direction:row;flex-direction:row;}.lsd-button-group >*:not(:last-child).lsd-button--outlined,.lsd-button-group >*:not(:last-child) .lsd-button--outlined{border-right:none;}</style><style data-emotion="css-global 17u9w7w">.lsd-date-range-picker{box-sizing:border-box;}.lsd-date-range-picker .lsd-date-field--outlined{border:none;}.lsd-date-range-picker .lsd-date-field__input-container__icon{padding:8px;}.lsd-date-range-picker__label{display:block;}.lsd-date-range-picker__input-container{box-sizing:border-box;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;border:1px solid transparent;}.lsd-date-picker__calendar{border-top:none!important;}.lsd-date-picker__calendar .lsd-tooltip-base__arrow-tip{-webkit-transition:left 0.2s ease-in-out;transition:left 0.2s ease-in-out;}.lsd-date-range-picker--calendar-open .lsd-date-range-picker__input-container{border-bottom:1px solid rgb(var(--lsd-border-primary));}.lsd-date-range-picker__icon{cursor:pointer;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:center;-ms-flex-pack:center;-webkit-justify-content:center;justify-content:center;-webkit-box-flex:1;-webkit-flex-grow:1;-ms-flex-positive:1;flex-grow:1;padding:0 10px;}.lsd-date-range-picker--disabled{opacity:0.3;}.lsd-date-range-picker__supporting-text{position:absolute;}.lsd-date-range-picker--large{width:318px;}.lsd-date-range-picker--large .lsd-date-field--large{width:156px;}.lsd-date-range-picker--large .lsd-date-field__input-container__input{padding-right:0;}.lsd-date-range-picker--large .lsd-date-field__input-container__icon{padding:11px 12px;}.lsd-date-range-picker--large .lsd-date-range-picker__label{margin:0 0 6px 18px;}.lsd-date-range-picker--large .lsd-date-range-picker__input-container{height:40px;}.lsd-date-range-picker--large .lsd-date-range-picker__supporting-text{margin:6px 18px 0 18px;}.lsd-date-range-picker--medium{width:290px;}.lsd-date-range-picker--medium .lsd-date-field--medium{width:142px;}.lsd-date-range-picker--medium .lsd-date-field__input-container__input{padding-right:0;}.lsd-date-range-picker--medium .lsd-date-field__input-container__icon{padding:7px 8px;}.lsd-date-range-picker--medium .lsd-date-range-picker__label{margin:0 0 6px 14px;}.lsd-date-range-picker--medium .lsd-date-range-picker__input-container{height:32px;}.lsd-date-range-picker--medium .lsd-date-range-picker__supporting-text{margin:6px 14px 0 14px;}.lsd-date-range-picker--small{width:262px;}.lsd-date-range-picker--small .lsd-date-field--small{width:128px;}.lsd-date-range-picker--small .lsd-date-field__input-container__input{padding-right:0;}.lsd-date-range-picker--small .lsd-date-field__input-container__icon{padding:5px 7px;}.lsd-date-range-picker--small .lsd-date-range-picker__label{margin:0 0 6px 12px;}.lsd-date-range-picker--small .lsd-date-range-picker__input-container{height:28px;}.lsd-date-range-picker--small .lsd-date-range-picker__supporting-text{margin:6px 12px 0 12px;}.lsd-date-range-picker__separator{margin-left:3px;width:1px;height:100%;}.lsd-date-range-picker__separator{border-left:1px solid transparent;}.lsd-date-range-picker--outlined{border:1px solid rgb(var(--lsd-border-primary));}.lsd-date-range-picker--outlined .lsd-date-range-picker__separator{border-left:1px solid rgb(var(--lsd-border-primary));}</style><style data-emotion="css-global 19d282h">.lsd-tooltip-base{border:1px solid rgb(var(--lsd-border-primary));position:relative;}.lsd-tooltip-base__arrow-tip{border:1px solid rgb(var(--lsd-border-primary));position:absolute;background:rgb(var(--lsd-surface-primary));}.lsd-tooltip-base__content{background:rgb(var(--lsd-surface-primary));width:100%;height:100%;position:relative;z-index:1;}</style><style data-emotion="css-global 1o77wkp">[data-theme=dark]{--lsd-display1-fontSize:5.5rem;--lsd-display1-fontWeight:normal;--lsd-display1-lineHeight:6rem;--lsd-display2-fontSize:4rem;--lsd-display2-fontWeight:normal;--lsd-display2-lineHeight:4.5rem;--lsd-display3-fontSize:3.5rem;--lsd-display3-fontWeight:normal;--lsd-display3-lineHeight:4rem;--lsd-display4-fontSize:3rem;--lsd-display4-fontWeight:normal;--lsd-display4-lineHeight:3.5rem;--lsd-h1-fontSize:2.5rem;--lsd-h1-fontWeight:normal;--lsd-h1-lineHeight:3rem;--lsd-h2-fontSize:2rem;--lsd-h2-fontWeight:normal;--lsd-h2-lineHeight:2.5rem;--lsd-h3-fontSize:1.75rem;--lsd-h3-fontWeight:normal;--lsd-h3-lineHeight:2.25rem;--lsd-h4-fontSize:1.5rem;--lsd-h4-fontWeight:normal;--lsd-h4-lineHeight:2rem;--lsd-h5-fontSize:1.25rem;--lsd-h5-fontWeight:normal;--lsd-h5-lineHeight:1.75rem;--lsd-h6-fontSize:1rem;--lsd-h6-fontWeight:normal;--lsd-h6-lineHeight:1.5rem;--lsd-subtitle1-fontSize:1.125rem;--lsd-subtitle1-fontWeight:normal;--lsd-subtitle1-lineHeight:1.5rem;--lsd-subtitle2-fontSize:1rem;--lsd-subtitle2-fontWeight:normal;--lsd-subtitle2-lineHeight:1.5rem;--lsd-subtitle3-fontSize:0.875rem;--lsd-subtitle3-fontWeight:normal;--lsd-subtitle3-lineHeight:1.25rem;--lsd-subtitle4-fontSize:0.75rem;--lsd-subtitle4-fontWeight:normal;--lsd-subtitle4-lineHeight:1rem;--lsd-body1-fontSize:1rem;--lsd-body1-fontWeight:normal;--lsd-body1-lineHeight:1.5rem;--lsd-body2-fontSize:0.875rem;--lsd-body2-fontWeight:normal;--lsd-body2-lineHeight:1.25rem;--lsd-body3-fontSize:0.75rem;--lsd-body3-fontWeight:normal;--lsd-body3-lineHeight:1rem;--lsd-label1-fontSize:0.875rem;--lsd-label1-fontWeight:normal;--lsd-label1-lineHeight:1.25rem;--lsd-label2-fontSize:0.75rem;--lsd-label2-fontWeight:normal;--lsd-label2-lineHeight:1rem;--lsd-typography-generic-font-family:sans-serif;--lsd-theme-primary:255,255,255;--lsd-theme-secondary:0,0,0;--lsd-surface-primary:0,0,0;--lsd-surface-secondary:255,255,255;--lsd-border-primary:255,255,255;--lsd-border-secondary:0,0,0;--lsd-icon-primary:255,255,255;--lsd-icon-secondary:0,0,0;--lsd-text-primary:255,255,255;--lsd-text-secondary:0,0,0;--lsd-text-tertiary:255,255,255,0.34;--lsd-spacing-4:4px;--lsd-spacing-8:8px;--lsd-spacing-16:16px;--lsd-spacing-24:24px;--lsd-spacing-32:32px;--lsd-spacing-40:40px;--lsd-spacing-64:64px;--lsd-spacing-80:80px;--lsd-spacing-96:96px;--lsd-spacing-120:120px;}</style><style data-emotion="css-global yon3n1">[data-theme=light]{--lsd-display1-fontSize:5.5rem;--lsd-display1-fontWeight:normal;--lsd-display1-lineHeight:6rem;--lsd-display2-fontSize:4rem;--lsd-display2-fontWeight:normal;--lsd-display2-lineHeight:4.5rem;--lsd-display3-fontSize:3.5rem;--lsd-display3-fontWeight:normal;--lsd-display3-lineHeight:4rem;--lsd-display4-fontSize:3rem;--lsd-display4-fontWeight:normal;--lsd-display4-lineHeight:3.5rem;--lsd-h1-fontSize:2.5rem;--lsd-h1-fontWeight:normal;--lsd-h1-lineHeight:3rem;--lsd-h2-fontSize:2rem;--lsd-h2-fontWeight:normal;--lsd-h2-lineHeight:2.5rem;--lsd-h3-fontSize:1.75rem;--lsd-h3-fontWeight:normal;--lsd-h3-lineHeight:2.25rem;--lsd-h4-fontSize:1.5rem;--lsd-h4-fontWeight:normal;--lsd-h4-lineHeight:2rem;--lsd-h5-fontSize:1.25rem;--lsd-h5-fontWeight:normal;--lsd-h5-lineHeight:1.75rem;--lsd-h6-fontSize:1rem;--lsd-h6-fontWeight:normal;--lsd-h6-lineHeight:1.5rem;--lsd-subtitle1-fontSize:1.125rem;--lsd-subtitle1-fontWeight:normal;--lsd-subtitle1-lineHeight:1.5rem;--lsd-subtitle2-fontSize:1rem;--lsd-subtitle2-fontWeight:normal;--lsd-subtitle2-lineHeight:1.5rem;--lsd-subtitle3-fontSize:0.875rem;--lsd-subtitle3-fontWeight:normal;--lsd-subtitle3-lineHeight:1.25rem;--lsd-subtitle4-fontSize:0.75rem;--lsd-subtitle4-fontWeight:normal;--lsd-subtitle4-lineHeight:1rem;--lsd-body1-fontSize:1rem;--lsd-body1-fontWeight:normal;--lsd-body1-lineHeight:1.5rem;--lsd-body2-fontSize:0.875rem;--lsd-body2-fontWeight:normal;--lsd-body2-lineHeight:1.25rem;--lsd-body3-fontSize:0.75rem;--lsd-body3-fontWeight:normal;--lsd-body3-lineHeight:1rem;--lsd-label1-fontSize:0.875rem;--lsd-label1-fontWeight:normal;--lsd-label1-lineHeight:1.25rem;--lsd-label2-fontSize:0.75rem;--lsd-label2-fontWeight:normal;--lsd-label2-lineHeight:1rem;--lsd-typography-generic-font-family:sans-serif;--lsd-theme-primary:0,0,0;--lsd-theme-secondary:255,255,255;--lsd-surface-primary:255,255,255;--lsd-surface-secondary:0,0,0;--lsd-border-primary:0,0,0;--lsd-border-secondary:255,255,255;--lsd-icon-primary:0,0,0;--lsd-icon-secondary:255,255,255;--lsd-text-primary:0,0,0;--lsd-text-secondary:255,255,255;--lsd-text-tertiary:0,0,0,0.34;--lsd-spacing-4:4px;--lsd-spacing-8:8px;--lsd-spacing-16:16px;--lsd-spacing-24:24px;--lsd-spacing-32:32px;--lsd-spacing-40:40px;--lsd-spacing-64:64px;--lsd-spacing-80:80px;--lsd-spacing-96:96px;--lsd-spacing-120:120px;}</style><div class="root_QACb"><div role="region" aria-label="Skip to main content"><a class="skipToContent_fXgn" href="#__docusaurus_skipToContent_fallback">Skip to main content</a></div><nav aria-label="Main" class="navbar navbar--fixed-top navbarHideable_OoEf"><div class="navbar__inner"><div class="navbar__left"><a class="navbar__brand" href="/"><div class="navbar__logo"><img src="/theme/image/logo.svg" alt="Vac Research" class="themedImage_ToTc themedImage--light_HNdA" height="26"><img src="/theme/image/logo.svg" alt="Vac Research" class="themedImage_ToTc themedImage--dark_i4oU" height="26"></div><b class="navbar__title text--truncate"></b></a></div><div class="navbar__left-items"><a class="navbar__item navbar__link" href="/"><div class="lsd-typography lsd-typography--body2 linkContent__x3v">About Vac</div></a><a class="navbar__item navbar__link" href="/community"><div class="lsd-typography lsd-typography--body2 linkContent__x3v">Community</div></a><a class="navbar__item navbar__link" href="/rlog"><div class="lsd-typography lsd-typography--body2 linkContent__x3v">Research Blog</div></a><a aria-current="page" class="navbar__item navbar__link navbar__link--active" href="/join-us"><div class="lsd-typography lsd-typography--body2 linkContent__x3v">Join Us</div></a></div><div class="navbar__right-items"><div class="iconButtonGroup_ktNv lsd-icon-button-group lsd-icon-button-group--medium lsd-icon-button-group--outlined"><button class="clean-btn toggle_K23S colorModeToggle_GSaI navbar__color-mode-toggle toggleButtonDisabled_AAS_ lsd-icon-button lsd-icon-button--medium lsd-icon-button--outlined lsd-icon-button--disabled" type="button" title="Switch between dark and light mode (currently dark mode)" aria-label="Switch between dark and light mode (currently dark mode)" aria-live="polite"><svg viewBox="0 0 24 24" width="24" height="24" class="lightToggleIcon_K4TL"><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"></path></svg><svg viewBox="0 0 24 24" width="24" height="24" class="darkToggleIcon_lKkA"><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"></path></svg></button><button aria-label="Toggle navigation bar" aria-expanded="false" class="navbar__toggle clean-btn" type="button"><svg width="30" height="30" viewBox="0 0 30 30" aria-hidden="true"><path stroke="currentColor" stroke-linecap="round" stroke-miterlimit="10" stroke-width="2" d="M4 7h22M4 15h22M4 23h22"></path></svg></button></div></div></div><div role="presentation" class="navbar-sidebar__backdrop"></div></nav><div id="__docusaurus_skipToContent_fallback" class="main-wrapper mainWrapper_z2l0 docsWrapper_BCFX"><button aria-label="Scroll back to top" class="clean-btn theme-back-to-top-button backToTopButton_sjWU" type="button"></button><div class="docPage__5DB"><main class="docMainContainer_gTbr docMainContainerEnhanced_Uz_u"><div class="container padding-top--md padding-bottom--lg"><div class="row docItemGrid_SzoZ"><div class="docItemCol_F52z"><div class="docItemContainer_hrrU"><article><div class="theme-doc-markdown markdown"><div><h1 class="lsd-typography lsd-typography--h1 mdx-jpd__header">Current job openings</h1><div class="mdx-jpd__single-job-department-container"><span class="lsd-typography lsd-typography--subtitle2 mdx-jpd__department-title">Vac</span><ul class="mdx-jpd__job-list"><li class="mdx-jpd__job-list-item"><a href="https://boards.greenhouse.io/vac/jobs/5671819" target="_blank" rel="noopener noreferrer" class="mdx-jpd__job-link"><div class="mdx-jpd__job-title-container"><h5 class="lsd-typography lsd-typography--h5 mdx-jpd__job-title">Libp2p Networking Engineer</h5><div class="icon_S7Kx m_thRi mdx-jpd__external-link-icon"><svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg" role="img"><path fill-rule="evenodd" clip-rule="evenodd" d="M11.192 4H3.428V2.857h9.715v9.715H12V4.808l-8.167 8.168-.809-.808L11.192 4Z" fill="#fff"></path></svg></div></div><div class="lsd-typography lsd-typography--subtitle2">Remote (Worldwide)</div></a></li><li class="mdx-jpd__job-list-item"><a href="https://boards.greenhouse.io/vac/jobs/5700917" target="_blank" rel="noopener noreferrer" class="mdx-jpd__job-link"><div class="mdx-jpd__job-title-container"><h5 class="lsd-typography lsd-typography--h5 mdx-jpd__job-title">Software Developer in Test (Low Level Programming)</h5><div class="icon_S7Kx m_thRi mdx-jpd__external-link-icon"><svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg" role="img"><path fill-rule="evenodd" clip-rule="evenodd" d="M11.192 4H3.428V2.857h9.715v9.715H12V4.808l-8.167 8.168-.809-.808L11.192 4Z" fill="#fff"></path></svg></div></div><div class="lsd-typography lsd-typography--subtitle2">Remote (Worldwide)</div></a></li><li class="mdx-jpd__job-list-item"><a href="https://boards.greenhouse.io/vac/jobs/5543925" target="_blank" rel="noopener noreferrer" class="mdx-jpd__job-link"><div class="mdx-jpd__job-title-container"><h5 class="lsd-typography lsd-typography--h5 mdx-jpd__job-title">Zero Knowledge Research Engineer (ACZ)</h5><div class="icon_S7Kx m_thRi mdx-jpd__external-link-icon"><svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg" role="img"><path fill-rule="evenodd" clip-rule="evenodd" d="M11.192 4H3.428V2.857h9.715v9.715H12V4.808l-8.167 8.168-.809-.808L11.192 4Z" fill="#fff"></path></svg></div></div><div class="lsd-typography lsd-typography--subtitle2">Remote (Worldwide)</div></a></li><li class="mdx-jpd__job-list-item"><a href="https://boards.greenhouse.io/vac/jobs/5453093" target="_blank" rel="noopener noreferrer" class="mdx-jpd__job-link"><div class="mdx-jpd__job-title-container"><h5 class="lsd-typography lsd-typography--h5 mdx-jpd__job-title">Zero Knowledge Researcher (Nescience) </h5><div class="icon_S7Kx m_thRi mdx-jpd__external-link-icon"><svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg" role="img"><path fill-rule="evenodd" clip-rule="evenodd" d="M11.192 4H3.428V2.857h9.715v9.715H12V4.808l-8.167 8.168-.809-.808L11.192 4Z" fill="#fff"></path></svg></div></div><div class="lsd-typography lsd-typography--subtitle2">Remote (Worldwide)</div></a></li></ul></div></div></div></article><nav class="pagination-nav docusaurus-mt-lg" aria-label="Docs pages"></nav></div></div><div class="gap1_XuuQ"></div></div></div></main></div></div><footer class="footer"><div class="container container-fluid firstRow_ar1q"><div class="footer__bottom text--center"><div class="margin-bottom--sm"><a class="footerLogoLink_BH7S" href="/"><img src="/theme/image/logo.svg" alt="Vac Research" class="themedImage_ToTc themedImage--light_HNdA footer__logo" width="22"><img src="/theme/image/logo.svg" alt="Vac Research" class="themedImage_ToTc themedImage--dark_i4oU footer__logo" width="22"></a></div><div class="footer__copyright">Vac Research © 2024<br>All rights reserved.</div></div><div class="row footer__links"><div class="col footer__col"><div class="footer__title"></div><ul class="footer__items clean-list"><li class="footer__item"><a href="https://twitter.com/vacp2p" target="_blank" rel="noopener noreferrer" class="footer__link-item">Twitter<svg width="13.5" height="13.5" aria-hidden="true" viewBox="0 0 24 24" class="iconExternalLink_nPIU"><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"></path></svg></a></li><li class="footer__item"><a href="https://discord.gg/PQFdubGt6d" target="_blank" rel="noopener noreferrer" class="footer__link-item">Discord<svg width="13.5" height="13.5" aria-hidden="true" viewBox="0 0 24 24" class="iconExternalLink_nPIU"><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"></path></svg></a></li><li class="footer__item"><a href="https://github.com/vacp2p" target="_blank" rel="noopener noreferrer" class="footer__link-item">Github<svg width="13.5" height="13.5" aria-hidden="true" viewBox="0 0 24 24" class="iconExternalLink_nPIU"><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"></path></svg></a></li></ul></div><div class="col footer__col"><div class="footer__title"></div><ul class="footer__items clean-list"><li class="footer__item"><a href="https://jobs.status.im/" target="_blank" rel="noopener noreferrer" class="footer__link-item">Work With Us<svg width="13.5" height="13.5" aria-hidden="true" viewBox="0 0 24 24" class="iconExternalLink_nPIU"><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"></path></svg></a></li><li class="footer__item"><a class="footer__link-item" href="/terms">Terms & Conditions</a></li><li class="footer__item"><a class="footer__link-item" href="/privacy-policy">Privacy Policy</a></li><li class="footer__item"><a class="footer__link-item" href="/security">Security</a></li></ul></div></div></div><div class="secondRow__ww3"><div class="footer__bottom text--center">Logos Collective</div><div class="row footer__links"><div class="col footer__col"><div class="footer__title">Research</div><ul class="footer__items clean-list"><li class="footer__item"><a href="https://vac.dev" target="_blank" rel="noopener noreferrer" class="footer__link-item">VacP2P<svg width="13.5" height="13.5" aria-hidden="true" viewBox="0 0 24 24" class="iconExternalLink_nPIU"><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"></path></svg></a></li><li class="footer__item"><a href="https://afaik.institute" target="_blank" rel="noopener noreferrer" class="footer__link-item">AFAIK<svg width="13.5" height="13.5" aria-hidden="true" viewBox="0 0 24 24" class="iconExternalLink_nPIU"><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"></path></svg></a></li></ul></div><div class="col footer__col"><div class="footer__title">Infrastructure</div><ul class="footer__items clean-list"><li class="footer__item"><a href="https://waku.org/" target="_blank" rel="noopener noreferrer" class="footer__link-item">Waku<svg width="13.5" height="13.5" aria-hidden="true" viewBox="0 0 24 24" class="iconExternalLink_nPIU"><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"></path></svg></a></li><li class="footer__item"><a href="https://nimbus.team/" target="_blank" rel="noopener noreferrer" class="footer__link-item">Nimbus<svg width="13.5" height="13.5" aria-hidden="true" viewBox="0 0 24 24" class="iconExternalLink_nPIU"><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"></path></svg></a></li><li class="footer__item"><a href="https://codex.storage" target="_blank" rel="noopener noreferrer" class="footer__link-item">Codex<svg width="13.5" height="13.5" aria-hidden="true" viewBox="0 0 24 24" class="iconExternalLink_nPIU"><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"></path></svg></a></li><li class="footer__item"><a href="https://nomos.tech" target="_blank" rel="noopener noreferrer" class="footer__link-item">Nomos<svg width="13.5" height="13.5" aria-hidden="true" viewBox="0 0 24 24" class="iconExternalLink_nPIU"><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"></path></svg></a></li></ul></div><div class="col footer__col"><div class="footer__title">Creative Studio</div><ul class="footer__items clean-list"><li class="footer__item"><a href="https://acid.info" target="_blank" rel="noopener noreferrer" class="footer__link-item">Acid.info<svg width="13.5" height="13.5" aria-hidden="true" viewBox="0 0 24 24" class="iconExternalLink_nPIU"><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"></path></svg></a></li></ul></div><div class="col footer__col"><div class="footer__title">Movement</div><ul class="footer__items clean-list"><li class="footer__item"><a href="https://logos.co" target="_blank" rel="noopener noreferrer" class="footer__link-item">Logos<svg width="13.5" height="13.5" aria-hidden="true" viewBox="0 0 24 24" class="iconExternalLink_nPIU"><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"></path></svg></a></li></ul></div><div class="col footer__col"><div class="footer__title">User-facing products</div><ul class="footer__items clean-list"><li class="footer__item"><a href="https://status.im" target="_blank" rel="noopener noreferrer" class="footer__link-item">Status<svg width="13.5" height="13.5" aria-hidden="true" viewBox="0 0 24 24" class="iconExternalLink_nPIU"><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"></path></svg></a></li><li class="footer__item"><a href="https://keycard.tech" target="_blank" rel="noopener noreferrer" class="footer__link-item">Keycard<svg width="13.5" height="13.5" aria-hidden="true" viewBox="0 0 24 24" class="iconExternalLink_nPIU"><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"></path></svg></a></li></ul></div></div></div><button class="backToTop_wDfN lsd-button lsd-button--small lsd-button--outlined"><span class="lsd-typography lsd-typography--label2 lsd-button__text">Back to top ↑</span></button></footer></div></div> -<script src="/assets/js/runtime~main.556fa6f5.js"></script> -<script src="/assets/js/main.ffc20c94.js"></script> + ) .lsd-dropdown__trigger:focus .lsd-dropdown__option-label{-webkit-text-decoration:underline;text-decoration:underline;}.lsd-dropdown__label{display:block;}.lsd-dropdown__button-container{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-box-pack:justify;-webkit-justify-content:space-between;justify-content:space-between;}.lsd-dropdown__trigger{width:100%;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:row;-ms-flex-direction:row;flex-direction:row;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:justify;-webkit-justify-content:space-between;justify-content:space-between;border:none;cursor:pointer;background:none;}.lsd-dropdown__trigger:focus{outline:none;}.lsd-dropdown__option-label{cursor:inherit;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;}.lsd-dropdown__icons{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:row;-ms-flex-direction:row;flex-direction:row;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:center;-ms-flex-pack:center;-webkit-justify-content:center;justify-content:center;gap:8px;}.lsd-dropdown__icon{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;}.lsd-dropdown__supporting-text{margin:6px 14px;}.lsd-dropdown--error .lsd-dropdown__option-label{-webkit-text-decoration:line-through;text-decoration:line-through;}.lsd-dropdown--disabled{opacity:0.34;cursor:initial;}.lsd-dropdown--large{width:208px;}.lsd-dropdown--large.lsd-dropdown--error{width:230px;}.lsd-dropdown--large .lsd-dropdown__label{margin:0 0 6px 18px;}.lsd-dropdown--large .lsd-dropdown__button-container{height:40px;}.lsd-dropdown--large .lsd-dropdown__trigger{padding:10px 0px 10px 18px;}.lsd-dropdown--large .lsd-dropdown__icons{padding:0px 14px;}.lsd-dropdown--medium{width:188px;}.lsd-dropdown--medium.lsd-dropdown--error{width:210px;}.lsd-dropdown--medium .lsd-dropdown__label{margin:0 0 6px 14px;}.lsd-dropdown--medium .lsd-dropdown__button-container{height:32px;}.lsd-dropdown--medium .lsd-dropdown__trigger{padding:6px 0px 6px 14px;}.lsd-dropdown--medium .lsd-dropdown__icons{padding:0px 12px;}.lsd-dropdown--small{width:164px;}.lsd-dropdown--small.lsd-dropdown--error{width:186px;}.lsd-dropdown--small .lsd-dropdown__label{margin:0 0 6px 12px;}.lsd-dropdown--small .lsd-dropdown__button-container{height:28px;}.lsd-dropdown--small .lsd-dropdown__trigger{padding:6px 0px 6px 12px;}.lsd-dropdown--small .lsd-dropdown__icons{padding:0px 10px;}.lsd-dropdown--outlined .lsd-dropdown__button-container{border:1px solid rgb(var(--lsd-border-primary));}.lsd-dropdown--underlined .lsd-dropdown__button-container{border:1px solid transparent;border-bottom:1px solid rgb(var(--lsd-border-primary));}</style><style data-emotion="css-global w2g5fy">.lsd-dropdown-item{width:100%;box-sizing:border-box;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:row;-ms-flex-direction:row;flex-direction:row;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;border:1px solid rgb(var(--lsd-border-primary));}.lsd-dropdown-item:not(.lsd-dropdown-item--disabled){cursor:pointer;}.lsd-dropdown-item:not(.lsd-dropdown-item--disabled):hover,.lsd-dropdown-item:not(.lsd-dropdown-item--disabled):focus{outline:none;}.lsd-dropdown-item:not(.lsd-dropdown-item--disabled):hover .lsd-dropdown-item__label,.lsd-dropdown-item:not(.lsd-dropdown-item--disabled):focus .lsd-dropdown-item__label{-webkit-text-decoration:underline;text-decoration:underline;}.lsd-dropdown-item__label{display:block;overflow:hidden;white-space:nowrap;text-overflow:ellipsis;}.lsd-dropdown-item--disabled{opacity:0.34;}.lsd-dropdown-item__icon{margin-right:18px;-webkit-flex-shrink:0;-ms-flex-negative:0;flex-shrink:0;}.lsd-dropdown-item--small{padding:5px 9px;height:28px;}.lsd-dropdown-item--medium{padding:5px 11px;height:32px;}.lsd-dropdown-item--large{padding:5px 13px;height:40px;}</style><style data-emotion="css-global ww9kgc">.lsd-breadcrumb__list{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:row;-ms-flex-direction:row;flex-direction:row;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;list-style-type:none;margin:0;padding:0;}.lsd-breadcrumb--disabled .lsd-breadcrumb__list{opacity:0.34;cursor:initial;pointer-events:none;}.lsd-breadcrumb__dropdown-menu{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column;overflow:auto;border:1px solid rgb(var(--lsd-border-primary));margin-top:10px;position:absolute;width:auto!important;}.lsd-breadcrumb__dropdown-menu>li{cursor:pointer;}.lsd-breadcrumb__dropdown-menu>li:not(:last-child){border-bottom:1px solid rgb(var(--lsd-border-primary));}.lsd-breadcrumb__dropdown-menu>li:hover,.lsd-breadcrumb__dropdown-menu>li:focus{-webkit-text-decoration:underline;text-decoration:underline;text-decoration-color:rgb(var(--lsd-border-primary));}.lsd-breadcrumb__dropdown-menu li>a{width:164px;padding:5px 11px;}</style><style data-emotion="css-global 4gvini">.lsd-breadcrumb-item{list-style-type:none;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;}.lsd-breadcrumb__list>li:not(:last-child)::after{display:inline-block;margin-inline:12px;content:'/';}.lsd-breadcrumb-item__link{-webkit-text-decoration:none;text-decoration:none;cursor:pointer;}.lsd-breadcrumb-item--outlined{padding:3px 11px;border:1px solid rgb(var(--lsd-border-primary));}.lsd-breadcrumb:not(.lsd-breadcrumb--disabled) .lsd-breadcrumb-item__link:hover,.lsd-breadcrumb:not(.lsd-breadcrumb--disabled) .lsd-breadcrumb-item__link:focus{-webkit-text-decoration:underline;text-decoration:underline;text-decoration-color:rgb(var(--lsd-border-primary));}</style><style data-emotion="css-global 1cwg3oc">.lsd-card{box-sizing:border-box;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column;}.lsd-card>.lsd-card-header{margin-bottom:-1px;}</style><style data-emotion="css-global v7d76i">.lsd-card-header{box-sizing:border-box;padding:10px 18px;text-align:center;border:1px solid rgb(var(--lsd-border-primary));}.lsd-card-header__title{overflow:hidden;word-break:break-all;}.lsd-card-header--large{padding:10px 18px;}.lsd-card-header--medium{padding:6px 14px;}.lsd-card-header--small{padding:6px 12px;}</style><style data-emotion="css-global 1txgafh">.lsd-card-body{box-sizing:border-box;padding:14px 22px;border:1px solid rgb(var(--lsd-border-primary));}</style><style data-emotion="css-global kzy52c">.lsd-tag{width:-webkit-fit-content;width:-moz-fit-content;width:fit-content;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:row;-ms-flex-direction:row;flex-direction:row;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:center;-ms-flex-pack:center;-webkit-justify-content:center;justify-content:center;box-sizing:border-box;border:1px solid rgb(var(--lsd-icon-primary));}.lsd-tag:hover,.lsd-tag:focus{-webkit-text-decoration:underline;text-decoration:underline;cursor:pointer;}.lsd-badge--large{padding:3px 11px;gap:12px;height:28px;}.lsd-badge--small{padding:3px 7px;gap:8px;height:24px;}.lsd-tag--filled{background-color:rgb(var(--lsd-icon-primary));}.lsd-tag--filled .lsd-tag__label{color:rgb(var(--lsd-text-secondary));}.lsd-tag--filled svg{--lsd-icon-primary:var(--lsd-icon-secondary);}.lsd-tag--outlined{color:rgb(var(--lsd-text-primary));}.lsd-tag--disabled{opacity:0.3;cursor:initial;pointer-events:none;}</style><style data-emotion="css-global 4wy0ub">.lsd-text-field{box-sizing:border-box;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column;}.lsd-text-field__input-container{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:justify;-webkit-justify-content:space-between;justify-content:space-between;}.lsd-text-field--disabled{opacity:0.34;}.lsd-text-field__input{border:none;outline:none;font-size:14px;color:rgb(var(--lsd-text-primary));background:none;width:100%;}.lsd-text-field__input:hover{outline:none;}.lsd-text-field__input::-webkit-input-placeholder{color:rgb(var(--lsd-text-primary));opacity:0.3;}.lsd-text-field__input::-moz-placeholder{color:rgb(var(--lsd-text-primary));opacity:0.3;}.lsd-text-field__input:-ms-input-placeholder{color:rgb(var(--lsd-text-primary));opacity:0.3;}.lsd-text-field__input::placeholder{color:rgb(var(--lsd-text-primary));opacity:0.3;}.lsd-text-field--error .lsd-text-field__input{-webkit-text-decoration:line-through;text-decoration:line-through;}.lsd-text-field__supporting-text{width:-webkit-fit-content;width:-moz-fit-content;width:fit-content;}.lsd-text-field--large{width:208px;}.lsd-text-field--large>*{padding:10px 14px 10px 18px;}.lsd-text-field--medium{width:188px;}.lsd-text-field--medium>*{padding:6px 12px 6px 14px;}.lsd-text-field--small{width:164px;}.lsd-text-field--small>*{padding:6px 10px 6px 12px;}.lsd-text-field__label{padding-top:0;padding-bottom:6px;}.lsd-text-field__supporting-text{padding-bottom:0;padding-top:6px;}.lsd-text-field--outlined .lsd-text-field__input-container{border:1px solid rgb(var(--lsd-border-primary));}.lsd-text-field--underlined .lsd-text-field__input-container{border:1px solid transparent;border-bottom:1px solid rgb(var(--lsd-border-primary));}.lsd-text-field__clear-button{padding:0;width:auto;height:auto;margin:0;border:0;}</style><style data-emotion="css-global uhig7c">.lsd-checkbox{position:relative;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:row;-ms-flex-direction:row;flex-direction:row;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;}.lsd-checkbox__input{opacity:0;position:absolute;left:0;top:0;padding:0;margin:0;width:100%;height:100%;}.lsd-checkbox:not(.lsd-checkbox--disabled):hover,.lsd-checkbox:not(.lsd-checkbox--disabled).lsd-checkbox--focused{-webkit-text-decoration:underline;text-decoration:underline;}.lsd-checkbox:not(.lsd-checkbox--disabled) .lsd-checkbox__input{cursor:pointer;}.lsd-checkbox--disabled{opacity:0.34;}.lsd-checkbox__label{margin-left:18px;}.lsd-checkbox--large .lsd-checkbox__label{margin-left:18px;}.lsd-checkbox--medium .lsd-checkbox__label{margin-left:14px;}.lsd-checkbox--small .lsd-checkbox__label{margin-left:12px;}</style><style data-emotion="css-global txommo">.lsd-autocomplete{box-sizing:border-box;}.lsd-autocomplete__label{display:block;}.lsd-autocomplete__input-container{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-box-pack:justify;-webkit-justify-content:space-between;justify-content:space-between;}.lsd-autocomplete--disabled{opacity:0.34;}.lsd-autocomplete__input{border:none;outline:none;font-size:14px;color:rgb(var(--lsd-text-primary));background:none;width:100%;}.lsd-autocomplete__input:hover{outline:none;}.lsd-autocomplete__input::-webkit-input-placeholder{color:rgb(var(--lsd-text-primary));opacity:0.3;}.lsd-autocomplete__input::-moz-placeholder{color:rgb(var(--lsd-text-primary));opacity:0.3;}.lsd-autocomplete__input:-ms-input-placeholder{color:rgb(var(--lsd-text-primary));opacity:0.3;}.lsd-autocomplete__input::placeholder{color:rgb(var(--lsd-text-primary));opacity:0.3;}.lsd-autocomplete__icon{cursor:pointer;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;}.lsd-autocomplete--error{-webkit-text-decoration:line-through;text-decoration:line-through;}.lsd-autocomplete--large{width:208px;}.lsd-autocomplete--large .lsd-autocomplete__label{margin:0 0 6px 18px;}.lsd-autocomplete--large .lsd-autocomplete__input-container{height:40px;}.lsd-autocomplete--large .lsd-autocomplete__input{padding:9px 17px;}.lsd-autocomplete--large .lsd-autocomplete__icon{padding:12px 13px;}.lsd-autocomplete--medium{width:188px;}.lsd-autocomplete--medium .lsd-autocomplete__label{margin:0 0 6px 14px;}.lsd-autocomplete--medium .lsd-autocomplete__input-container{height:32px;}.lsd-autocomplete--medium .lsd-autocomplete__input{padding:5px 13px;}.lsd-autocomplete--medium .lsd-autocomplete__icon{padding:8px 11px;}.lsd-autocomplete--small{width:164px;}.lsd-autocomplete--small .lsd-autocomplete__label{margin:0 0 6px 12px;}.lsd-autocomplete--small .lsd-autocomplete__input-container{height:28px;}.lsd-autocomplete--small .lsd-autocomplete__input{padding:5px 11px;}.lsd-autocomplete--small .lsd-autocomplete__icon{padding:6px 9px;}.lsd-autocomplete--outlined .lsd-autocomplete__input-container{border:1px solid rgb(var(--lsd-border-primary));}.lsd-autocomplete--underlined .lsd-autocomplete__input-container{border:1px solid transparent;border-bottom:1px solid rgb(var(--lsd-border-primary));}.lsd-autocomplete__dropdown-item-placeholder{opacity:0.5;white-space:pre;}</style><style data-emotion="css-global quxxm6">.lsd-quote{color:rgb(var(--lsd-text-primary));white-space:pre-wrap;}.lsd-quote--indented-inline{border-left:1px solid rgb(var(--lsd-border-primary));padding:4px 8px 4px 28px;}.lsd-quote--parentheses{padding:0px;text-align:center;}.lsd-quote--parentheses::before{content:'***';}.lsd-quote--parentheses::after{content:'***';}</style><style data-emotion="css-global a49t4h">.lsd-collapse{box-sizing:border-box;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column;}.lsd-collapse--open .lsd-collapse__content{border-top:1px solid transparent;}.lsd-collapse__content{border:1px solid rgb(var(--lsd-border-primary));}</style><style data-emotion="css-global 12ppw0q">.lsd-collapse-header{box-sizing:border-box;}.lsd-collapse-header:not(.lsd-collapse-header--disabled) .lsd-collapse-header__trigger:hover .lsd-collapse-header__label{-webkit-text-decoration:underline;text-decoration:underline;}.lsd-collapse-header__trigger{width:100%;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:row;-ms-flex-direction:row;flex-direction:row;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:justify;-webkit-justify-content:space-between;justify-content:space-between;cursor:pointer;background:none;border:1px solid rgb(var(--lsd-border-primary));}.lsd-collapse-header__trigger:focus{outline:none;}.lsd-collapse-header__label{cursor:inherit;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;margin:auto;}.lsd-collapse-header__icons{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:row;-ms-flex-direction:row;flex-direction:row;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:end;-ms-flex-pack:end;-webkit-justify-content:flex-end;justify-content:flex-end;}.lsd-collapse-header__icon{margin-right:8px;}.lsd-collapse-header--disabled .lsd-collapse-header__trigger{opacity:0.34;cursor:initial;}.lsd-collapse-header--large .lsd-collapse-header__trigger{width:299px;height:40px;padding:9px 17px;}.lsd-collapse-header--medium .lsd-collapse-header__trigger{width:270px;height:32px;padding:5px 13px;}.lsd-collapse-header--small .lsd-collapse-header__trigger{width:235px;height:28px;padding:5px 11px;}</style><style data-emotion="css-global dixc0i">.lsd-checkbox-group{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column;gap:6px;width:-webkit-fit-content;width:-moz-fit-content;width:fit-content;}.lsd-checkbox-group__label{margin-bottom:6px;}</style><style data-emotion="css-global q2n2hz">.lsd-badge{width:-webkit-fit-content;width:-moz-fit-content;width:fit-content;box-sizing:border-box;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:row;-ms-flex-direction:row;flex-direction:row;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:center;-ms-flex-pack:center;-webkit-justify-content:center;justify-content:center;border:1px solid rgb(var(--lsd-icon-primary));border-radius:20px;}.lsd-badge:hover,.lsd-badge:focus{-webkit-text-decoration:underline;text-decoration:underline;cursor:pointer;}.lsd-badge--large{padding:3px 11px;gap:12px;height:28px;}.lsd-badge--small{padding:3px 7px;gap:8px;height:24px;}.lsd-badge--filled{background-color:rgb(var(--lsd-icon-primary));}.lsd-badge--filled .lsd-badge__label{color:rgb(var(--lsd-text-secondary));}.lsd-badge--filled svg{--lsd-icon-primary:var(--lsd-icon-secondary);}.lsd-badge--outlined{color:rgb(var(--lsd-text-primary));}.lsd-badge--disabled{opacity:0.3;cursor:initial;pointer-events:none;}</style><style data-emotion="css-global rlst54">.lsd-radio-button{position:relative;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:row;-ms-flex-direction:row;flex-direction:row;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;}.lsd-radio-button__input{opacity:0;position:absolute;left:0;top:0;padding:0;margin:0;width:100%;height:100%;}.lsd-radio-button:not(.lsd-radio-button--disabled):hover{-webkit-text-decoration:underline;text-decoration:underline;}.lsd-radio-button:not(.lsd-radio-button--disabled) .lsd-radio-button__input{cursor:pointer;}.lsd-radio-button--disabled{opacity:0.34;}.lsd-radio-button__label{margin-left:18px;}.lsd-radio-button--large .lsd-radio-button__label{margin-left:18px;}.lsd-radio-button--medium .lsd-radio-button__label{margin-left:14px;}.lsd-radio-button--small .lsd-radio-button__label{margin-left:12px;}</style><style data-emotion="css-global mo7h6o">.lsd-radio-button-group{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column;gap:6px;width:-webkit-fit-content;width:-moz-fit-content;width:fit-content;}.lsd-radio-button-group__label{margin-bottom:6px;}</style><style data-emotion="css-global amncrr">.lsd-table{box-sizing:border-box;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column;}.lsd-table>.lsd-table-header{margin-bottom:-1px;}</style><style data-emotion="css-global 1fkbozr">.lsd-table-header{box-sizing:border-box;border:1px solid rgb(var(--lsd-border-primary));}</style><style data-emotion="css-global 1fb1r54">.lsd-table-body table{border-collapse:collapse;text-align:center;table-layout:fixed;width:100%;height:auto;}.lsd-table-body table tr:first-of-type td label:has(input[type='radio']){display:none;}.lsd-table-body__toolbar{box-sizing:border-box;padding:10px;border:1px solid rgb(var(--lsd-border-primary));border-bottom:none;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-box-pack:justify;-webkit-justify-content:space-between;justify-content:space-between;}</style><style data-emotion="css-global 607rj8">.lsd-table-item{border:1px solid rgb(var(--lsd-border-primary));}.lsd-table-item:has(> label){width:40px;}.lsd-table-item:has(> label) input{position:relative;width:14px;height:14px;margin:auto;}.lsd-table-item:has(> label) span{margin-left:14px!important;}.lsd-table-item--large{padding:10px;}.lsd-table-item--medium{padding:6px 8px;}.lsd-table-item--small{padding:6px;}</style><style data-emotion="css-global 1vlh57l">.lsd-table-row{-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;}</style><style data-emotion="css-global 1fw5y3v">.lsd-number-input{width:auto;box-sizing:border-box;}.lsd-number-input__main-container:hover{-webkit-text-decoration:underline;text-decoration:underline;}.lsd-number-input--error .lsd-number-input__main-container{-webkit-text-decoration:line-through;text-decoration:line-through;}.lsd-number-input__label{display:block;}.lsd-number-input__plus-minus-icons{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-shrink:0;-ms-flex-negative:0;flex-shrink:0;}.lsd-number-input__input-container{box-sizing:border-box;border:1px solid rgb(var(--lsd-border-primary));border-left:0px;border-right:0px;}.lsd-number-input__error-icon{cursor:pointer;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;padding:10px 8px;}.lsd-number-input__input-container{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:justify;-webkit-justify-content:space-between;justify-content:space-between;}.lsd-number-input--disabled{opacity:0.34;}.lsd-number-input__main-container{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;}.lsd-number-input__input{border:none;outline:none;font-size:14px;color:rgb(var(--lsd-text-primary));background:none;text-align:center;padding:0 4px;}.lsd-number-input__input::-webkit-inner-spin-button{display:none;-webkit-appearance:none;}.lsd-number-input__input:hover{outline:none;}.lsd-number-input__supporting-text{position:absolute;}.lsd-number-input--large .lsd-number-input__label{margin:0 0 6px 18px;}.lsd-number-input--large .lsd-number-input__input-container{height:40px;}.lsd-number-input--large .lsd-number-input__input{width:62px;}.lsd-number-input--large .lsd-number-input__plus-minus-icons{height:40px;width:40px;}.lsd-number-input--large .lsd-number-input__supporting-text{margin:6px 18px 0 18px;}.lsd-number-input--medium .lsd-number-input__label{margin:0 0 6px 14px;}.lsd-number-input--medium .lsd-number-input__input-container{height:32px;}.lsd-number-input--medium .lsd-number-input__input{width:58px;}.lsd-number-input--medium .lsd-number-input__plus-minus-icons{height:32px;width:32px;}.lsd-number-input--medium .lsd-number-input__supporting-text{margin:6px 14px 0 14px;}.lsd-number-input--small .lsd-number-input__label{margin:0 0 6px 12px;}.lsd-number-input--small .lsd-number-input__input-container{height:28px;}.lsd-number-input--small .lsd-number-input__input{width:50px;}.lsd-number-input--small .lsd-number-input__plus-minus-icons{height:28px;width:28px;}.lsd-number-input--small .lsd-number-input__supporting-text{margin:6px 12px 0 12px;}</style><style data-emotion="css-global 12rmo7o">.lsd-modal{box-sizing:border-box;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column;position:fixed;top:0;left:0;right:0;bottom:0;background-color:rgba(0, 0, 0, 0.5);display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-box-pack:center;-ms-flex-pack:center;-webkit-justify-content:center;justify-content:center;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;z-index:9999;}.lsd-modal__container{position:relative;background:rgb(var(--lsd-surface-primary));padding:20px;max-width:90%;box-sizing:border-box;border:1px solid rgb(var(--lsd-border-primary));}.lsd-modal__header{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-box-pack:justify;-webkit-justify-content:space-between;justify-content:space-between;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;}.lsd-modal__close-icon{position:absolute;top:8px;right:8px;cursor:pointer;}.lsd-modal__title-and-subtitle-container{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column;}.lsd-modal--large .lsd-modal__container{min-width:960px;}.lsd-modal--medium .lsd-modal__container{min-width:768px;}.lsd-modal--small .lsd-modal__container{min-width:614px;}.lsd-modal--extra-small .lsd-modal__container{min-width:490px;}</style><style data-emotion="css-global 1k7gzc">.lsd-modal-footer{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;}</style><style data-emotion="css-global 1b9t8so">.lsd-modal-body{margin:18px 0;}</style><style data-emotion="css-global dyud2a">.lsd-date-picker{width:-webkit-fit-content;width:-moz-fit-content;width:fit-content;}.lsd-date-picker__calendar{border-top:none!important;}.lsd-date-picker--large .lsd-date-field--large{width:318px;}.lsd-date-picker--medium .lsd-date-field--medium{width:290px;}.lsd-date-picker--small .lsd-date-field--small{width:262px;}</style><style data-emotion="css-global olq3nk">.lsd-date-field{width:auto;box-sizing:border-box;}.lsd-date-field__label{display:block;}.lsd-date-field__input-container__icon{position:absolute;right:0;cursor:pointer;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;background-color:rgb(var(--lsd-surface-primary));}.lsd-date-field__input-container__icon:focus{background:blue;background-color:pink;border:1px solid rgb(var(--lsd-border-primary));}.lsd-date-field__input-container__no-icon{position:absolute;right:0;background-color:rgb(var(--lsd-surface-primary));padding:12px;}.lsd-date-field--outlined{border:1px solid rgb(var(--lsd-border-primary));}.lsd-date-field--underlined{border-bottom:1px solid rgb(var(--lsd-border-primary));}.lsd-date-field__input-container{position:relative;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:justify;-webkit-justify-content:space-between;justify-content:space-between;}.lsd-date-field--disabled{opacity:0.34;}.lsd-date-field__input-container__input{border:none;outline:none;font-size:14px;color:rgb(var(--lsd-text-primary));background:none;width:100%;opacity:0.4;-webkit-transition:opacity 0.2s ease-in-out;transition:opacity 0.2s ease-in-out;}.lsd-date-field__input-container__input::-webkit-inner-spin-button,.lsd-date-field__input-container__input::-webkit-calendar-picker-indicator{display:none;-webkit-appearance:none;}.lsd-date-field__input-container__input:hover{outline:none;}.lsd-date-field__supporting-text{position:absolute;}.lsd-date-field--large{width:208px;}.lsd-date-field--large .lsd-date-field__label{margin:0 0 6px 18px;}.lsd-date-field--large .lsd-date-field__input-container{height:40px;}.lsd-date-field--large .lsd-date-field__input-container__input{padding:9px 0px 9px 17px;}.lsd-date-field--large .lsd-date-field__input-container__icon{padding:12px 13px;}.lsd-date-field--large .lsd-date-field__supporting-text{margin:6px 18px 0 18px;}.lsd-date-field--medium{width:188px;}.lsd-date-field--medium .lsd-date-field__label{margin:0 0 6px 14px;}.lsd-date-field--medium .lsd-date-field__input-container{height:32px;}.lsd-date-field--medium .lsd-date-field__input-container__input{padding:5px 11px 5px 13px;}.lsd-date-field--medium .lsd-date-field__input-container__icon{padding:8px 11px;}.lsd-date-field--medium .lsd-date-field__supporting-text{margin:6px 14px 0 14px;}.lsd-date-field--small{width:164px;}.lsd-date-field--small .lsd-date-field__label{margin:0 0 6px 12px;}.lsd-date-field--small .lsd-date-field__input-container{height:28px;}.lsd-date-field--small .lsd-date-field__input-container__input{padding:5px 9px 5px 11px;font-size:12px;}.lsd-date-field--small .lsd-date-field__input-container__icon{padding:6px 9px;}.lsd-date-field--small .lsd-date-field__supporting-text{margin:6px 12px 0 12px;}.lsd-date-field__input-container__input:invalid,.lsd-date-field__input-container__input--filled{color:rgb(var(--lsd-border-primary));opacity:1;}.lsd-date-field--error .lsd-date-field__input-container__input::-webkit-datetime-edit-year-field,.lsd-date-field--error .lsd-date-field__input-container__input::-webkit-datetime-edit-month-field,.lsd-date-field--error .lsd-date-field__input-container__input::-webkit-datetime-edit-day-field{-webkit-text-decoration:line-through;text-decoration:line-through;}@supports not selector(::-webkit-datetime-edit-day-field){.lsd-date-field--error .lsd-date-field__input-container__input{-webkit-text-decoration:line-through;text-decoration:line-through;}}</style><style data-emotion="css-global 1gjtao4">.lsd-calendar{border:1px solid rgb(var(--lsd-border-primary));visibility:hidden;position:absolute!important;top:0;left:0;opacity:0;visibility:hidden;margin:0;padding:0;box-sizing:border-box;background:rgb(var(--lsd-surface-primary));-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;}.lsd-calendar-container{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column;padding:8px;}.lsd-calendar--open{opacity:1;visibility:visible;}.lsd-calendar-header{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-box-pack:center;-ms-flex-pack:center;-webkit-justify-content:center;justify-content:center;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;height:32px;margin-bottom:8px;}.lsd-calendar__week_day{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-box-pack:center;-ms-flex-pack:center;-webkit-justify-content:center;justify-content:center;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;aspect-ratio:1/1;margin-bottom:4px;}.lsd-calendar__change-year{position:relative;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-box-pack:center;-ms-flex-pack:center;-webkit-justify-content:center;justify-content:center;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;padding:2px 0xp 2px 8px;gap:6px;border:1px solid transparent;}.lsd-calendar__change-year--active .lsd-calendar__year-and-icon{border:1px solid rgb(var(--lsd-border-primary));}.lsd-calendar__change-year-icon-container{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-box-pack:center;-ms-flex-pack:center;-webkit-justify-content:center;justify-content:center;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;cursor:pointer;border:none;}.lsd-calendar-month{margin-right:8px;}.lsd-calendar__month-and-year{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:center;-ms-flex-pack:center;-webkit-justify-content:center;justify-content:center;}.lsd-calendar-day__container{cursor:pointer;background:transparent;position:relative;box-sizing:border-box;border:1px solid transparent;}.lsd-calendar-day{aspect-ratio:1/1;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-box-pack:center;-ms-flex-pack:center;-webkit-justify-content:center;justify-content:center;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;}.lsd-calendar-day:hover{cursor:pointer;-webkit-text-decoration:underline;text-decoration:underline;text-decoration-color:rgb(var(--lsd-border-primary));}.lsd-calendar-day label:hover{cursor:pointer;}.lsd-calendar-day--selected{border:1px solid rgb(var(--lsd-border-primary));}.lsd-calendar-day--disabled{opacity:0.3;cursor:default;}.lsd-calendar-day__today_indicator{position:absolute;left:50%;-webkit-transform:translateX(-50%);-moz-transform:translateX(-50%);-ms-transform:translateX(-50%);transform:translateX(-50%);bottom:2px;}.lsd-calendar--disabled{pointer-events:none;border:1px solid rgba(var(--lsd-border-primary), 0.3);}.lsd-calendar--disabled label{opacity:0.3;}.lsd-calendar--disabled .lsd-calendar__button{opacity:0.3;}.lsd-calendar--disabled .lsd-calendar-day--selected{opacity:0.3;}.lsd-calendar__button{border:1px solid rgb(var(--lsd-border-primary));cursor:pointer;background:transparent;width:32px;height:32px;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:center;-ms-flex-pack:center;-webkit-justify-content:center;justify-content:center;position:absolute;}.lsd-calendar__next-month-button{top:8px;right:8px;}.lsd-calendar__previous-month-button{top:8px;left:8px;}.lsd-calendar-day--border-left{border-left:1px double rgb(var(--lsd-border-primary));}.lsd-calendar-day--border-right{border-right:1px double rgb(var(--lsd-border-primary));}.lsd-calendar-day--border-left-and-right{border-left:1px double rgb(var(--lsd-border-primary));border-right:1px double rgb(var(--lsd-border-primary));}.lsd-calendar-day--border-top-and-bottom{border-top:1px double rgb(var(--lsd-border-primary));border-bottom:1px double rgb(var(--lsd-border-primary));}.lsd-calendar__month-table{border-collapse:collapse;}.lsd-calendar__year-dropdown{box-sizing:border-box;position:absolute;top:100%;left:0;max-height:200px;overflow-y:auto;width:100%;border:1px solid rgb(var(--lsd-border-primary));border-top:none;z-index:1;}.lsd-calendar__year-dropdown .lsd-calendar-year{border-bottom:1px solid rgb(var(--lsd-border-primary));}.lsd-calendar__year-dropdown--hidden{visibility:hidden;}.lsd-calendar-year{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;cursor:pointer;-webkit-transition:background-color 0.2s;transition:background-color 0.2s;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;background:rgb(var(--lsd-surface-primary));}.lsd-calendar-year:hover{-webkit-text-decoration:underline;text-decoration:underline;}.lsd-calendar__year-and-icon{border:1px solid rgb(var(--lsd-border-primary));}.lsd-calendar--large .lsd-calendar-year{padding:6px 0px 6px 14px;}.lsd-calendar--large .lsd-calendar__change-year-icon-container{width:32px;}.lsd-calendar--medium .lsd-calendar-year{padding:6px 0px 6px 12px;}.lsd-calendar--medium .lsd-calendar__change-year-icon-container{width:28px;}.lsd-calendar--small .lsd-calendar-year{padding:6px 0px 6px 12px;}.lsd-calendar--small .lsd-calendar__change-year-icon-container{width:28px;}</style><style data-emotion="css-global dlrd7d">.lsd-toast{box-sizing:border-box;display:-webkit-inline-box;display:-webkit-inline-flex;display:-ms-inline-flexbox;display:inline-flex;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;background:rgb(var(--lsd-surface-primary));border:1px solid rgb(var(--lsd-border-primary));padding:8px;height:-webkit-fit-content;height:-moz-fit-content;height:fit-content;}.lsd-toast__inline-button-container{-webkit-flex-shrink:0;-ms-flex-negative:0;flex-shrink:0;}.lsd-toast__column-button-container{margin-top:18px;margin-bottom:6px;}.lsd-toast__inline-container{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:justify;-webkit-justify-content:space-between;justify-content:space-between;-webkit-box-flex:1;-webkit-flex-grow:1;-ms-flex-positive:1;flex-grow:1;}.lsd-toast__column-container{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column;-webkit-box-pack:justify;-webkit-justify-content:space-between;justify-content:space-between;}.lsd-toast__text-container{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column;color:rgb(var(--lsd-text-secondary));padding-left:12px;}.lsd-toast__title{position:relative;}.lsd-toast__information{margin-top:4px;}.lsd-toast__button-container{min-height:28px;min-width:60px;width:-webkit-fit-content;width:-moz-fit-content;width:fit-content;padding:0px 12px;}.lsd-toast__close-button{margin-bottom:auto;-webkit-flex-shrink:0;-ms-flex-negative:0;flex-shrink:0;height:28px;width:28px;margin-left:auto;}.lsd-toast__column-icon-container{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-box-pack:center;-ms-flex-pack:center;-webkit-justify-content:center;justify-content:center;margin-bottom:auto;position:relative;top:4px;padding-left:4px;}.lsd-toast__inline-icon-container{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:center;-ms-flex-pack:center;-webkit-justify-content:center;justify-content:center;padding-left:4px;}.lsd-toast__icon{position:relative;}.lsd-toast--large{width:364px;}.lsd-toast--medium{width:336px;}.lsd-toast--small{width:296px;}.lsd-toast--small .lsd-toast__icon{top:0px;}</style><style data-emotion="css-global 5wlfwk">.lsd-toast-provider__toast-container{position:fixed;-webkit-transition:all 230ms cubic-bezier(0.21, 1.02, 0.73, 1);transition:all 230ms cubic-bezier(0.21, 1.02, 0.73, 1);z-index:9999;}.lsd-toast-provider__toast--top-left,.lsd-toast-provider__toast--top-center,.lsd-toast-provider__toast--top-right{top:0;}.lsd-toast-provider__toast--bottom-left,.lsd-toast-provider__toast--bottom-center,.lsd-toast-provider__toast--bottom-right{bottom:0;}.lsd-toast-provider__toast--top-center,.lsd-toast-provider__toast--bottom-center{left:50%;}.lsd-toast-provider__toast--top-right,.lsd-toast-provider__toast--bottom-right{right:0;}</style><style data-emotion="css-global 9yw6e1">.lsd-button-group{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:row;-ms-flex-direction:row;flex-direction:row;}.lsd-button-group >*:not(:last-child).lsd-button--outlined,.lsd-button-group >*:not(:last-child) .lsd-button--outlined{border-right:none;}</style><style data-emotion="css-global 17u9w7w">.lsd-date-range-picker{box-sizing:border-box;}.lsd-date-range-picker .lsd-date-field--outlined{border:none;}.lsd-date-range-picker .lsd-date-field__input-container__icon{padding:8px;}.lsd-date-range-picker__label{display:block;}.lsd-date-range-picker__input-container{box-sizing:border-box;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;border:1px solid transparent;}.lsd-date-picker__calendar{border-top:none!important;}.lsd-date-picker__calendar .lsd-tooltip-base__arrow-tip{-webkit-transition:left 0.2s ease-in-out;transition:left 0.2s ease-in-out;}.lsd-date-range-picker--calendar-open .lsd-date-range-picker__input-container{border-bottom:1px solid rgb(var(--lsd-border-primary));}.lsd-date-range-picker__icon{cursor:pointer;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:center;-ms-flex-pack:center;-webkit-justify-content:center;justify-content:center;-webkit-box-flex:1;-webkit-flex-grow:1;-ms-flex-positive:1;flex-grow:1;padding:0 10px;}.lsd-date-range-picker--disabled{opacity:0.3;}.lsd-date-range-picker__supporting-text{position:absolute;}.lsd-date-range-picker--large{width:318px;}.lsd-date-range-picker--large .lsd-date-field--large{width:156px;}.lsd-date-range-picker--large .lsd-date-field__input-container__input{padding-right:0;}.lsd-date-range-picker--large .lsd-date-field__input-container__icon{padding:11px 12px;}.lsd-date-range-picker--large .lsd-date-range-picker__label{margin:0 0 6px 18px;}.lsd-date-range-picker--large .lsd-date-range-picker__input-container{height:40px;}.lsd-date-range-picker--large .lsd-date-range-picker__supporting-text{margin:6px 18px 0 18px;}.lsd-date-range-picker--medium{width:290px;}.lsd-date-range-picker--medium .lsd-date-field--medium{width:142px;}.lsd-date-range-picker--medium .lsd-date-field__input-container__input{padding-right:0;}.lsd-date-range-picker--medium .lsd-date-field__input-container__icon{padding:7px 8px;}.lsd-date-range-picker--medium .lsd-date-range-picker__label{margin:0 0 6px 14px;}.lsd-date-range-picker--medium .lsd-date-range-picker__input-container{height:32px;}.lsd-date-range-picker--medium .lsd-date-range-picker__supporting-text{margin:6px 14px 0 14px;}.lsd-date-range-picker--small{width:262px;}.lsd-date-range-picker--small .lsd-date-field--small{width:128px;}.lsd-date-range-picker--small .lsd-date-field__input-container__input{padding-right:0;}.lsd-date-range-picker--small .lsd-date-field__input-container__icon{padding:5px 7px;}.lsd-date-range-picker--small .lsd-date-range-picker__label{margin:0 0 6px 12px;}.lsd-date-range-picker--small .lsd-date-range-picker__input-container{height:28px;}.lsd-date-range-picker--small .lsd-date-range-picker__supporting-text{margin:6px 12px 0 12px;}.lsd-date-range-picker__separator{margin-left:3px;width:1px;height:100%;}.lsd-date-range-picker__separator{border-left:1px solid transparent;}.lsd-date-range-picker--outlined{border:1px solid rgb(var(--lsd-border-primary));}.lsd-date-range-picker--outlined .lsd-date-range-picker__separator{border-left:1px solid rgb(var(--lsd-border-primary));}</style><style data-emotion="css-global 19d282h">.lsd-tooltip-base{border:1px solid rgb(var(--lsd-border-primary));position:relative;}.lsd-tooltip-base__arrow-tip{border:1px solid rgb(var(--lsd-border-primary));position:absolute;background:rgb(var(--lsd-surface-primary));}.lsd-tooltip-base__content{background:rgb(var(--lsd-surface-primary));width:100%;height:100%;position:relative;z-index:1;}</style><style data-emotion="css-global 1o77wkp">[data-theme=dark]{--lsd-display1-fontSize:5.5rem;--lsd-display1-fontWeight:normal;--lsd-display1-lineHeight:6rem;--lsd-display2-fontSize:4rem;--lsd-display2-fontWeight:normal;--lsd-display2-lineHeight:4.5rem;--lsd-display3-fontSize:3.5rem;--lsd-display3-fontWeight:normal;--lsd-display3-lineHeight:4rem;--lsd-display4-fontSize:3rem;--lsd-display4-fontWeight:normal;--lsd-display4-lineHeight:3.5rem;--lsd-h1-fontSize:2.5rem;--lsd-h1-fontWeight:normal;--lsd-h1-lineHeight:3rem;--lsd-h2-fontSize:2rem;--lsd-h2-fontWeight:normal;--lsd-h2-lineHeight:2.5rem;--lsd-h3-fontSize:1.75rem;--lsd-h3-fontWeight:normal;--lsd-h3-lineHeight:2.25rem;--lsd-h4-fontSize:1.5rem;--lsd-h4-fontWeight:normal;--lsd-h4-lineHeight:2rem;--lsd-h5-fontSize:1.25rem;--lsd-h5-fontWeight:normal;--lsd-h5-lineHeight:1.75rem;--lsd-h6-fontSize:1rem;--lsd-h6-fontWeight:normal;--lsd-h6-lineHeight:1.5rem;--lsd-subtitle1-fontSize:1.125rem;--lsd-subtitle1-fontWeight:normal;--lsd-subtitle1-lineHeight:1.5rem;--lsd-subtitle2-fontSize:1rem;--lsd-subtitle2-fontWeight:normal;--lsd-subtitle2-lineHeight:1.5rem;--lsd-subtitle3-fontSize:0.875rem;--lsd-subtitle3-fontWeight:normal;--lsd-subtitle3-lineHeight:1.25rem;--lsd-subtitle4-fontSize:0.75rem;--lsd-subtitle4-fontWeight:normal;--lsd-subtitle4-lineHeight:1rem;--lsd-body1-fontSize:1rem;--lsd-body1-fontWeight:normal;--lsd-body1-lineHeight:1.5rem;--lsd-body2-fontSize:0.875rem;--lsd-body2-fontWeight:normal;--lsd-body2-lineHeight:1.25rem;--lsd-body3-fontSize:0.75rem;--lsd-body3-fontWeight:normal;--lsd-body3-lineHeight:1rem;--lsd-label1-fontSize:0.875rem;--lsd-label1-fontWeight:normal;--lsd-label1-lineHeight:1.25rem;--lsd-label2-fontSize:0.75rem;--lsd-label2-fontWeight:normal;--lsd-label2-lineHeight:1rem;--lsd-typography-generic-font-family:sans-serif;--lsd-theme-primary:255,255,255;--lsd-theme-secondary:0,0,0;--lsd-surface-primary:0,0,0;--lsd-surface-secondary:255,255,255;--lsd-border-primary:255,255,255;--lsd-border-secondary:0,0,0;--lsd-icon-primary:255,255,255;--lsd-icon-secondary:0,0,0;--lsd-text-primary:255,255,255;--lsd-text-secondary:0,0,0;--lsd-text-tertiary:255,255,255,0.34;--lsd-spacing-4:4px;--lsd-spacing-8:8px;--lsd-spacing-16:16px;--lsd-spacing-24:24px;--lsd-spacing-32:32px;--lsd-spacing-40:40px;--lsd-spacing-64:64px;--lsd-spacing-80:80px;--lsd-spacing-96:96px;--lsd-spacing-120:120px;}</style><style data-emotion="css-global yon3n1">[data-theme=light]{--lsd-display1-fontSize:5.5rem;--lsd-display1-fontWeight:normal;--lsd-display1-lineHeight:6rem;--lsd-display2-fontSize:4rem;--lsd-display2-fontWeight:normal;--lsd-display2-lineHeight:4.5rem;--lsd-display3-fontSize:3.5rem;--lsd-display3-fontWeight:normal;--lsd-display3-lineHeight:4rem;--lsd-display4-fontSize:3rem;--lsd-display4-fontWeight:normal;--lsd-display4-lineHeight:3.5rem;--lsd-h1-fontSize:2.5rem;--lsd-h1-fontWeight:normal;--lsd-h1-lineHeight:3rem;--lsd-h2-fontSize:2rem;--lsd-h2-fontWeight:normal;--lsd-h2-lineHeight:2.5rem;--lsd-h3-fontSize:1.75rem;--lsd-h3-fontWeight:normal;--lsd-h3-lineHeight:2.25rem;--lsd-h4-fontSize:1.5rem;--lsd-h4-fontWeight:normal;--lsd-h4-lineHeight:2rem;--lsd-h5-fontSize:1.25rem;--lsd-h5-fontWeight:normal;--lsd-h5-lineHeight:1.75rem;--lsd-h6-fontSize:1rem;--lsd-h6-fontWeight:normal;--lsd-h6-lineHeight:1.5rem;--lsd-subtitle1-fontSize:1.125rem;--lsd-subtitle1-fontWeight:normal;--lsd-subtitle1-lineHeight:1.5rem;--lsd-subtitle2-fontSize:1rem;--lsd-subtitle2-fontWeight:normal;--lsd-subtitle2-lineHeight:1.5rem;--lsd-subtitle3-fontSize:0.875rem;--lsd-subtitle3-fontWeight:normal;--lsd-subtitle3-lineHeight:1.25rem;--lsd-subtitle4-fontSize:0.75rem;--lsd-subtitle4-fontWeight:normal;--lsd-subtitle4-lineHeight:1rem;--lsd-body1-fontSize:1rem;--lsd-body1-fontWeight:normal;--lsd-body1-lineHeight:1.5rem;--lsd-body2-fontSize:0.875rem;--lsd-body2-fontWeight:normal;--lsd-body2-lineHeight:1.25rem;--lsd-body3-fontSize:0.75rem;--lsd-body3-fontWeight:normal;--lsd-body3-lineHeight:1rem;--lsd-label1-fontSize:0.875rem;--lsd-label1-fontWeight:normal;--lsd-label1-lineHeight:1.25rem;--lsd-label2-fontSize:0.75rem;--lsd-label2-fontWeight:normal;--lsd-label2-lineHeight:1rem;--lsd-typography-generic-font-family:sans-serif;--lsd-theme-primary:0,0,0;--lsd-theme-secondary:255,255,255;--lsd-surface-primary:255,255,255;--lsd-surface-secondary:0,0,0;--lsd-border-primary:0,0,0;--lsd-border-secondary:255,255,255;--lsd-icon-primary:0,0,0;--lsd-icon-secondary:255,255,255;--lsd-text-primary:0,0,0;--lsd-text-secondary:255,255,255;--lsd-text-tertiary:0,0,0,0.34;--lsd-spacing-4:4px;--lsd-spacing-8:8px;--lsd-spacing-16:16px;--lsd-spacing-24:24px;--lsd-spacing-32:32px;--lsd-spacing-40:40px;--lsd-spacing-64:64px;--lsd-spacing-80:80px;--lsd-spacing-96:96px;--lsd-spacing-120:120px;}</style><div class="root_QACb"><div role="region" aria-label="Skip to main content"><a class="skipToContent_fXgn" href="#__docusaurus_skipToContent_fallback">Skip to main content</a></div><nav aria-label="Main" class="navbar navbar--fixed-top navbarHideable_OoEf"><div class="navbar__inner"><div class="navbar__left"><a class="navbar__brand" href="/"><div class="navbar__logo"><img src="/theme/image/logo.svg" alt="Vac Research" class="themedImage_ToTc themedImage--light_HNdA" height="26"><img src="/theme/image/logo.svg" alt="Vac Research" class="themedImage_ToTc themedImage--dark_i4oU" height="26"></div><b class="navbar__title text--truncate"></b></a></div><div class="navbar__left-items"><a class="navbar__item navbar__link" href="/"><div class="lsd-typography lsd-typography--body2 linkContent__x3v">About Vac</div></a><a class="navbar__item navbar__link" href="/community"><div class="lsd-typography lsd-typography--body2 linkContent__x3v">Community</div></a><a class="navbar__item navbar__link" href="/rlog"><div class="lsd-typography lsd-typography--body2 linkContent__x3v">Research Blog</div></a><a aria-current="page" class="navbar__item navbar__link navbar__link--active" href="/join-us"><div class="lsd-typography lsd-typography--body2 linkContent__x3v">Join Us</div></a></div><div class="navbar__right-items"><div class="iconButtonGroup_ktNv lsd-icon-button-group lsd-icon-button-group--medium lsd-icon-button-group--outlined"><button class="clean-btn toggle_K23S colorModeToggle_GSaI navbar__color-mode-toggle toggleButtonDisabled_AAS_ lsd-icon-button lsd-icon-button--medium lsd-icon-button--outlined lsd-icon-button--disabled" type="button" title="Switch between dark and light mode (currently dark mode)" aria-label="Switch between dark and light mode (currently dark mode)" aria-live="polite"><svg viewBox="0 0 24 24" width="24" height="24" class="lightToggleIcon_K4TL"><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"></path></svg><svg viewBox="0 0 24 24" width="24" height="24" class="darkToggleIcon_lKkA"><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"></path></svg></button><button aria-label="Toggle navigation bar" aria-expanded="false" class="navbar__toggle clean-btn" type="button"><svg width="30" height="30" viewBox="0 0 30 30" aria-hidden="true"><path stroke="currentColor" stroke-linecap="round" stroke-miterlimit="10" stroke-width="2" d="M4 7h22M4 15h22M4 23h22"></path></svg></button></div></div></div><div role="presentation" class="navbar-sidebar__backdrop"></div></nav><div id="__docusaurus_skipToContent_fallback" class="main-wrapper mainWrapper_z2l0 docsWrapper_BCFX"><button aria-label="Scroll back to top" class="clean-btn theme-back-to-top-button backToTopButton_sjWU" type="button"></button><div class="docPage__5DB"><main class="docMainContainer_gTbr docMainContainerEnhanced_Uz_u"><div class="container padding-top--md padding-bottom--lg"><div class="row docItemGrid_SzoZ"><div class="docItemCol_F52z"><div class="docItemContainer_hrrU"><article><div class="theme-doc-markdown markdown"><div><h1 class="lsd-typography lsd-typography--h1 mdx-jpd__header">Current job openings</h1><div class="mdx-jpd__single-job-department-container"><span class="lsd-typography lsd-typography--subtitle2 mdx-jpd__department-title">Vac</span><ul class="mdx-jpd__job-list"><li class="mdx-jpd__job-list-item"><a href="https://boards.greenhouse.io/vac/jobs/6258104" target="_blank" rel="noopener noreferrer" class="mdx-jpd__job-link"><div class="mdx-jpd__job-title-container"><h5 class="lsd-typography lsd-typography--h5 mdx-jpd__job-title">Networking Engineer P2P </h5><div class="icon_S7Kx m_thRi mdx-jpd__external-link-icon"><svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg" role="img"><path fill-rule="evenodd" clip-rule="evenodd" d="M11.192 4H3.428V2.857h9.715v9.715H12V4.808l-8.167 8.168-.809-.808L11.192 4Z" fill="#fff"></path></svg></div></div><div class="lsd-typography lsd-typography--subtitle2">Remote (Worldwide)</div></a></li><li class="mdx-jpd__job-list-item"><a href="https://boards.greenhouse.io/vac/jobs/5543925" target="_blank" rel="noopener noreferrer" class="mdx-jpd__job-link"><div class="mdx-jpd__job-title-container"><h5 class="lsd-typography lsd-typography--h5 mdx-jpd__job-title">Zero Knowledge Research Engineer (ACZ)</h5><div class="icon_S7Kx m_thRi mdx-jpd__external-link-icon"><svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg" role="img"><path fill-rule="evenodd" clip-rule="evenodd" d="M11.192 4H3.428V2.857h9.715v9.715H12V4.808l-8.167 8.168-.809-.808L11.192 4Z" fill="#fff"></path></svg></div></div><div class="lsd-typography lsd-typography--subtitle2">Remote (Worldwide)</div></a></li><li class="mdx-jpd__job-list-item"><a href="https://boards.greenhouse.io/vac/jobs/5453093" target="_blank" rel="noopener noreferrer" class="mdx-jpd__job-link"><div class="mdx-jpd__job-title-container"><h5 class="lsd-typography lsd-typography--h5 mdx-jpd__job-title">Zero Knowledge Researcher (Nescience) </h5><div class="icon_S7Kx m_thRi mdx-jpd__external-link-icon"><svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg" role="img"><path fill-rule="evenodd" clip-rule="evenodd" d="M11.192 4H3.428V2.857h9.715v9.715H12V4.808l-8.167 8.168-.809-.808L11.192 4Z" fill="#fff"></path></svg></div></div><div class="lsd-typography lsd-typography--subtitle2">Remote (Worldwide)</div></a></li></ul></div></div></div></article><nav class="pagination-nav docusaurus-mt-lg" aria-label="Docs pages"></nav></div></div><div class="gap1_XuuQ"></div></div></div></main></div></div><footer class="footer"><div class="container container-fluid firstRow_ar1q"><div class="footer__bottom text--center"><div class="margin-bottom--sm"><a class="footerLogoLink_BH7S" href="/"><img src="/theme/image/logo.svg" alt="Vac Research" class="themedImage_ToTc themedImage--light_HNdA footer__logo" width="22"><img src="/theme/image/logo.svg" alt="Vac Research" class="themedImage_ToTc themedImage--dark_i4oU footer__logo" width="22"></a></div><div class="footer__copyright">Vac Research © 2024<br>All rights reserved.</div></div><div class="row footer__links"><div class="col footer__col"><div class="footer__title"></div><ul class="footer__items clean-list"><li class="footer__item"><a href="https://twitter.com/vacp2p" target="_blank" rel="noopener noreferrer" class="footer__link-item">Twitter<svg width="13.5" height="13.5" aria-hidden="true" viewBox="0 0 24 24" class="iconExternalLink_nPIU"><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"></path></svg></a></li><li class="footer__item"><a href="https://discord.gg/PQFdubGt6d" target="_blank" rel="noopener noreferrer" class="footer__link-item">Discord<svg width="13.5" height="13.5" aria-hidden="true" viewBox="0 0 24 24" class="iconExternalLink_nPIU"><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"></path></svg></a></li><li class="footer__item"><a href="https://github.com/vacp2p" target="_blank" rel="noopener noreferrer" class="footer__link-item">Github<svg width="13.5" height="13.5" aria-hidden="true" viewBox="0 0 24 24" class="iconExternalLink_nPIU"><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"></path></svg></a></li></ul></div><div class="col footer__col"><div class="footer__title"></div><ul class="footer__items clean-list"><li class="footer__item"><a href="https://jobs.status.im/" target="_blank" rel="noopener noreferrer" class="footer__link-item">Work With Us<svg width="13.5" height="13.5" aria-hidden="true" viewBox="0 0 24 24" class="iconExternalLink_nPIU"><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"></path></svg></a></li><li class="footer__item"><a class="footer__link-item" href="/terms">Terms & Conditions</a></li><li class="footer__item"><a class="footer__link-item" href="/privacy-policy">Privacy Policy</a></li><li class="footer__item"><a class="footer__link-item" href="/security">Security</a></li></ul></div></div></div><div class="secondRow__ww3"><div class="footer__bottom text--center">Logos Collective</div><div class="row footer__links"><div class="col footer__col"><div class="footer__title">Research</div><ul class="footer__items clean-list"><li class="footer__item"><a href="https://vac.dev" target="_blank" rel="noopener noreferrer" class="footer__link-item">VacP2P<svg width="13.5" height="13.5" aria-hidden="true" viewBox="0 0 24 24" class="iconExternalLink_nPIU"><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"></path></svg></a></li><li class="footer__item"><a href="https://afaik.institute" target="_blank" rel="noopener noreferrer" class="footer__link-item">AFAIK<svg width="13.5" height="13.5" aria-hidden="true" viewBox="0 0 24 24" class="iconExternalLink_nPIU"><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"></path></svg></a></li></ul></div><div class="col footer__col"><div class="footer__title">Infrastructure</div><ul class="footer__items clean-list"><li class="footer__item"><a href="https://waku.org/" target="_blank" rel="noopener noreferrer" class="footer__link-item">Waku<svg width="13.5" height="13.5" aria-hidden="true" viewBox="0 0 24 24" class="iconExternalLink_nPIU"><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"></path></svg></a></li><li class="footer__item"><a href="https://nimbus.team/" target="_blank" rel="noopener noreferrer" class="footer__link-item">Nimbus<svg width="13.5" height="13.5" aria-hidden="true" viewBox="0 0 24 24" class="iconExternalLink_nPIU"><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"></path></svg></a></li><li class="footer__item"><a href="https://codex.storage" target="_blank" rel="noopener noreferrer" class="footer__link-item">Codex<svg width="13.5" height="13.5" aria-hidden="true" viewBox="0 0 24 24" class="iconExternalLink_nPIU"><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"></path></svg></a></li><li class="footer__item"><a href="https://nomos.tech" target="_blank" rel="noopener noreferrer" class="footer__link-item">Nomos<svg width="13.5" height="13.5" aria-hidden="true" viewBox="0 0 24 24" class="iconExternalLink_nPIU"><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"></path></svg></a></li></ul></div><div class="col footer__col"><div class="footer__title">Creative Studio</div><ul class="footer__items clean-list"><li class="footer__item"><a href="https://acid.info" target="_blank" rel="noopener noreferrer" class="footer__link-item">Acid.info<svg width="13.5" height="13.5" aria-hidden="true" viewBox="0 0 24 24" class="iconExternalLink_nPIU"><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"></path></svg></a></li></ul></div><div class="col footer__col"><div class="footer__title">Movement</div><ul class="footer__items clean-list"><li class="footer__item"><a href="https://logos.co" target="_blank" rel="noopener noreferrer" class="footer__link-item">Logos<svg width="13.5" height="13.5" aria-hidden="true" viewBox="0 0 24 24" class="iconExternalLink_nPIU"><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"></path></svg></a></li></ul></div><div class="col footer__col"><div class="footer__title">User-facing products</div><ul class="footer__items clean-list"><li class="footer__item"><a href="https://status.im" target="_blank" rel="noopener noreferrer" class="footer__link-item">Status<svg width="13.5" height="13.5" aria-hidden="true" viewBox="0 0 24 24" class="iconExternalLink_nPIU"><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"></path></svg></a></li><li class="footer__item"><a href="https://keycard.tech" target="_blank" rel="noopener noreferrer" class="footer__link-item">Keycard<svg width="13.5" height="13.5" aria-hidden="true" viewBox="0 0 24 24" class="iconExternalLink_nPIU"><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"></path></svg></a></li></ul></div></div></div><button class="backToTop_wDfN lsd-button lsd-button--small lsd-button--outlined"><span class="lsd-typography lsd-typography--label2 lsd-button__text">Back to top ↑</span></button></footer></div></div> +<script src="/assets/js/runtime~main.a9103199.js"></script> +<script src="/assets/js/main.5454aec3.js"></script> </body> </html> \ No newline at end of file diff --git a/media/index.html b/media/index.html index c8ea835e..a534ddb0 100644 --- a/media/index.html +++ b/media/index.html @@ -10,8 +10,8 @@ <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/katex@0.13.24/dist/katex.min.css" integrity="sha384-odtC+0UGzzFL/6PNoE8rX/SPcQDXBJ+uRepguP4QkPCm2LBxH3FA3y+fKSiJ+AmM" crossorigin="anonymous"><link rel="stylesheet" href="/assets/css/styles.08d697e6.css"> -<link rel="preload" href="/assets/js/runtime~main.556fa6f5.js" as="script"> -<link rel="preload" href="/assets/js/main.ffc20c94.js" as="script"> +<link rel="preload" href="/assets/js/runtime~main.a9103199.js" as="script"> +<link rel="preload" href="/assets/js/main.5454aec3.js" as="script"> <meta property="og:image" content="https://vac.dev/_og/155b0a17201a7353cb7a0b44848491c819704c1c.png"><meta name="twitter:image" content="https://vac.dev/_og/155b0a17201a7353cb7a0b44848491c819704c1c.png"></head> <body class="navigation-with-keyboard"> <script>!function(){function e(e){document.documentElement.setAttribute("data-theme",e)}var t=function(){var e=null;try{e=new URLSearchParams(window.location.search).get("docusaurus-theme")}catch(e){}return e}()||function(){var e=null;try{e=localStorage.getItem("theme")}catch(e){}return e}();null!==t?e(t):window.matchMedia("(prefers-color-scheme: dark)").matches?e("dark"):window.matchMedia("(prefers-color-scheme: light)").matches?e("light"):e("dark")}()</script><div id="__docusaurus"> @@ -20,7 +20,7 @@ ) .lsd-dropdown__trigger:hover .lsd-dropdown__option-label,.lsd-dropdown:not(.lsd-dropdown--disabled):not( .lsd-dropdown--error ) .lsd-dropdown__trigger:focus .lsd-dropdown__option-label{-webkit-text-decoration:underline;text-decoration:underline;}.lsd-dropdown__label{display:block;}.lsd-dropdown__button-container{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-box-pack:justify;-webkit-justify-content:space-between;justify-content:space-between;}.lsd-dropdown__trigger{width:100%;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:row;-ms-flex-direction:row;flex-direction:row;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:justify;-webkit-justify-content:space-between;justify-content:space-between;border:none;cursor:pointer;background:none;}.lsd-dropdown__trigger:focus{outline:none;}.lsd-dropdown__option-label{cursor:inherit;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;}.lsd-dropdown__icons{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:row;-ms-flex-direction:row;flex-direction:row;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:center;-ms-flex-pack:center;-webkit-justify-content:center;justify-content:center;gap:8px;}.lsd-dropdown__icon{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;}.lsd-dropdown__supporting-text{margin:6px 14px;}.lsd-dropdown--error .lsd-dropdown__option-label{-webkit-text-decoration:line-through;text-decoration:line-through;}.lsd-dropdown--disabled{opacity:0.34;cursor:initial;}.lsd-dropdown--large{width:208px;}.lsd-dropdown--large.lsd-dropdown--error{width:230px;}.lsd-dropdown--large .lsd-dropdown__label{margin:0 0 6px 18px;}.lsd-dropdown--large .lsd-dropdown__button-container{height:40px;}.lsd-dropdown--large .lsd-dropdown__trigger{padding:10px 0px 10px 18px;}.lsd-dropdown--large .lsd-dropdown__icons{padding:0px 14px;}.lsd-dropdown--medium{width:188px;}.lsd-dropdown--medium.lsd-dropdown--error{width:210px;}.lsd-dropdown--medium .lsd-dropdown__label{margin:0 0 6px 14px;}.lsd-dropdown--medium .lsd-dropdown__button-container{height:32px;}.lsd-dropdown--medium .lsd-dropdown__trigger{padding:6px 0px 6px 14px;}.lsd-dropdown--medium .lsd-dropdown__icons{padding:0px 12px;}.lsd-dropdown--small{width:164px;}.lsd-dropdown--small.lsd-dropdown--error{width:186px;}.lsd-dropdown--small .lsd-dropdown__label{margin:0 0 6px 12px;}.lsd-dropdown--small .lsd-dropdown__button-container{height:28px;}.lsd-dropdown--small .lsd-dropdown__trigger{padding:6px 0px 6px 12px;}.lsd-dropdown--small .lsd-dropdown__icons{padding:0px 10px;}.lsd-dropdown--outlined .lsd-dropdown__button-container{border:1px solid rgb(var(--lsd-border-primary));}.lsd-dropdown--underlined .lsd-dropdown__button-container{border:1px solid transparent;border-bottom:1px solid rgb(var(--lsd-border-primary));}</style><style data-emotion="css-global w2g5fy">.lsd-dropdown-item{width:100%;box-sizing:border-box;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:row;-ms-flex-direction:row;flex-direction:row;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;border:1px solid rgb(var(--lsd-border-primary));}.lsd-dropdown-item:not(.lsd-dropdown-item--disabled){cursor:pointer;}.lsd-dropdown-item:not(.lsd-dropdown-item--disabled):hover,.lsd-dropdown-item:not(.lsd-dropdown-item--disabled):focus{outline:none;}.lsd-dropdown-item:not(.lsd-dropdown-item--disabled):hover .lsd-dropdown-item__label,.lsd-dropdown-item:not(.lsd-dropdown-item--disabled):focus .lsd-dropdown-item__label{-webkit-text-decoration:underline;text-decoration:underline;}.lsd-dropdown-item__label{display:block;overflow:hidden;white-space:nowrap;text-overflow:ellipsis;}.lsd-dropdown-item--disabled{opacity:0.34;}.lsd-dropdown-item__icon{margin-right:18px;-webkit-flex-shrink:0;-ms-flex-negative:0;flex-shrink:0;}.lsd-dropdown-item--small{padding:5px 9px;height:28px;}.lsd-dropdown-item--medium{padding:5px 11px;height:32px;}.lsd-dropdown-item--large{padding:5px 13px;height:40px;}</style><style data-emotion="css-global ww9kgc">.lsd-breadcrumb__list{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:row;-ms-flex-direction:row;flex-direction:row;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;list-style-type:none;margin:0;padding:0;}.lsd-breadcrumb--disabled .lsd-breadcrumb__list{opacity:0.34;cursor:initial;pointer-events:none;}.lsd-breadcrumb__dropdown-menu{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column;overflow:auto;border:1px solid rgb(var(--lsd-border-primary));margin-top:10px;position:absolute;width:auto!important;}.lsd-breadcrumb__dropdown-menu>li{cursor:pointer;}.lsd-breadcrumb__dropdown-menu>li:not(:last-child){border-bottom:1px solid rgb(var(--lsd-border-primary));}.lsd-breadcrumb__dropdown-menu>li:hover,.lsd-breadcrumb__dropdown-menu>li:focus{-webkit-text-decoration:underline;text-decoration:underline;text-decoration-color:rgb(var(--lsd-border-primary));}.lsd-breadcrumb__dropdown-menu li>a{width:164px;padding:5px 11px;}</style><style data-emotion="css-global 4gvini">.lsd-breadcrumb-item{list-style-type:none;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;}.lsd-breadcrumb__list>li:not(:last-child)::after{display:inline-block;margin-inline:12px;content:'/';}.lsd-breadcrumb-item__link{-webkit-text-decoration:none;text-decoration:none;cursor:pointer;}.lsd-breadcrumb-item--outlined{padding:3px 11px;border:1px solid rgb(var(--lsd-border-primary));}.lsd-breadcrumb:not(.lsd-breadcrumb--disabled) .lsd-breadcrumb-item__link:hover,.lsd-breadcrumb:not(.lsd-breadcrumb--disabled) .lsd-breadcrumb-item__link:focus{-webkit-text-decoration:underline;text-decoration:underline;text-decoration-color:rgb(var(--lsd-border-primary));}</style><style data-emotion="css-global 1cwg3oc">.lsd-card{box-sizing:border-box;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column;}.lsd-card>.lsd-card-header{margin-bottom:-1px;}</style><style data-emotion="css-global v7d76i">.lsd-card-header{box-sizing:border-box;padding:10px 18px;text-align:center;border:1px solid rgb(var(--lsd-border-primary));}.lsd-card-header__title{overflow:hidden;word-break:break-all;}.lsd-card-header--large{padding:10px 18px;}.lsd-card-header--medium{padding:6px 14px;}.lsd-card-header--small{padding:6px 12px;}</style><style data-emotion="css-global 1txgafh">.lsd-card-body{box-sizing:border-box;padding:14px 22px;border:1px solid rgb(var(--lsd-border-primary));}</style><style data-emotion="css-global kzy52c">.lsd-tag{width:-webkit-fit-content;width:-moz-fit-content;width:fit-content;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:row;-ms-flex-direction:row;flex-direction:row;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:center;-ms-flex-pack:center;-webkit-justify-content:center;justify-content:center;box-sizing:border-box;border:1px solid rgb(var(--lsd-icon-primary));}.lsd-tag:hover,.lsd-tag:focus{-webkit-text-decoration:underline;text-decoration:underline;cursor:pointer;}.lsd-badge--large{padding:3px 11px;gap:12px;height:28px;}.lsd-badge--small{padding:3px 7px;gap:8px;height:24px;}.lsd-tag--filled{background-color:rgb(var(--lsd-icon-primary));}.lsd-tag--filled .lsd-tag__label{color:rgb(var(--lsd-text-secondary));}.lsd-tag--filled svg{--lsd-icon-primary:var(--lsd-icon-secondary);}.lsd-tag--outlined{color:rgb(var(--lsd-text-primary));}.lsd-tag--disabled{opacity:0.3;cursor:initial;pointer-events:none;}</style><style data-emotion="css-global 4wy0ub">.lsd-text-field{box-sizing:border-box;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column;}.lsd-text-field__input-container{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:justify;-webkit-justify-content:space-between;justify-content:space-between;}.lsd-text-field--disabled{opacity:0.34;}.lsd-text-field__input{border:none;outline:none;font-size:14px;color:rgb(var(--lsd-text-primary));background:none;width:100%;}.lsd-text-field__input:hover{outline:none;}.lsd-text-field__input::-webkit-input-placeholder{color:rgb(var(--lsd-text-primary));opacity:0.3;}.lsd-text-field__input::-moz-placeholder{color:rgb(var(--lsd-text-primary));opacity:0.3;}.lsd-text-field__input:-ms-input-placeholder{color:rgb(var(--lsd-text-primary));opacity:0.3;}.lsd-text-field__input::placeholder{color:rgb(var(--lsd-text-primary));opacity:0.3;}.lsd-text-field--error .lsd-text-field__input{-webkit-text-decoration:line-through;text-decoration:line-through;}.lsd-text-field__supporting-text{width:-webkit-fit-content;width:-moz-fit-content;width:fit-content;}.lsd-text-field--large{width:208px;}.lsd-text-field--large>*{padding:10px 14px 10px 18px;}.lsd-text-field--medium{width:188px;}.lsd-text-field--medium>*{padding:6px 12px 6px 14px;}.lsd-text-field--small{width:164px;}.lsd-text-field--small>*{padding:6px 10px 6px 12px;}.lsd-text-field__label{padding-top:0;padding-bottom:6px;}.lsd-text-field__supporting-text{padding-bottom:0;padding-top:6px;}.lsd-text-field--outlined .lsd-text-field__input-container{border:1px solid rgb(var(--lsd-border-primary));}.lsd-text-field--underlined .lsd-text-field__input-container{border:1px solid transparent;border-bottom:1px solid rgb(var(--lsd-border-primary));}.lsd-text-field__clear-button{padding:0;width:auto;height:auto;margin:0;border:0;}</style><style data-emotion="css-global uhig7c">.lsd-checkbox{position:relative;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:row;-ms-flex-direction:row;flex-direction:row;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;}.lsd-checkbox__input{opacity:0;position:absolute;left:0;top:0;padding:0;margin:0;width:100%;height:100%;}.lsd-checkbox:not(.lsd-checkbox--disabled):hover,.lsd-checkbox:not(.lsd-checkbox--disabled).lsd-checkbox--focused{-webkit-text-decoration:underline;text-decoration:underline;}.lsd-checkbox:not(.lsd-checkbox--disabled) .lsd-checkbox__input{cursor:pointer;}.lsd-checkbox--disabled{opacity:0.34;}.lsd-checkbox__label{margin-left:18px;}.lsd-checkbox--large .lsd-checkbox__label{margin-left:18px;}.lsd-checkbox--medium .lsd-checkbox__label{margin-left:14px;}.lsd-checkbox--small .lsd-checkbox__label{margin-left:12px;}</style><style data-emotion="css-global txommo">.lsd-autocomplete{box-sizing:border-box;}.lsd-autocomplete__label{display:block;}.lsd-autocomplete__input-container{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-box-pack:justify;-webkit-justify-content:space-between;justify-content:space-between;}.lsd-autocomplete--disabled{opacity:0.34;}.lsd-autocomplete__input{border:none;outline:none;font-size:14px;color:rgb(var(--lsd-text-primary));background:none;width:100%;}.lsd-autocomplete__input:hover{outline:none;}.lsd-autocomplete__input::-webkit-input-placeholder{color:rgb(var(--lsd-text-primary));opacity:0.3;}.lsd-autocomplete__input::-moz-placeholder{color:rgb(var(--lsd-text-primary));opacity:0.3;}.lsd-autocomplete__input:-ms-input-placeholder{color:rgb(var(--lsd-text-primary));opacity:0.3;}.lsd-autocomplete__input::placeholder{color:rgb(var(--lsd-text-primary));opacity:0.3;}.lsd-autocomplete__icon{cursor:pointer;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;}.lsd-autocomplete--error{-webkit-text-decoration:line-through;text-decoration:line-through;}.lsd-autocomplete--large{width:208px;}.lsd-autocomplete--large .lsd-autocomplete__label{margin:0 0 6px 18px;}.lsd-autocomplete--large .lsd-autocomplete__input-container{height:40px;}.lsd-autocomplete--large .lsd-autocomplete__input{padding:9px 17px;}.lsd-autocomplete--large .lsd-autocomplete__icon{padding:12px 13px;}.lsd-autocomplete--medium{width:188px;}.lsd-autocomplete--medium .lsd-autocomplete__label{margin:0 0 6px 14px;}.lsd-autocomplete--medium .lsd-autocomplete__input-container{height:32px;}.lsd-autocomplete--medium .lsd-autocomplete__input{padding:5px 13px;}.lsd-autocomplete--medium .lsd-autocomplete__icon{padding:8px 11px;}.lsd-autocomplete--small{width:164px;}.lsd-autocomplete--small .lsd-autocomplete__label{margin:0 0 6px 12px;}.lsd-autocomplete--small .lsd-autocomplete__input-container{height:28px;}.lsd-autocomplete--small .lsd-autocomplete__input{padding:5px 11px;}.lsd-autocomplete--small .lsd-autocomplete__icon{padding:6px 9px;}.lsd-autocomplete--outlined .lsd-autocomplete__input-container{border:1px solid rgb(var(--lsd-border-primary));}.lsd-autocomplete--underlined .lsd-autocomplete__input-container{border:1px solid transparent;border-bottom:1px solid rgb(var(--lsd-border-primary));}.lsd-autocomplete__dropdown-item-placeholder{opacity:0.5;white-space:pre;}</style><style data-emotion="css-global quxxm6">.lsd-quote{color:rgb(var(--lsd-text-primary));white-space:pre-wrap;}.lsd-quote--indented-inline{border-left:1px solid rgb(var(--lsd-border-primary));padding:4px 8px 4px 28px;}.lsd-quote--parentheses{padding:0px;text-align:center;}.lsd-quote--parentheses::before{content:'***';}.lsd-quote--parentheses::after{content:'***';}</style><style data-emotion="css-global a49t4h">.lsd-collapse{box-sizing:border-box;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column;}.lsd-collapse--open .lsd-collapse__content{border-top:1px solid transparent;}.lsd-collapse__content{border:1px solid rgb(var(--lsd-border-primary));}</style><style data-emotion="css-global 12ppw0q">.lsd-collapse-header{box-sizing:border-box;}.lsd-collapse-header:not(.lsd-collapse-header--disabled) .lsd-collapse-header__trigger:hover .lsd-collapse-header__label{-webkit-text-decoration:underline;text-decoration:underline;}.lsd-collapse-header__trigger{width:100%;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:row;-ms-flex-direction:row;flex-direction:row;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:justify;-webkit-justify-content:space-between;justify-content:space-between;cursor:pointer;background:none;border:1px solid rgb(var(--lsd-border-primary));}.lsd-collapse-header__trigger:focus{outline:none;}.lsd-collapse-header__label{cursor:inherit;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;margin:auto;}.lsd-collapse-header__icons{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:row;-ms-flex-direction:row;flex-direction:row;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:end;-ms-flex-pack:end;-webkit-justify-content:flex-end;justify-content:flex-end;}.lsd-collapse-header__icon{margin-right:8px;}.lsd-collapse-header--disabled .lsd-collapse-header__trigger{opacity:0.34;cursor:initial;}.lsd-collapse-header--large .lsd-collapse-header__trigger{width:299px;height:40px;padding:9px 17px;}.lsd-collapse-header--medium .lsd-collapse-header__trigger{width:270px;height:32px;padding:5px 13px;}.lsd-collapse-header--small .lsd-collapse-header__trigger{width:235px;height:28px;padding:5px 11px;}</style><style data-emotion="css-global dixc0i">.lsd-checkbox-group{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column;gap:6px;width:-webkit-fit-content;width:-moz-fit-content;width:fit-content;}.lsd-checkbox-group__label{margin-bottom:6px;}</style><style data-emotion="css-global q2n2hz">.lsd-badge{width:-webkit-fit-content;width:-moz-fit-content;width:fit-content;box-sizing:border-box;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:row;-ms-flex-direction:row;flex-direction:row;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:center;-ms-flex-pack:center;-webkit-justify-content:center;justify-content:center;border:1px solid rgb(var(--lsd-icon-primary));border-radius:20px;}.lsd-badge:hover,.lsd-badge:focus{-webkit-text-decoration:underline;text-decoration:underline;cursor:pointer;}.lsd-badge--large{padding:3px 11px;gap:12px;height:28px;}.lsd-badge--small{padding:3px 7px;gap:8px;height:24px;}.lsd-badge--filled{background-color:rgb(var(--lsd-icon-primary));}.lsd-badge--filled .lsd-badge__label{color:rgb(var(--lsd-text-secondary));}.lsd-badge--filled svg{--lsd-icon-primary:var(--lsd-icon-secondary);}.lsd-badge--outlined{color:rgb(var(--lsd-text-primary));}.lsd-badge--disabled{opacity:0.3;cursor:initial;pointer-events:none;}</style><style data-emotion="css-global rlst54">.lsd-radio-button{position:relative;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:row;-ms-flex-direction:row;flex-direction:row;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;}.lsd-radio-button__input{opacity:0;position:absolute;left:0;top:0;padding:0;margin:0;width:100%;height:100%;}.lsd-radio-button:not(.lsd-radio-button--disabled):hover{-webkit-text-decoration:underline;text-decoration:underline;}.lsd-radio-button:not(.lsd-radio-button--disabled) .lsd-radio-button__input{cursor:pointer;}.lsd-radio-button--disabled{opacity:0.34;}.lsd-radio-button__label{margin-left:18px;}.lsd-radio-button--large .lsd-radio-button__label{margin-left:18px;}.lsd-radio-button--medium .lsd-radio-button__label{margin-left:14px;}.lsd-radio-button--small .lsd-radio-button__label{margin-left:12px;}</style><style data-emotion="css-global mo7h6o">.lsd-radio-button-group{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column;gap:6px;width:-webkit-fit-content;width:-moz-fit-content;width:fit-content;}.lsd-radio-button-group__label{margin-bottom:6px;}</style><style data-emotion="css-global amncrr">.lsd-table{box-sizing:border-box;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column;}.lsd-table>.lsd-table-header{margin-bottom:-1px;}</style><style data-emotion="css-global 1fkbozr">.lsd-table-header{box-sizing:border-box;border:1px solid rgb(var(--lsd-border-primary));}</style><style data-emotion="css-global 1fb1r54">.lsd-table-body table{border-collapse:collapse;text-align:center;table-layout:fixed;width:100%;height:auto;}.lsd-table-body table tr:first-of-type td label:has(input[type='radio']){display:none;}.lsd-table-body__toolbar{box-sizing:border-box;padding:10px;border:1px solid rgb(var(--lsd-border-primary));border-bottom:none;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-box-pack:justify;-webkit-justify-content:space-between;justify-content:space-between;}</style><style data-emotion="css-global 607rj8">.lsd-table-item{border:1px solid rgb(var(--lsd-border-primary));}.lsd-table-item:has(> label){width:40px;}.lsd-table-item:has(> label) input{position:relative;width:14px;height:14px;margin:auto;}.lsd-table-item:has(> label) span{margin-left:14px!important;}.lsd-table-item--large{padding:10px;}.lsd-table-item--medium{padding:6px 8px;}.lsd-table-item--small{padding:6px;}</style><style data-emotion="css-global 1vlh57l">.lsd-table-row{-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;}</style><style data-emotion="css-global 1fw5y3v">.lsd-number-input{width:auto;box-sizing:border-box;}.lsd-number-input__main-container:hover{-webkit-text-decoration:underline;text-decoration:underline;}.lsd-number-input--error .lsd-number-input__main-container{-webkit-text-decoration:line-through;text-decoration:line-through;}.lsd-number-input__label{display:block;}.lsd-number-input__plus-minus-icons{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-shrink:0;-ms-flex-negative:0;flex-shrink:0;}.lsd-number-input__input-container{box-sizing:border-box;border:1px solid rgb(var(--lsd-border-primary));border-left:0px;border-right:0px;}.lsd-number-input__error-icon{cursor:pointer;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;padding:10px 8px;}.lsd-number-input__input-container{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:justify;-webkit-justify-content:space-between;justify-content:space-between;}.lsd-number-input--disabled{opacity:0.34;}.lsd-number-input__main-container{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;}.lsd-number-input__input{border:none;outline:none;font-size:14px;color:rgb(var(--lsd-text-primary));background:none;text-align:center;padding:0 4px;}.lsd-number-input__input::-webkit-inner-spin-button{display:none;-webkit-appearance:none;}.lsd-number-input__input:hover{outline:none;}.lsd-number-input__supporting-text{position:absolute;}.lsd-number-input--large .lsd-number-input__label{margin:0 0 6px 18px;}.lsd-number-input--large .lsd-number-input__input-container{height:40px;}.lsd-number-input--large .lsd-number-input__input{width:62px;}.lsd-number-input--large .lsd-number-input__plus-minus-icons{height:40px;width:40px;}.lsd-number-input--large .lsd-number-input__supporting-text{margin:6px 18px 0 18px;}.lsd-number-input--medium .lsd-number-input__label{margin:0 0 6px 14px;}.lsd-number-input--medium .lsd-number-input__input-container{height:32px;}.lsd-number-input--medium .lsd-number-input__input{width:58px;}.lsd-number-input--medium .lsd-number-input__plus-minus-icons{height:32px;width:32px;}.lsd-number-input--medium .lsd-number-input__supporting-text{margin:6px 14px 0 14px;}.lsd-number-input--small .lsd-number-input__label{margin:0 0 6px 12px;}.lsd-number-input--small .lsd-number-input__input-container{height:28px;}.lsd-number-input--small .lsd-number-input__input{width:50px;}.lsd-number-input--small .lsd-number-input__plus-minus-icons{height:28px;width:28px;}.lsd-number-input--small .lsd-number-input__supporting-text{margin:6px 12px 0 12px;}</style><style data-emotion="css-global 12rmo7o">.lsd-modal{box-sizing:border-box;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column;position:fixed;top:0;left:0;right:0;bottom:0;background-color:rgba(0, 0, 0, 0.5);display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-box-pack:center;-ms-flex-pack:center;-webkit-justify-content:center;justify-content:center;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;z-index:9999;}.lsd-modal__container{position:relative;background:rgb(var(--lsd-surface-primary));padding:20px;max-width:90%;box-sizing:border-box;border:1px solid rgb(var(--lsd-border-primary));}.lsd-modal__header{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-box-pack:justify;-webkit-justify-content:space-between;justify-content:space-between;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;}.lsd-modal__close-icon{position:absolute;top:8px;right:8px;cursor:pointer;}.lsd-modal__title-and-subtitle-container{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column;}.lsd-modal--large .lsd-modal__container{min-width:960px;}.lsd-modal--medium .lsd-modal__container{min-width:768px;}.lsd-modal--small .lsd-modal__container{min-width:614px;}.lsd-modal--extra-small .lsd-modal__container{min-width:490px;}</style><style data-emotion="css-global 1k7gzc">.lsd-modal-footer{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;}</style><style data-emotion="css-global 1b9t8so">.lsd-modal-body{margin:18px 0;}</style><style data-emotion="css-global dyud2a">.lsd-date-picker{width:-webkit-fit-content;width:-moz-fit-content;width:fit-content;}.lsd-date-picker__calendar{border-top:none!important;}.lsd-date-picker--large .lsd-date-field--large{width:318px;}.lsd-date-picker--medium .lsd-date-field--medium{width:290px;}.lsd-date-picker--small .lsd-date-field--small{width:262px;}</style><style data-emotion="css-global olq3nk">.lsd-date-field{width:auto;box-sizing:border-box;}.lsd-date-field__label{display:block;}.lsd-date-field__input-container__icon{position:absolute;right:0;cursor:pointer;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;background-color:rgb(var(--lsd-surface-primary));}.lsd-date-field__input-container__icon:focus{background:blue;background-color:pink;border:1px solid rgb(var(--lsd-border-primary));}.lsd-date-field__input-container__no-icon{position:absolute;right:0;background-color:rgb(var(--lsd-surface-primary));padding:12px;}.lsd-date-field--outlined{border:1px solid rgb(var(--lsd-border-primary));}.lsd-date-field--underlined{border-bottom:1px solid rgb(var(--lsd-border-primary));}.lsd-date-field__input-container{position:relative;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:justify;-webkit-justify-content:space-between;justify-content:space-between;}.lsd-date-field--disabled{opacity:0.34;}.lsd-date-field__input-container__input{border:none;outline:none;font-size:14px;color:rgb(var(--lsd-text-primary));background:none;width:100%;opacity:0.4;-webkit-transition:opacity 0.2s ease-in-out;transition:opacity 0.2s ease-in-out;}.lsd-date-field__input-container__input::-webkit-inner-spin-button,.lsd-date-field__input-container__input::-webkit-calendar-picker-indicator{display:none;-webkit-appearance:none;}.lsd-date-field__input-container__input:hover{outline:none;}.lsd-date-field__supporting-text{position:absolute;}.lsd-date-field--large{width:208px;}.lsd-date-field--large .lsd-date-field__label{margin:0 0 6px 18px;}.lsd-date-field--large .lsd-date-field__input-container{height:40px;}.lsd-date-field--large .lsd-date-field__input-container__input{padding:9px 0px 9px 17px;}.lsd-date-field--large .lsd-date-field__input-container__icon{padding:12px 13px;}.lsd-date-field--large .lsd-date-field__supporting-text{margin:6px 18px 0 18px;}.lsd-date-field--medium{width:188px;}.lsd-date-field--medium .lsd-date-field__label{margin:0 0 6px 14px;}.lsd-date-field--medium .lsd-date-field__input-container{height:32px;}.lsd-date-field--medium .lsd-date-field__input-container__input{padding:5px 11px 5px 13px;}.lsd-date-field--medium .lsd-date-field__input-container__icon{padding:8px 11px;}.lsd-date-field--medium .lsd-date-field__supporting-text{margin:6px 14px 0 14px;}.lsd-date-field--small{width:164px;}.lsd-date-field--small .lsd-date-field__label{margin:0 0 6px 12px;}.lsd-date-field--small .lsd-date-field__input-container{height:28px;}.lsd-date-field--small .lsd-date-field__input-container__input{padding:5px 9px 5px 11px;font-size:12px;}.lsd-date-field--small .lsd-date-field__input-container__icon{padding:6px 9px;}.lsd-date-field--small .lsd-date-field__supporting-text{margin:6px 12px 0 12px;}.lsd-date-field__input-container__input:invalid,.lsd-date-field__input-container__input--filled{color:rgb(var(--lsd-border-primary));opacity:1;}.lsd-date-field--error .lsd-date-field__input-container__input::-webkit-datetime-edit-year-field,.lsd-date-field--error .lsd-date-field__input-container__input::-webkit-datetime-edit-month-field,.lsd-date-field--error .lsd-date-field__input-container__input::-webkit-datetime-edit-day-field{-webkit-text-decoration:line-through;text-decoration:line-through;}@supports not selector(::-webkit-datetime-edit-day-field){.lsd-date-field--error .lsd-date-field__input-container__input{-webkit-text-decoration:line-through;text-decoration:line-through;}}</style><style data-emotion="css-global 1gjtao4">.lsd-calendar{border:1px solid rgb(var(--lsd-border-primary));visibility:hidden;position:absolute!important;top:0;left:0;opacity:0;visibility:hidden;margin:0;padding:0;box-sizing:border-box;background:rgb(var(--lsd-surface-primary));-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;}.lsd-calendar-container{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column;padding:8px;}.lsd-calendar--open{opacity:1;visibility:visible;}.lsd-calendar-header{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-box-pack:center;-ms-flex-pack:center;-webkit-justify-content:center;justify-content:center;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;height:32px;margin-bottom:8px;}.lsd-calendar__week_day{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-box-pack:center;-ms-flex-pack:center;-webkit-justify-content:center;justify-content:center;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;aspect-ratio:1/1;margin-bottom:4px;}.lsd-calendar__change-year{position:relative;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-box-pack:center;-ms-flex-pack:center;-webkit-justify-content:center;justify-content:center;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;padding:2px 0xp 2px 8px;gap:6px;border:1px solid transparent;}.lsd-calendar__change-year--active .lsd-calendar__year-and-icon{border:1px solid rgb(var(--lsd-border-primary));}.lsd-calendar__change-year-icon-container{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-box-pack:center;-ms-flex-pack:center;-webkit-justify-content:center;justify-content:center;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;cursor:pointer;border:none;}.lsd-calendar-month{margin-right:8px;}.lsd-calendar__month-and-year{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:center;-ms-flex-pack:center;-webkit-justify-content:center;justify-content:center;}.lsd-calendar-day__container{cursor:pointer;background:transparent;position:relative;box-sizing:border-box;border:1px solid transparent;}.lsd-calendar-day{aspect-ratio:1/1;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-box-pack:center;-ms-flex-pack:center;-webkit-justify-content:center;justify-content:center;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;}.lsd-calendar-day:hover{cursor:pointer;-webkit-text-decoration:underline;text-decoration:underline;text-decoration-color:rgb(var(--lsd-border-primary));}.lsd-calendar-day label:hover{cursor:pointer;}.lsd-calendar-day--selected{border:1px solid rgb(var(--lsd-border-primary));}.lsd-calendar-day--disabled{opacity:0.3;cursor:default;}.lsd-calendar-day__today_indicator{position:absolute;left:50%;-webkit-transform:translateX(-50%);-moz-transform:translateX(-50%);-ms-transform:translateX(-50%);transform:translateX(-50%);bottom:2px;}.lsd-calendar--disabled{pointer-events:none;border:1px solid rgba(var(--lsd-border-primary), 0.3);}.lsd-calendar--disabled label{opacity:0.3;}.lsd-calendar--disabled .lsd-calendar__button{opacity:0.3;}.lsd-calendar--disabled .lsd-calendar-day--selected{opacity:0.3;}.lsd-calendar__button{border:1px solid rgb(var(--lsd-border-primary));cursor:pointer;background:transparent;width:32px;height:32px;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:center;-ms-flex-pack:center;-webkit-justify-content:center;justify-content:center;position:absolute;}.lsd-calendar__next-month-button{top:8px;right:8px;}.lsd-calendar__previous-month-button{top:8px;left:8px;}.lsd-calendar-day--border-left{border-left:1px double rgb(var(--lsd-border-primary));}.lsd-calendar-day--border-right{border-right:1px double rgb(var(--lsd-border-primary));}.lsd-calendar-day--border-left-and-right{border-left:1px double rgb(var(--lsd-border-primary));border-right:1px double rgb(var(--lsd-border-primary));}.lsd-calendar-day--border-top-and-bottom{border-top:1px double rgb(var(--lsd-border-primary));border-bottom:1px double rgb(var(--lsd-border-primary));}.lsd-calendar__month-table{border-collapse:collapse;}.lsd-calendar__year-dropdown{box-sizing:border-box;position:absolute;top:100%;left:0;max-height:200px;overflow-y:auto;width:100%;border:1px solid rgb(var(--lsd-border-primary));border-top:none;z-index:1;}.lsd-calendar__year-dropdown .lsd-calendar-year{border-bottom:1px solid rgb(var(--lsd-border-primary));}.lsd-calendar__year-dropdown--hidden{visibility:hidden;}.lsd-calendar-year{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;cursor:pointer;-webkit-transition:background-color 0.2s;transition:background-color 0.2s;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;background:rgb(var(--lsd-surface-primary));}.lsd-calendar-year:hover{-webkit-text-decoration:underline;text-decoration:underline;}.lsd-calendar__year-and-icon{border:1px solid rgb(var(--lsd-border-primary));}.lsd-calendar--large .lsd-calendar-year{padding:6px 0px 6px 14px;}.lsd-calendar--large .lsd-calendar__change-year-icon-container{width:32px;}.lsd-calendar--medium .lsd-calendar-year{padding:6px 0px 6px 12px;}.lsd-calendar--medium .lsd-calendar__change-year-icon-container{width:28px;}.lsd-calendar--small .lsd-calendar-year{padding:6px 0px 6px 12px;}.lsd-calendar--small .lsd-calendar__change-year-icon-container{width:28px;}</style><style data-emotion="css-global dlrd7d">.lsd-toast{box-sizing:border-box;display:-webkit-inline-box;display:-webkit-inline-flex;display:-ms-inline-flexbox;display:inline-flex;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;background:rgb(var(--lsd-surface-primary));border:1px solid rgb(var(--lsd-border-primary));padding:8px;height:-webkit-fit-content;height:-moz-fit-content;height:fit-content;}.lsd-toast__inline-button-container{-webkit-flex-shrink:0;-ms-flex-negative:0;flex-shrink:0;}.lsd-toast__column-button-container{margin-top:18px;margin-bottom:6px;}.lsd-toast__inline-container{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:justify;-webkit-justify-content:space-between;justify-content:space-between;-webkit-box-flex:1;-webkit-flex-grow:1;-ms-flex-positive:1;flex-grow:1;}.lsd-toast__column-container{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column;-webkit-box-pack:justify;-webkit-justify-content:space-between;justify-content:space-between;}.lsd-toast__text-container{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column;color:rgb(var(--lsd-text-secondary));padding-left:12px;}.lsd-toast__title{position:relative;}.lsd-toast__information{margin-top:4px;}.lsd-toast__button-container{min-height:28px;min-width:60px;width:-webkit-fit-content;width:-moz-fit-content;width:fit-content;padding:0px 12px;}.lsd-toast__close-button{margin-bottom:auto;-webkit-flex-shrink:0;-ms-flex-negative:0;flex-shrink:0;height:28px;width:28px;margin-left:auto;}.lsd-toast__column-icon-container{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-box-pack:center;-ms-flex-pack:center;-webkit-justify-content:center;justify-content:center;margin-bottom:auto;position:relative;top:4px;padding-left:4px;}.lsd-toast__inline-icon-container{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:center;-ms-flex-pack:center;-webkit-justify-content:center;justify-content:center;padding-left:4px;}.lsd-toast__icon{position:relative;}.lsd-toast--large{width:364px;}.lsd-toast--medium{width:336px;}.lsd-toast--small{width:296px;}.lsd-toast--small .lsd-toast__icon{top:0px;}</style><style data-emotion="css-global 5wlfwk">.lsd-toast-provider__toast-container{position:fixed;-webkit-transition:all 230ms cubic-bezier(0.21, 1.02, 0.73, 1);transition:all 230ms cubic-bezier(0.21, 1.02, 0.73, 1);z-index:9999;}.lsd-toast-provider__toast--top-left,.lsd-toast-provider__toast--top-center,.lsd-toast-provider__toast--top-right{top:0;}.lsd-toast-provider__toast--bottom-left,.lsd-toast-provider__toast--bottom-center,.lsd-toast-provider__toast--bottom-right{bottom:0;}.lsd-toast-provider__toast--top-center,.lsd-toast-provider__toast--bottom-center{left:50%;}.lsd-toast-provider__toast--top-right,.lsd-toast-provider__toast--bottom-right{right:0;}</style><style data-emotion="css-global 9yw6e1">.lsd-button-group{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:row;-ms-flex-direction:row;flex-direction:row;}.lsd-button-group >*:not(:last-child).lsd-button--outlined,.lsd-button-group >*:not(:last-child) .lsd-button--outlined{border-right:none;}</style><style data-emotion="css-global 17u9w7w">.lsd-date-range-picker{box-sizing:border-box;}.lsd-date-range-picker .lsd-date-field--outlined{border:none;}.lsd-date-range-picker .lsd-date-field__input-container__icon{padding:8px;}.lsd-date-range-picker__label{display:block;}.lsd-date-range-picker__input-container{box-sizing:border-box;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;border:1px solid transparent;}.lsd-date-picker__calendar{border-top:none!important;}.lsd-date-picker__calendar .lsd-tooltip-base__arrow-tip{-webkit-transition:left 0.2s ease-in-out;transition:left 0.2s ease-in-out;}.lsd-date-range-picker--calendar-open .lsd-date-range-picker__input-container{border-bottom:1px solid rgb(var(--lsd-border-primary));}.lsd-date-range-picker__icon{cursor:pointer;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:center;-ms-flex-pack:center;-webkit-justify-content:center;justify-content:center;-webkit-box-flex:1;-webkit-flex-grow:1;-ms-flex-positive:1;flex-grow:1;padding:0 10px;}.lsd-date-range-picker--disabled{opacity:0.3;}.lsd-date-range-picker__supporting-text{position:absolute;}.lsd-date-range-picker--large{width:318px;}.lsd-date-range-picker--large .lsd-date-field--large{width:156px;}.lsd-date-range-picker--large .lsd-date-field__input-container__input{padding-right:0;}.lsd-date-range-picker--large .lsd-date-field__input-container__icon{padding:11px 12px;}.lsd-date-range-picker--large .lsd-date-range-picker__label{margin:0 0 6px 18px;}.lsd-date-range-picker--large .lsd-date-range-picker__input-container{height:40px;}.lsd-date-range-picker--large .lsd-date-range-picker__supporting-text{margin:6px 18px 0 18px;}.lsd-date-range-picker--medium{width:290px;}.lsd-date-range-picker--medium .lsd-date-field--medium{width:142px;}.lsd-date-range-picker--medium .lsd-date-field__input-container__input{padding-right:0;}.lsd-date-range-picker--medium .lsd-date-field__input-container__icon{padding:7px 8px;}.lsd-date-range-picker--medium .lsd-date-range-picker__label{margin:0 0 6px 14px;}.lsd-date-range-picker--medium .lsd-date-range-picker__input-container{height:32px;}.lsd-date-range-picker--medium .lsd-date-range-picker__supporting-text{margin:6px 14px 0 14px;}.lsd-date-range-picker--small{width:262px;}.lsd-date-range-picker--small .lsd-date-field--small{width:128px;}.lsd-date-range-picker--small .lsd-date-field__input-container__input{padding-right:0;}.lsd-date-range-picker--small .lsd-date-field__input-container__icon{padding:5px 7px;}.lsd-date-range-picker--small .lsd-date-range-picker__label{margin:0 0 6px 12px;}.lsd-date-range-picker--small .lsd-date-range-picker__input-container{height:28px;}.lsd-date-range-picker--small .lsd-date-range-picker__supporting-text{margin:6px 12px 0 12px;}.lsd-date-range-picker__separator{margin-left:3px;width:1px;height:100%;}.lsd-date-range-picker__separator{border-left:1px solid transparent;}.lsd-date-range-picker--outlined{border:1px solid rgb(var(--lsd-border-primary));}.lsd-date-range-picker--outlined .lsd-date-range-picker__separator{border-left:1px solid rgb(var(--lsd-border-primary));}</style><style data-emotion="css-global 19d282h">.lsd-tooltip-base{border:1px solid rgb(var(--lsd-border-primary));position:relative;}.lsd-tooltip-base__arrow-tip{border:1px solid rgb(var(--lsd-border-primary));position:absolute;background:rgb(var(--lsd-surface-primary));}.lsd-tooltip-base__content{background:rgb(var(--lsd-surface-primary));width:100%;height:100%;position:relative;z-index:1;}</style><style data-emotion="css-global 1o77wkp">[data-theme=dark]{--lsd-display1-fontSize:5.5rem;--lsd-display1-fontWeight:normal;--lsd-display1-lineHeight:6rem;--lsd-display2-fontSize:4rem;--lsd-display2-fontWeight:normal;--lsd-display2-lineHeight:4.5rem;--lsd-display3-fontSize:3.5rem;--lsd-display3-fontWeight:normal;--lsd-display3-lineHeight:4rem;--lsd-display4-fontSize:3rem;--lsd-display4-fontWeight:normal;--lsd-display4-lineHeight:3.5rem;--lsd-h1-fontSize:2.5rem;--lsd-h1-fontWeight:normal;--lsd-h1-lineHeight:3rem;--lsd-h2-fontSize:2rem;--lsd-h2-fontWeight:normal;--lsd-h2-lineHeight:2.5rem;--lsd-h3-fontSize:1.75rem;--lsd-h3-fontWeight:normal;--lsd-h3-lineHeight:2.25rem;--lsd-h4-fontSize:1.5rem;--lsd-h4-fontWeight:normal;--lsd-h4-lineHeight:2rem;--lsd-h5-fontSize:1.25rem;--lsd-h5-fontWeight:normal;--lsd-h5-lineHeight:1.75rem;--lsd-h6-fontSize:1rem;--lsd-h6-fontWeight:normal;--lsd-h6-lineHeight:1.5rem;--lsd-subtitle1-fontSize:1.125rem;--lsd-subtitle1-fontWeight:normal;--lsd-subtitle1-lineHeight:1.5rem;--lsd-subtitle2-fontSize:1rem;--lsd-subtitle2-fontWeight:normal;--lsd-subtitle2-lineHeight:1.5rem;--lsd-subtitle3-fontSize:0.875rem;--lsd-subtitle3-fontWeight:normal;--lsd-subtitle3-lineHeight:1.25rem;--lsd-subtitle4-fontSize:0.75rem;--lsd-subtitle4-fontWeight:normal;--lsd-subtitle4-lineHeight:1rem;--lsd-body1-fontSize:1rem;--lsd-body1-fontWeight:normal;--lsd-body1-lineHeight:1.5rem;--lsd-body2-fontSize:0.875rem;--lsd-body2-fontWeight:normal;--lsd-body2-lineHeight:1.25rem;--lsd-body3-fontSize:0.75rem;--lsd-body3-fontWeight:normal;--lsd-body3-lineHeight:1rem;--lsd-label1-fontSize:0.875rem;--lsd-label1-fontWeight:normal;--lsd-label1-lineHeight:1.25rem;--lsd-label2-fontSize:0.75rem;--lsd-label2-fontWeight:normal;--lsd-label2-lineHeight:1rem;--lsd-typography-generic-font-family:sans-serif;--lsd-theme-primary:255,255,255;--lsd-theme-secondary:0,0,0;--lsd-surface-primary:0,0,0;--lsd-surface-secondary:255,255,255;--lsd-border-primary:255,255,255;--lsd-border-secondary:0,0,0;--lsd-icon-primary:255,255,255;--lsd-icon-secondary:0,0,0;--lsd-text-primary:255,255,255;--lsd-text-secondary:0,0,0;--lsd-text-tertiary:255,255,255,0.34;--lsd-spacing-4:4px;--lsd-spacing-8:8px;--lsd-spacing-16:16px;--lsd-spacing-24:24px;--lsd-spacing-32:32px;--lsd-spacing-40:40px;--lsd-spacing-64:64px;--lsd-spacing-80:80px;--lsd-spacing-96:96px;--lsd-spacing-120:120px;}</style><style data-emotion="css-global yon3n1">[data-theme=light]{--lsd-display1-fontSize:5.5rem;--lsd-display1-fontWeight:normal;--lsd-display1-lineHeight:6rem;--lsd-display2-fontSize:4rem;--lsd-display2-fontWeight:normal;--lsd-display2-lineHeight:4.5rem;--lsd-display3-fontSize:3.5rem;--lsd-display3-fontWeight:normal;--lsd-display3-lineHeight:4rem;--lsd-display4-fontSize:3rem;--lsd-display4-fontWeight:normal;--lsd-display4-lineHeight:3.5rem;--lsd-h1-fontSize:2.5rem;--lsd-h1-fontWeight:normal;--lsd-h1-lineHeight:3rem;--lsd-h2-fontSize:2rem;--lsd-h2-fontWeight:normal;--lsd-h2-lineHeight:2.5rem;--lsd-h3-fontSize:1.75rem;--lsd-h3-fontWeight:normal;--lsd-h3-lineHeight:2.25rem;--lsd-h4-fontSize:1.5rem;--lsd-h4-fontWeight:normal;--lsd-h4-lineHeight:2rem;--lsd-h5-fontSize:1.25rem;--lsd-h5-fontWeight:normal;--lsd-h5-lineHeight:1.75rem;--lsd-h6-fontSize:1rem;--lsd-h6-fontWeight:normal;--lsd-h6-lineHeight:1.5rem;--lsd-subtitle1-fontSize:1.125rem;--lsd-subtitle1-fontWeight:normal;--lsd-subtitle1-lineHeight:1.5rem;--lsd-subtitle2-fontSize:1rem;--lsd-subtitle2-fontWeight:normal;--lsd-subtitle2-lineHeight:1.5rem;--lsd-subtitle3-fontSize:0.875rem;--lsd-subtitle3-fontWeight:normal;--lsd-subtitle3-lineHeight:1.25rem;--lsd-subtitle4-fontSize:0.75rem;--lsd-subtitle4-fontWeight:normal;--lsd-subtitle4-lineHeight:1rem;--lsd-body1-fontSize:1rem;--lsd-body1-fontWeight:normal;--lsd-body1-lineHeight:1.5rem;--lsd-body2-fontSize:0.875rem;--lsd-body2-fontWeight:normal;--lsd-body2-lineHeight:1.25rem;--lsd-body3-fontSize:0.75rem;--lsd-body3-fontWeight:normal;--lsd-body3-lineHeight:1rem;--lsd-label1-fontSize:0.875rem;--lsd-label1-fontWeight:normal;--lsd-label1-lineHeight:1.25rem;--lsd-label2-fontSize:0.75rem;--lsd-label2-fontWeight:normal;--lsd-label2-lineHeight:1rem;--lsd-typography-generic-font-family:sans-serif;--lsd-theme-primary:0,0,0;--lsd-theme-secondary:255,255,255;--lsd-surface-primary:255,255,255;--lsd-surface-secondary:0,0,0;--lsd-border-primary:0,0,0;--lsd-border-secondary:255,255,255;--lsd-icon-primary:0,0,0;--lsd-icon-secondary:255,255,255;--lsd-text-primary:0,0,0;--lsd-text-secondary:255,255,255;--lsd-text-tertiary:0,0,0,0.34;--lsd-spacing-4:4px;--lsd-spacing-8:8px;--lsd-spacing-16:16px;--lsd-spacing-24:24px;--lsd-spacing-32:32px;--lsd-spacing-40:40px;--lsd-spacing-64:64px;--lsd-spacing-80:80px;--lsd-spacing-96:96px;--lsd-spacing-120:120px;}</style><div class="root_QACb"><div role="region" aria-label="Skip to main content"><a class="skipToContent_fXgn" href="#__docusaurus_skipToContent_fallback">Skip to main content</a></div><nav aria-label="Main" class="navbar navbar--fixed-top navbarHideable_OoEf"><div class="navbar__inner"><div class="navbar__left"><a class="navbar__brand" href="/"><div class="navbar__logo"><img src="/theme/image/logo.svg" alt="Vac Research" class="themedImage_ToTc themedImage--light_HNdA" height="26"><img src="/theme/image/logo.svg" alt="Vac Research" class="themedImage_ToTc themedImage--dark_i4oU" height="26"></div><b class="navbar__title text--truncate"></b></a></div><div class="navbar__left-items"><a class="navbar__item navbar__link" href="/"><div class="lsd-typography lsd-typography--body2 linkContent__x3v">About Vac</div></a><a class="navbar__item navbar__link" href="/community"><div class="lsd-typography lsd-typography--body2 linkContent__x3v">Community</div></a><a class="navbar__item navbar__link" href="/rlog"><div class="lsd-typography lsd-typography--body2 linkContent__x3v">Research Blog</div></a><a class="navbar__item navbar__link" href="/join-us"><div class="lsd-typography lsd-typography--body2 linkContent__x3v">Join Us</div></a></div><div class="navbar__right-items"><div class="iconButtonGroup_ktNv lsd-icon-button-group lsd-icon-button-group--medium lsd-icon-button-group--outlined"><button class="clean-btn toggle_K23S colorModeToggle_GSaI navbar__color-mode-toggle toggleButtonDisabled_AAS_ lsd-icon-button lsd-icon-button--medium lsd-icon-button--outlined lsd-icon-button--disabled" type="button" title="Switch between dark and light mode (currently dark mode)" aria-label="Switch between dark and light mode (currently dark mode)" aria-live="polite"><svg viewBox="0 0 24 24" width="24" height="24" class="lightToggleIcon_K4TL"><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"></path></svg><svg viewBox="0 0 24 24" width="24" height="24" class="darkToggleIcon_lKkA"><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"></path></svg></button><button aria-label="Toggle navigation bar" aria-expanded="false" class="navbar__toggle clean-btn" type="button"><svg width="30" height="30" viewBox="0 0 30 30" aria-hidden="true"><path stroke="currentColor" stroke-linecap="round" stroke-miterlimit="10" stroke-width="2" d="M4 7h22M4 15h22M4 23h22"></path></svg></button></div></div></div><div role="presentation" class="navbar-sidebar__backdrop"></div></nav><div id="__docusaurus_skipToContent_fallback" class="main-wrapper mainWrapper_z2l0 docsWrapper_BCFX"><button aria-label="Scroll back to top" class="clean-btn theme-back-to-top-button backToTopButton_sjWU" type="button"></button><div class="docPage__5DB"><main class="docMainContainer_gTbr docMainContainerEnhanced_Uz_u"><div class="container padding-top--md padding-bottom--lg"><div class="row docItemGrid_SzoZ"><div class="docItemCol_F52z"><div class="docItemContainer_hrrU"><article><div class="theme-doc-markdown markdown"><h1></h1><p><a href="https://drive.google.com/file/d/19P3oDNXGBDClfcS6Sgp0t9LYr3UbIFGt/view" target="_blank" rel="noopener noreferrer">Waku v2 training session</a></p><p><a href="https://www.youtube.com/watch?v=GXU5Fd6gMVw&t=21692s" target="_blank" rel="noopener noreferrer">Waku: Enabling a New Dimension for dApps</a></p><p><a href="https://www.youtube.com/watch?v=s0ATpQ4_XFc&ab_channel=OsakaThorp" target="_blank" rel="noopener noreferrer">Vac, Waku v2 and Ethereum Messaging</a></p><p><a href="https://www.youtube.com/watch?v=S782Ppzvkd0&ab_channel=ZeroKnowledge" target="_blank" rel="noopener noreferrer">ZKPodcast: ZKPs for Spam Protection & Decentralized Messaging with Status</a></p><p><a href="https://www.youtube.com/watch?v=rQOp3qoDF0g&ab_channel=AmphiPoissy" target="_blank" rel="noopener noreferrer">Franck Royer : DappConnect: Enabling decentralised communications using Waku</a></p><p><a href="https://www.youtube.com/watch?v=lUDy1MoeYnI&ab_channel=TaipeiEthereumMeetup" target="_blank" rel="noopener noreferrer">Oskar Thoren | Vac, Waku v2 and Ethereum Messaging</a></p><p><a href="https://www.youtube.com/watch?v=6lLT33tsJjs&ab_channel=AmphiStGermain" target="_blank" rel="noopener noreferrer">Dean Eigenman & Oskar Thoren: From Whisper to Waku</a></p><p><a href="https://www.youtube.com/watch?v=zxN-PqYkZ1M&ab_channel=EthereumFoundation" target="_blank" rel="noopener noreferrer">Private and Reliable Data Sync for Messaging Over Whisper by Dean Eigenmann & Oskar Thoren (Devcon5)</a></p></div></article><nav class="pagination-nav docusaurus-mt-lg" aria-label="Docs pages"></nav></div></div><div class="gap1_XuuQ"></div></div></div></main></div></div><footer class="footer"><div class="container container-fluid firstRow_ar1q"><div class="footer__bottom text--center"><div class="margin-bottom--sm"><a class="footerLogoLink_BH7S" href="/"><img src="/theme/image/logo.svg" alt="Vac Research" class="themedImage_ToTc themedImage--light_HNdA footer__logo" width="22"><img src="/theme/image/logo.svg" alt="Vac Research" class="themedImage_ToTc themedImage--dark_i4oU footer__logo" width="22"></a></div><div class="footer__copyright">Vac Research © 2024<br>All rights reserved.</div></div><div class="row footer__links"><div class="col footer__col"><div class="footer__title"></div><ul class="footer__items clean-list"><li class="footer__item"><a href="https://twitter.com/vacp2p" target="_blank" rel="noopener noreferrer" class="footer__link-item">Twitter<svg width="13.5" height="13.5" aria-hidden="true" viewBox="0 0 24 24" class="iconExternalLink_nPIU"><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"></path></svg></a></li><li class="footer__item"><a href="https://discord.gg/PQFdubGt6d" target="_blank" rel="noopener noreferrer" class="footer__link-item">Discord<svg width="13.5" height="13.5" aria-hidden="true" viewBox="0 0 24 24" class="iconExternalLink_nPIU"><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"></path></svg></a></li><li class="footer__item"><a href="https://github.com/vacp2p" target="_blank" rel="noopener noreferrer" class="footer__link-item">Github<svg width="13.5" height="13.5" aria-hidden="true" viewBox="0 0 24 24" class="iconExternalLink_nPIU"><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"></path></svg></a></li></ul></div><div class="col footer__col"><div class="footer__title"></div><ul class="footer__items clean-list"><li class="footer__item"><a href="https://jobs.status.im/" target="_blank" rel="noopener noreferrer" class="footer__link-item">Work With Us<svg width="13.5" height="13.5" aria-hidden="true" viewBox="0 0 24 24" class="iconExternalLink_nPIU"><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"></path></svg></a></li><li class="footer__item"><a class="footer__link-item" href="/terms">Terms & Conditions</a></li><li class="footer__item"><a class="footer__link-item" href="/privacy-policy">Privacy Policy</a></li><li class="footer__item"><a class="footer__link-item" href="/security">Security</a></li></ul></div></div></div><div class="secondRow__ww3"><div class="footer__bottom text--center">Logos Collective</div><div class="row footer__links"><div class="col footer__col"><div class="footer__title">Research</div><ul class="footer__items clean-list"><li class="footer__item"><a href="https://vac.dev" target="_blank" rel="noopener noreferrer" class="footer__link-item">VacP2P<svg width="13.5" height="13.5" aria-hidden="true" viewBox="0 0 24 24" class="iconExternalLink_nPIU"><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"></path></svg></a></li><li class="footer__item"><a href="https://afaik.institute" target="_blank" rel="noopener noreferrer" class="footer__link-item">AFAIK<svg width="13.5" height="13.5" aria-hidden="true" viewBox="0 0 24 24" class="iconExternalLink_nPIU"><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"></path></svg></a></li></ul></div><div class="col footer__col"><div class="footer__title">Infrastructure</div><ul class="footer__items clean-list"><li class="footer__item"><a href="https://waku.org/" target="_blank" rel="noopener noreferrer" class="footer__link-item">Waku<svg width="13.5" height="13.5" aria-hidden="true" viewBox="0 0 24 24" class="iconExternalLink_nPIU"><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"></path></svg></a></li><li class="footer__item"><a href="https://nimbus.team/" target="_blank" rel="noopener noreferrer" class="footer__link-item">Nimbus<svg width="13.5" height="13.5" aria-hidden="true" viewBox="0 0 24 24" class="iconExternalLink_nPIU"><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"></path></svg></a></li><li class="footer__item"><a href="https://codex.storage" target="_blank" rel="noopener noreferrer" class="footer__link-item">Codex<svg width="13.5" height="13.5" aria-hidden="true" viewBox="0 0 24 24" class="iconExternalLink_nPIU"><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"></path></svg></a></li><li class="footer__item"><a href="https://nomos.tech" target="_blank" rel="noopener noreferrer" class="footer__link-item">Nomos<svg width="13.5" height="13.5" aria-hidden="true" viewBox="0 0 24 24" class="iconExternalLink_nPIU"><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"></path></svg></a></li></ul></div><div class="col footer__col"><div class="footer__title">Creative Studio</div><ul class="footer__items clean-list"><li class="footer__item"><a href="https://acid.info" target="_blank" rel="noopener noreferrer" class="footer__link-item">Acid.info<svg width="13.5" height="13.5" aria-hidden="true" viewBox="0 0 24 24" class="iconExternalLink_nPIU"><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"></path></svg></a></li></ul></div><div class="col footer__col"><div class="footer__title">Movement</div><ul class="footer__items clean-list"><li class="footer__item"><a href="https://logos.co" target="_blank" rel="noopener noreferrer" class="footer__link-item">Logos<svg width="13.5" height="13.5" aria-hidden="true" viewBox="0 0 24 24" class="iconExternalLink_nPIU"><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"></path></svg></a></li></ul></div><div class="col footer__col"><div class="footer__title">User-facing products</div><ul class="footer__items clean-list"><li class="footer__item"><a href="https://status.im" target="_blank" rel="noopener noreferrer" class="footer__link-item">Status<svg width="13.5" height="13.5" aria-hidden="true" viewBox="0 0 24 24" class="iconExternalLink_nPIU"><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"></path></svg></a></li><li class="footer__item"><a href="https://keycard.tech" target="_blank" rel="noopener noreferrer" class="footer__link-item">Keycard<svg width="13.5" height="13.5" aria-hidden="true" viewBox="0 0 24 24" class="iconExternalLink_nPIU"><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"></path></svg></a></li></ul></div></div></div><button class="backToTop_wDfN lsd-button lsd-button--small lsd-button--outlined"><span class="lsd-typography lsd-typography--label2 lsd-button__text">Back to top ↑</span></button></footer></div></div> -<script src="/assets/js/runtime~main.556fa6f5.js"></script> -<script src="/assets/js/main.ffc20c94.js"></script> +<script src="/assets/js/runtime~main.a9103199.js"></script> +<script src="/assets/js/main.5454aec3.js"></script> </body> </html> \ No newline at end of file diff --git a/principles/index.html b/principles/index.html index e39959d9..9d2420c8 100644 --- a/principles/index.html +++ b/principles/index.html @@ -10,8 +10,8 @@ <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/katex@0.13.24/dist/katex.min.css" integrity="sha384-odtC+0UGzzFL/6PNoE8rX/SPcQDXBJ+uRepguP4QkPCm2LBxH3FA3y+fKSiJ+AmM" crossorigin="anonymous"><link rel="stylesheet" href="/assets/css/styles.08d697e6.css"> -<link rel="preload" href="/assets/js/runtime~main.556fa6f5.js" as="script"> -<link rel="preload" href="/assets/js/main.ffc20c94.js" as="script"> +<link rel="preload" href="/assets/js/runtime~main.a9103199.js" as="script"> +<link rel="preload" href="/assets/js/main.5454aec3.js" as="script"> <meta property="og:image" content="https://vac.dev/_og/6ed71ddd5cb47aede5f4435ef75d558887c12978.png"><meta name="twitter:image" content="https://vac.dev/_og/6ed71ddd5cb47aede5f4435ef75d558887c12978.png"></head> <body class="navigation-with-keyboard"> <script>!function(){function e(e){document.documentElement.setAttribute("data-theme",e)}var t=function(){var e=null;try{e=new URLSearchParams(window.location.search).get("docusaurus-theme")}catch(e){}return e}()||function(){var e=null;try{e=localStorage.getItem("theme")}catch(e){}return e}();null!==t?e(t):window.matchMedia("(prefers-color-scheme: dark)").matches?e("dark"):window.matchMedia("(prefers-color-scheme: light)").matches?e("light"):e("dark")}()</script><div id="__docusaurus"> @@ -47,7 +47,7 @@ As we grow and have ready access to capital, it is our obligation to token holders to fight bureaucracy and inefficiencies within the organisation. This means solving problems in the most effective way possible at lower economic costs (in terms of capital, time, and resources).</p></div></article><nav class="pagination-nav docusaurus-mt-lg" aria-label="Docs pages"><a class="pagination-nav__link pagination-nav__link--prev" href="/vips"><div class="icon_S7Kx m_thRi"><svg width="14" height="14" viewBox="0 0 14 14" fill="none" xmlns="http://www.w3.org/2000/svg" role="img"><path d="M11.667 6.417h-7.1l3.261-3.261L7 2.333 2.333 7 7 11.667l.823-.823-3.255-3.26h7.099V6.417Z" fill="#fff"></path></svg></div><span class="lsd-typography lsd-typography--body2 pagination-nav__label">Incubator Projects</span></a><a class="pagination-nav__link pagination-nav__link--next" href="/contribute"><span class="lsd-typography lsd-typography--body2 pagination-nav__label">Contribute</span><div class="icon_S7Kx m_thRi"><svg width="14" height="14" viewBox="0 0 14 14" fill="none" xmlns="http://www.w3.org/2000/svg" role="img"><path d="m7 2.333-.823.823 3.255 3.26H2.333v1.167h7.1l-3.256 3.261.823.823L11.667 7 7 2.333Z" fill="#fff"></path></svg></div></a></nav></div></div><div class="gap1_XuuQ"></div></div></div></main></div></div><footer class="footer"><div class="container container-fluid firstRow_ar1q"><div class="footer__bottom text--center"><div class="margin-bottom--sm"><a class="footerLogoLink_BH7S" href="/"><img src="/theme/image/logo.svg" alt="Vac Research" class="themedImage_ToTc themedImage--light_HNdA footer__logo" width="22"><img src="/theme/image/logo.svg" alt="Vac Research" class="themedImage_ToTc themedImage--dark_i4oU footer__logo" width="22"></a></div><div class="footer__copyright">Vac Research © 2024<br>All rights reserved.</div></div><div class="row footer__links"><div class="col footer__col"><div class="footer__title"></div><ul class="footer__items clean-list"><li class="footer__item"><a href="https://twitter.com/vacp2p" target="_blank" rel="noopener noreferrer" class="footer__link-item">Twitter<svg width="13.5" height="13.5" aria-hidden="true" viewBox="0 0 24 24" class="iconExternalLink_nPIU"><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"></path></svg></a></li><li class="footer__item"><a href="https://discord.gg/PQFdubGt6d" target="_blank" rel="noopener noreferrer" class="footer__link-item">Discord<svg width="13.5" height="13.5" aria-hidden="true" viewBox="0 0 24 24" class="iconExternalLink_nPIU"><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"></path></svg></a></li><li class="footer__item"><a href="https://github.com/vacp2p" target="_blank" rel="noopener noreferrer" class="footer__link-item">Github<svg width="13.5" height="13.5" aria-hidden="true" viewBox="0 0 24 24" class="iconExternalLink_nPIU"><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"></path></svg></a></li></ul></div><div class="col footer__col"><div class="footer__title"></div><ul class="footer__items clean-list"><li class="footer__item"><a href="https://jobs.status.im/" target="_blank" rel="noopener noreferrer" class="footer__link-item">Work With Us<svg width="13.5" height="13.5" aria-hidden="true" viewBox="0 0 24 24" class="iconExternalLink_nPIU"><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"></path></svg></a></li><li class="footer__item"><a class="footer__link-item" href="/terms">Terms & Conditions</a></li><li class="footer__item"><a class="footer__link-item" href="/privacy-policy">Privacy Policy</a></li><li class="footer__item"><a class="footer__link-item" href="/security">Security</a></li></ul></div></div></div><div class="secondRow__ww3"><div class="footer__bottom text--center">Logos Collective</div><div class="row footer__links"><div class="col footer__col"><div class="footer__title">Research</div><ul class="footer__items clean-list"><li class="footer__item"><a href="https://vac.dev" target="_blank" rel="noopener noreferrer" class="footer__link-item">VacP2P<svg width="13.5" height="13.5" aria-hidden="true" viewBox="0 0 24 24" class="iconExternalLink_nPIU"><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"></path></svg></a></li><li class="footer__item"><a href="https://afaik.institute" target="_blank" rel="noopener noreferrer" class="footer__link-item">AFAIK<svg width="13.5" height="13.5" aria-hidden="true" viewBox="0 0 24 24" class="iconExternalLink_nPIU"><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"></path></svg></a></li></ul></div><div class="col footer__col"><div class="footer__title">Infrastructure</div><ul class="footer__items clean-list"><li class="footer__item"><a href="https://waku.org/" target="_blank" rel="noopener noreferrer" class="footer__link-item">Waku<svg width="13.5" height="13.5" aria-hidden="true" viewBox="0 0 24 24" class="iconExternalLink_nPIU"><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"></path></svg></a></li><li class="footer__item"><a href="https://nimbus.team/" target="_blank" rel="noopener noreferrer" class="footer__link-item">Nimbus<svg width="13.5" height="13.5" aria-hidden="true" viewBox="0 0 24 24" class="iconExternalLink_nPIU"><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"></path></svg></a></li><li class="footer__item"><a href="https://codex.storage" target="_blank" rel="noopener noreferrer" class="footer__link-item">Codex<svg width="13.5" height="13.5" aria-hidden="true" viewBox="0 0 24 24" class="iconExternalLink_nPIU"><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"></path></svg></a></li><li class="footer__item"><a href="https://nomos.tech" target="_blank" rel="noopener noreferrer" class="footer__link-item">Nomos<svg width="13.5" height="13.5" aria-hidden="true" viewBox="0 0 24 24" class="iconExternalLink_nPIU"><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"></path></svg></a></li></ul></div><div class="col footer__col"><div class="footer__title">Creative Studio</div><ul class="footer__items clean-list"><li class="footer__item"><a href="https://acid.info" target="_blank" rel="noopener noreferrer" class="footer__link-item">Acid.info<svg width="13.5" height="13.5" aria-hidden="true" viewBox="0 0 24 24" class="iconExternalLink_nPIU"><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"></path></svg></a></li></ul></div><div class="col footer__col"><div class="footer__title">Movement</div><ul class="footer__items clean-list"><li class="footer__item"><a href="https://logos.co" target="_blank" rel="noopener noreferrer" class="footer__link-item">Logos<svg width="13.5" height="13.5" aria-hidden="true" viewBox="0 0 24 24" class="iconExternalLink_nPIU"><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"></path></svg></a></li></ul></div><div class="col footer__col"><div class="footer__title">User-facing products</div><ul class="footer__items clean-list"><li class="footer__item"><a href="https://status.im" target="_blank" rel="noopener noreferrer" class="footer__link-item">Status<svg width="13.5" height="13.5" aria-hidden="true" viewBox="0 0 24 24" class="iconExternalLink_nPIU"><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"></path></svg></a></li><li class="footer__item"><a href="https://keycard.tech" target="_blank" rel="noopener noreferrer" class="footer__link-item">Keycard<svg width="13.5" height="13.5" aria-hidden="true" viewBox="0 0 24 24" class="iconExternalLink_nPIU"><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"></path></svg></a></li></ul></div></div></div><button class="backToTop_wDfN lsd-button lsd-button--small lsd-button--outlined"><span class="lsd-typography lsd-typography--label2 lsd-button__text">Back to top ↑</span></button></footer></div></div> -<script src="/assets/js/runtime~main.556fa6f5.js"></script> -<script src="/assets/js/main.ffc20c94.js"></script> +<script src="/assets/js/runtime~main.a9103199.js"></script> +<script src="/assets/js/main.5454aec3.js"></script> </body> </html> \ No newline at end of file diff --git a/privacy-policy/index.html b/privacy-policy/index.html index 350ee077..78200de8 100644 --- a/privacy-policy/index.html +++ b/privacy-policy/index.html @@ -10,8 +10,8 @@ <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/katex@0.13.24/dist/katex.min.css" integrity="sha384-odtC+0UGzzFL/6PNoE8rX/SPcQDXBJ+uRepguP4QkPCm2LBxH3FA3y+fKSiJ+AmM" crossorigin="anonymous"><link rel="stylesheet" href="/assets/css/styles.08d697e6.css"> -<link rel="preload" href="/assets/js/runtime~main.556fa6f5.js" as="script"> -<link rel="preload" href="/assets/js/main.ffc20c94.js" as="script"> +<link rel="preload" href="/assets/js/runtime~main.a9103199.js" as="script"> +<link rel="preload" href="/assets/js/main.5454aec3.js" as="script"> <meta property="og:image" content="https://vac.dev/_og/2ad4545239f59aac174a1cab2945a014cb5b8bd5.png"><meta name="twitter:image" content="https://vac.dev/_og/2ad4545239f59aac174a1cab2945a014cb5b8bd5.png"></head> <body class="navigation-with-keyboard"> <script>!function(){function e(e){document.documentElement.setAttribute("data-theme",e)}var t=function(){var e=null;try{e=new URLSearchParams(window.location.search).get("docusaurus-theme")}catch(e){}return e}()||function(){var e=null;try{e=localStorage.getItem("theme")}catch(e){}return e}();null!==t?e(t):window.matchMedia("(prefers-color-scheme: dark)").matches?e("dark"):window.matchMedia("(prefers-color-scheme: light)").matches?e("light"):e("dark")}()</script><div id="__docusaurus"> @@ -20,7 +20,7 @@ ) .lsd-dropdown__trigger:hover .lsd-dropdown__option-label,.lsd-dropdown:not(.lsd-dropdown--disabled):not( .lsd-dropdown--error ) .lsd-dropdown__trigger:focus .lsd-dropdown__option-label{-webkit-text-decoration:underline;text-decoration:underline;}.lsd-dropdown__label{display:block;}.lsd-dropdown__button-container{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-box-pack:justify;-webkit-justify-content:space-between;justify-content:space-between;}.lsd-dropdown__trigger{width:100%;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:row;-ms-flex-direction:row;flex-direction:row;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:justify;-webkit-justify-content:space-between;justify-content:space-between;border:none;cursor:pointer;background:none;}.lsd-dropdown__trigger:focus{outline:none;}.lsd-dropdown__option-label{cursor:inherit;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;}.lsd-dropdown__icons{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:row;-ms-flex-direction:row;flex-direction:row;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:center;-ms-flex-pack:center;-webkit-justify-content:center;justify-content:center;gap:8px;}.lsd-dropdown__icon{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;}.lsd-dropdown__supporting-text{margin:6px 14px;}.lsd-dropdown--error .lsd-dropdown__option-label{-webkit-text-decoration:line-through;text-decoration:line-through;}.lsd-dropdown--disabled{opacity:0.34;cursor:initial;}.lsd-dropdown--large{width:208px;}.lsd-dropdown--large.lsd-dropdown--error{width:230px;}.lsd-dropdown--large .lsd-dropdown__label{margin:0 0 6px 18px;}.lsd-dropdown--large .lsd-dropdown__button-container{height:40px;}.lsd-dropdown--large .lsd-dropdown__trigger{padding:10px 0px 10px 18px;}.lsd-dropdown--large .lsd-dropdown__icons{padding:0px 14px;}.lsd-dropdown--medium{width:188px;}.lsd-dropdown--medium.lsd-dropdown--error{width:210px;}.lsd-dropdown--medium .lsd-dropdown__label{margin:0 0 6px 14px;}.lsd-dropdown--medium .lsd-dropdown__button-container{height:32px;}.lsd-dropdown--medium .lsd-dropdown__trigger{padding:6px 0px 6px 14px;}.lsd-dropdown--medium .lsd-dropdown__icons{padding:0px 12px;}.lsd-dropdown--small{width:164px;}.lsd-dropdown--small.lsd-dropdown--error{width:186px;}.lsd-dropdown--small .lsd-dropdown__label{margin:0 0 6px 12px;}.lsd-dropdown--small .lsd-dropdown__button-container{height:28px;}.lsd-dropdown--small .lsd-dropdown__trigger{padding:6px 0px 6px 12px;}.lsd-dropdown--small .lsd-dropdown__icons{padding:0px 10px;}.lsd-dropdown--outlined .lsd-dropdown__button-container{border:1px solid rgb(var(--lsd-border-primary));}.lsd-dropdown--underlined .lsd-dropdown__button-container{border:1px solid transparent;border-bottom:1px solid rgb(var(--lsd-border-primary));}</style><style data-emotion="css-global w2g5fy">.lsd-dropdown-item{width:100%;box-sizing:border-box;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:row;-ms-flex-direction:row;flex-direction:row;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;border:1px solid rgb(var(--lsd-border-primary));}.lsd-dropdown-item:not(.lsd-dropdown-item--disabled){cursor:pointer;}.lsd-dropdown-item:not(.lsd-dropdown-item--disabled):hover,.lsd-dropdown-item:not(.lsd-dropdown-item--disabled):focus{outline:none;}.lsd-dropdown-item:not(.lsd-dropdown-item--disabled):hover .lsd-dropdown-item__label,.lsd-dropdown-item:not(.lsd-dropdown-item--disabled):focus .lsd-dropdown-item__label{-webkit-text-decoration:underline;text-decoration:underline;}.lsd-dropdown-item__label{display:block;overflow:hidden;white-space:nowrap;text-overflow:ellipsis;}.lsd-dropdown-item--disabled{opacity:0.34;}.lsd-dropdown-item__icon{margin-right:18px;-webkit-flex-shrink:0;-ms-flex-negative:0;flex-shrink:0;}.lsd-dropdown-item--small{padding:5px 9px;height:28px;}.lsd-dropdown-item--medium{padding:5px 11px;height:32px;}.lsd-dropdown-item--large{padding:5px 13px;height:40px;}</style><style data-emotion="css-global ww9kgc">.lsd-breadcrumb__list{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:row;-ms-flex-direction:row;flex-direction:row;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;list-style-type:none;margin:0;padding:0;}.lsd-breadcrumb--disabled .lsd-breadcrumb__list{opacity:0.34;cursor:initial;pointer-events:none;}.lsd-breadcrumb__dropdown-menu{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column;overflow:auto;border:1px solid rgb(var(--lsd-border-primary));margin-top:10px;position:absolute;width:auto!important;}.lsd-breadcrumb__dropdown-menu>li{cursor:pointer;}.lsd-breadcrumb__dropdown-menu>li:not(:last-child){border-bottom:1px solid rgb(var(--lsd-border-primary));}.lsd-breadcrumb__dropdown-menu>li:hover,.lsd-breadcrumb__dropdown-menu>li:focus{-webkit-text-decoration:underline;text-decoration:underline;text-decoration-color:rgb(var(--lsd-border-primary));}.lsd-breadcrumb__dropdown-menu li>a{width:164px;padding:5px 11px;}</style><style data-emotion="css-global 4gvini">.lsd-breadcrumb-item{list-style-type:none;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;}.lsd-breadcrumb__list>li:not(:last-child)::after{display:inline-block;margin-inline:12px;content:'/';}.lsd-breadcrumb-item__link{-webkit-text-decoration:none;text-decoration:none;cursor:pointer;}.lsd-breadcrumb-item--outlined{padding:3px 11px;border:1px solid rgb(var(--lsd-border-primary));}.lsd-breadcrumb:not(.lsd-breadcrumb--disabled) .lsd-breadcrumb-item__link:hover,.lsd-breadcrumb:not(.lsd-breadcrumb--disabled) .lsd-breadcrumb-item__link:focus{-webkit-text-decoration:underline;text-decoration:underline;text-decoration-color:rgb(var(--lsd-border-primary));}</style><style data-emotion="css-global 1cwg3oc">.lsd-card{box-sizing:border-box;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column;}.lsd-card>.lsd-card-header{margin-bottom:-1px;}</style><style data-emotion="css-global v7d76i">.lsd-card-header{box-sizing:border-box;padding:10px 18px;text-align:center;border:1px solid rgb(var(--lsd-border-primary));}.lsd-card-header__title{overflow:hidden;word-break:break-all;}.lsd-card-header--large{padding:10px 18px;}.lsd-card-header--medium{padding:6px 14px;}.lsd-card-header--small{padding:6px 12px;}</style><style data-emotion="css-global 1txgafh">.lsd-card-body{box-sizing:border-box;padding:14px 22px;border:1px solid rgb(var(--lsd-border-primary));}</style><style data-emotion="css-global kzy52c">.lsd-tag{width:-webkit-fit-content;width:-moz-fit-content;width:fit-content;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:row;-ms-flex-direction:row;flex-direction:row;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:center;-ms-flex-pack:center;-webkit-justify-content:center;justify-content:center;box-sizing:border-box;border:1px solid rgb(var(--lsd-icon-primary));}.lsd-tag:hover,.lsd-tag:focus{-webkit-text-decoration:underline;text-decoration:underline;cursor:pointer;}.lsd-badge--large{padding:3px 11px;gap:12px;height:28px;}.lsd-badge--small{padding:3px 7px;gap:8px;height:24px;}.lsd-tag--filled{background-color:rgb(var(--lsd-icon-primary));}.lsd-tag--filled .lsd-tag__label{color:rgb(var(--lsd-text-secondary));}.lsd-tag--filled svg{--lsd-icon-primary:var(--lsd-icon-secondary);}.lsd-tag--outlined{color:rgb(var(--lsd-text-primary));}.lsd-tag--disabled{opacity:0.3;cursor:initial;pointer-events:none;}</style><style data-emotion="css-global 4wy0ub">.lsd-text-field{box-sizing:border-box;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column;}.lsd-text-field__input-container{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:justify;-webkit-justify-content:space-between;justify-content:space-between;}.lsd-text-field--disabled{opacity:0.34;}.lsd-text-field__input{border:none;outline:none;font-size:14px;color:rgb(var(--lsd-text-primary));background:none;width:100%;}.lsd-text-field__input:hover{outline:none;}.lsd-text-field__input::-webkit-input-placeholder{color:rgb(var(--lsd-text-primary));opacity:0.3;}.lsd-text-field__input::-moz-placeholder{color:rgb(var(--lsd-text-primary));opacity:0.3;}.lsd-text-field__input:-ms-input-placeholder{color:rgb(var(--lsd-text-primary));opacity:0.3;}.lsd-text-field__input::placeholder{color:rgb(var(--lsd-text-primary));opacity:0.3;}.lsd-text-field--error .lsd-text-field__input{-webkit-text-decoration:line-through;text-decoration:line-through;}.lsd-text-field__supporting-text{width:-webkit-fit-content;width:-moz-fit-content;width:fit-content;}.lsd-text-field--large{width:208px;}.lsd-text-field--large>*{padding:10px 14px 10px 18px;}.lsd-text-field--medium{width:188px;}.lsd-text-field--medium>*{padding:6px 12px 6px 14px;}.lsd-text-field--small{width:164px;}.lsd-text-field--small>*{padding:6px 10px 6px 12px;}.lsd-text-field__label{padding-top:0;padding-bottom:6px;}.lsd-text-field__supporting-text{padding-bottom:0;padding-top:6px;}.lsd-text-field--outlined .lsd-text-field__input-container{border:1px solid rgb(var(--lsd-border-primary));}.lsd-text-field--underlined .lsd-text-field__input-container{border:1px solid transparent;border-bottom:1px solid rgb(var(--lsd-border-primary));}.lsd-text-field__clear-button{padding:0;width:auto;height:auto;margin:0;border:0;}</style><style data-emotion="css-global uhig7c">.lsd-checkbox{position:relative;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:row;-ms-flex-direction:row;flex-direction:row;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;}.lsd-checkbox__input{opacity:0;position:absolute;left:0;top:0;padding:0;margin:0;width:100%;height:100%;}.lsd-checkbox:not(.lsd-checkbox--disabled):hover,.lsd-checkbox:not(.lsd-checkbox--disabled).lsd-checkbox--focused{-webkit-text-decoration:underline;text-decoration:underline;}.lsd-checkbox:not(.lsd-checkbox--disabled) .lsd-checkbox__input{cursor:pointer;}.lsd-checkbox--disabled{opacity:0.34;}.lsd-checkbox__label{margin-left:18px;}.lsd-checkbox--large .lsd-checkbox__label{margin-left:18px;}.lsd-checkbox--medium .lsd-checkbox__label{margin-left:14px;}.lsd-checkbox--small .lsd-checkbox__label{margin-left:12px;}</style><style data-emotion="css-global txommo">.lsd-autocomplete{box-sizing:border-box;}.lsd-autocomplete__label{display:block;}.lsd-autocomplete__input-container{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-box-pack:justify;-webkit-justify-content:space-between;justify-content:space-between;}.lsd-autocomplete--disabled{opacity:0.34;}.lsd-autocomplete__input{border:none;outline:none;font-size:14px;color:rgb(var(--lsd-text-primary));background:none;width:100%;}.lsd-autocomplete__input:hover{outline:none;}.lsd-autocomplete__input::-webkit-input-placeholder{color:rgb(var(--lsd-text-primary));opacity:0.3;}.lsd-autocomplete__input::-moz-placeholder{color:rgb(var(--lsd-text-primary));opacity:0.3;}.lsd-autocomplete__input:-ms-input-placeholder{color:rgb(var(--lsd-text-primary));opacity:0.3;}.lsd-autocomplete__input::placeholder{color:rgb(var(--lsd-text-primary));opacity:0.3;}.lsd-autocomplete__icon{cursor:pointer;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;}.lsd-autocomplete--error{-webkit-text-decoration:line-through;text-decoration:line-through;}.lsd-autocomplete--large{width:208px;}.lsd-autocomplete--large .lsd-autocomplete__label{margin:0 0 6px 18px;}.lsd-autocomplete--large .lsd-autocomplete__input-container{height:40px;}.lsd-autocomplete--large .lsd-autocomplete__input{padding:9px 17px;}.lsd-autocomplete--large .lsd-autocomplete__icon{padding:12px 13px;}.lsd-autocomplete--medium{width:188px;}.lsd-autocomplete--medium .lsd-autocomplete__label{margin:0 0 6px 14px;}.lsd-autocomplete--medium .lsd-autocomplete__input-container{height:32px;}.lsd-autocomplete--medium .lsd-autocomplete__input{padding:5px 13px;}.lsd-autocomplete--medium .lsd-autocomplete__icon{padding:8px 11px;}.lsd-autocomplete--small{width:164px;}.lsd-autocomplete--small .lsd-autocomplete__label{margin:0 0 6px 12px;}.lsd-autocomplete--small .lsd-autocomplete__input-container{height:28px;}.lsd-autocomplete--small .lsd-autocomplete__input{padding:5px 11px;}.lsd-autocomplete--small .lsd-autocomplete__icon{padding:6px 9px;}.lsd-autocomplete--outlined .lsd-autocomplete__input-container{border:1px solid rgb(var(--lsd-border-primary));}.lsd-autocomplete--underlined .lsd-autocomplete__input-container{border:1px solid transparent;border-bottom:1px solid rgb(var(--lsd-border-primary));}.lsd-autocomplete__dropdown-item-placeholder{opacity:0.5;white-space:pre;}</style><style data-emotion="css-global quxxm6">.lsd-quote{color:rgb(var(--lsd-text-primary));white-space:pre-wrap;}.lsd-quote--indented-inline{border-left:1px solid rgb(var(--lsd-border-primary));padding:4px 8px 4px 28px;}.lsd-quote--parentheses{padding:0px;text-align:center;}.lsd-quote--parentheses::before{content:'***';}.lsd-quote--parentheses::after{content:'***';}</style><style data-emotion="css-global a49t4h">.lsd-collapse{box-sizing:border-box;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column;}.lsd-collapse--open .lsd-collapse__content{border-top:1px solid transparent;}.lsd-collapse__content{border:1px solid rgb(var(--lsd-border-primary));}</style><style data-emotion="css-global 12ppw0q">.lsd-collapse-header{box-sizing:border-box;}.lsd-collapse-header:not(.lsd-collapse-header--disabled) .lsd-collapse-header__trigger:hover .lsd-collapse-header__label{-webkit-text-decoration:underline;text-decoration:underline;}.lsd-collapse-header__trigger{width:100%;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:row;-ms-flex-direction:row;flex-direction:row;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:justify;-webkit-justify-content:space-between;justify-content:space-between;cursor:pointer;background:none;border:1px solid rgb(var(--lsd-border-primary));}.lsd-collapse-header__trigger:focus{outline:none;}.lsd-collapse-header__label{cursor:inherit;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;margin:auto;}.lsd-collapse-header__icons{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:row;-ms-flex-direction:row;flex-direction:row;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:end;-ms-flex-pack:end;-webkit-justify-content:flex-end;justify-content:flex-end;}.lsd-collapse-header__icon{margin-right:8px;}.lsd-collapse-header--disabled .lsd-collapse-header__trigger{opacity:0.34;cursor:initial;}.lsd-collapse-header--large .lsd-collapse-header__trigger{width:299px;height:40px;padding:9px 17px;}.lsd-collapse-header--medium .lsd-collapse-header__trigger{width:270px;height:32px;padding:5px 13px;}.lsd-collapse-header--small .lsd-collapse-header__trigger{width:235px;height:28px;padding:5px 11px;}</style><style data-emotion="css-global dixc0i">.lsd-checkbox-group{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column;gap:6px;width:-webkit-fit-content;width:-moz-fit-content;width:fit-content;}.lsd-checkbox-group__label{margin-bottom:6px;}</style><style data-emotion="css-global q2n2hz">.lsd-badge{width:-webkit-fit-content;width:-moz-fit-content;width:fit-content;box-sizing:border-box;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:row;-ms-flex-direction:row;flex-direction:row;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:center;-ms-flex-pack:center;-webkit-justify-content:center;justify-content:center;border:1px solid rgb(var(--lsd-icon-primary));border-radius:20px;}.lsd-badge:hover,.lsd-badge:focus{-webkit-text-decoration:underline;text-decoration:underline;cursor:pointer;}.lsd-badge--large{padding:3px 11px;gap:12px;height:28px;}.lsd-badge--small{padding:3px 7px;gap:8px;height:24px;}.lsd-badge--filled{background-color:rgb(var(--lsd-icon-primary));}.lsd-badge--filled .lsd-badge__label{color:rgb(var(--lsd-text-secondary));}.lsd-badge--filled svg{--lsd-icon-primary:var(--lsd-icon-secondary);}.lsd-badge--outlined{color:rgb(var(--lsd-text-primary));}.lsd-badge--disabled{opacity:0.3;cursor:initial;pointer-events:none;}</style><style data-emotion="css-global rlst54">.lsd-radio-button{position:relative;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:row;-ms-flex-direction:row;flex-direction:row;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;}.lsd-radio-button__input{opacity:0;position:absolute;left:0;top:0;padding:0;margin:0;width:100%;height:100%;}.lsd-radio-button:not(.lsd-radio-button--disabled):hover{-webkit-text-decoration:underline;text-decoration:underline;}.lsd-radio-button:not(.lsd-radio-button--disabled) .lsd-radio-button__input{cursor:pointer;}.lsd-radio-button--disabled{opacity:0.34;}.lsd-radio-button__label{margin-left:18px;}.lsd-radio-button--large .lsd-radio-button__label{margin-left:18px;}.lsd-radio-button--medium .lsd-radio-button__label{margin-left:14px;}.lsd-radio-button--small .lsd-radio-button__label{margin-left:12px;}</style><style data-emotion="css-global mo7h6o">.lsd-radio-button-group{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column;gap:6px;width:-webkit-fit-content;width:-moz-fit-content;width:fit-content;}.lsd-radio-button-group__label{margin-bottom:6px;}</style><style data-emotion="css-global amncrr">.lsd-table{box-sizing:border-box;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column;}.lsd-table>.lsd-table-header{margin-bottom:-1px;}</style><style data-emotion="css-global 1fkbozr">.lsd-table-header{box-sizing:border-box;border:1px solid rgb(var(--lsd-border-primary));}</style><style data-emotion="css-global 1fb1r54">.lsd-table-body table{border-collapse:collapse;text-align:center;table-layout:fixed;width:100%;height:auto;}.lsd-table-body table tr:first-of-type td label:has(input[type='radio']){display:none;}.lsd-table-body__toolbar{box-sizing:border-box;padding:10px;border:1px solid rgb(var(--lsd-border-primary));border-bottom:none;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-box-pack:justify;-webkit-justify-content:space-between;justify-content:space-between;}</style><style data-emotion="css-global 607rj8">.lsd-table-item{border:1px solid rgb(var(--lsd-border-primary));}.lsd-table-item:has(> label){width:40px;}.lsd-table-item:has(> label) input{position:relative;width:14px;height:14px;margin:auto;}.lsd-table-item:has(> label) span{margin-left:14px!important;}.lsd-table-item--large{padding:10px;}.lsd-table-item--medium{padding:6px 8px;}.lsd-table-item--small{padding:6px;}</style><style data-emotion="css-global 1vlh57l">.lsd-table-row{-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;}</style><style data-emotion="css-global 1fw5y3v">.lsd-number-input{width:auto;box-sizing:border-box;}.lsd-number-input__main-container:hover{-webkit-text-decoration:underline;text-decoration:underline;}.lsd-number-input--error .lsd-number-input__main-container{-webkit-text-decoration:line-through;text-decoration:line-through;}.lsd-number-input__label{display:block;}.lsd-number-input__plus-minus-icons{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-shrink:0;-ms-flex-negative:0;flex-shrink:0;}.lsd-number-input__input-container{box-sizing:border-box;border:1px solid rgb(var(--lsd-border-primary));border-left:0px;border-right:0px;}.lsd-number-input__error-icon{cursor:pointer;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;padding:10px 8px;}.lsd-number-input__input-container{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:justify;-webkit-justify-content:space-between;justify-content:space-between;}.lsd-number-input--disabled{opacity:0.34;}.lsd-number-input__main-container{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;}.lsd-number-input__input{border:none;outline:none;font-size:14px;color:rgb(var(--lsd-text-primary));background:none;text-align:center;padding:0 4px;}.lsd-number-input__input::-webkit-inner-spin-button{display:none;-webkit-appearance:none;}.lsd-number-input__input:hover{outline:none;}.lsd-number-input__supporting-text{position:absolute;}.lsd-number-input--large .lsd-number-input__label{margin:0 0 6px 18px;}.lsd-number-input--large .lsd-number-input__input-container{height:40px;}.lsd-number-input--large .lsd-number-input__input{width:62px;}.lsd-number-input--large .lsd-number-input__plus-minus-icons{height:40px;width:40px;}.lsd-number-input--large .lsd-number-input__supporting-text{margin:6px 18px 0 18px;}.lsd-number-input--medium .lsd-number-input__label{margin:0 0 6px 14px;}.lsd-number-input--medium .lsd-number-input__input-container{height:32px;}.lsd-number-input--medium .lsd-number-input__input{width:58px;}.lsd-number-input--medium .lsd-number-input__plus-minus-icons{height:32px;width:32px;}.lsd-number-input--medium .lsd-number-input__supporting-text{margin:6px 14px 0 14px;}.lsd-number-input--small .lsd-number-input__label{margin:0 0 6px 12px;}.lsd-number-input--small .lsd-number-input__input-container{height:28px;}.lsd-number-input--small .lsd-number-input__input{width:50px;}.lsd-number-input--small .lsd-number-input__plus-minus-icons{height:28px;width:28px;}.lsd-number-input--small .lsd-number-input__supporting-text{margin:6px 12px 0 12px;}</style><style data-emotion="css-global 12rmo7o">.lsd-modal{box-sizing:border-box;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column;position:fixed;top:0;left:0;right:0;bottom:0;background-color:rgba(0, 0, 0, 0.5);display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-box-pack:center;-ms-flex-pack:center;-webkit-justify-content:center;justify-content:center;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;z-index:9999;}.lsd-modal__container{position:relative;background:rgb(var(--lsd-surface-primary));padding:20px;max-width:90%;box-sizing:border-box;border:1px solid rgb(var(--lsd-border-primary));}.lsd-modal__header{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-box-pack:justify;-webkit-justify-content:space-between;justify-content:space-between;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;}.lsd-modal__close-icon{position:absolute;top:8px;right:8px;cursor:pointer;}.lsd-modal__title-and-subtitle-container{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column;}.lsd-modal--large .lsd-modal__container{min-width:960px;}.lsd-modal--medium .lsd-modal__container{min-width:768px;}.lsd-modal--small .lsd-modal__container{min-width:614px;}.lsd-modal--extra-small .lsd-modal__container{min-width:490px;}</style><style data-emotion="css-global 1k7gzc">.lsd-modal-footer{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;}</style><style data-emotion="css-global 1b9t8so">.lsd-modal-body{margin:18px 0;}</style><style data-emotion="css-global dyud2a">.lsd-date-picker{width:-webkit-fit-content;width:-moz-fit-content;width:fit-content;}.lsd-date-picker__calendar{border-top:none!important;}.lsd-date-picker--large .lsd-date-field--large{width:318px;}.lsd-date-picker--medium .lsd-date-field--medium{width:290px;}.lsd-date-picker--small .lsd-date-field--small{width:262px;}</style><style data-emotion="css-global olq3nk">.lsd-date-field{width:auto;box-sizing:border-box;}.lsd-date-field__label{display:block;}.lsd-date-field__input-container__icon{position:absolute;right:0;cursor:pointer;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;background-color:rgb(var(--lsd-surface-primary));}.lsd-date-field__input-container__icon:focus{background:blue;background-color:pink;border:1px solid rgb(var(--lsd-border-primary));}.lsd-date-field__input-container__no-icon{position:absolute;right:0;background-color:rgb(var(--lsd-surface-primary));padding:12px;}.lsd-date-field--outlined{border:1px solid rgb(var(--lsd-border-primary));}.lsd-date-field--underlined{border-bottom:1px solid rgb(var(--lsd-border-primary));}.lsd-date-field__input-container{position:relative;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:justify;-webkit-justify-content:space-between;justify-content:space-between;}.lsd-date-field--disabled{opacity:0.34;}.lsd-date-field__input-container__input{border:none;outline:none;font-size:14px;color:rgb(var(--lsd-text-primary));background:none;width:100%;opacity:0.4;-webkit-transition:opacity 0.2s ease-in-out;transition:opacity 0.2s ease-in-out;}.lsd-date-field__input-container__input::-webkit-inner-spin-button,.lsd-date-field__input-container__input::-webkit-calendar-picker-indicator{display:none;-webkit-appearance:none;}.lsd-date-field__input-container__input:hover{outline:none;}.lsd-date-field__supporting-text{position:absolute;}.lsd-date-field--large{width:208px;}.lsd-date-field--large .lsd-date-field__label{margin:0 0 6px 18px;}.lsd-date-field--large .lsd-date-field__input-container{height:40px;}.lsd-date-field--large .lsd-date-field__input-container__input{padding:9px 0px 9px 17px;}.lsd-date-field--large .lsd-date-field__input-container__icon{padding:12px 13px;}.lsd-date-field--large .lsd-date-field__supporting-text{margin:6px 18px 0 18px;}.lsd-date-field--medium{width:188px;}.lsd-date-field--medium .lsd-date-field__label{margin:0 0 6px 14px;}.lsd-date-field--medium .lsd-date-field__input-container{height:32px;}.lsd-date-field--medium .lsd-date-field__input-container__input{padding:5px 11px 5px 13px;}.lsd-date-field--medium .lsd-date-field__input-container__icon{padding:8px 11px;}.lsd-date-field--medium .lsd-date-field__supporting-text{margin:6px 14px 0 14px;}.lsd-date-field--small{width:164px;}.lsd-date-field--small .lsd-date-field__label{margin:0 0 6px 12px;}.lsd-date-field--small .lsd-date-field__input-container{height:28px;}.lsd-date-field--small .lsd-date-field__input-container__input{padding:5px 9px 5px 11px;font-size:12px;}.lsd-date-field--small .lsd-date-field__input-container__icon{padding:6px 9px;}.lsd-date-field--small .lsd-date-field__supporting-text{margin:6px 12px 0 12px;}.lsd-date-field__input-container__input:invalid,.lsd-date-field__input-container__input--filled{color:rgb(var(--lsd-border-primary));opacity:1;}.lsd-date-field--error .lsd-date-field__input-container__input::-webkit-datetime-edit-year-field,.lsd-date-field--error .lsd-date-field__input-container__input::-webkit-datetime-edit-month-field,.lsd-date-field--error .lsd-date-field__input-container__input::-webkit-datetime-edit-day-field{-webkit-text-decoration:line-through;text-decoration:line-through;}@supports not selector(::-webkit-datetime-edit-day-field){.lsd-date-field--error .lsd-date-field__input-container__input{-webkit-text-decoration:line-through;text-decoration:line-through;}}</style><style data-emotion="css-global 1gjtao4">.lsd-calendar{border:1px solid rgb(var(--lsd-border-primary));visibility:hidden;position:absolute!important;top:0;left:0;opacity:0;visibility:hidden;margin:0;padding:0;box-sizing:border-box;background:rgb(var(--lsd-surface-primary));-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;}.lsd-calendar-container{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column;padding:8px;}.lsd-calendar--open{opacity:1;visibility:visible;}.lsd-calendar-header{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-box-pack:center;-ms-flex-pack:center;-webkit-justify-content:center;justify-content:center;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;height:32px;margin-bottom:8px;}.lsd-calendar__week_day{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-box-pack:center;-ms-flex-pack:center;-webkit-justify-content:center;justify-content:center;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;aspect-ratio:1/1;margin-bottom:4px;}.lsd-calendar__change-year{position:relative;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-box-pack:center;-ms-flex-pack:center;-webkit-justify-content:center;justify-content:center;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;padding:2px 0xp 2px 8px;gap:6px;border:1px solid transparent;}.lsd-calendar__change-year--active .lsd-calendar__year-and-icon{border:1px solid rgb(var(--lsd-border-primary));}.lsd-calendar__change-year-icon-container{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-box-pack:center;-ms-flex-pack:center;-webkit-justify-content:center;justify-content:center;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;cursor:pointer;border:none;}.lsd-calendar-month{margin-right:8px;}.lsd-calendar__month-and-year{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:center;-ms-flex-pack:center;-webkit-justify-content:center;justify-content:center;}.lsd-calendar-day__container{cursor:pointer;background:transparent;position:relative;box-sizing:border-box;border:1px solid transparent;}.lsd-calendar-day{aspect-ratio:1/1;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-box-pack:center;-ms-flex-pack:center;-webkit-justify-content:center;justify-content:center;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;}.lsd-calendar-day:hover{cursor:pointer;-webkit-text-decoration:underline;text-decoration:underline;text-decoration-color:rgb(var(--lsd-border-primary));}.lsd-calendar-day label:hover{cursor:pointer;}.lsd-calendar-day--selected{border:1px solid rgb(var(--lsd-border-primary));}.lsd-calendar-day--disabled{opacity:0.3;cursor:default;}.lsd-calendar-day__today_indicator{position:absolute;left:50%;-webkit-transform:translateX(-50%);-moz-transform:translateX(-50%);-ms-transform:translateX(-50%);transform:translateX(-50%);bottom:2px;}.lsd-calendar--disabled{pointer-events:none;border:1px solid rgba(var(--lsd-border-primary), 0.3);}.lsd-calendar--disabled label{opacity:0.3;}.lsd-calendar--disabled .lsd-calendar__button{opacity:0.3;}.lsd-calendar--disabled .lsd-calendar-day--selected{opacity:0.3;}.lsd-calendar__button{border:1px solid rgb(var(--lsd-border-primary));cursor:pointer;background:transparent;width:32px;height:32px;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:center;-ms-flex-pack:center;-webkit-justify-content:center;justify-content:center;position:absolute;}.lsd-calendar__next-month-button{top:8px;right:8px;}.lsd-calendar__previous-month-button{top:8px;left:8px;}.lsd-calendar-day--border-left{border-left:1px double rgb(var(--lsd-border-primary));}.lsd-calendar-day--border-right{border-right:1px double rgb(var(--lsd-border-primary));}.lsd-calendar-day--border-left-and-right{border-left:1px double rgb(var(--lsd-border-primary));border-right:1px double rgb(var(--lsd-border-primary));}.lsd-calendar-day--border-top-and-bottom{border-top:1px double rgb(var(--lsd-border-primary));border-bottom:1px double rgb(var(--lsd-border-primary));}.lsd-calendar__month-table{border-collapse:collapse;}.lsd-calendar__year-dropdown{box-sizing:border-box;position:absolute;top:100%;left:0;max-height:200px;overflow-y:auto;width:100%;border:1px solid rgb(var(--lsd-border-primary));border-top:none;z-index:1;}.lsd-calendar__year-dropdown .lsd-calendar-year{border-bottom:1px solid rgb(var(--lsd-border-primary));}.lsd-calendar__year-dropdown--hidden{visibility:hidden;}.lsd-calendar-year{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;cursor:pointer;-webkit-transition:background-color 0.2s;transition:background-color 0.2s;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;background:rgb(var(--lsd-surface-primary));}.lsd-calendar-year:hover{-webkit-text-decoration:underline;text-decoration:underline;}.lsd-calendar__year-and-icon{border:1px solid rgb(var(--lsd-border-primary));}.lsd-calendar--large .lsd-calendar-year{padding:6px 0px 6px 14px;}.lsd-calendar--large .lsd-calendar__change-year-icon-container{width:32px;}.lsd-calendar--medium .lsd-calendar-year{padding:6px 0px 6px 12px;}.lsd-calendar--medium .lsd-calendar__change-year-icon-container{width:28px;}.lsd-calendar--small .lsd-calendar-year{padding:6px 0px 6px 12px;}.lsd-calendar--small .lsd-calendar__change-year-icon-container{width:28px;}</style><style data-emotion="css-global dlrd7d">.lsd-toast{box-sizing:border-box;display:-webkit-inline-box;display:-webkit-inline-flex;display:-ms-inline-flexbox;display:inline-flex;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;background:rgb(var(--lsd-surface-primary));border:1px solid rgb(var(--lsd-border-primary));padding:8px;height:-webkit-fit-content;height:-moz-fit-content;height:fit-content;}.lsd-toast__inline-button-container{-webkit-flex-shrink:0;-ms-flex-negative:0;flex-shrink:0;}.lsd-toast__column-button-container{margin-top:18px;margin-bottom:6px;}.lsd-toast__inline-container{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:justify;-webkit-justify-content:space-between;justify-content:space-between;-webkit-box-flex:1;-webkit-flex-grow:1;-ms-flex-positive:1;flex-grow:1;}.lsd-toast__column-container{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column;-webkit-box-pack:justify;-webkit-justify-content:space-between;justify-content:space-between;}.lsd-toast__text-container{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column;color:rgb(var(--lsd-text-secondary));padding-left:12px;}.lsd-toast__title{position:relative;}.lsd-toast__information{margin-top:4px;}.lsd-toast__button-container{min-height:28px;min-width:60px;width:-webkit-fit-content;width:-moz-fit-content;width:fit-content;padding:0px 12px;}.lsd-toast__close-button{margin-bottom:auto;-webkit-flex-shrink:0;-ms-flex-negative:0;flex-shrink:0;height:28px;width:28px;margin-left:auto;}.lsd-toast__column-icon-container{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-box-pack:center;-ms-flex-pack:center;-webkit-justify-content:center;justify-content:center;margin-bottom:auto;position:relative;top:4px;padding-left:4px;}.lsd-toast__inline-icon-container{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:center;-ms-flex-pack:center;-webkit-justify-content:center;justify-content:center;padding-left:4px;}.lsd-toast__icon{position:relative;}.lsd-toast--large{width:364px;}.lsd-toast--medium{width:336px;}.lsd-toast--small{width:296px;}.lsd-toast--small .lsd-toast__icon{top:0px;}</style><style data-emotion="css-global 5wlfwk">.lsd-toast-provider__toast-container{position:fixed;-webkit-transition:all 230ms cubic-bezier(0.21, 1.02, 0.73, 1);transition:all 230ms cubic-bezier(0.21, 1.02, 0.73, 1);z-index:9999;}.lsd-toast-provider__toast--top-left,.lsd-toast-provider__toast--top-center,.lsd-toast-provider__toast--top-right{top:0;}.lsd-toast-provider__toast--bottom-left,.lsd-toast-provider__toast--bottom-center,.lsd-toast-provider__toast--bottom-right{bottom:0;}.lsd-toast-provider__toast--top-center,.lsd-toast-provider__toast--bottom-center{left:50%;}.lsd-toast-provider__toast--top-right,.lsd-toast-provider__toast--bottom-right{right:0;}</style><style data-emotion="css-global 9yw6e1">.lsd-button-group{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:row;-ms-flex-direction:row;flex-direction:row;}.lsd-button-group >*:not(:last-child).lsd-button--outlined,.lsd-button-group >*:not(:last-child) .lsd-button--outlined{border-right:none;}</style><style data-emotion="css-global 17u9w7w">.lsd-date-range-picker{box-sizing:border-box;}.lsd-date-range-picker .lsd-date-field--outlined{border:none;}.lsd-date-range-picker .lsd-date-field__input-container__icon{padding:8px;}.lsd-date-range-picker__label{display:block;}.lsd-date-range-picker__input-container{box-sizing:border-box;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;border:1px solid transparent;}.lsd-date-picker__calendar{border-top:none!important;}.lsd-date-picker__calendar .lsd-tooltip-base__arrow-tip{-webkit-transition:left 0.2s ease-in-out;transition:left 0.2s ease-in-out;}.lsd-date-range-picker--calendar-open .lsd-date-range-picker__input-container{border-bottom:1px solid rgb(var(--lsd-border-primary));}.lsd-date-range-picker__icon{cursor:pointer;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:center;-ms-flex-pack:center;-webkit-justify-content:center;justify-content:center;-webkit-box-flex:1;-webkit-flex-grow:1;-ms-flex-positive:1;flex-grow:1;padding:0 10px;}.lsd-date-range-picker--disabled{opacity:0.3;}.lsd-date-range-picker__supporting-text{position:absolute;}.lsd-date-range-picker--large{width:318px;}.lsd-date-range-picker--large .lsd-date-field--large{width:156px;}.lsd-date-range-picker--large .lsd-date-field__input-container__input{padding-right:0;}.lsd-date-range-picker--large .lsd-date-field__input-container__icon{padding:11px 12px;}.lsd-date-range-picker--large .lsd-date-range-picker__label{margin:0 0 6px 18px;}.lsd-date-range-picker--large .lsd-date-range-picker__input-container{height:40px;}.lsd-date-range-picker--large .lsd-date-range-picker__supporting-text{margin:6px 18px 0 18px;}.lsd-date-range-picker--medium{width:290px;}.lsd-date-range-picker--medium .lsd-date-field--medium{width:142px;}.lsd-date-range-picker--medium .lsd-date-field__input-container__input{padding-right:0;}.lsd-date-range-picker--medium .lsd-date-field__input-container__icon{padding:7px 8px;}.lsd-date-range-picker--medium .lsd-date-range-picker__label{margin:0 0 6px 14px;}.lsd-date-range-picker--medium .lsd-date-range-picker__input-container{height:32px;}.lsd-date-range-picker--medium .lsd-date-range-picker__supporting-text{margin:6px 14px 0 14px;}.lsd-date-range-picker--small{width:262px;}.lsd-date-range-picker--small .lsd-date-field--small{width:128px;}.lsd-date-range-picker--small .lsd-date-field__input-container__input{padding-right:0;}.lsd-date-range-picker--small .lsd-date-field__input-container__icon{padding:5px 7px;}.lsd-date-range-picker--small .lsd-date-range-picker__label{margin:0 0 6px 12px;}.lsd-date-range-picker--small .lsd-date-range-picker__input-container{height:28px;}.lsd-date-range-picker--small .lsd-date-range-picker__supporting-text{margin:6px 12px 0 12px;}.lsd-date-range-picker__separator{margin-left:3px;width:1px;height:100%;}.lsd-date-range-picker__separator{border-left:1px solid transparent;}.lsd-date-range-picker--outlined{border:1px solid rgb(var(--lsd-border-primary));}.lsd-date-range-picker--outlined .lsd-date-range-picker__separator{border-left:1px solid rgb(var(--lsd-border-primary));}</style><style data-emotion="css-global 19d282h">.lsd-tooltip-base{border:1px solid rgb(var(--lsd-border-primary));position:relative;}.lsd-tooltip-base__arrow-tip{border:1px solid rgb(var(--lsd-border-primary));position:absolute;background:rgb(var(--lsd-surface-primary));}.lsd-tooltip-base__content{background:rgb(var(--lsd-surface-primary));width:100%;height:100%;position:relative;z-index:1;}</style><style data-emotion="css-global 1o77wkp">[data-theme=dark]{--lsd-display1-fontSize:5.5rem;--lsd-display1-fontWeight:normal;--lsd-display1-lineHeight:6rem;--lsd-display2-fontSize:4rem;--lsd-display2-fontWeight:normal;--lsd-display2-lineHeight:4.5rem;--lsd-display3-fontSize:3.5rem;--lsd-display3-fontWeight:normal;--lsd-display3-lineHeight:4rem;--lsd-display4-fontSize:3rem;--lsd-display4-fontWeight:normal;--lsd-display4-lineHeight:3.5rem;--lsd-h1-fontSize:2.5rem;--lsd-h1-fontWeight:normal;--lsd-h1-lineHeight:3rem;--lsd-h2-fontSize:2rem;--lsd-h2-fontWeight:normal;--lsd-h2-lineHeight:2.5rem;--lsd-h3-fontSize:1.75rem;--lsd-h3-fontWeight:normal;--lsd-h3-lineHeight:2.25rem;--lsd-h4-fontSize:1.5rem;--lsd-h4-fontWeight:normal;--lsd-h4-lineHeight:2rem;--lsd-h5-fontSize:1.25rem;--lsd-h5-fontWeight:normal;--lsd-h5-lineHeight:1.75rem;--lsd-h6-fontSize:1rem;--lsd-h6-fontWeight:normal;--lsd-h6-lineHeight:1.5rem;--lsd-subtitle1-fontSize:1.125rem;--lsd-subtitle1-fontWeight:normal;--lsd-subtitle1-lineHeight:1.5rem;--lsd-subtitle2-fontSize:1rem;--lsd-subtitle2-fontWeight:normal;--lsd-subtitle2-lineHeight:1.5rem;--lsd-subtitle3-fontSize:0.875rem;--lsd-subtitle3-fontWeight:normal;--lsd-subtitle3-lineHeight:1.25rem;--lsd-subtitle4-fontSize:0.75rem;--lsd-subtitle4-fontWeight:normal;--lsd-subtitle4-lineHeight:1rem;--lsd-body1-fontSize:1rem;--lsd-body1-fontWeight:normal;--lsd-body1-lineHeight:1.5rem;--lsd-body2-fontSize:0.875rem;--lsd-body2-fontWeight:normal;--lsd-body2-lineHeight:1.25rem;--lsd-body3-fontSize:0.75rem;--lsd-body3-fontWeight:normal;--lsd-body3-lineHeight:1rem;--lsd-label1-fontSize:0.875rem;--lsd-label1-fontWeight:normal;--lsd-label1-lineHeight:1.25rem;--lsd-label2-fontSize:0.75rem;--lsd-label2-fontWeight:normal;--lsd-label2-lineHeight:1rem;--lsd-typography-generic-font-family:sans-serif;--lsd-theme-primary:255,255,255;--lsd-theme-secondary:0,0,0;--lsd-surface-primary:0,0,0;--lsd-surface-secondary:255,255,255;--lsd-border-primary:255,255,255;--lsd-border-secondary:0,0,0;--lsd-icon-primary:255,255,255;--lsd-icon-secondary:0,0,0;--lsd-text-primary:255,255,255;--lsd-text-secondary:0,0,0;--lsd-text-tertiary:255,255,255,0.34;--lsd-spacing-4:4px;--lsd-spacing-8:8px;--lsd-spacing-16:16px;--lsd-spacing-24:24px;--lsd-spacing-32:32px;--lsd-spacing-40:40px;--lsd-spacing-64:64px;--lsd-spacing-80:80px;--lsd-spacing-96:96px;--lsd-spacing-120:120px;}</style><style data-emotion="css-global yon3n1">[data-theme=light]{--lsd-display1-fontSize:5.5rem;--lsd-display1-fontWeight:normal;--lsd-display1-lineHeight:6rem;--lsd-display2-fontSize:4rem;--lsd-display2-fontWeight:normal;--lsd-display2-lineHeight:4.5rem;--lsd-display3-fontSize:3.5rem;--lsd-display3-fontWeight:normal;--lsd-display3-lineHeight:4rem;--lsd-display4-fontSize:3rem;--lsd-display4-fontWeight:normal;--lsd-display4-lineHeight:3.5rem;--lsd-h1-fontSize:2.5rem;--lsd-h1-fontWeight:normal;--lsd-h1-lineHeight:3rem;--lsd-h2-fontSize:2rem;--lsd-h2-fontWeight:normal;--lsd-h2-lineHeight:2.5rem;--lsd-h3-fontSize:1.75rem;--lsd-h3-fontWeight:normal;--lsd-h3-lineHeight:2.25rem;--lsd-h4-fontSize:1.5rem;--lsd-h4-fontWeight:normal;--lsd-h4-lineHeight:2rem;--lsd-h5-fontSize:1.25rem;--lsd-h5-fontWeight:normal;--lsd-h5-lineHeight:1.75rem;--lsd-h6-fontSize:1rem;--lsd-h6-fontWeight:normal;--lsd-h6-lineHeight:1.5rem;--lsd-subtitle1-fontSize:1.125rem;--lsd-subtitle1-fontWeight:normal;--lsd-subtitle1-lineHeight:1.5rem;--lsd-subtitle2-fontSize:1rem;--lsd-subtitle2-fontWeight:normal;--lsd-subtitle2-lineHeight:1.5rem;--lsd-subtitle3-fontSize:0.875rem;--lsd-subtitle3-fontWeight:normal;--lsd-subtitle3-lineHeight:1.25rem;--lsd-subtitle4-fontSize:0.75rem;--lsd-subtitle4-fontWeight:normal;--lsd-subtitle4-lineHeight:1rem;--lsd-body1-fontSize:1rem;--lsd-body1-fontWeight:normal;--lsd-body1-lineHeight:1.5rem;--lsd-body2-fontSize:0.875rem;--lsd-body2-fontWeight:normal;--lsd-body2-lineHeight:1.25rem;--lsd-body3-fontSize:0.75rem;--lsd-body3-fontWeight:normal;--lsd-body3-lineHeight:1rem;--lsd-label1-fontSize:0.875rem;--lsd-label1-fontWeight:normal;--lsd-label1-lineHeight:1.25rem;--lsd-label2-fontSize:0.75rem;--lsd-label2-fontWeight:normal;--lsd-label2-lineHeight:1rem;--lsd-typography-generic-font-family:sans-serif;--lsd-theme-primary:0,0,0;--lsd-theme-secondary:255,255,255;--lsd-surface-primary:255,255,255;--lsd-surface-secondary:0,0,0;--lsd-border-primary:0,0,0;--lsd-border-secondary:255,255,255;--lsd-icon-primary:0,0,0;--lsd-icon-secondary:255,255,255;--lsd-text-primary:0,0,0;--lsd-text-secondary:255,255,255;--lsd-text-tertiary:0,0,0,0.34;--lsd-spacing-4:4px;--lsd-spacing-8:8px;--lsd-spacing-16:16px;--lsd-spacing-24:24px;--lsd-spacing-32:32px;--lsd-spacing-40:40px;--lsd-spacing-64:64px;--lsd-spacing-80:80px;--lsd-spacing-96:96px;--lsd-spacing-120:120px;}</style><div class="root_QACb"><div role="region" aria-label="Skip to main content"><a class="skipToContent_fXgn" href="#__docusaurus_skipToContent_fallback">Skip to main content</a></div><nav aria-label="Main" class="navbar navbar--fixed-top navbarHideable_OoEf"><div class="navbar__inner"><div class="navbar__left"><a class="navbar__brand" href="/"><div class="navbar__logo"><img src="/theme/image/logo.svg" alt="Vac Research" class="themedImage_ToTc themedImage--light_HNdA" height="26"><img src="/theme/image/logo.svg" alt="Vac Research" class="themedImage_ToTc themedImage--dark_i4oU" height="26"></div><b class="navbar__title text--truncate"></b></a></div><div class="navbar__left-items"><a class="navbar__item navbar__link" href="/"><div class="lsd-typography lsd-typography--body2 linkContent__x3v">About Vac</div></a><a class="navbar__item navbar__link" href="/community"><div class="lsd-typography lsd-typography--body2 linkContent__x3v">Community</div></a><a class="navbar__item navbar__link" href="/rlog"><div class="lsd-typography lsd-typography--body2 linkContent__x3v">Research Blog</div></a><a class="navbar__item navbar__link" href="/join-us"><div class="lsd-typography lsd-typography--body2 linkContent__x3v">Join Us</div></a></div><div class="navbar__right-items"><div class="iconButtonGroup_ktNv lsd-icon-button-group lsd-icon-button-group--medium lsd-icon-button-group--outlined"><button class="clean-btn toggle_K23S colorModeToggle_GSaI navbar__color-mode-toggle toggleButtonDisabled_AAS_ lsd-icon-button lsd-icon-button--medium lsd-icon-button--outlined lsd-icon-button--disabled" type="button" title="Switch between dark and light mode (currently dark mode)" aria-label="Switch between dark and light mode (currently dark mode)" aria-live="polite"><svg viewBox="0 0 24 24" width="24" height="24" class="lightToggleIcon_K4TL"><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"></path></svg><svg viewBox="0 0 24 24" width="24" height="24" class="darkToggleIcon_lKkA"><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"></path></svg></button><button aria-label="Toggle navigation bar" aria-expanded="false" class="navbar__toggle clean-btn" type="button"><svg width="30" height="30" viewBox="0 0 30 30" aria-hidden="true"><path stroke="currentColor" stroke-linecap="round" stroke-miterlimit="10" stroke-width="2" d="M4 7h22M4 15h22M4 23h22"></path></svg></button></div></div></div><div role="presentation" class="navbar-sidebar__backdrop"></div></nav><div id="__docusaurus_skipToContent_fallback" class="main-wrapper mainWrapper_z2l0 docsWrapper_BCFX"><button aria-label="Scroll back to top" class="clean-btn theme-back-to-top-button backToTopButton_sjWU" type="button"></button><div class="docPage__5DB"><main class="docMainContainer_gTbr docMainContainerEnhanced_Uz_u"><div class="container padding-top--md padding-bottom--lg"><div class="row docItemGrid_SzoZ"><div class="docItemCol_F52z"><div class="docItemContainer_hrrU"><article><div class="theme-doc-markdown markdown"><h1>Privacy Policy</h1><div class="tocMobile_imaF"><div class="tocCollapsible_ROek theme-doc-toc-mobile tocMobile_ITEo"><button type="button" class="clean-btn tocCollapsibleButton_dxRj"><div></div><span class="lsd-typography lsd-typography--body2">On this page</span><svg width="14" height="14" viewBox="0 0 14 14" fill="none" xmlns="http://www.w3.org/2000/svg" class="lsd-icon lsd-icon--small lsd-icon--filled"><path d="M10.5 5.66125L9.6775 4.83875L7 7.51041L4.3225 4.83874L3.5 5.66125L7 9.16125L10.5 5.66125Z" fill="black"></path></svg></button></div></div><p>Last updated: 9 February 2024</p><p>This Privacy Policy is intended to inform users of our approach to privacy in respect of this website (<strong>"Website"</strong>). In this regard, if you are visiting our Website, this Privacy Policy applies to you.</p><h3 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="1-who-we-are">1) Who we are<a href="#1-who-we-are" class="hash-link" aria-label="Direct link to 1) Who we are" title="Direct link to 1) Who we are">​</a></h3><p>For the purposes of this Privacy Policy and the collection and processing of personal data as a controller, the relevant entity is the Logos Collective Association, which has its registered office in Zug and its legal domicile address at</p><div class="codeBlockContainer_EB2s codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:rgba(var(--lsd-surface-secondary), 0.08)"><div class="codeBlockContent_ugSV"><pre tabindex="0" class="prism-code language-text codeBlock_TWhw thin-scrollbar"><code class="codeBlockLines_LDrR"><span class="token-line" style="color:#F8F8F2"><span class="token plain">Logos Collective Association</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">c/o PST Consulting GmbH</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">Baarerstrasse 10</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">6300 Zug</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">Switzerland</span><br></span></code></pre><div class="buttonGroup_Qu4e"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_an20" aria-hidden="true"><div class="icon_S7Kx m_thRi copyButtonIcon_ZL7v"><svg width="14" height="14" viewBox="0 0 14 14" fill="none" xmlns="http://www.w3.org/2000/svg" role="img"><path d="M2.917 12.833c-.321 0-.596-.114-.825-.343a1.121 1.121 0 0 1-.342-.823V3.5h1.167v8.167h6.416v1.166H2.917ZM5.25 10.5c-.32 0-.596-.114-.824-.343a1.121 1.121 0 0 1-.343-.824v-7c0-.32.115-.595.343-.824.229-.229.504-.343.824-.342h5.25c.32 0 .596.114.824.343.229.228.343.503.343.823v7c0 .321-.115.596-.343.825a1.121 1.121 0 0 1-.824.342H5.25Zm0-1.167h5.25v-7H5.25v7Z" fill="#fff"></path></svg></div></span></button></div></div></div><p>Whenever we refer to “Logos”, “we” or other similar references, we are referring to the Logos Collective Association.</p><h3 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="2-we-limit-the-collection-and-processing-of-personal-data-from-your-use-of-the-website">2) We limit the collection and processing of personal data from your use of the Website<a href="#2-we-limit-the-collection-and-processing-of-personal-data-from-your-use-of-the-website" class="hash-link" aria-label="Direct link to 2) We limit the collection and processing of personal data from your use of the Website" title="Direct link to 2) We limit the collection and processing of personal data from your use of the Website">​</a></h3><p>We aim to limit the collection and collection and processing of personal data from users of the Website. We only collect and process certain personal data for specific purposes and where we have the legal basis to do so under applicable privacy legislation. We will not collect or process any personal data that we don’t need and where we do store any personal data, we will only store it for the least amount of time needed for the indicated purpose. </p><p>In this regard, we collect and process the following personal data from your use of the Website: </p><ul><li><strong>IP address</strong>: As part of such use of the Website we briefly process your IP address but we have no way of identifying you. We however have a legitimate interest in processing such IP addresses to ensure the technical functionality and enhance the security measures of the Website. This IP address is not stored by us over time.</li></ul><h3 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="3-third-party-processing-of-personal-data">3) Third party processing of personal data<a href="#3-third-party-processing-of-personal-data" class="hash-link" aria-label="Direct link to 3) Third party processing of personal data" title="Direct link to 3) Third party processing of personal data">​</a></h3><p>In addition to our limited and collection of personal data, third parties may collect or process personal data as a result of the Website making use of certain features or to provide certain content. To the extent you interact with such third party content or features, their respective privacy policies will apply. </p><h3 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="4-security-measures-we-take-in-respect-of-the-website">4) Security measures we take in respect of the Website<a href="#4-security-measures-we-take-in-respect-of-the-website" class="hash-link" aria-label="Direct link to 4) Security measures we take in respect of the Website" title="Direct link to 4) Security measures we take in respect of the Website">​</a></h3><p>As a general approach, we take data security seriously and we have implemented a variety of security measures on the Website to maintain the safety of your personal data when you submit such information to us. </p><h3 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="5-exporting-data-outside-the-european-union-and-switzerland">5) Exporting data outside the European Union and Switzerland<a href="#5-exporting-data-outside-the-european-union-and-switzerland" class="hash-link" aria-label="Direct link to 5) Exporting data outside the European Union and Switzerland" title="Direct link to 5) Exporting data outside the European Union and Switzerland">​</a></h3><p>We are obliged to protect the privacy of personal data that you may have submitted in the unlikely event that we export your personal data to places outside the European Union or Switzerland. This means that personal data will only be processed in countries or by parties that provide an adequate level of protection as deemed by Switzerland or the European Commission. Otherwise, we will use other forms of protections, such as specific forms of contractual clauses to ensure such personal data is provided the same protection as required in Switzerland or Europe. In any event, the transmission of personal data outside the European Union and Switzerland will always occur in conformity with applicable privacy legislation. </p><h3 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="6-your-choices-and-rights">6) Your choices and rights<a href="#6-your-choices-and-rights" class="hash-link" aria-label="Direct link to 6) Your choices and rights" title="Direct link to 6) Your choices and rights">​</a></h3><p>As explained in this Privacy Policy, we limit our collection and processing of your personal data wherever possible. Nonetheless, you still have certain choices and rights in respect of the personal data which we do collect and process. As laid out in relevant privacy legislation, you have the right to:</p><ul><li><p>Ask us to correct or update your personal data (where reasonably possible);</p></li><li><p>Ask us to remove your personal data from our systems;</p></li><li><p>Ask us for a copy of your personal data, which may also be transferred to another data controller at your request;</p></li><li><p>Withdraw your consent to process your personal data (only if consent was asked for a processing activity), which only affects processing activities that are based on your consent and doesn’t affect the validity of such processing activities before you have withdrawn your consent;</p></li><li><p>Object to the processing of your personal data; and</p></li><li><p>File a complaint with the Federal Data Protection and Information Commissioner (FDPIC), if you believe that your personal data has been processed unlawfully.</p></li></ul><h3 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="7-third-party-links">7) Third party links<a href="#7-third-party-links" class="hash-link" aria-label="Direct link to 7) Third party links" title="Direct link to 7) Third party links">​</a></h3><p>On this Website, you may come across links to third party websites. These third party sites have separate and independent privacy policies. We therefore have no responsibility or liability for the content and activities of these third party websites.</p><h3 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="8-this-privacy-policy-might-change">8) This Privacy Policy might change<a href="#8-this-privacy-policy-might-change" class="hash-link" aria-label="Direct link to 8) This Privacy Policy might change" title="Direct link to 8) This Privacy Policy might change">​</a></h3><p>We may modify or replace any part of this Privacy Policy at any time and without notice. Please check the Website periodically for any changes. The new Privacy Policy will be effective immediately upon its posting on our Website.</p><h3 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="9-contact-information">9) Contact information<a href="#9-contact-information" class="hash-link" aria-label="Direct link to 9) Contact information" title="Direct link to 9) Contact information">​</a></h3><p>To the extent that you have any questions about the Privacy Policy, please contact us at <a href="mailto:legal@free.technology" target="_blank" rel="noopener noreferrer">legal@free.technology</a>.</p><p>This document is licensed under CC-BY-SA.</p></div></article><nav class="pagination-nav docusaurus-mt-lg" aria-label="Docs pages"></nav></div></div><div class="gap1_XuuQ"></div><div class="toc_pP_5"><div class="tableOfContents_bqdL thin-scrollbar theme-doc-toc-desktop"><ul class="table-of-contents table-of-contents__left-border"><li><a href="#1-who-we-are" class="table-of-contents__link toc-highlight">1) Who we are</a></li><li><a href="#2-we-limit-the-collection-and-processing-of-personal-data-from-your-use-of-the-website" class="table-of-contents__link toc-highlight">2) We limit the collection and processing of personal data from your use of the Website</a></li><li><a href="#3-third-party-processing-of-personal-data" class="table-of-contents__link toc-highlight">3) Third party processing of personal data</a></li><li><a href="#4-security-measures-we-take-in-respect-of-the-website" class="table-of-contents__link toc-highlight">4) Security measures we take in respect of the Website</a></li><li><a href="#5-exporting-data-outside-the-european-union-and-switzerland" class="table-of-contents__link toc-highlight">5) Exporting data outside the European Union and Switzerland</a></li><li><a href="#6-your-choices-and-rights" class="table-of-contents__link toc-highlight">6) Your choices and rights</a></li><li><a href="#7-third-party-links" class="table-of-contents__link toc-highlight">7) Third party links</a></li><li><a href="#8-this-privacy-policy-might-change" class="table-of-contents__link toc-highlight">8) This Privacy Policy might change</a></li><li><a href="#9-contact-information" class="table-of-contents__link toc-highlight">9) Contact information</a></li></ul></div></div></div></div></main></div></div><footer class="footer"><div class="container container-fluid firstRow_ar1q"><div class="footer__bottom text--center"><div class="margin-bottom--sm"><a class="footerLogoLink_BH7S" href="/"><img src="/theme/image/logo.svg" alt="Vac Research" class="themedImage_ToTc themedImage--light_HNdA footer__logo" width="22"><img src="/theme/image/logo.svg" alt="Vac Research" class="themedImage_ToTc themedImage--dark_i4oU footer__logo" width="22"></a></div><div class="footer__copyright">Vac Research © 2024<br>All rights reserved.</div></div><div class="row footer__links"><div class="col footer__col"><div class="footer__title"></div><ul class="footer__items clean-list"><li class="footer__item"><a href="https://twitter.com/vacp2p" target="_blank" rel="noopener noreferrer" class="footer__link-item">Twitter<svg width="13.5" height="13.5" aria-hidden="true" viewBox="0 0 24 24" class="iconExternalLink_nPIU"><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"></path></svg></a></li><li class="footer__item"><a href="https://discord.gg/PQFdubGt6d" target="_blank" rel="noopener noreferrer" class="footer__link-item">Discord<svg width="13.5" height="13.5" aria-hidden="true" viewBox="0 0 24 24" class="iconExternalLink_nPIU"><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"></path></svg></a></li><li class="footer__item"><a href="https://github.com/vacp2p" target="_blank" rel="noopener noreferrer" class="footer__link-item">Github<svg width="13.5" height="13.5" aria-hidden="true" viewBox="0 0 24 24" class="iconExternalLink_nPIU"><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"></path></svg></a></li></ul></div><div class="col footer__col"><div class="footer__title"></div><ul class="footer__items clean-list"><li class="footer__item"><a href="https://jobs.status.im/" target="_blank" rel="noopener noreferrer" class="footer__link-item">Work With Us<svg width="13.5" height="13.5" aria-hidden="true" viewBox="0 0 24 24" class="iconExternalLink_nPIU"><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"></path></svg></a></li><li class="footer__item"><a class="footer__link-item" href="/terms">Terms & Conditions</a></li><li class="footer__item"><a class="footer__link-item" href="/privacy-policy">Privacy Policy</a></li><li class="footer__item"><a class="footer__link-item" href="/security">Security</a></li></ul></div></div></div><div class="secondRow__ww3"><div class="footer__bottom text--center">Logos Collective</div><div class="row footer__links"><div class="col footer__col"><div class="footer__title">Research</div><ul class="footer__items clean-list"><li class="footer__item"><a href="https://vac.dev" target="_blank" rel="noopener noreferrer" class="footer__link-item">VacP2P<svg width="13.5" height="13.5" aria-hidden="true" viewBox="0 0 24 24" class="iconExternalLink_nPIU"><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"></path></svg></a></li><li class="footer__item"><a href="https://afaik.institute" target="_blank" rel="noopener noreferrer" class="footer__link-item">AFAIK<svg width="13.5" height="13.5" aria-hidden="true" viewBox="0 0 24 24" class="iconExternalLink_nPIU"><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"></path></svg></a></li></ul></div><div class="col footer__col"><div class="footer__title">Infrastructure</div><ul class="footer__items clean-list"><li class="footer__item"><a href="https://waku.org/" target="_blank" rel="noopener noreferrer" class="footer__link-item">Waku<svg width="13.5" height="13.5" aria-hidden="true" viewBox="0 0 24 24" class="iconExternalLink_nPIU"><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"></path></svg></a></li><li class="footer__item"><a href="https://nimbus.team/" target="_blank" rel="noopener noreferrer" class="footer__link-item">Nimbus<svg width="13.5" height="13.5" aria-hidden="true" viewBox="0 0 24 24" class="iconExternalLink_nPIU"><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"></path></svg></a></li><li class="footer__item"><a href="https://codex.storage" target="_blank" rel="noopener noreferrer" class="footer__link-item">Codex<svg width="13.5" height="13.5" aria-hidden="true" viewBox="0 0 24 24" class="iconExternalLink_nPIU"><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"></path></svg></a></li><li class="footer__item"><a href="https://nomos.tech" target="_blank" rel="noopener noreferrer" class="footer__link-item">Nomos<svg width="13.5" height="13.5" aria-hidden="true" viewBox="0 0 24 24" class="iconExternalLink_nPIU"><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"></path></svg></a></li></ul></div><div class="col footer__col"><div class="footer__title">Creative Studio</div><ul class="footer__items clean-list"><li class="footer__item"><a href="https://acid.info" target="_blank" rel="noopener noreferrer" class="footer__link-item">Acid.info<svg width="13.5" height="13.5" aria-hidden="true" viewBox="0 0 24 24" class="iconExternalLink_nPIU"><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"></path></svg></a></li></ul></div><div class="col footer__col"><div class="footer__title">Movement</div><ul class="footer__items clean-list"><li class="footer__item"><a href="https://logos.co" target="_blank" rel="noopener noreferrer" class="footer__link-item">Logos<svg width="13.5" height="13.5" aria-hidden="true" viewBox="0 0 24 24" class="iconExternalLink_nPIU"><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"></path></svg></a></li></ul></div><div class="col footer__col"><div class="footer__title">User-facing products</div><ul class="footer__items clean-list"><li class="footer__item"><a href="https://status.im" target="_blank" rel="noopener noreferrer" class="footer__link-item">Status<svg width="13.5" height="13.5" aria-hidden="true" viewBox="0 0 24 24" class="iconExternalLink_nPIU"><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"></path></svg></a></li><li class="footer__item"><a href="https://keycard.tech" target="_blank" rel="noopener noreferrer" class="footer__link-item">Keycard<svg width="13.5" height="13.5" aria-hidden="true" viewBox="0 0 24 24" class="iconExternalLink_nPIU"><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"></path></svg></a></li></ul></div></div></div><button class="backToTop_wDfN lsd-button lsd-button--small lsd-button--outlined"><span class="lsd-typography lsd-typography--label2 lsd-button__text">Back to top ↑</span></button></footer></div></div> -<script src="/assets/js/runtime~main.556fa6f5.js"></script> -<script src="/assets/js/main.ffc20c94.js"></script> +<script src="/assets/js/runtime~main.a9103199.js"></script> +<script src="/assets/js/main.5454aec3.js"></script> </body> </html> \ No newline at end of file diff --git a/publications/index.html b/publications/index.html index 520b4a51..1be5494d 100644 --- a/publications/index.html +++ b/publications/index.html @@ -10,8 +10,8 @@ <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/katex@0.13.24/dist/katex.min.css" integrity="sha384-odtC+0UGzzFL/6PNoE8rX/SPcQDXBJ+uRepguP4QkPCm2LBxH3FA3y+fKSiJ+AmM" crossorigin="anonymous"><link rel="stylesheet" href="/assets/css/styles.08d697e6.css"> -<link rel="preload" href="/assets/js/runtime~main.556fa6f5.js" as="script"> -<link rel="preload" href="/assets/js/main.ffc20c94.js" as="script"> +<link rel="preload" href="/assets/js/runtime~main.a9103199.js" as="script"> +<link rel="preload" href="/assets/js/main.5454aec3.js" as="script"> <meta property="og:image" content="https://vac.dev/_og/25862de817a428dfdd6c662ee453f35e9e277db3.png"><meta name="twitter:image" content="https://vac.dev/_og/25862de817a428dfdd6c662ee453f35e9e277db3.png"></head> <body class="navigation-with-keyboard"> <script>!function(){function e(e){document.documentElement.setAttribute("data-theme",e)}var t=function(){var e=null;try{e=new URLSearchParams(window.location.search).get("docusaurus-theme")}catch(e){}return e}()||function(){var e=null;try{e=localStorage.getItem("theme")}catch(e){}return e}();null!==t?e(t):window.matchMedia("(prefers-color-scheme: dark)").matches?e("dark"):window.matchMedia("(prefers-color-scheme: light)").matches?e("light"):e("dark")}()</script><div id="__docusaurus"> @@ -20,7 +20,7 @@ ) .lsd-dropdown__trigger:hover .lsd-dropdown__option-label,.lsd-dropdown:not(.lsd-dropdown--disabled):not( .lsd-dropdown--error ) .lsd-dropdown__trigger:focus .lsd-dropdown__option-label{-webkit-text-decoration:underline;text-decoration:underline;}.lsd-dropdown__label{display:block;}.lsd-dropdown__button-container{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-box-pack:justify;-webkit-justify-content:space-between;justify-content:space-between;}.lsd-dropdown__trigger{width:100%;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:row;-ms-flex-direction:row;flex-direction:row;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:justify;-webkit-justify-content:space-between;justify-content:space-between;border:none;cursor:pointer;background:none;}.lsd-dropdown__trigger:focus{outline:none;}.lsd-dropdown__option-label{cursor:inherit;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;}.lsd-dropdown__icons{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:row;-ms-flex-direction:row;flex-direction:row;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:center;-ms-flex-pack:center;-webkit-justify-content:center;justify-content:center;gap:8px;}.lsd-dropdown__icon{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;}.lsd-dropdown__supporting-text{margin:6px 14px;}.lsd-dropdown--error .lsd-dropdown__option-label{-webkit-text-decoration:line-through;text-decoration:line-through;}.lsd-dropdown--disabled{opacity:0.34;cursor:initial;}.lsd-dropdown--large{width:208px;}.lsd-dropdown--large.lsd-dropdown--error{width:230px;}.lsd-dropdown--large .lsd-dropdown__label{margin:0 0 6px 18px;}.lsd-dropdown--large .lsd-dropdown__button-container{height:40px;}.lsd-dropdown--large .lsd-dropdown__trigger{padding:10px 0px 10px 18px;}.lsd-dropdown--large .lsd-dropdown__icons{padding:0px 14px;}.lsd-dropdown--medium{width:188px;}.lsd-dropdown--medium.lsd-dropdown--error{width:210px;}.lsd-dropdown--medium .lsd-dropdown__label{margin:0 0 6px 14px;}.lsd-dropdown--medium .lsd-dropdown__button-container{height:32px;}.lsd-dropdown--medium .lsd-dropdown__trigger{padding:6px 0px 6px 14px;}.lsd-dropdown--medium .lsd-dropdown__icons{padding:0px 12px;}.lsd-dropdown--small{width:164px;}.lsd-dropdown--small.lsd-dropdown--error{width:186px;}.lsd-dropdown--small .lsd-dropdown__label{margin:0 0 6px 12px;}.lsd-dropdown--small .lsd-dropdown__button-container{height:28px;}.lsd-dropdown--small .lsd-dropdown__trigger{padding:6px 0px 6px 12px;}.lsd-dropdown--small .lsd-dropdown__icons{padding:0px 10px;}.lsd-dropdown--outlined .lsd-dropdown__button-container{border:1px solid rgb(var(--lsd-border-primary));}.lsd-dropdown--underlined .lsd-dropdown__button-container{border:1px solid transparent;border-bottom:1px solid rgb(var(--lsd-border-primary));}</style><style data-emotion="css-global w2g5fy">.lsd-dropdown-item{width:100%;box-sizing:border-box;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:row;-ms-flex-direction:row;flex-direction:row;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;border:1px solid rgb(var(--lsd-border-primary));}.lsd-dropdown-item:not(.lsd-dropdown-item--disabled){cursor:pointer;}.lsd-dropdown-item:not(.lsd-dropdown-item--disabled):hover,.lsd-dropdown-item:not(.lsd-dropdown-item--disabled):focus{outline:none;}.lsd-dropdown-item:not(.lsd-dropdown-item--disabled):hover .lsd-dropdown-item__label,.lsd-dropdown-item:not(.lsd-dropdown-item--disabled):focus .lsd-dropdown-item__label{-webkit-text-decoration:underline;text-decoration:underline;}.lsd-dropdown-item__label{display:block;overflow:hidden;white-space:nowrap;text-overflow:ellipsis;}.lsd-dropdown-item--disabled{opacity:0.34;}.lsd-dropdown-item__icon{margin-right:18px;-webkit-flex-shrink:0;-ms-flex-negative:0;flex-shrink:0;}.lsd-dropdown-item--small{padding:5px 9px;height:28px;}.lsd-dropdown-item--medium{padding:5px 11px;height:32px;}.lsd-dropdown-item--large{padding:5px 13px;height:40px;}</style><style data-emotion="css-global ww9kgc">.lsd-breadcrumb__list{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:row;-ms-flex-direction:row;flex-direction:row;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;list-style-type:none;margin:0;padding:0;}.lsd-breadcrumb--disabled .lsd-breadcrumb__list{opacity:0.34;cursor:initial;pointer-events:none;}.lsd-breadcrumb__dropdown-menu{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column;overflow:auto;border:1px solid rgb(var(--lsd-border-primary));margin-top:10px;position:absolute;width:auto!important;}.lsd-breadcrumb__dropdown-menu>li{cursor:pointer;}.lsd-breadcrumb__dropdown-menu>li:not(:last-child){border-bottom:1px solid rgb(var(--lsd-border-primary));}.lsd-breadcrumb__dropdown-menu>li:hover,.lsd-breadcrumb__dropdown-menu>li:focus{-webkit-text-decoration:underline;text-decoration:underline;text-decoration-color:rgb(var(--lsd-border-primary));}.lsd-breadcrumb__dropdown-menu li>a{width:164px;padding:5px 11px;}</style><style data-emotion="css-global 4gvini">.lsd-breadcrumb-item{list-style-type:none;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;}.lsd-breadcrumb__list>li:not(:last-child)::after{display:inline-block;margin-inline:12px;content:'/';}.lsd-breadcrumb-item__link{-webkit-text-decoration:none;text-decoration:none;cursor:pointer;}.lsd-breadcrumb-item--outlined{padding:3px 11px;border:1px solid rgb(var(--lsd-border-primary));}.lsd-breadcrumb:not(.lsd-breadcrumb--disabled) .lsd-breadcrumb-item__link:hover,.lsd-breadcrumb:not(.lsd-breadcrumb--disabled) .lsd-breadcrumb-item__link:focus{-webkit-text-decoration:underline;text-decoration:underline;text-decoration-color:rgb(var(--lsd-border-primary));}</style><style data-emotion="css-global 1cwg3oc">.lsd-card{box-sizing:border-box;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column;}.lsd-card>.lsd-card-header{margin-bottom:-1px;}</style><style data-emotion="css-global v7d76i">.lsd-card-header{box-sizing:border-box;padding:10px 18px;text-align:center;border:1px solid rgb(var(--lsd-border-primary));}.lsd-card-header__title{overflow:hidden;word-break:break-all;}.lsd-card-header--large{padding:10px 18px;}.lsd-card-header--medium{padding:6px 14px;}.lsd-card-header--small{padding:6px 12px;}</style><style data-emotion="css-global 1txgafh">.lsd-card-body{box-sizing:border-box;padding:14px 22px;border:1px solid rgb(var(--lsd-border-primary));}</style><style data-emotion="css-global kzy52c">.lsd-tag{width:-webkit-fit-content;width:-moz-fit-content;width:fit-content;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:row;-ms-flex-direction:row;flex-direction:row;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:center;-ms-flex-pack:center;-webkit-justify-content:center;justify-content:center;box-sizing:border-box;border:1px solid rgb(var(--lsd-icon-primary));}.lsd-tag:hover,.lsd-tag:focus{-webkit-text-decoration:underline;text-decoration:underline;cursor:pointer;}.lsd-badge--large{padding:3px 11px;gap:12px;height:28px;}.lsd-badge--small{padding:3px 7px;gap:8px;height:24px;}.lsd-tag--filled{background-color:rgb(var(--lsd-icon-primary));}.lsd-tag--filled .lsd-tag__label{color:rgb(var(--lsd-text-secondary));}.lsd-tag--filled svg{--lsd-icon-primary:var(--lsd-icon-secondary);}.lsd-tag--outlined{color:rgb(var(--lsd-text-primary));}.lsd-tag--disabled{opacity:0.3;cursor:initial;pointer-events:none;}</style><style data-emotion="css-global 4wy0ub">.lsd-text-field{box-sizing:border-box;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column;}.lsd-text-field__input-container{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:justify;-webkit-justify-content:space-between;justify-content:space-between;}.lsd-text-field--disabled{opacity:0.34;}.lsd-text-field__input{border:none;outline:none;font-size:14px;color:rgb(var(--lsd-text-primary));background:none;width:100%;}.lsd-text-field__input:hover{outline:none;}.lsd-text-field__input::-webkit-input-placeholder{color:rgb(var(--lsd-text-primary));opacity:0.3;}.lsd-text-field__input::-moz-placeholder{color:rgb(var(--lsd-text-primary));opacity:0.3;}.lsd-text-field__input:-ms-input-placeholder{color:rgb(var(--lsd-text-primary));opacity:0.3;}.lsd-text-field__input::placeholder{color:rgb(var(--lsd-text-primary));opacity:0.3;}.lsd-text-field--error .lsd-text-field__input{-webkit-text-decoration:line-through;text-decoration:line-through;}.lsd-text-field__supporting-text{width:-webkit-fit-content;width:-moz-fit-content;width:fit-content;}.lsd-text-field--large{width:208px;}.lsd-text-field--large>*{padding:10px 14px 10px 18px;}.lsd-text-field--medium{width:188px;}.lsd-text-field--medium>*{padding:6px 12px 6px 14px;}.lsd-text-field--small{width:164px;}.lsd-text-field--small>*{padding:6px 10px 6px 12px;}.lsd-text-field__label{padding-top:0;padding-bottom:6px;}.lsd-text-field__supporting-text{padding-bottom:0;padding-top:6px;}.lsd-text-field--outlined .lsd-text-field__input-container{border:1px solid rgb(var(--lsd-border-primary));}.lsd-text-field--underlined .lsd-text-field__input-container{border:1px solid transparent;border-bottom:1px solid rgb(var(--lsd-border-primary));}.lsd-text-field__clear-button{padding:0;width:auto;height:auto;margin:0;border:0;}</style><style data-emotion="css-global uhig7c">.lsd-checkbox{position:relative;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:row;-ms-flex-direction:row;flex-direction:row;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;}.lsd-checkbox__input{opacity:0;position:absolute;left:0;top:0;padding:0;margin:0;width:100%;height:100%;}.lsd-checkbox:not(.lsd-checkbox--disabled):hover,.lsd-checkbox:not(.lsd-checkbox--disabled).lsd-checkbox--focused{-webkit-text-decoration:underline;text-decoration:underline;}.lsd-checkbox:not(.lsd-checkbox--disabled) .lsd-checkbox__input{cursor:pointer;}.lsd-checkbox--disabled{opacity:0.34;}.lsd-checkbox__label{margin-left:18px;}.lsd-checkbox--large .lsd-checkbox__label{margin-left:18px;}.lsd-checkbox--medium .lsd-checkbox__label{margin-left:14px;}.lsd-checkbox--small .lsd-checkbox__label{margin-left:12px;}</style><style data-emotion="css-global txommo">.lsd-autocomplete{box-sizing:border-box;}.lsd-autocomplete__label{display:block;}.lsd-autocomplete__input-container{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-box-pack:justify;-webkit-justify-content:space-between;justify-content:space-between;}.lsd-autocomplete--disabled{opacity:0.34;}.lsd-autocomplete__input{border:none;outline:none;font-size:14px;color:rgb(var(--lsd-text-primary));background:none;width:100%;}.lsd-autocomplete__input:hover{outline:none;}.lsd-autocomplete__input::-webkit-input-placeholder{color:rgb(var(--lsd-text-primary));opacity:0.3;}.lsd-autocomplete__input::-moz-placeholder{color:rgb(var(--lsd-text-primary));opacity:0.3;}.lsd-autocomplete__input:-ms-input-placeholder{color:rgb(var(--lsd-text-primary));opacity:0.3;}.lsd-autocomplete__input::placeholder{color:rgb(var(--lsd-text-primary));opacity:0.3;}.lsd-autocomplete__icon{cursor:pointer;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;}.lsd-autocomplete--error{-webkit-text-decoration:line-through;text-decoration:line-through;}.lsd-autocomplete--large{width:208px;}.lsd-autocomplete--large .lsd-autocomplete__label{margin:0 0 6px 18px;}.lsd-autocomplete--large .lsd-autocomplete__input-container{height:40px;}.lsd-autocomplete--large .lsd-autocomplete__input{padding:9px 17px;}.lsd-autocomplete--large .lsd-autocomplete__icon{padding:12px 13px;}.lsd-autocomplete--medium{width:188px;}.lsd-autocomplete--medium .lsd-autocomplete__label{margin:0 0 6px 14px;}.lsd-autocomplete--medium .lsd-autocomplete__input-container{height:32px;}.lsd-autocomplete--medium .lsd-autocomplete__input{padding:5px 13px;}.lsd-autocomplete--medium .lsd-autocomplete__icon{padding:8px 11px;}.lsd-autocomplete--small{width:164px;}.lsd-autocomplete--small .lsd-autocomplete__label{margin:0 0 6px 12px;}.lsd-autocomplete--small .lsd-autocomplete__input-container{height:28px;}.lsd-autocomplete--small .lsd-autocomplete__input{padding:5px 11px;}.lsd-autocomplete--small .lsd-autocomplete__icon{padding:6px 9px;}.lsd-autocomplete--outlined .lsd-autocomplete__input-container{border:1px solid rgb(var(--lsd-border-primary));}.lsd-autocomplete--underlined .lsd-autocomplete__input-container{border:1px solid transparent;border-bottom:1px solid rgb(var(--lsd-border-primary));}.lsd-autocomplete__dropdown-item-placeholder{opacity:0.5;white-space:pre;}</style><style data-emotion="css-global quxxm6">.lsd-quote{color:rgb(var(--lsd-text-primary));white-space:pre-wrap;}.lsd-quote--indented-inline{border-left:1px solid rgb(var(--lsd-border-primary));padding:4px 8px 4px 28px;}.lsd-quote--parentheses{padding:0px;text-align:center;}.lsd-quote--parentheses::before{content:'***';}.lsd-quote--parentheses::after{content:'***';}</style><style data-emotion="css-global a49t4h">.lsd-collapse{box-sizing:border-box;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column;}.lsd-collapse--open .lsd-collapse__content{border-top:1px solid transparent;}.lsd-collapse__content{border:1px solid rgb(var(--lsd-border-primary));}</style><style data-emotion="css-global 12ppw0q">.lsd-collapse-header{box-sizing:border-box;}.lsd-collapse-header:not(.lsd-collapse-header--disabled) .lsd-collapse-header__trigger:hover .lsd-collapse-header__label{-webkit-text-decoration:underline;text-decoration:underline;}.lsd-collapse-header__trigger{width:100%;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:row;-ms-flex-direction:row;flex-direction:row;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:justify;-webkit-justify-content:space-between;justify-content:space-between;cursor:pointer;background:none;border:1px solid rgb(var(--lsd-border-primary));}.lsd-collapse-header__trigger:focus{outline:none;}.lsd-collapse-header__label{cursor:inherit;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;margin:auto;}.lsd-collapse-header__icons{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:row;-ms-flex-direction:row;flex-direction:row;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:end;-ms-flex-pack:end;-webkit-justify-content:flex-end;justify-content:flex-end;}.lsd-collapse-header__icon{margin-right:8px;}.lsd-collapse-header--disabled .lsd-collapse-header__trigger{opacity:0.34;cursor:initial;}.lsd-collapse-header--large .lsd-collapse-header__trigger{width:299px;height:40px;padding:9px 17px;}.lsd-collapse-header--medium .lsd-collapse-header__trigger{width:270px;height:32px;padding:5px 13px;}.lsd-collapse-header--small .lsd-collapse-header__trigger{width:235px;height:28px;padding:5px 11px;}</style><style data-emotion="css-global dixc0i">.lsd-checkbox-group{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column;gap:6px;width:-webkit-fit-content;width:-moz-fit-content;width:fit-content;}.lsd-checkbox-group__label{margin-bottom:6px;}</style><style data-emotion="css-global q2n2hz">.lsd-badge{width:-webkit-fit-content;width:-moz-fit-content;width:fit-content;box-sizing:border-box;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:row;-ms-flex-direction:row;flex-direction:row;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:center;-ms-flex-pack:center;-webkit-justify-content:center;justify-content:center;border:1px solid rgb(var(--lsd-icon-primary));border-radius:20px;}.lsd-badge:hover,.lsd-badge:focus{-webkit-text-decoration:underline;text-decoration:underline;cursor:pointer;}.lsd-badge--large{padding:3px 11px;gap:12px;height:28px;}.lsd-badge--small{padding:3px 7px;gap:8px;height:24px;}.lsd-badge--filled{background-color:rgb(var(--lsd-icon-primary));}.lsd-badge--filled .lsd-badge__label{color:rgb(var(--lsd-text-secondary));}.lsd-badge--filled svg{--lsd-icon-primary:var(--lsd-icon-secondary);}.lsd-badge--outlined{color:rgb(var(--lsd-text-primary));}.lsd-badge--disabled{opacity:0.3;cursor:initial;pointer-events:none;}</style><style data-emotion="css-global rlst54">.lsd-radio-button{position:relative;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:row;-ms-flex-direction:row;flex-direction:row;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;}.lsd-radio-button__input{opacity:0;position:absolute;left:0;top:0;padding:0;margin:0;width:100%;height:100%;}.lsd-radio-button:not(.lsd-radio-button--disabled):hover{-webkit-text-decoration:underline;text-decoration:underline;}.lsd-radio-button:not(.lsd-radio-button--disabled) .lsd-radio-button__input{cursor:pointer;}.lsd-radio-button--disabled{opacity:0.34;}.lsd-radio-button__label{margin-left:18px;}.lsd-radio-button--large .lsd-radio-button__label{margin-left:18px;}.lsd-radio-button--medium .lsd-radio-button__label{margin-left:14px;}.lsd-radio-button--small .lsd-radio-button__label{margin-left:12px;}</style><style data-emotion="css-global mo7h6o">.lsd-radio-button-group{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column;gap:6px;width:-webkit-fit-content;width:-moz-fit-content;width:fit-content;}.lsd-radio-button-group__label{margin-bottom:6px;}</style><style data-emotion="css-global amncrr">.lsd-table{box-sizing:border-box;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column;}.lsd-table>.lsd-table-header{margin-bottom:-1px;}</style><style data-emotion="css-global 1fkbozr">.lsd-table-header{box-sizing:border-box;border:1px solid rgb(var(--lsd-border-primary));}</style><style data-emotion="css-global 1fb1r54">.lsd-table-body table{border-collapse:collapse;text-align:center;table-layout:fixed;width:100%;height:auto;}.lsd-table-body table tr:first-of-type td label:has(input[type='radio']){display:none;}.lsd-table-body__toolbar{box-sizing:border-box;padding:10px;border:1px solid rgb(var(--lsd-border-primary));border-bottom:none;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-box-pack:justify;-webkit-justify-content:space-between;justify-content:space-between;}</style><style data-emotion="css-global 607rj8">.lsd-table-item{border:1px solid rgb(var(--lsd-border-primary));}.lsd-table-item:has(> label){width:40px;}.lsd-table-item:has(> label) input{position:relative;width:14px;height:14px;margin:auto;}.lsd-table-item:has(> label) span{margin-left:14px!important;}.lsd-table-item--large{padding:10px;}.lsd-table-item--medium{padding:6px 8px;}.lsd-table-item--small{padding:6px;}</style><style data-emotion="css-global 1vlh57l">.lsd-table-row{-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;}</style><style data-emotion="css-global 1fw5y3v">.lsd-number-input{width:auto;box-sizing:border-box;}.lsd-number-input__main-container:hover{-webkit-text-decoration:underline;text-decoration:underline;}.lsd-number-input--error .lsd-number-input__main-container{-webkit-text-decoration:line-through;text-decoration:line-through;}.lsd-number-input__label{display:block;}.lsd-number-input__plus-minus-icons{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-shrink:0;-ms-flex-negative:0;flex-shrink:0;}.lsd-number-input__input-container{box-sizing:border-box;border:1px solid rgb(var(--lsd-border-primary));border-left:0px;border-right:0px;}.lsd-number-input__error-icon{cursor:pointer;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;padding:10px 8px;}.lsd-number-input__input-container{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:justify;-webkit-justify-content:space-between;justify-content:space-between;}.lsd-number-input--disabled{opacity:0.34;}.lsd-number-input__main-container{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;}.lsd-number-input__input{border:none;outline:none;font-size:14px;color:rgb(var(--lsd-text-primary));background:none;text-align:center;padding:0 4px;}.lsd-number-input__input::-webkit-inner-spin-button{display:none;-webkit-appearance:none;}.lsd-number-input__input:hover{outline:none;}.lsd-number-input__supporting-text{position:absolute;}.lsd-number-input--large .lsd-number-input__label{margin:0 0 6px 18px;}.lsd-number-input--large .lsd-number-input__input-container{height:40px;}.lsd-number-input--large .lsd-number-input__input{width:62px;}.lsd-number-input--large .lsd-number-input__plus-minus-icons{height:40px;width:40px;}.lsd-number-input--large .lsd-number-input__supporting-text{margin:6px 18px 0 18px;}.lsd-number-input--medium .lsd-number-input__label{margin:0 0 6px 14px;}.lsd-number-input--medium .lsd-number-input__input-container{height:32px;}.lsd-number-input--medium .lsd-number-input__input{width:58px;}.lsd-number-input--medium .lsd-number-input__plus-minus-icons{height:32px;width:32px;}.lsd-number-input--medium .lsd-number-input__supporting-text{margin:6px 14px 0 14px;}.lsd-number-input--small .lsd-number-input__label{margin:0 0 6px 12px;}.lsd-number-input--small .lsd-number-input__input-container{height:28px;}.lsd-number-input--small .lsd-number-input__input{width:50px;}.lsd-number-input--small .lsd-number-input__plus-minus-icons{height:28px;width:28px;}.lsd-number-input--small .lsd-number-input__supporting-text{margin:6px 12px 0 12px;}</style><style data-emotion="css-global 12rmo7o">.lsd-modal{box-sizing:border-box;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column;position:fixed;top:0;left:0;right:0;bottom:0;background-color:rgba(0, 0, 0, 0.5);display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-box-pack:center;-ms-flex-pack:center;-webkit-justify-content:center;justify-content:center;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;z-index:9999;}.lsd-modal__container{position:relative;background:rgb(var(--lsd-surface-primary));padding:20px;max-width:90%;box-sizing:border-box;border:1px solid rgb(var(--lsd-border-primary));}.lsd-modal__header{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-box-pack:justify;-webkit-justify-content:space-between;justify-content:space-between;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;}.lsd-modal__close-icon{position:absolute;top:8px;right:8px;cursor:pointer;}.lsd-modal__title-and-subtitle-container{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column;}.lsd-modal--large .lsd-modal__container{min-width:960px;}.lsd-modal--medium .lsd-modal__container{min-width:768px;}.lsd-modal--small .lsd-modal__container{min-width:614px;}.lsd-modal--extra-small .lsd-modal__container{min-width:490px;}</style><style data-emotion="css-global 1k7gzc">.lsd-modal-footer{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;}</style><style data-emotion="css-global 1b9t8so">.lsd-modal-body{margin:18px 0;}</style><style data-emotion="css-global dyud2a">.lsd-date-picker{width:-webkit-fit-content;width:-moz-fit-content;width:fit-content;}.lsd-date-picker__calendar{border-top:none!important;}.lsd-date-picker--large .lsd-date-field--large{width:318px;}.lsd-date-picker--medium .lsd-date-field--medium{width:290px;}.lsd-date-picker--small .lsd-date-field--small{width:262px;}</style><style data-emotion="css-global olq3nk">.lsd-date-field{width:auto;box-sizing:border-box;}.lsd-date-field__label{display:block;}.lsd-date-field__input-container__icon{position:absolute;right:0;cursor:pointer;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;background-color:rgb(var(--lsd-surface-primary));}.lsd-date-field__input-container__icon:focus{background:blue;background-color:pink;border:1px solid rgb(var(--lsd-border-primary));}.lsd-date-field__input-container__no-icon{position:absolute;right:0;background-color:rgb(var(--lsd-surface-primary));padding:12px;}.lsd-date-field--outlined{border:1px solid rgb(var(--lsd-border-primary));}.lsd-date-field--underlined{border-bottom:1px solid rgb(var(--lsd-border-primary));}.lsd-date-field__input-container{position:relative;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:justify;-webkit-justify-content:space-between;justify-content:space-between;}.lsd-date-field--disabled{opacity:0.34;}.lsd-date-field__input-container__input{border:none;outline:none;font-size:14px;color:rgb(var(--lsd-text-primary));background:none;width:100%;opacity:0.4;-webkit-transition:opacity 0.2s ease-in-out;transition:opacity 0.2s ease-in-out;}.lsd-date-field__input-container__input::-webkit-inner-spin-button,.lsd-date-field__input-container__input::-webkit-calendar-picker-indicator{display:none;-webkit-appearance:none;}.lsd-date-field__input-container__input:hover{outline:none;}.lsd-date-field__supporting-text{position:absolute;}.lsd-date-field--large{width:208px;}.lsd-date-field--large .lsd-date-field__label{margin:0 0 6px 18px;}.lsd-date-field--large .lsd-date-field__input-container{height:40px;}.lsd-date-field--large .lsd-date-field__input-container__input{padding:9px 0px 9px 17px;}.lsd-date-field--large .lsd-date-field__input-container__icon{padding:12px 13px;}.lsd-date-field--large .lsd-date-field__supporting-text{margin:6px 18px 0 18px;}.lsd-date-field--medium{width:188px;}.lsd-date-field--medium .lsd-date-field__label{margin:0 0 6px 14px;}.lsd-date-field--medium .lsd-date-field__input-container{height:32px;}.lsd-date-field--medium .lsd-date-field__input-container__input{padding:5px 11px 5px 13px;}.lsd-date-field--medium .lsd-date-field__input-container__icon{padding:8px 11px;}.lsd-date-field--medium .lsd-date-field__supporting-text{margin:6px 14px 0 14px;}.lsd-date-field--small{width:164px;}.lsd-date-field--small .lsd-date-field__label{margin:0 0 6px 12px;}.lsd-date-field--small .lsd-date-field__input-container{height:28px;}.lsd-date-field--small .lsd-date-field__input-container__input{padding:5px 9px 5px 11px;font-size:12px;}.lsd-date-field--small .lsd-date-field__input-container__icon{padding:6px 9px;}.lsd-date-field--small .lsd-date-field__supporting-text{margin:6px 12px 0 12px;}.lsd-date-field__input-container__input:invalid,.lsd-date-field__input-container__input--filled{color:rgb(var(--lsd-border-primary));opacity:1;}.lsd-date-field--error .lsd-date-field__input-container__input::-webkit-datetime-edit-year-field,.lsd-date-field--error .lsd-date-field__input-container__input::-webkit-datetime-edit-month-field,.lsd-date-field--error .lsd-date-field__input-container__input::-webkit-datetime-edit-day-field{-webkit-text-decoration:line-through;text-decoration:line-through;}@supports not selector(::-webkit-datetime-edit-day-field){.lsd-date-field--error .lsd-date-field__input-container__input{-webkit-text-decoration:line-through;text-decoration:line-through;}}</style><style data-emotion="css-global 1gjtao4">.lsd-calendar{border:1px solid rgb(var(--lsd-border-primary));visibility:hidden;position:absolute!important;top:0;left:0;opacity:0;visibility:hidden;margin:0;padding:0;box-sizing:border-box;background:rgb(var(--lsd-surface-primary));-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;}.lsd-calendar-container{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column;padding:8px;}.lsd-calendar--open{opacity:1;visibility:visible;}.lsd-calendar-header{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-box-pack:center;-ms-flex-pack:center;-webkit-justify-content:center;justify-content:center;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;height:32px;margin-bottom:8px;}.lsd-calendar__week_day{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-box-pack:center;-ms-flex-pack:center;-webkit-justify-content:center;justify-content:center;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;aspect-ratio:1/1;margin-bottom:4px;}.lsd-calendar__change-year{position:relative;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-box-pack:center;-ms-flex-pack:center;-webkit-justify-content:center;justify-content:center;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;padding:2px 0xp 2px 8px;gap:6px;border:1px solid transparent;}.lsd-calendar__change-year--active .lsd-calendar__year-and-icon{border:1px solid rgb(var(--lsd-border-primary));}.lsd-calendar__change-year-icon-container{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-box-pack:center;-ms-flex-pack:center;-webkit-justify-content:center;justify-content:center;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;cursor:pointer;border:none;}.lsd-calendar-month{margin-right:8px;}.lsd-calendar__month-and-year{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:center;-ms-flex-pack:center;-webkit-justify-content:center;justify-content:center;}.lsd-calendar-day__container{cursor:pointer;background:transparent;position:relative;box-sizing:border-box;border:1px solid transparent;}.lsd-calendar-day{aspect-ratio:1/1;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-box-pack:center;-ms-flex-pack:center;-webkit-justify-content:center;justify-content:center;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;}.lsd-calendar-day:hover{cursor:pointer;-webkit-text-decoration:underline;text-decoration:underline;text-decoration-color:rgb(var(--lsd-border-primary));}.lsd-calendar-day label:hover{cursor:pointer;}.lsd-calendar-day--selected{border:1px solid rgb(var(--lsd-border-primary));}.lsd-calendar-day--disabled{opacity:0.3;cursor:default;}.lsd-calendar-day__today_indicator{position:absolute;left:50%;-webkit-transform:translateX(-50%);-moz-transform:translateX(-50%);-ms-transform:translateX(-50%);transform:translateX(-50%);bottom:2px;}.lsd-calendar--disabled{pointer-events:none;border:1px solid rgba(var(--lsd-border-primary), 0.3);}.lsd-calendar--disabled label{opacity:0.3;}.lsd-calendar--disabled .lsd-calendar__button{opacity:0.3;}.lsd-calendar--disabled .lsd-calendar-day--selected{opacity:0.3;}.lsd-calendar__button{border:1px solid rgb(var(--lsd-border-primary));cursor:pointer;background:transparent;width:32px;height:32px;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:center;-ms-flex-pack:center;-webkit-justify-content:center;justify-content:center;position:absolute;}.lsd-calendar__next-month-button{top:8px;right:8px;}.lsd-calendar__previous-month-button{top:8px;left:8px;}.lsd-calendar-day--border-left{border-left:1px double rgb(var(--lsd-border-primary));}.lsd-calendar-day--border-right{border-right:1px double rgb(var(--lsd-border-primary));}.lsd-calendar-day--border-left-and-right{border-left:1px double rgb(var(--lsd-border-primary));border-right:1px double rgb(var(--lsd-border-primary));}.lsd-calendar-day--border-top-and-bottom{border-top:1px double rgb(var(--lsd-border-primary));border-bottom:1px double rgb(var(--lsd-border-primary));}.lsd-calendar__month-table{border-collapse:collapse;}.lsd-calendar__year-dropdown{box-sizing:border-box;position:absolute;top:100%;left:0;max-height:200px;overflow-y:auto;width:100%;border:1px solid rgb(var(--lsd-border-primary));border-top:none;z-index:1;}.lsd-calendar__year-dropdown .lsd-calendar-year{border-bottom:1px solid rgb(var(--lsd-border-primary));}.lsd-calendar__year-dropdown--hidden{visibility:hidden;}.lsd-calendar-year{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;cursor:pointer;-webkit-transition:background-color 0.2s;transition:background-color 0.2s;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;background:rgb(var(--lsd-surface-primary));}.lsd-calendar-year:hover{-webkit-text-decoration:underline;text-decoration:underline;}.lsd-calendar__year-and-icon{border:1px solid rgb(var(--lsd-border-primary));}.lsd-calendar--large .lsd-calendar-year{padding:6px 0px 6px 14px;}.lsd-calendar--large .lsd-calendar__change-year-icon-container{width:32px;}.lsd-calendar--medium .lsd-calendar-year{padding:6px 0px 6px 12px;}.lsd-calendar--medium .lsd-calendar__change-year-icon-container{width:28px;}.lsd-calendar--small .lsd-calendar-year{padding:6px 0px 6px 12px;}.lsd-calendar--small .lsd-calendar__change-year-icon-container{width:28px;}</style><style data-emotion="css-global dlrd7d">.lsd-toast{box-sizing:border-box;display:-webkit-inline-box;display:-webkit-inline-flex;display:-ms-inline-flexbox;display:inline-flex;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;background:rgb(var(--lsd-surface-primary));border:1px solid rgb(var(--lsd-border-primary));padding:8px;height:-webkit-fit-content;height:-moz-fit-content;height:fit-content;}.lsd-toast__inline-button-container{-webkit-flex-shrink:0;-ms-flex-negative:0;flex-shrink:0;}.lsd-toast__column-button-container{margin-top:18px;margin-bottom:6px;}.lsd-toast__inline-container{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:justify;-webkit-justify-content:space-between;justify-content:space-between;-webkit-box-flex:1;-webkit-flex-grow:1;-ms-flex-positive:1;flex-grow:1;}.lsd-toast__column-container{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column;-webkit-box-pack:justify;-webkit-justify-content:space-between;justify-content:space-between;}.lsd-toast__text-container{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column;color:rgb(var(--lsd-text-secondary));padding-left:12px;}.lsd-toast__title{position:relative;}.lsd-toast__information{margin-top:4px;}.lsd-toast__button-container{min-height:28px;min-width:60px;width:-webkit-fit-content;width:-moz-fit-content;width:fit-content;padding:0px 12px;}.lsd-toast__close-button{margin-bottom:auto;-webkit-flex-shrink:0;-ms-flex-negative:0;flex-shrink:0;height:28px;width:28px;margin-left:auto;}.lsd-toast__column-icon-container{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-box-pack:center;-ms-flex-pack:center;-webkit-justify-content:center;justify-content:center;margin-bottom:auto;position:relative;top:4px;padding-left:4px;}.lsd-toast__inline-icon-container{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:center;-ms-flex-pack:center;-webkit-justify-content:center;justify-content:center;padding-left:4px;}.lsd-toast__icon{position:relative;}.lsd-toast--large{width:364px;}.lsd-toast--medium{width:336px;}.lsd-toast--small{width:296px;}.lsd-toast--small .lsd-toast__icon{top:0px;}</style><style data-emotion="css-global 5wlfwk">.lsd-toast-provider__toast-container{position:fixed;-webkit-transition:all 230ms cubic-bezier(0.21, 1.02, 0.73, 1);transition:all 230ms cubic-bezier(0.21, 1.02, 0.73, 1);z-index:9999;}.lsd-toast-provider__toast--top-left,.lsd-toast-provider__toast--top-center,.lsd-toast-provider__toast--top-right{top:0;}.lsd-toast-provider__toast--bottom-left,.lsd-toast-provider__toast--bottom-center,.lsd-toast-provider__toast--bottom-right{bottom:0;}.lsd-toast-provider__toast--top-center,.lsd-toast-provider__toast--bottom-center{left:50%;}.lsd-toast-provider__toast--top-right,.lsd-toast-provider__toast--bottom-right{right:0;}</style><style data-emotion="css-global 9yw6e1">.lsd-button-group{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:row;-ms-flex-direction:row;flex-direction:row;}.lsd-button-group >*:not(:last-child).lsd-button--outlined,.lsd-button-group >*:not(:last-child) .lsd-button--outlined{border-right:none;}</style><style data-emotion="css-global 17u9w7w">.lsd-date-range-picker{box-sizing:border-box;}.lsd-date-range-picker .lsd-date-field--outlined{border:none;}.lsd-date-range-picker .lsd-date-field__input-container__icon{padding:8px;}.lsd-date-range-picker__label{display:block;}.lsd-date-range-picker__input-container{box-sizing:border-box;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;border:1px solid transparent;}.lsd-date-picker__calendar{border-top:none!important;}.lsd-date-picker__calendar .lsd-tooltip-base__arrow-tip{-webkit-transition:left 0.2s ease-in-out;transition:left 0.2s ease-in-out;}.lsd-date-range-picker--calendar-open .lsd-date-range-picker__input-container{border-bottom:1px solid rgb(var(--lsd-border-primary));}.lsd-date-range-picker__icon{cursor:pointer;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:center;-ms-flex-pack:center;-webkit-justify-content:center;justify-content:center;-webkit-box-flex:1;-webkit-flex-grow:1;-ms-flex-positive:1;flex-grow:1;padding:0 10px;}.lsd-date-range-picker--disabled{opacity:0.3;}.lsd-date-range-picker__supporting-text{position:absolute;}.lsd-date-range-picker--large{width:318px;}.lsd-date-range-picker--large .lsd-date-field--large{width:156px;}.lsd-date-range-picker--large .lsd-date-field__input-container__input{padding-right:0;}.lsd-date-range-picker--large .lsd-date-field__input-container__icon{padding:11px 12px;}.lsd-date-range-picker--large .lsd-date-range-picker__label{margin:0 0 6px 18px;}.lsd-date-range-picker--large .lsd-date-range-picker__input-container{height:40px;}.lsd-date-range-picker--large .lsd-date-range-picker__supporting-text{margin:6px 18px 0 18px;}.lsd-date-range-picker--medium{width:290px;}.lsd-date-range-picker--medium .lsd-date-field--medium{width:142px;}.lsd-date-range-picker--medium .lsd-date-field__input-container__input{padding-right:0;}.lsd-date-range-picker--medium .lsd-date-field__input-container__icon{padding:7px 8px;}.lsd-date-range-picker--medium .lsd-date-range-picker__label{margin:0 0 6px 14px;}.lsd-date-range-picker--medium .lsd-date-range-picker__input-container{height:32px;}.lsd-date-range-picker--medium .lsd-date-range-picker__supporting-text{margin:6px 14px 0 14px;}.lsd-date-range-picker--small{width:262px;}.lsd-date-range-picker--small .lsd-date-field--small{width:128px;}.lsd-date-range-picker--small .lsd-date-field__input-container__input{padding-right:0;}.lsd-date-range-picker--small .lsd-date-field__input-container__icon{padding:5px 7px;}.lsd-date-range-picker--small .lsd-date-range-picker__label{margin:0 0 6px 12px;}.lsd-date-range-picker--small .lsd-date-range-picker__input-container{height:28px;}.lsd-date-range-picker--small .lsd-date-range-picker__supporting-text{margin:6px 12px 0 12px;}.lsd-date-range-picker__separator{margin-left:3px;width:1px;height:100%;}.lsd-date-range-picker__separator{border-left:1px solid transparent;}.lsd-date-range-picker--outlined{border:1px solid rgb(var(--lsd-border-primary));}.lsd-date-range-picker--outlined .lsd-date-range-picker__separator{border-left:1px solid rgb(var(--lsd-border-primary));}</style><style data-emotion="css-global 19d282h">.lsd-tooltip-base{border:1px solid rgb(var(--lsd-border-primary));position:relative;}.lsd-tooltip-base__arrow-tip{border:1px solid rgb(var(--lsd-border-primary));position:absolute;background:rgb(var(--lsd-surface-primary));}.lsd-tooltip-base__content{background:rgb(var(--lsd-surface-primary));width:100%;height:100%;position:relative;z-index:1;}</style><style data-emotion="css-global 1o77wkp">[data-theme=dark]{--lsd-display1-fontSize:5.5rem;--lsd-display1-fontWeight:normal;--lsd-display1-lineHeight:6rem;--lsd-display2-fontSize:4rem;--lsd-display2-fontWeight:normal;--lsd-display2-lineHeight:4.5rem;--lsd-display3-fontSize:3.5rem;--lsd-display3-fontWeight:normal;--lsd-display3-lineHeight:4rem;--lsd-display4-fontSize:3rem;--lsd-display4-fontWeight:normal;--lsd-display4-lineHeight:3.5rem;--lsd-h1-fontSize:2.5rem;--lsd-h1-fontWeight:normal;--lsd-h1-lineHeight:3rem;--lsd-h2-fontSize:2rem;--lsd-h2-fontWeight:normal;--lsd-h2-lineHeight:2.5rem;--lsd-h3-fontSize:1.75rem;--lsd-h3-fontWeight:normal;--lsd-h3-lineHeight:2.25rem;--lsd-h4-fontSize:1.5rem;--lsd-h4-fontWeight:normal;--lsd-h4-lineHeight:2rem;--lsd-h5-fontSize:1.25rem;--lsd-h5-fontWeight:normal;--lsd-h5-lineHeight:1.75rem;--lsd-h6-fontSize:1rem;--lsd-h6-fontWeight:normal;--lsd-h6-lineHeight:1.5rem;--lsd-subtitle1-fontSize:1.125rem;--lsd-subtitle1-fontWeight:normal;--lsd-subtitle1-lineHeight:1.5rem;--lsd-subtitle2-fontSize:1rem;--lsd-subtitle2-fontWeight:normal;--lsd-subtitle2-lineHeight:1.5rem;--lsd-subtitle3-fontSize:0.875rem;--lsd-subtitle3-fontWeight:normal;--lsd-subtitle3-lineHeight:1.25rem;--lsd-subtitle4-fontSize:0.75rem;--lsd-subtitle4-fontWeight:normal;--lsd-subtitle4-lineHeight:1rem;--lsd-body1-fontSize:1rem;--lsd-body1-fontWeight:normal;--lsd-body1-lineHeight:1.5rem;--lsd-body2-fontSize:0.875rem;--lsd-body2-fontWeight:normal;--lsd-body2-lineHeight:1.25rem;--lsd-body3-fontSize:0.75rem;--lsd-body3-fontWeight:normal;--lsd-body3-lineHeight:1rem;--lsd-label1-fontSize:0.875rem;--lsd-label1-fontWeight:normal;--lsd-label1-lineHeight:1.25rem;--lsd-label2-fontSize:0.75rem;--lsd-label2-fontWeight:normal;--lsd-label2-lineHeight:1rem;--lsd-typography-generic-font-family:sans-serif;--lsd-theme-primary:255,255,255;--lsd-theme-secondary:0,0,0;--lsd-surface-primary:0,0,0;--lsd-surface-secondary:255,255,255;--lsd-border-primary:255,255,255;--lsd-border-secondary:0,0,0;--lsd-icon-primary:255,255,255;--lsd-icon-secondary:0,0,0;--lsd-text-primary:255,255,255;--lsd-text-secondary:0,0,0;--lsd-text-tertiary:255,255,255,0.34;--lsd-spacing-4:4px;--lsd-spacing-8:8px;--lsd-spacing-16:16px;--lsd-spacing-24:24px;--lsd-spacing-32:32px;--lsd-spacing-40:40px;--lsd-spacing-64:64px;--lsd-spacing-80:80px;--lsd-spacing-96:96px;--lsd-spacing-120:120px;}</style><style data-emotion="css-global yon3n1">[data-theme=light]{--lsd-display1-fontSize:5.5rem;--lsd-display1-fontWeight:normal;--lsd-display1-lineHeight:6rem;--lsd-display2-fontSize:4rem;--lsd-display2-fontWeight:normal;--lsd-display2-lineHeight:4.5rem;--lsd-display3-fontSize:3.5rem;--lsd-display3-fontWeight:normal;--lsd-display3-lineHeight:4rem;--lsd-display4-fontSize:3rem;--lsd-display4-fontWeight:normal;--lsd-display4-lineHeight:3.5rem;--lsd-h1-fontSize:2.5rem;--lsd-h1-fontWeight:normal;--lsd-h1-lineHeight:3rem;--lsd-h2-fontSize:2rem;--lsd-h2-fontWeight:normal;--lsd-h2-lineHeight:2.5rem;--lsd-h3-fontSize:1.75rem;--lsd-h3-fontWeight:normal;--lsd-h3-lineHeight:2.25rem;--lsd-h4-fontSize:1.5rem;--lsd-h4-fontWeight:normal;--lsd-h4-lineHeight:2rem;--lsd-h5-fontSize:1.25rem;--lsd-h5-fontWeight:normal;--lsd-h5-lineHeight:1.75rem;--lsd-h6-fontSize:1rem;--lsd-h6-fontWeight:normal;--lsd-h6-lineHeight:1.5rem;--lsd-subtitle1-fontSize:1.125rem;--lsd-subtitle1-fontWeight:normal;--lsd-subtitle1-lineHeight:1.5rem;--lsd-subtitle2-fontSize:1rem;--lsd-subtitle2-fontWeight:normal;--lsd-subtitle2-lineHeight:1.5rem;--lsd-subtitle3-fontSize:0.875rem;--lsd-subtitle3-fontWeight:normal;--lsd-subtitle3-lineHeight:1.25rem;--lsd-subtitle4-fontSize:0.75rem;--lsd-subtitle4-fontWeight:normal;--lsd-subtitle4-lineHeight:1rem;--lsd-body1-fontSize:1rem;--lsd-body1-fontWeight:normal;--lsd-body1-lineHeight:1.5rem;--lsd-body2-fontSize:0.875rem;--lsd-body2-fontWeight:normal;--lsd-body2-lineHeight:1.25rem;--lsd-body3-fontSize:0.75rem;--lsd-body3-fontWeight:normal;--lsd-body3-lineHeight:1rem;--lsd-label1-fontSize:0.875rem;--lsd-label1-fontWeight:normal;--lsd-label1-lineHeight:1.25rem;--lsd-label2-fontSize:0.75rem;--lsd-label2-fontWeight:normal;--lsd-label2-lineHeight:1rem;--lsd-typography-generic-font-family:sans-serif;--lsd-theme-primary:0,0,0;--lsd-theme-secondary:255,255,255;--lsd-surface-primary:255,255,255;--lsd-surface-secondary:0,0,0;--lsd-border-primary:0,0,0;--lsd-border-secondary:255,255,255;--lsd-icon-primary:0,0,0;--lsd-icon-secondary:255,255,255;--lsd-text-primary:0,0,0;--lsd-text-secondary:255,255,255;--lsd-text-tertiary:0,0,0,0.34;--lsd-spacing-4:4px;--lsd-spacing-8:8px;--lsd-spacing-16:16px;--lsd-spacing-24:24px;--lsd-spacing-32:32px;--lsd-spacing-40:40px;--lsd-spacing-64:64px;--lsd-spacing-80:80px;--lsd-spacing-96:96px;--lsd-spacing-120:120px;}</style><div class="root_QACb"><div role="region" aria-label="Skip to main content"><a class="skipToContent_fXgn" href="#__docusaurus_skipToContent_fallback">Skip to main content</a></div><nav aria-label="Main" class="navbar navbar--fixed-top navbarHideable_OoEf"><div class="navbar__inner"><div class="navbar__left"><a class="navbar__brand" href="/"><div class="navbar__logo"><img src="/theme/image/logo.svg" alt="Vac Research" class="themedImage_ToTc themedImage--light_HNdA" height="26"><img src="/theme/image/logo.svg" alt="Vac Research" class="themedImage_ToTc themedImage--dark_i4oU" height="26"></div><b class="navbar__title text--truncate"></b></a></div><div class="navbar__left-items"><a class="navbar__item navbar__link" href="/"><div class="lsd-typography lsd-typography--body2 linkContent__x3v">About Vac</div></a><a class="navbar__item navbar__link" href="/community"><div class="lsd-typography lsd-typography--body2 linkContent__x3v">Community</div></a><a class="navbar__item navbar__link" href="/rlog"><div class="lsd-typography lsd-typography--body2 linkContent__x3v">Research Blog</div></a><a class="navbar__item navbar__link" href="/join-us"><div class="lsd-typography lsd-typography--body2 linkContent__x3v">Join Us</div></a></div><div class="navbar__right-items"><div class="iconButtonGroup_ktNv lsd-icon-button-group lsd-icon-button-group--medium lsd-icon-button-group--outlined"><button class="clean-btn toggle_K23S colorModeToggle_GSaI navbar__color-mode-toggle toggleButtonDisabled_AAS_ lsd-icon-button lsd-icon-button--medium lsd-icon-button--outlined lsd-icon-button--disabled" type="button" title="Switch between dark and light mode (currently dark mode)" aria-label="Switch between dark and light mode (currently dark mode)" aria-live="polite"><svg viewBox="0 0 24 24" width="24" height="24" class="lightToggleIcon_K4TL"><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"></path></svg><svg viewBox="0 0 24 24" width="24" height="24" class="darkToggleIcon_lKkA"><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"></path></svg></button><button aria-label="Toggle navigation bar" aria-expanded="false" class="navbar__toggle clean-btn" type="button"><svg width="30" height="30" viewBox="0 0 30 30" aria-hidden="true"><path stroke="currentColor" stroke-linecap="round" stroke-miterlimit="10" stroke-width="2" d="M4 7h22M4 15h22M4 23h22"></path></svg></button></div></div></div><div role="presentation" class="navbar-sidebar__backdrop"></div></nav><div id="__docusaurus_skipToContent_fallback" class="main-wrapper mainWrapper_z2l0 docsWrapper_BCFX"><button aria-label="Scroll back to top" class="clean-btn theme-back-to-top-button backToTopButton_sjWU" type="button"></button><div class="docPage__5DB"><main class="docMainContainer_gTbr docMainContainerEnhanced_Uz_u"><div class="container padding-top--md padding-bottom--lg"><div class="row docItemGrid_SzoZ"><div class="docItemCol_F52z"><div class="docItemContainer_hrrU"><article><div class="theme-doc-markdown markdown"><h1>Publications</h1><h2 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="papers">Papers<a href="#papers" class="hash-link" aria-label="Direct link to Papers" title="Direct link to Papers">​</a></h2><ul><li><p><a href="https://arxiv.org/abs/2207.00038" target="_blank" rel="noopener noreferrer">Waku: A Family of Modular P2P Protocols For Secure & Censorship-Resistant Communication</a> (demo)</p></li><li><p><a href="https://arxiv.org/pdf/2207.00117.pdf" target="_blank" rel="noopener noreferrer">WAKU-RLN-RELAY: Privacy-Preserving Peer-to-Peer Economic Spam Protection</a> (full)</p></li><li><p><a href="https://arxiv.org/abs/2207.00116" target="_blank" rel="noopener noreferrer">Privacy-Preserving Spam-Protected Gossip-Based Routing</a> (poster)</p></li></ul><h2 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="write-ups">Write-ups<a href="#write-ups" class="hash-link" aria-label="Direct link to Write-ups" title="Direct link to Write-ups">​</a></h2><p>See <a href="/rlog">write-ups</a>.</p></div></article><nav class="pagination-nav docusaurus-mt-lg" aria-label="Docs pages"></nav></div></div><div class="gap1_XuuQ"></div></div></div></main></div></div><footer class="footer"><div class="container container-fluid firstRow_ar1q"><div class="footer__bottom text--center"><div class="margin-bottom--sm"><a class="footerLogoLink_BH7S" href="/"><img src="/theme/image/logo.svg" alt="Vac Research" class="themedImage_ToTc themedImage--light_HNdA footer__logo" width="22"><img src="/theme/image/logo.svg" alt="Vac Research" class="themedImage_ToTc themedImage--dark_i4oU footer__logo" width="22"></a></div><div class="footer__copyright">Vac Research © 2024<br>All rights reserved.</div></div><div class="row footer__links"><div class="col footer__col"><div class="footer__title"></div><ul class="footer__items clean-list"><li class="footer__item"><a href="https://twitter.com/vacp2p" target="_blank" rel="noopener noreferrer" class="footer__link-item">Twitter<svg width="13.5" height="13.5" aria-hidden="true" viewBox="0 0 24 24" class="iconExternalLink_nPIU"><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"></path></svg></a></li><li class="footer__item"><a href="https://discord.gg/PQFdubGt6d" target="_blank" rel="noopener noreferrer" class="footer__link-item">Discord<svg width="13.5" height="13.5" aria-hidden="true" viewBox="0 0 24 24" class="iconExternalLink_nPIU"><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"></path></svg></a></li><li class="footer__item"><a href="https://github.com/vacp2p" target="_blank" rel="noopener noreferrer" class="footer__link-item">Github<svg width="13.5" height="13.5" aria-hidden="true" viewBox="0 0 24 24" class="iconExternalLink_nPIU"><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"></path></svg></a></li></ul></div><div class="col footer__col"><div class="footer__title"></div><ul class="footer__items clean-list"><li class="footer__item"><a href="https://jobs.status.im/" target="_blank" rel="noopener noreferrer" class="footer__link-item">Work With Us<svg width="13.5" height="13.5" aria-hidden="true" viewBox="0 0 24 24" class="iconExternalLink_nPIU"><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"></path></svg></a></li><li class="footer__item"><a class="footer__link-item" href="/terms">Terms & Conditions</a></li><li class="footer__item"><a class="footer__link-item" href="/privacy-policy">Privacy Policy</a></li><li class="footer__item"><a class="footer__link-item" href="/security">Security</a></li></ul></div></div></div><div class="secondRow__ww3"><div class="footer__bottom text--center">Logos Collective</div><div class="row footer__links"><div class="col footer__col"><div class="footer__title">Research</div><ul class="footer__items clean-list"><li class="footer__item"><a href="https://vac.dev" target="_blank" rel="noopener noreferrer" class="footer__link-item">VacP2P<svg width="13.5" height="13.5" aria-hidden="true" viewBox="0 0 24 24" class="iconExternalLink_nPIU"><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"></path></svg></a></li><li class="footer__item"><a href="https://afaik.institute" target="_blank" rel="noopener noreferrer" class="footer__link-item">AFAIK<svg width="13.5" height="13.5" aria-hidden="true" viewBox="0 0 24 24" class="iconExternalLink_nPIU"><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"></path></svg></a></li></ul></div><div class="col footer__col"><div class="footer__title">Infrastructure</div><ul class="footer__items clean-list"><li class="footer__item"><a href="https://waku.org/" target="_blank" rel="noopener noreferrer" class="footer__link-item">Waku<svg width="13.5" height="13.5" aria-hidden="true" viewBox="0 0 24 24" class="iconExternalLink_nPIU"><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"></path></svg></a></li><li class="footer__item"><a href="https://nimbus.team/" target="_blank" rel="noopener noreferrer" class="footer__link-item">Nimbus<svg width="13.5" height="13.5" aria-hidden="true" viewBox="0 0 24 24" class="iconExternalLink_nPIU"><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"></path></svg></a></li><li class="footer__item"><a href="https://codex.storage" target="_blank" rel="noopener noreferrer" class="footer__link-item">Codex<svg width="13.5" height="13.5" aria-hidden="true" viewBox="0 0 24 24" class="iconExternalLink_nPIU"><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"></path></svg></a></li><li class="footer__item"><a href="https://nomos.tech" target="_blank" rel="noopener noreferrer" class="footer__link-item">Nomos<svg width="13.5" height="13.5" aria-hidden="true" viewBox="0 0 24 24" class="iconExternalLink_nPIU"><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"></path></svg></a></li></ul></div><div class="col footer__col"><div class="footer__title">Creative Studio</div><ul class="footer__items clean-list"><li class="footer__item"><a href="https://acid.info" target="_blank" rel="noopener noreferrer" class="footer__link-item">Acid.info<svg width="13.5" height="13.5" aria-hidden="true" viewBox="0 0 24 24" class="iconExternalLink_nPIU"><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"></path></svg></a></li></ul></div><div class="col footer__col"><div class="footer__title">Movement</div><ul class="footer__items clean-list"><li class="footer__item"><a href="https://logos.co" target="_blank" rel="noopener noreferrer" class="footer__link-item">Logos<svg width="13.5" height="13.5" aria-hidden="true" viewBox="0 0 24 24" class="iconExternalLink_nPIU"><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"></path></svg></a></li></ul></div><div class="col footer__col"><div class="footer__title">User-facing products</div><ul class="footer__items clean-list"><li class="footer__item"><a href="https://status.im" target="_blank" rel="noopener noreferrer" class="footer__link-item">Status<svg width="13.5" height="13.5" aria-hidden="true" viewBox="0 0 24 24" class="iconExternalLink_nPIU"><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"></path></svg></a></li><li class="footer__item"><a href="https://keycard.tech" target="_blank" rel="noopener noreferrer" class="footer__link-item">Keycard<svg width="13.5" height="13.5" aria-hidden="true" viewBox="0 0 24 24" class="iconExternalLink_nPIU"><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"></path></svg></a></li></ul></div></div></div><button class="backToTop_wDfN lsd-button lsd-button--small lsd-button--outlined"><span class="lsd-typography lsd-typography--label2 lsd-button__text">Back to top ↑</span></button></footer></div></div> -<script src="/assets/js/runtime~main.556fa6f5.js"></script> -<script src="/assets/js/main.ffc20c94.js"></script> +<script src="/assets/js/runtime~main.a9103199.js"></script> +<script src="/assets/js/main.5454aec3.js"></script> </body> </html> \ No newline at end of file diff --git a/rfcprocess/index.html b/rfcprocess/index.html index af2eaca2..f9c0cacf 100644 --- a/rfcprocess/index.html +++ b/rfcprocess/index.html @@ -10,8 +10,8 @@ <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/katex@0.13.24/dist/katex.min.css" integrity="sha384-odtC+0UGzzFL/6PNoE8rX/SPcQDXBJ+uRepguP4QkPCm2LBxH3FA3y+fKSiJ+AmM" crossorigin="anonymous"><link rel="stylesheet" href="/assets/css/styles.08d697e6.css"> -<link rel="preload" href="/assets/js/runtime~main.556fa6f5.js" as="script"> -<link rel="preload" href="/assets/js/main.ffc20c94.js" as="script"> +<link rel="preload" href="/assets/js/runtime~main.a9103199.js" as="script"> +<link rel="preload" href="/assets/js/main.5454aec3.js" as="script"> <meta property="og:image" content="https://vac.dev/_og/25a9021010dcf8acedf95d00db7c92121f695cc1.png"><meta name="twitter:image" content="https://vac.dev/_og/25a9021010dcf8acedf95d00db7c92121f695cc1.png"></head> <body class="navigation-with-keyboard"> <script>!function(){function e(e){document.documentElement.setAttribute("data-theme",e)}var t=function(){var e=null;try{e=new URLSearchParams(window.location.search).get("docusaurus-theme")}catch(e){}return e}()||function(){var e=null;try{e=localStorage.getItem("theme")}catch(e){}return e}();null!==t?e(t):window.matchMedia("(prefers-color-scheme: dark)").matches?e("dark"):window.matchMedia("(prefers-color-scheme: light)").matches?e("light"):e("dark")}()</script><div id="__docusaurus"> @@ -23,7 +23,7 @@ taking on the responsibility of shepherding and editing <a href="https://rfc.vac.dev/" target="_blank" rel="noopener noreferrer">specifications</a> for Logos projects and Vac incubator projects. By meticulously crafting and overseeing these specifications, the Vac RFC unit acts as a linchpin for ensuring standardised and interoperable protocols within the Logos ecosystem. Their expertise and attention to detail contribute to a cohesive and collaborative environment, facilitating seamless integration and advancement of decentralised technologies throughout the Logos collective and beyond.</p></div></article><nav class="pagination-nav docusaurus-mt-lg" aria-label="Docs pages"></nav></div></div><div class="gap1_XuuQ"></div></div></div></main></div></div><footer class="footer"><div class="container container-fluid firstRow_ar1q"><div class="footer__bottom text--center"><div class="margin-bottom--sm"><a class="footerLogoLink_BH7S" href="/"><img src="/theme/image/logo.svg" alt="Vac Research" class="themedImage_ToTc themedImage--light_HNdA footer__logo" width="22"><img src="/theme/image/logo.svg" alt="Vac Research" class="themedImage_ToTc themedImage--dark_i4oU footer__logo" width="22"></a></div><div class="footer__copyright">Vac Research © 2024<br>All rights reserved.</div></div><div class="row footer__links"><div class="col footer__col"><div class="footer__title"></div><ul class="footer__items clean-list"><li class="footer__item"><a href="https://twitter.com/vacp2p" target="_blank" rel="noopener noreferrer" class="footer__link-item">Twitter<svg width="13.5" height="13.5" aria-hidden="true" viewBox="0 0 24 24" class="iconExternalLink_nPIU"><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"></path></svg></a></li><li class="footer__item"><a href="https://discord.gg/PQFdubGt6d" target="_blank" rel="noopener noreferrer" class="footer__link-item">Discord<svg width="13.5" height="13.5" aria-hidden="true" viewBox="0 0 24 24" class="iconExternalLink_nPIU"><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"></path></svg></a></li><li class="footer__item"><a href="https://github.com/vacp2p" target="_blank" rel="noopener noreferrer" class="footer__link-item">Github<svg width="13.5" height="13.5" aria-hidden="true" viewBox="0 0 24 24" class="iconExternalLink_nPIU"><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"></path></svg></a></li></ul></div><div class="col footer__col"><div class="footer__title"></div><ul class="footer__items clean-list"><li class="footer__item"><a href="https://jobs.status.im/" target="_blank" rel="noopener noreferrer" class="footer__link-item">Work With Us<svg width="13.5" height="13.5" aria-hidden="true" viewBox="0 0 24 24" class="iconExternalLink_nPIU"><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"></path></svg></a></li><li class="footer__item"><a class="footer__link-item" href="/terms">Terms & Conditions</a></li><li class="footer__item"><a class="footer__link-item" href="/privacy-policy">Privacy Policy</a></li><li class="footer__item"><a class="footer__link-item" href="/security">Security</a></li></ul></div></div></div><div class="secondRow__ww3"><div class="footer__bottom text--center">Logos Collective</div><div class="row footer__links"><div class="col footer__col"><div class="footer__title">Research</div><ul class="footer__items clean-list"><li class="footer__item"><a href="https://vac.dev" target="_blank" rel="noopener noreferrer" class="footer__link-item">VacP2P<svg width="13.5" height="13.5" aria-hidden="true" viewBox="0 0 24 24" class="iconExternalLink_nPIU"><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"></path></svg></a></li><li class="footer__item"><a href="https://afaik.institute" target="_blank" rel="noopener noreferrer" class="footer__link-item">AFAIK<svg width="13.5" height="13.5" aria-hidden="true" viewBox="0 0 24 24" class="iconExternalLink_nPIU"><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"></path></svg></a></li></ul></div><div class="col footer__col"><div class="footer__title">Infrastructure</div><ul class="footer__items clean-list"><li class="footer__item"><a href="https://waku.org/" target="_blank" rel="noopener noreferrer" class="footer__link-item">Waku<svg width="13.5" height="13.5" aria-hidden="true" viewBox="0 0 24 24" class="iconExternalLink_nPIU"><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"></path></svg></a></li><li class="footer__item"><a href="https://nimbus.team/" target="_blank" rel="noopener noreferrer" class="footer__link-item">Nimbus<svg width="13.5" height="13.5" aria-hidden="true" viewBox="0 0 24 24" class="iconExternalLink_nPIU"><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"></path></svg></a></li><li class="footer__item"><a href="https://codex.storage" target="_blank" rel="noopener noreferrer" class="footer__link-item">Codex<svg width="13.5" height="13.5" aria-hidden="true" viewBox="0 0 24 24" class="iconExternalLink_nPIU"><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"></path></svg></a></li><li class="footer__item"><a href="https://nomos.tech" target="_blank" rel="noopener noreferrer" class="footer__link-item">Nomos<svg width="13.5" height="13.5" aria-hidden="true" viewBox="0 0 24 24" class="iconExternalLink_nPIU"><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"></path></svg></a></li></ul></div><div class="col footer__col"><div class="footer__title">Creative Studio</div><ul class="footer__items clean-list"><li class="footer__item"><a href="https://acid.info" target="_blank" rel="noopener noreferrer" class="footer__link-item">Acid.info<svg width="13.5" height="13.5" aria-hidden="true" viewBox="0 0 24 24" class="iconExternalLink_nPIU"><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"></path></svg></a></li></ul></div><div class="col footer__col"><div class="footer__title">Movement</div><ul class="footer__items clean-list"><li class="footer__item"><a href="https://logos.co" target="_blank" rel="noopener noreferrer" class="footer__link-item">Logos<svg width="13.5" height="13.5" aria-hidden="true" viewBox="0 0 24 24" class="iconExternalLink_nPIU"><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"></path></svg></a></li></ul></div><div class="col footer__col"><div class="footer__title">User-facing products</div><ul class="footer__items clean-list"><li class="footer__item"><a href="https://status.im" target="_blank" rel="noopener noreferrer" class="footer__link-item">Status<svg width="13.5" height="13.5" aria-hidden="true" viewBox="0 0 24 24" class="iconExternalLink_nPIU"><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"></path></svg></a></li><li class="footer__item"><a href="https://keycard.tech" target="_blank" rel="noopener noreferrer" class="footer__link-item">Keycard<svg width="13.5" height="13.5" aria-hidden="true" viewBox="0 0 24 24" class="iconExternalLink_nPIU"><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"></path></svg></a></li></ul></div></div></div><button class="backToTop_wDfN lsd-button lsd-button--small lsd-button--outlined"><span class="lsd-typography lsd-typography--label2 lsd-button__text">Back to top ↑</span></button></footer></div></div> -<script src="/assets/js/runtime~main.556fa6f5.js"></script> -<script src="/assets/js/main.ffc20c94.js"></script> +<script src="/assets/js/runtime~main.a9103199.js"></script> +<script src="/assets/js/main.5454aec3.js"></script> </body> </html> \ No newline at end of file diff --git a/rlog/GossipSub Improvements/index.html b/rlog/GossipSub Improvements/index.html index aacb51ae..0095a1d9 100644 --- a/rlog/GossipSub Improvements/index.html +++ b/rlog/GossipSub Improvements/index.html @@ -10,8 +10,8 @@ <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/katex@0.13.24/dist/katex.min.css" integrity="sha384-odtC+0UGzzFL/6PNoE8rX/SPcQDXBJ+uRepguP4QkPCm2LBxH3FA3y+fKSiJ+AmM" crossorigin="anonymous"><link rel="stylesheet" href="/assets/css/styles.08d697e6.css"> -<link rel="preload" href="/assets/js/runtime~main.556fa6f5.js" as="script"> -<link rel="preload" href="/assets/js/main.ffc20c94.js" as="script"> +<link rel="preload" href="/assets/js/runtime~main.a9103199.js" as="script"> +<link rel="preload" href="/assets/js/main.5454aec3.js" as="script"> <meta property="og:image" content="https://vac.dev/_og/f56275d6f463a5db79d44003d33ab32143f55ab3.png"><meta name="twitter:image" content="https://vac.dev/_og/f56275d6f463a5db79d44003d33ab32143f55ab3.png"></head> <body class="navigation-with-keyboard"> <script>!function(){function e(e){document.documentElement.setAttribute("data-theme",e)}var t=function(){var e=null;try{e=new URLSearchParams(window.location.search).get("docusaurus-theme")}catch(e){}return e}()||function(){var e=null;try{e=localStorage.getItem("theme")}catch(e){}return e}();null!==t?e(t):window.matchMedia("(prefers-color-scheme: dark)").matches?e("dark"):window.matchMedia("(prefers-color-scheme: light)").matches?e("light"):e("dark")}()</script><div id="__docusaurus"> @@ -103,7 +103,7 @@ On the other hand, a hierarchical overlay can bring scalability at the cost of i Regardless of the overlay design, a continuous readjustment to appropriate peering links is essential for superior performance. At the same time, bandwidth preservation (through message aggregation, caching at strategic locations, metadata sharing, pull-based operation, etc.) can help minimize latency. However, problems like peer churn and in-network adversaries can be best alleviated through balanced redundant coverage, and frequent reshuffling of the peering links.</p><h1>References</h1><ul><li>[1] D. Vyzovitis, Y. Napora, D. McCormick, D. Dias, and Y. Psaras, “Gossipsub: Attack-resilient message propagation in the filecoin and eth2. 0 networks,” arXiv preprint arXiv:2007.02754, 2020. Retrieved from <a href="https://arxiv.org/pdf/2007.02754.pdf" target="_blank" rel="noopener noreferrer">https://arxiv.org/pdf/2007.02754.pdf</a></li><li>[2] M. Matos, V. Schiavoni, P. Felber, R. Oliveira, and E. Riviere, “Brisa: Combining efficiency and reliability in epidemic data dissemination,” in 2012 IEEE 26th International Parallel and Distributed Processing Symposium. IEEE, 2012, pp. 983–994. Retrieved from <a href="https://ieeexplore.ieee.org/abstract/document/6267905" target="_blank" rel="noopener noreferrer">https://ieeexplore.ieee.org/abstract/document/6267905</a></li><li>[3] P. T. Eugster, R. Guerraoui, A. M. Kermarrec, and L. Massouli, “Epidemic information dissemination in distributed systems,” IEEE Computer, vol. 37, no. 5, 2004. Retrieved from <a href="https://infoscience.epfl.ch/record/83478/files/EugGueKerMas04IEEEComp.pdf" target="_blank" rel="noopener noreferrer">https://infoscience.epfl.ch/record/83478/files/EugGueKerMas04IEEEComp.pdf</a></li><li>[4] D. Frey, “Epidemic protocols: From large scale to big data,” Ph.D. dissertation, Universite De Rennes 1, 2019. Retrieved from <a href="https://inria.hal.science/tel-02375909/document" target="_blank" rel="noopener noreferrer">https://inria.hal.science/tel-02375909/document</a></li><li>[5] M. Jain and C. Dovrolis, “End-to-end available bandwidth: measurement methodology, dynamics, and relation with tcp throughput,” IEEE/ACM Transactions on networking, vol. 11, no. 4, pp. 537–549, 2003. Retrieved from <a href="https://ieeexplore.ieee.org/abstract/document/1224454" target="_blank" rel="noopener noreferrer">https://ieeexplore.ieee.org/abstract/document/1224454</a></li><li>[6] R. Prasad, C. Dovrolis, M. Murray, and K. Claffy, “Bandwidth estimation: metrics, measurement techniques, and tools,” IEEE network, vol. 17, no. 6, pp. 27–35, 2003. Retrieved from <a href="https://ieeexplore.ieee.org/abstract/document/1248658" target="_blank" rel="noopener noreferrer">https://ieeexplore.ieee.org/abstract/document/1248658</a></li><li>[7] D. Kostic, A. Rodriguez, J. Albrecht, and A. Vahdat, “Bullet: High bandwidth data dissemination using an overlay mesh,” in Proceedings of the nineteenth ACM symposium on Operating systems principles, 2003, pp. 282–297. Retrieved from <a href="https://dl.acm.org/doi/abs/10.1145/945445.945473" target="_blank" rel="noopener noreferrer">https://dl.acm.org/doi/abs/10.1145/945445.945473</a></li><li>[8] V. Pai, K. Kumar, K. Tamilmani, V. Sambamurthy, and A. E. Mohr, “Chainsaw: Eliminating trees from overlay multicast,” in Peer-to-Peer Systems IV: 4th International Workshop, IPTPS 2005, Ithaca, NY, USA, February 24-25, 2005. Revised Selected Papers 4. Springer, 2005, pp. 127–140. Retrieved from <a href="https://link.springer.com/chapter/10.1007/11558989_12" target="_blank" rel="noopener noreferrer">https://link.springer.com/chapter/10.1007/11558989_12</a></li><li>[9] Y.-D. Bromberg, Q. Dufour, and D. Frey, “Multisource rumor spreading with network coding,” in IEEE INFOCOM 2019-IEEE Conference on Computer Communications. IEEE, 2019, pp. 2359–2367. Retrieved from <a href="https://ieeexplore.ieee.org/abstract/document/8737576" target="_blank" rel="noopener noreferrer">https://ieeexplore.ieee.org/abstract/document/8737576</a></li><li>[10] B. Haeupler, “Analyzing network coding gossip made easy,” in Proceedings of the forty-third annual ACM symposium on Theory of computing, 2011, pp. 293–302. Retrieved from <a href="https://dl.acm.org/doi/abs/10.1145/1993636.1993676" target="_blank" rel="noopener noreferrer">https://dl.acm.org/doi/abs/10.1145/1993636.1993676</a></li><li>[11] S. Yu and Z. Li, “Massive data delivery in unstructured peer-to-peer networks with network coding,” in 6th IEEE/ACIS International Conference on Computer and Information Science (ICIS 2007). IEEE, 2007, pp. 592–597. Retrieved from <a href="https://ieeexplore.ieee.org/abstract/document/4276446" target="_blank" rel="noopener noreferrer">https://ieeexplore.ieee.org/abstract/document/4276446</a></li><li>[12] V. Buterin, D. Feist, D. Loerakker, G. Kadianakis, M. Garnett, M. Taiwo, and A. Dietrichs, “Eip-4844: Shard blob transactions scale data-availability of ethereum in a simple, forwards-compatible manner,” 2022. Retrieved from <a href="https://eips.ethereum.org/EIPS/eip-4844" target="_blank" rel="noopener noreferrer">https://eips.ethereum.org/EIPS/eip-4844</a></li><li>[13] A. Manning, “Gossipsub extension for epidemic meshes (v1.2.0),” 2022. Retrieved from <a href="https://github.com/libp2p/specs/pull/413" target="_blank" rel="noopener noreferrer">https://github.com/libp2p/specs/pull/413</a></li><li>[14] Z. Duan, C. Tian, M. Zhou, X. Wang, N. Zhang, H. Du, and L. Wang, “Two-layer hybrid peer-to-peer networks,” Peer-to-Peer Networking and Applications, vol. 10, pp. 1304–1322, 2017. Retrieved from <a href="https://link.springer.com/article/10.1007/s12083-016-0460-5" target="_blank" rel="noopener noreferrer">https://link.springer.com/article/10.1007/s12083-016-0460-5</a></li><li>[15] W. Hao, J. Zeng, X. Dai, J. Xiao, Q. Hua, H. Chen, K.-C. Li, and H. Jin, “Blockp2p: Enabling fast blockchain broadcast with scalable peer-to-peer network topology,” in Green, Pervasive, and Cloud Computing: 14th International Conference, GPC 2019, Uberlandia, Brazil, May 26–28, 2019, Proceedings 14. Springer, 2019, pp. 223–237. Retrieved from <a href="https://link.springer.com/chapter/10.1007/978-3-030-19223-5_16" target="_blank" rel="noopener noreferrer">https://link.springer.com/chapter/10.1007/978-3-030-19223-5_16</a></li><li>[16] H. Qiu, T. Ji, S. Zhao, X. Chen, J. Qi, H. Cui, and S. Wang, “A geography-based p2p overlay network for fast and robust blockchain systems,” IEEE Transactions on Services Computing, 2022. Retrieved from <a href="https://ieeexplore.ieee.org/abstract/document/9826458" target="_blank" rel="noopener noreferrer">https://ieeexplore.ieee.org/abstract/document/9826458</a></li></ul></div></article><nav class="pagination-nav docusaurus-mt-lg" aria-label="Blog post page navigation"><a class="pagination-nav__link pagination-nav__link--prev" href="/rlog/rln-anonymous-dos-prevention"><div class="icon_S7Kx m_thRi"><svg width="14" height="14" viewBox="0 0 14 14" fill="none" xmlns="http://www.w3.org/2000/svg" role="img"><path d="M11.667 6.417h-7.1l3.261-3.261L7 2.333 2.333 7 7 11.667l.823-.823-3.255-3.26h7.099V6.417Z" fill="#fff"></path></svg></div><span class="lsd-typography lsd-typography--body2 pagination-nav__label">Strengthening Anonymous DoS Prevention with Rate Limiting Nullifiers in Waku</span></a><a class="pagination-nav__link pagination-nav__link--next" href="/rlog/Nescience-A-zkVM-leveraging-hiding-properties"><span class="lsd-typography lsd-typography--body2 pagination-nav__label">Nescience - A zkVM leveraging hiding properties</span><div class="icon_S7Kx m_thRi"><svg width="14" height="14" viewBox="0 0 14 14" fill="none" xmlns="http://www.w3.org/2000/svg" role="img"><path d="m7 2.333-.823.823 3.255 3.26H2.333v1.167h7.1l-3.256 3.261.823.823L11.667 7 7 2.333Z" fill="#fff"></path></svg></div></a></nav></main><div class="col col--2"><div class="tableOfContents_bqdL thin-scrollbar"><ul class="table-of-contents table-of-contents__left-border"><li><a href="#motivitation" class="table-of-contents__link toc-highlight">Motivitation</a></li><li><a href="#introduction" class="table-of-contents__link toc-highlight">Introduction</a></li><li><a href="#goal1-low-latency-operation" class="table-of-contents__link toc-highlight">GOAL1: Low Latency Operation</a></li><li><a href="#goal2-considering-heterogeneity-in-overlay-design" class="table-of-contents__link toc-highlight">GOAL2: Considering Heterogeneity In Overlay Design</a></li><li><a href="#goal3-bandwidth-optimization" class="table-of-contents__link toc-highlight">GOAL3: Bandwidth Optimization</a></li><li><a href="#goal4-handling-large-messages" class="table-of-contents__link toc-highlight">GOAL4: Handling Large Messages</a></li><li><a href="#goal5-scalability" class="table-of-contents__link toc-highlight">GOAL5: Scalability</a></li><li><a href="#summary" class="table-of-contents__link toc-highlight">Summary</a></li></ul></div></div></div></div></div><footer class="footer"><div class="container container-fluid firstRow_ar1q"><div class="footer__bottom text--center"><div class="margin-bottom--sm"><a class="footerLogoLink_BH7S" href="/"><img src="/theme/image/logo.svg" alt="Vac Research" class="themedImage_ToTc themedImage--light_HNdA footer__logo" width="22"><img src="/theme/image/logo.svg" alt="Vac Research" class="themedImage_ToTc themedImage--dark_i4oU footer__logo" width="22"></a></div><div class="footer__copyright">Vac Research © 2024<br>All rights reserved.</div></div><div class="row footer__links"><div class="col footer__col"><div class="footer__title"></div><ul class="footer__items clean-list"><li class="footer__item"><a href="https://twitter.com/vacp2p" target="_blank" rel="noopener noreferrer" class="footer__link-item">Twitter<svg width="13.5" height="13.5" aria-hidden="true" viewBox="0 0 24 24" class="iconExternalLink_nPIU"><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"></path></svg></a></li><li class="footer__item"><a href="https://discord.gg/PQFdubGt6d" target="_blank" rel="noopener noreferrer" class="footer__link-item">Discord<svg width="13.5" height="13.5" aria-hidden="true" viewBox="0 0 24 24" class="iconExternalLink_nPIU"><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"></path></svg></a></li><li class="footer__item"><a href="https://github.com/vacp2p" target="_blank" rel="noopener noreferrer" class="footer__link-item">Github<svg width="13.5" height="13.5" aria-hidden="true" viewBox="0 0 24 24" class="iconExternalLink_nPIU"><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"></path></svg></a></li></ul></div><div class="col footer__col"><div class="footer__title"></div><ul class="footer__items clean-list"><li class="footer__item"><a href="https://jobs.status.im/" target="_blank" rel="noopener noreferrer" class="footer__link-item">Work With Us<svg width="13.5" height="13.5" aria-hidden="true" viewBox="0 0 24 24" class="iconExternalLink_nPIU"><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"></path></svg></a></li><li class="footer__item"><a class="footer__link-item" href="/terms">Terms & Conditions</a></li><li class="footer__item"><a class="footer__link-item" href="/privacy-policy">Privacy Policy</a></li><li class="footer__item"><a class="footer__link-item" href="/security">Security</a></li></ul></div></div></div><div class="secondRow__ww3"><div class="footer__bottom text--center">Logos Collective</div><div class="row footer__links"><div class="col footer__col"><div class="footer__title">Research</div><ul class="footer__items clean-list"><li class="footer__item"><a href="https://vac.dev" target="_blank" rel="noopener noreferrer" class="footer__link-item">VacP2P<svg width="13.5" height="13.5" aria-hidden="true" viewBox="0 0 24 24" class="iconExternalLink_nPIU"><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"></path></svg></a></li><li class="footer__item"><a href="https://afaik.institute" target="_blank" rel="noopener noreferrer" class="footer__link-item">AFAIK<svg width="13.5" height="13.5" aria-hidden="true" viewBox="0 0 24 24" class="iconExternalLink_nPIU"><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"></path></svg></a></li></ul></div><div class="col footer__col"><div class="footer__title">Infrastructure</div><ul class="footer__items clean-list"><li class="footer__item"><a href="https://waku.org/" target="_blank" rel="noopener noreferrer" class="footer__link-item">Waku<svg width="13.5" height="13.5" aria-hidden="true" viewBox="0 0 24 24" class="iconExternalLink_nPIU"><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"></path></svg></a></li><li class="footer__item"><a href="https://nimbus.team/" target="_blank" rel="noopener noreferrer" class="footer__link-item">Nimbus<svg width="13.5" height="13.5" aria-hidden="true" viewBox="0 0 24 24" class="iconExternalLink_nPIU"><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"></path></svg></a></li><li class="footer__item"><a href="https://codex.storage" target="_blank" rel="noopener noreferrer" class="footer__link-item">Codex<svg width="13.5" height="13.5" aria-hidden="true" viewBox="0 0 24 24" class="iconExternalLink_nPIU"><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"></path></svg></a></li><li class="footer__item"><a href="https://nomos.tech" target="_blank" rel="noopener noreferrer" class="footer__link-item">Nomos<svg width="13.5" height="13.5" aria-hidden="true" viewBox="0 0 24 24" class="iconExternalLink_nPIU"><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"></path></svg></a></li></ul></div><div class="col footer__col"><div class="footer__title">Creative Studio</div><ul class="footer__items clean-list"><li class="footer__item"><a href="https://acid.info" target="_blank" rel="noopener noreferrer" class="footer__link-item">Acid.info<svg width="13.5" height="13.5" aria-hidden="true" viewBox="0 0 24 24" class="iconExternalLink_nPIU"><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"></path></svg></a></li></ul></div><div class="col footer__col"><div class="footer__title">Movement</div><ul class="footer__items clean-list"><li class="footer__item"><a href="https://logos.co" target="_blank" rel="noopener noreferrer" class="footer__link-item">Logos<svg width="13.5" height="13.5" aria-hidden="true" viewBox="0 0 24 24" class="iconExternalLink_nPIU"><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"></path></svg></a></li></ul></div><div class="col footer__col"><div class="footer__title">User-facing products</div><ul class="footer__items clean-list"><li class="footer__item"><a href="https://status.im" target="_blank" rel="noopener noreferrer" class="footer__link-item">Status<svg width="13.5" height="13.5" aria-hidden="true" viewBox="0 0 24 24" class="iconExternalLink_nPIU"><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"></path></svg></a></li><li class="footer__item"><a href="https://keycard.tech" target="_blank" rel="noopener noreferrer" class="footer__link-item">Keycard<svg width="13.5" height="13.5" aria-hidden="true" viewBox="0 0 24 24" class="iconExternalLink_nPIU"><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"></path></svg></a></li></ul></div></div></div><button class="backToTop_wDfN lsd-button lsd-button--small lsd-button--outlined"><span class="lsd-typography lsd-typography--label2 lsd-button__text">Back to top ↑</span></button></footer></div></div> -<script src="/assets/js/runtime~main.556fa6f5.js"></script> -<script src="/assets/js/main.ffc20c94.js"></script> +<script src="/assets/js/runtime~main.a9103199.js"></script> +<script src="/assets/js/main.5454aec3.js"></script> </body> </html> \ No newline at end of file diff --git a/rlog/Nescience-A-zkVM-leveraging-hiding-properties/index.html b/rlog/Nescience-A-zkVM-leveraging-hiding-properties/index.html index f41b0e57..0a2bc05e 100644 --- a/rlog/Nescience-A-zkVM-leveraging-hiding-properties/index.html +++ b/rlog/Nescience-A-zkVM-leveraging-hiding-properties/index.html @@ -10,8 +10,8 @@ <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/katex@0.13.24/dist/katex.min.css" integrity="sha384-odtC+0UGzzFL/6PNoE8rX/SPcQDXBJ+uRepguP4QkPCm2LBxH3FA3y+fKSiJ+AmM" crossorigin="anonymous"><link rel="stylesheet" href="/assets/css/styles.08d697e6.css"> -<link rel="preload" href="/assets/js/runtime~main.556fa6f5.js" as="script"> -<link rel="preload" href="/assets/js/main.ffc20c94.js" as="script"> +<link rel="preload" href="/assets/js/runtime~main.a9103199.js" as="script"> +<link rel="preload" href="/assets/js/main.5454aec3.js" as="script"> <meta property="og:image" content="https://vac.dev/_og/96384e501123c5045cd44e97827e443a28520ed9.png"><meta name="twitter:image" content="https://vac.dev/_og/96384e501123c5045cd44e97827e443a28520ed9.png"></head> <body class="navigation-with-keyboard"> <script>!function(){function e(e){document.documentElement.setAttribute("data-theme",e)}var t=function(){var e=null;try{e=new URLSearchParams(window.location.search).get("docusaurus-theme")}catch(e){}return e}()||function(){var e=null;try{e=localStorage.getItem("theme")}catch(e){}return e}();null!==t?e(t):window.matchMedia("(prefers-color-scheme: dark)").matches?e("dark"):window.matchMedia("(prefers-color-scheme: light)").matches?e("light"):e("dark")}()</script><div id="__docusaurus"> @@ -179,7 +179,7 @@ This intricate balance, while challenging, aims to fortify our system against po This incentivizes participation and encourages integrity.</p></li><li><p>Staking and Slashing: Introduce a staking mechanism where provers deposit tokens as collateral. Dishonest behavior results in slashing (partial or complete loss) of the staked tokens, while honest actions are rewarded.</p></li><li><p>Proof of Work/Proof of Stake: Implement a proof-of-work or proof-of- stake consensus mechanism for verification, aligning incentives with the blockchain’s broader consensus mechanism.</p></li></ul><p><a href="#fnref-1-c890aa" class="footnote-backref">↩</a></p></li></ol></div></div></article><nav class="pagination-nav docusaurus-mt-lg" aria-label="Blog post page navigation"><a class="pagination-nav__link pagination-nav__link--prev" href="/rlog/GossipSub Improvements"><div class="icon_S7Kx m_thRi"><svg width="14" height="14" viewBox="0 0 14 14" fill="none" xmlns="http://www.w3.org/2000/svg" role="img"><path d="M11.667 6.417h-7.1l3.261-3.261L7 2.333 2.333 7 7 11.667l.823-.823-3.255-3.26h7.099V6.417Z" fill="#fff"></path></svg></div><span class="lsd-typography lsd-typography--body2 pagination-nav__label">GossipSub Improvements: Evolution of Overlay Design and Message Dissemination in Unstructured P2P Networks</span></a><a class="pagination-nav__link pagination-nav__link--next" href="/rlog/device-pairing-in-js-waku-and-go-waku"><span class="lsd-typography lsd-typography--body2 pagination-nav__label">Device Pairing in Js-waku and Go-waku</span><div class="icon_S7Kx m_thRi"><svg width="14" height="14" viewBox="0 0 14 14" fill="none" xmlns="http://www.w3.org/2000/svg" role="img"><path d="m7 2.333-.823.823 3.255 3.26H2.333v1.167h7.1l-3.256 3.261.823.823L11.667 7 7 2.333Z" fill="#fff"></path></svg></div></a></nav></main><div class="col col--2"><div class="tableOfContents_bqdL thin-scrollbar"><ul class="table-of-contents table-of-contents__left-border"><li><a href="#introduction" class="table-of-contents__link toc-highlight">Introduction</a></li><li><a href="#goal-1-create-a-state-separation-architecture" class="table-of-contents__link toc-highlight">Goal 1: Create a State Separation Architecture</a><ul><li><a href="#-rationale-behind-the-dual-architecture-" class="table-of-contents__link toc-highlight"><ins> Rationale Behind the Dual Architecture: </ins></a></li><li><a href="#-harmonizing-the-two-systems-" class="table-of-contents__link toc-highlight"><ins> Harmonizing the Two Systems: </ins></a></li><li><a href="#-challenges-and-solutions-" class="table-of-contents__link toc-highlight"><ins> Challenges and Solutions </ins></a></li></ul></li><li><a href="#goal-2-virtual-machine-creation" class="table-of-contents__link toc-highlight">Goal 2: Virtual Machine Creation</a><ul><li><a href="#-optimization-concerns-for-wasm-and-risc-v-" class="table-of-contents__link toc-highlight"><ins> Optimization Concerns for WASM and RISC-V: </ins></a></li><li><a href="#-emerging-zkp-optimized-systems-considerations-" class="table-of-contents__link toc-highlight"><ins> Emerging ZKP Optimized Systems Considerations: </ins></a></li><li><a href="#-strategies-for-integration-" class="table-of-contents__link toc-highlight"><ins> Strategies for Integration: </ins></a></li></ul></li><li><a href="#goal-3-proofs-creation-and-verification" class="table-of-contents__link toc-highlight">Goal 3: Proofs Creation and Verification</a></li><li><a href="#goal-4-kernel-based-architecture-implementation" class="table-of-contents__link toc-highlight">Goal 4: Kernel-based Architecture Implementation</a></li><li><a href="#goal-5-seamless-interaction-design" class="table-of-contents__link toc-highlight">Goal 5: Seamless Interaction Design</a></li><li><a href="#goal-6-integration-of-defi-protocols-with-a-privacy-preserving-framework" class="table-of-contents__link toc-highlight">Goal 6: Integration of DeFi Protocols with a Privacy-Preserving Framework</a></li><li><a href="#-strategic-roadmap-for-goal-6-" class="table-of-contents__link toc-highlight"><ins> Strategic Roadmap for Goal 6 </ins></a></li><li><a href="#summary-of-the-architecture" class="table-of-contents__link toc-highlight">Summary of the Architecture</a></li><li><a href="#current-state" class="table-of-contents__link toc-highlight">Current State</a></li></ul></div></div></div></div></div><footer class="footer"><div class="container container-fluid firstRow_ar1q"><div class="footer__bottom text--center"><div class="margin-bottom--sm"><a class="footerLogoLink_BH7S" href="/"><img src="/theme/image/logo.svg" alt="Vac Research" class="themedImage_ToTc themedImage--light_HNdA footer__logo" width="22"><img src="/theme/image/logo.svg" alt="Vac Research" class="themedImage_ToTc themedImage--dark_i4oU footer__logo" width="22"></a></div><div class="footer__copyright">Vac Research © 2024<br>All rights reserved.</div></div><div class="row footer__links"><div class="col footer__col"><div class="footer__title"></div><ul class="footer__items clean-list"><li class="footer__item"><a href="https://twitter.com/vacp2p" target="_blank" rel="noopener noreferrer" class="footer__link-item">Twitter<svg width="13.5" height="13.5" aria-hidden="true" viewBox="0 0 24 24" class="iconExternalLink_nPIU"><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"></path></svg></a></li><li class="footer__item"><a href="https://discord.gg/PQFdubGt6d" target="_blank" rel="noopener noreferrer" class="footer__link-item">Discord<svg width="13.5" height="13.5" aria-hidden="true" viewBox="0 0 24 24" class="iconExternalLink_nPIU"><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"></path></svg></a></li><li class="footer__item"><a href="https://github.com/vacp2p" target="_blank" rel="noopener noreferrer" class="footer__link-item">Github<svg width="13.5" height="13.5" aria-hidden="true" viewBox="0 0 24 24" class="iconExternalLink_nPIU"><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"></path></svg></a></li></ul></div><div class="col footer__col"><div class="footer__title"></div><ul class="footer__items clean-list"><li class="footer__item"><a href="https://jobs.status.im/" target="_blank" rel="noopener noreferrer" class="footer__link-item">Work With Us<svg width="13.5" height="13.5" aria-hidden="true" viewBox="0 0 24 24" class="iconExternalLink_nPIU"><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"></path></svg></a></li><li class="footer__item"><a class="footer__link-item" href="/terms">Terms & Conditions</a></li><li class="footer__item"><a class="footer__link-item" href="/privacy-policy">Privacy Policy</a></li><li class="footer__item"><a class="footer__link-item" href="/security">Security</a></li></ul></div></div></div><div class="secondRow__ww3"><div class="footer__bottom text--center">Logos Collective</div><div class="row footer__links"><div class="col footer__col"><div class="footer__title">Research</div><ul class="footer__items clean-list"><li class="footer__item"><a href="https://vac.dev" target="_blank" rel="noopener noreferrer" class="footer__link-item">VacP2P<svg width="13.5" height="13.5" aria-hidden="true" viewBox="0 0 24 24" class="iconExternalLink_nPIU"><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"></path></svg></a></li><li class="footer__item"><a href="https://afaik.institute" target="_blank" rel="noopener noreferrer" class="footer__link-item">AFAIK<svg width="13.5" height="13.5" aria-hidden="true" viewBox="0 0 24 24" class="iconExternalLink_nPIU"><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"></path></svg></a></li></ul></div><div class="col footer__col"><div class="footer__title">Infrastructure</div><ul class="footer__items clean-list"><li class="footer__item"><a href="https://waku.org/" target="_blank" rel="noopener noreferrer" class="footer__link-item">Waku<svg width="13.5" height="13.5" aria-hidden="true" viewBox="0 0 24 24" class="iconExternalLink_nPIU"><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"></path></svg></a></li><li class="footer__item"><a href="https://nimbus.team/" target="_blank" rel="noopener noreferrer" class="footer__link-item">Nimbus<svg width="13.5" height="13.5" aria-hidden="true" viewBox="0 0 24 24" class="iconExternalLink_nPIU"><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"></path></svg></a></li><li class="footer__item"><a href="https://codex.storage" target="_blank" rel="noopener noreferrer" class="footer__link-item">Codex<svg width="13.5" height="13.5" aria-hidden="true" viewBox="0 0 24 24" class="iconExternalLink_nPIU"><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"></path></svg></a></li><li class="footer__item"><a href="https://nomos.tech" target="_blank" rel="noopener noreferrer" class="footer__link-item">Nomos<svg width="13.5" height="13.5" aria-hidden="true" viewBox="0 0 24 24" class="iconExternalLink_nPIU"><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"></path></svg></a></li></ul></div><div class="col footer__col"><div class="footer__title">Creative Studio</div><ul class="footer__items clean-list"><li class="footer__item"><a href="https://acid.info" target="_blank" rel="noopener noreferrer" class="footer__link-item">Acid.info<svg width="13.5" height="13.5" aria-hidden="true" viewBox="0 0 24 24" class="iconExternalLink_nPIU"><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"></path></svg></a></li></ul></div><div class="col footer__col"><div class="footer__title">Movement</div><ul class="footer__items clean-list"><li class="footer__item"><a href="https://logos.co" target="_blank" rel="noopener noreferrer" class="footer__link-item">Logos<svg width="13.5" height="13.5" aria-hidden="true" viewBox="0 0 24 24" class="iconExternalLink_nPIU"><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"></path></svg></a></li></ul></div><div class="col footer__col"><div class="footer__title">User-facing products</div><ul class="footer__items clean-list"><li class="footer__item"><a href="https://status.im" target="_blank" rel="noopener noreferrer" class="footer__link-item">Status<svg width="13.5" height="13.5" aria-hidden="true" viewBox="0 0 24 24" class="iconExternalLink_nPIU"><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"></path></svg></a></li><li class="footer__item"><a href="https://keycard.tech" target="_blank" rel="noopener noreferrer" class="footer__link-item">Keycard<svg width="13.5" height="13.5" aria-hidden="true" viewBox="0 0 24 24" class="iconExternalLink_nPIU"><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"></path></svg></a></li></ul></div></div></div><button class="backToTop_wDfN lsd-button lsd-button--small lsd-button--outlined"><span class="lsd-typography lsd-typography--label2 lsd-button__text">Back to top ↑</span></button></footer></div></div> -<script src="/assets/js/runtime~main.556fa6f5.js"></script> -<script src="/assets/js/main.ffc20c94.js"></script> +<script src="/assets/js/runtime~main.a9103199.js"></script> +<script src="/assets/js/main.5454aec3.js"></script> </body> </html> \ No newline at end of file diff --git a/rlog/Nescience-state-separation-architecture/index.html b/rlog/Nescience-state-separation-architecture/index.html index b227d187..ff9bccae 100644 --- a/rlog/Nescience-state-separation-architecture/index.html +++ b/rlog/Nescience-state-separation-architecture/index.html @@ -10,8 +10,8 @@ <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/katex@0.13.24/dist/katex.min.css" integrity="sha384-odtC+0UGzzFL/6PNoE8rX/SPcQDXBJ+uRepguP4QkPCm2LBxH3FA3y+fKSiJ+AmM" crossorigin="anonymous"><link rel="stylesheet" href="/assets/css/styles.08d697e6.css"> -<link rel="preload" href="/assets/js/runtime~main.556fa6f5.js" as="script"> -<link rel="preload" href="/assets/js/main.ffc20c94.js" as="script"> +<link rel="preload" href="/assets/js/runtime~main.a9103199.js" as="script"> +<link rel="preload" href="/assets/js/main.5454aec3.js" as="script"> <meta property="og:image" content="https://vac.dev/_og/fc5c70c77ce4bc4423198438d20cd073587a12f2.png"><meta name="twitter:image" content="https://vac.dev/_og/fc5c70c77ce4bc4423198438d20cd073587a12f2.png"></head> <body class="navigation-with-keyboard"> <script>!function(){function e(e){document.documentElement.setAttribute("data-theme",e)}var t=function(){var e=null;try{e=new URLSearchParams(window.location.search).get("docusaurus-theme")}catch(e){}return e}()||function(){var e=null;try{e=localStorage.getItem("theme")}catch(e){}return e}();null!==t?e(t):window.matchMedia("(prefers-color-scheme: dark)").matches?e("dark"):window.matchMedia("(prefers-color-scheme: light)").matches?e("light"):e("dark")}()</script><div id="__docusaurus"> @@ -529,7 +529,7 @@ This node will handle complex, private transactions at scale while integrating a Nescience aims to provide users with an infrastructure that balances privacy, security, and efficiency, ensuring the network remains resilient and capable of handling future demands.</p><p>By pursuing these future plans, Nescience is poised to not only address current challenges around scalability and key management but also lead the way in applying advanced cryptography to decentralized systems. This vision will help secure the long-term integrity and performance of the Nescience state-separation model as the blockchain grows and evolves.</p><h1>References</h1><p>[1] Nakamoto, S. (2008). Bitcoin: A Peer-to-Peer Electronic Cash System. Retrieved from <a href="https://bitcoin.org/bitcoin.pdf" target="_blank" rel="noopener noreferrer">https://bitcoin.org/bitcoin.pdf</a></p><p>[2] Sanchez, F. (2021). Cardano’s Extended UTXO accounting model. Retrived from <a href="https://iohk.io/en/blog/posts/2021/03/11/cardanos-extended-utxo-accounting-model/" target="_blank" rel="noopener noreferrer">https://iohk.io/en/blog/posts/2021/03/11/cardanos-extended-utxo-accounting-model/</a></p><p>[3] Morgan, D. (2020). HD Wallets Explained: From High Level to Nuts and Bolts. Retrieved from <a href="https://medium.com/mycrypto/the-journey-from-mnemonic-phrase-to-address-6c5e86e11e14" target="_blank" rel="noopener noreferrer">https://medium.com/mycrypto/the-journey-from-mnemonic-phrase-to-address-6c5e86e11e14</a></p><p>[4] Wuille, P. (2012). Bitcoin Improvement Proposal (BIP) 32. Retrieved from <a href="https://github.com/bitcoin/bips/blob/master/bip-0032.mediawiki" target="_blank" rel="noopener noreferrer">https://github.com/bitcoin/bips/blob/master/bip-0032.mediawiki</a></p><p>[5] Sin7y Tech Review (29): Design Principles of Private Transactions in Aleo & Zcash. Retrieved from <a href="https://hackmd.io/@sin7y/rkxFXLkgs" target="_blank" rel="noopener noreferrer">https://hackmd.io/@sin7y/rkxFXLkgs</a></p><p>[6] Sin7y Tech Review (33): Principles of private transactions and regulatory compliance issues. Retrieved from <a href="https://hackmd.io/@sin7y/S16RyFzZn" target="_blank" rel="noopener noreferrer">https://hackmd.io/@sin7y/S16RyFzZn</a></p><p>[7] Zcash Protocol Specification. Retrieved from <a href="https://zips.z.cash/protocol/protocol.pdf" target="_blank" rel="noopener noreferrer">https://zips.z.cash/protocol/protocol.pdf</a></p><p>[8] Anatomy of a Zcash Transaction. Retrieved from <a href="https://electriccoin.co/blog/anatomy-of-zcash" target="_blank" rel="noopener noreferrer">https://electriccoin.co/blog/anatomy-of-zcash</a></p><p>[9] The Penumbra Protocol: Notes, Nullifiers, and Trees. Retrieved from <a href="https://protocol.penumbra.zone/main/concepts/notes_nullifiers_trees.html" target="_blank" rel="noopener noreferrer">https://protocol.penumbra.zone/main/concepts/notes_nullifiers_trees.html</a></p><p>[10] Zero-knowledge Virtual Machine (ZKVM). Retrieved from <a href="https://medium.com/@abhilashkrish/zero-knowledge-virtual-machine-zkvm-95adc2082cfd" target="_blank" rel="noopener noreferrer">https://medium.com/@abhilashkrish/zero-knowledge-virtual-machine-zkvm-95adc2082cfd</a></p><p>[11] What's a Sparse Merkle tree?. Retrieved from <a href="https://medium.com/@kelvinfichter/whats-a-sparse-merkle-tree-acda70aeb837" target="_blank" rel="noopener noreferrer">https://medium.com/@kelvinfichter/whats-a-sparse-merkle-tree-acda70aeb837</a></p><p>[12] Lecture 10: Accounts Model and Merkle Trees. Retrieved from <a href="https://web.stanford.edu/class/ee374/lec_notes/lec10.pdf" target="_blank" rel="noopener noreferrer">https://web.stanford.edu/class/ee374/lec_notes/lec10.pdf</a></p><p>[13] The UTXO vs Account Model. Retrieved from <a href="https://www.horizen.io/academy/utxo-vs-account-model/" target="_blank" rel="noopener noreferrer">https://www.horizen.io/academy/utxo-vs-account-model/</a></p><p>[14] Addresses and Value Pools in Zcash. Retrieved from <a href="https://zcash.readthedocs.io/en/latest/rtd_pages/addresses.html" target="_blank" rel="noopener noreferrer">https://zcash.readthedocs.io/en/latest/rtd_pages/addresses.html</a></p></div></article><nav class="pagination-nav docusaurus-mt-lg" aria-label="Blog post page navigation"><a class="pagination-nav__link pagination-nav__link--prev" href="/rlog/zkVM-explorations"><div class="icon_S7Kx m_thRi"><svg width="14" height="14" viewBox="0 0 14 14" fill="none" xmlns="http://www.w3.org/2000/svg" role="img"><path d="M11.667 6.417h-7.1l3.261-3.261L7 2.333 2.333 7 7 11.667l.823-.823-3.255-3.26h7.099V6.417Z" fill="#fff"></path></svg></div><span class="lsd-typography lsd-typography--body2 pagination-nav__label">Exploring zkVMs: Which Projects Truly Qualify as Zero-Knowledge Virtual Machines?</span></a><a class="pagination-nav__link pagination-nav__link--next" href="/rlog/membership-with-bloom-filters-and-cuckoo-filters"><span class="lsd-typography lsd-typography--body2 pagination-nav__label">Membership with Bloom Filters and Cuckoo Filters</span><div class="icon_S7Kx m_thRi"><svg width="14" height="14" viewBox="0 0 14 14" fill="none" xmlns="http://www.w3.org/2000/svg" role="img"><path d="m7 2.333-.823.823 3.255 3.26H2.333v1.167h7.1l-3.256 3.261.823.823L11.667 7 7 2.333Z" fill="#fff"></path></svg></div></a></nav></main><div class="col col--2"><div class="tableOfContents_bqdL thin-scrollbar"><ul class="table-of-contents table-of-contents__left-border"><li><a href="#introducing-nssa-a-user-centric-approach" class="table-of-contents__link toc-highlight">Introducing NSSA: A user-centric approach</a></li><li><a href="#why-nssa-differs-from-other-hybrid-execution-platforms" class="table-of-contents__link toc-highlight">Why NSSA differs from other hybrid execution platforms</a></li><li><a href="#how-nescience-state-separation-architecture-can-be-used" class="table-of-contents__link toc-highlight">How Nescience state-separation architecture can be used</a><ul><li><a href="#use-case-adding-privacy-to-existing-dapps" class="table-of-contents__link toc-highlight">Use case: Adding privacy to existing dapps</a></li><li><a href="#key-advantage-decoupling-from-the-host-chain" class="table-of-contents__link toc-highlight">Key advantage: Decoupling from the host chain</a></li><li><a href="#conclusion" class="table-of-contents__link toc-highlight">Conclusion</a></li></ul></li><li><a href="#1-architectures-components" class="table-of-contents__link toc-highlight">1. Architecture's components</a><ul><li><a href="#a-public-state" class="table-of-contents__link toc-highlight">a) Public state</a></li><li><a href="#b-private-state" class="table-of-contents__link toc-highlight">b) Private state</a></li><li><a href="#c-zkvm-zero-knowledge-virtual-machine" class="table-of-contents__link toc-highlight">c) ZkVM (zero-knowledge virtual machine)</a></li><li><a href="#d-execution-types-in-nssa" class="table-of-contents__link toc-highlight">d) Execution types in NSSA</a><ul><li><a href="#1-public-executions" class="table-of-contents__link toc-highlight">1. Public executions</a></li><li><a href="#2-private-executions" class="table-of-contents__link toc-highlight">2. Private executions</a></li><li><a href="#3-shielded-executions" class="table-of-contents__link toc-highlight">3. Shielded executions</a></li><li><a href="#4-deshielded-executions" class="table-of-contents__link toc-highlight">4. Deshielded executions</a></li><li><a href="#table-of-execution-types" class="table-of-contents__link toc-highlight">Table of execution types</a></li></ul></li><li><a href="#e-nescience-users" class="table-of-contents__link toc-highlight">e) Nescience users</a></li><li><a href="#f-smart-contracts-in-nssa" class="table-of-contents__link toc-highlight">f) Smart contracts in NSSA</a></li></ul></li><li><a href="#2-general-execution-overview" class="table-of-contents__link toc-highlight">2. General execution overview</a><ul><li><a href="#user-actions" class="table-of-contents__link toc-highlight">User actions</a></li><li><a href="#sequencer-actions" class="table-of-contents__link toc-highlight">Sequencer actions</a></li></ul></li><li><a href="#3-execution-processes-and-utxo-management" class="table-of-contents__link toc-highlight">3. Execution processes and UTXO management</a><ul><li><a href="#a-components-of-a-nescience-utxo" class="table-of-contents__link toc-highlight">a) Components of a Nescience UTXO</a></li><li><a href="#b-utxo-lifecycle-from-generation-to-consumption" class="table-of-contents__link toc-highlight">b) UTXO lifecycle: From generation to consumption</a><ul><li><a href="#-i-utxos-in-private-executions" class="table-of-contents__link toc-highlight"><a id="pe"></a> I) UTXOs in private executions</a></li><li><a href="#ii-utxos-in-shielded-executions" class="table-of-contents__link toc-highlight">II) UTXOs in shielded executions</a><ul><li><a href="#a-how-shielded-executions-work" class="table-of-contents__link toc-highlight">a) How shielded executions work</a></li><li><a href="#b-summary-of-shielded-execution-flow" class="table-of-contents__link toc-highlight">b) Summary of shielded execution flow</a></li></ul></li><li><a href="#iii-utxos-in-deshielded-executions" class="table-of-contents__link toc-highlight">III) UTXOs in deshielded executions</a><ul><li><a href="#a-stages-of-deshielded-executions" class="table-of-contents__link toc-highlight">a) Stages of deshielded executions</a></li><li><a href="#b-how-deshielded-executions-work" class="table-of-contents__link toc-highlight">b) How deshielded executions work</a></li></ul></li></ul></li><li><a href="#summary-of-utxo-consumption-in-nssa" class="table-of-contents__link toc-highlight">Summary of UTXO consumption in NSSA</a><ul><li><a href="#example-alice-sending-tokens-to-bob" class="table-of-contents__link toc-highlight">Example: Alice sending tokens to Bob</a></li><li><a href="#the-importance-of-nullifiers" class="table-of-contents__link toc-highlight">The importance of nullifiers</a></li></ul></li></ul></li><li><a href="#a-hash-functions-in-nescience" class="table-of-contents__link toc-highlight">a) Hash functions in Nescience</a><ul><li><a href="#use-case-how-to-use-the-pedersen-hash-to-create-the-utxo-commitment" class="table-of-contents__link toc-highlight">Use case: How to use the Pedersen hash to create the UTXO commitment</a></li></ul></li><li><a href="#-b-key-management-and-addresses-in-nescience" class="table-of-contents__link toc-highlight"><a id="key"></a> b) Key management and addresses in Nescience</a><ul><li><a href="#i-spending-key" class="table-of-contents__link toc-highlight">I. Spending key</a></li><li><a href="#ii-private-keys" class="table-of-contents__link toc-highlight">II. Private keys</a></li><li><a href="#iii-public-keys" class="table-of-contents__link toc-highlight">III. Public keys</a></li><li><a href="#iv-viewing-key" class="table-of-contents__link toc-highlight">IV. Viewing key</a></li><li><a href="#-v-ephemeral-key" class="table-of-contents__link toc-highlight"><a id="key"></a> V. Ephemeral key</a></li><li><a href="#vi-nescience-addresses" class="table-of-contents__link toc-highlight">VI. Nescience addresses</a><ul><li><a href="#a-public-addresses" class="table-of-contents__link toc-highlight">a) Public addresses</a></li><li><a href="#b-private-addresses" class="table-of-contents__link toc-highlight">b) Private addresses</a></li></ul></li><li><a href="#vii-conclusion" class="table-of-contents__link toc-highlight">VII. Conclusion</a></li></ul></li><li><a href="#c-trees-in-nssa" class="table-of-contents__link toc-highlight">c) Trees in NSSA</a></li><li><a href="#e-recursive-friendly-privacy-preserving-zk-zkvm" class="table-of-contents__link toc-highlight">e) Recursive-friendly privacy-preserving zk-zkVM</a></li><li><a href="#f-mpc-based-synchronization-mechanism-under-review" class="table-of-contents__link toc-highlight">f) MPC-based synchronization mechanism (under review)</a></li></ul></div></div></div></div></div><footer class="footer"><div class="container container-fluid firstRow_ar1q"><div class="footer__bottom text--center"><div class="margin-bottom--sm"><a class="footerLogoLink_BH7S" href="/"><img src="/theme/image/logo.svg" alt="Vac Research" class="themedImage_ToTc themedImage--light_HNdA footer__logo" width="22"><img src="/theme/image/logo.svg" alt="Vac Research" class="themedImage_ToTc themedImage--dark_i4oU footer__logo" width="22"></a></div><div class="footer__copyright">Vac Research © 2024<br>All rights reserved.</div></div><div class="row footer__links"><div class="col footer__col"><div class="footer__title"></div><ul class="footer__items clean-list"><li class="footer__item"><a href="https://twitter.com/vacp2p" target="_blank" rel="noopener noreferrer" class="footer__link-item">Twitter<svg width="13.5" height="13.5" aria-hidden="true" viewBox="0 0 24 24" class="iconExternalLink_nPIU"><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"></path></svg></a></li><li class="footer__item"><a href="https://discord.gg/PQFdubGt6d" target="_blank" rel="noopener noreferrer" class="footer__link-item">Discord<svg width="13.5" height="13.5" aria-hidden="true" viewBox="0 0 24 24" class="iconExternalLink_nPIU"><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"></path></svg></a></li><li class="footer__item"><a href="https://github.com/vacp2p" target="_blank" rel="noopener noreferrer" class="footer__link-item">Github<svg width="13.5" height="13.5" aria-hidden="true" viewBox="0 0 24 24" class="iconExternalLink_nPIU"><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"></path></svg></a></li></ul></div><div class="col footer__col"><div class="footer__title"></div><ul class="footer__items clean-list"><li class="footer__item"><a href="https://jobs.status.im/" target="_blank" rel="noopener noreferrer" class="footer__link-item">Work With Us<svg width="13.5" height="13.5" aria-hidden="true" viewBox="0 0 24 24" class="iconExternalLink_nPIU"><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"></path></svg></a></li><li class="footer__item"><a class="footer__link-item" href="/terms">Terms & Conditions</a></li><li class="footer__item"><a class="footer__link-item" href="/privacy-policy">Privacy Policy</a></li><li class="footer__item"><a class="footer__link-item" href="/security">Security</a></li></ul></div></div></div><div class="secondRow__ww3"><div class="footer__bottom text--center">Logos Collective</div><div class="row footer__links"><div class="col footer__col"><div class="footer__title">Research</div><ul class="footer__items clean-list"><li class="footer__item"><a href="https://vac.dev" target="_blank" rel="noopener noreferrer" class="footer__link-item">VacP2P<svg width="13.5" height="13.5" aria-hidden="true" viewBox="0 0 24 24" class="iconExternalLink_nPIU"><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"></path></svg></a></li><li class="footer__item"><a href="https://afaik.institute" target="_blank" rel="noopener noreferrer" class="footer__link-item">AFAIK<svg width="13.5" height="13.5" aria-hidden="true" viewBox="0 0 24 24" class="iconExternalLink_nPIU"><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"></path></svg></a></li></ul></div><div class="col footer__col"><div class="footer__title">Infrastructure</div><ul class="footer__items clean-list"><li class="footer__item"><a href="https://waku.org/" target="_blank" rel="noopener noreferrer" class="footer__link-item">Waku<svg width="13.5" height="13.5" aria-hidden="true" viewBox="0 0 24 24" class="iconExternalLink_nPIU"><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"></path></svg></a></li><li class="footer__item"><a href="https://nimbus.team/" target="_blank" rel="noopener noreferrer" class="footer__link-item">Nimbus<svg width="13.5" height="13.5" aria-hidden="true" viewBox="0 0 24 24" class="iconExternalLink_nPIU"><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"></path></svg></a></li><li class="footer__item"><a href="https://codex.storage" target="_blank" rel="noopener noreferrer" class="footer__link-item">Codex<svg width="13.5" height="13.5" aria-hidden="true" viewBox="0 0 24 24" class="iconExternalLink_nPIU"><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"></path></svg></a></li><li class="footer__item"><a href="https://nomos.tech" target="_blank" rel="noopener noreferrer" class="footer__link-item">Nomos<svg width="13.5" height="13.5" aria-hidden="true" viewBox="0 0 24 24" class="iconExternalLink_nPIU"><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"></path></svg></a></li></ul></div><div class="col footer__col"><div class="footer__title">Creative Studio</div><ul class="footer__items clean-list"><li class="footer__item"><a href="https://acid.info" target="_blank" rel="noopener noreferrer" class="footer__link-item">Acid.info<svg width="13.5" height="13.5" aria-hidden="true" viewBox="0 0 24 24" class="iconExternalLink_nPIU"><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"></path></svg></a></li></ul></div><div class="col footer__col"><div class="footer__title">Movement</div><ul class="footer__items clean-list"><li class="footer__item"><a href="https://logos.co" target="_blank" rel="noopener noreferrer" class="footer__link-item">Logos<svg width="13.5" height="13.5" aria-hidden="true" viewBox="0 0 24 24" class="iconExternalLink_nPIU"><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"></path></svg></a></li></ul></div><div class="col footer__col"><div class="footer__title">User-facing products</div><ul class="footer__items clean-list"><li class="footer__item"><a href="https://status.im" target="_blank" rel="noopener noreferrer" class="footer__link-item">Status<svg width="13.5" height="13.5" aria-hidden="true" viewBox="0 0 24 24" class="iconExternalLink_nPIU"><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"></path></svg></a></li><li class="footer__item"><a href="https://keycard.tech" target="_blank" rel="noopener noreferrer" class="footer__link-item">Keycard<svg width="13.5" height="13.5" aria-hidden="true" viewBox="0 0 24 24" class="iconExternalLink_nPIU"><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"></path></svg></a></li></ul></div></div></div><button class="backToTop_wDfN lsd-button lsd-button--small lsd-button--outlined"><span class="lsd-typography lsd-typography--label2 lsd-button__text">Back to top ↑</span></button></footer></div></div> -<script src="/assets/js/runtime~main.556fa6f5.js"></script> -<script src="/assets/js/main.ffc20c94.js"></script> +<script src="/assets/js/runtime~main.a9103199.js"></script> +<script src="/assets/js/main.5454aec3.js"></script> </body> </html> \ No newline at end of file diff --git a/rlog/archive/index.html b/rlog/archive/index.html index b35d2d9d..930d58cf 100644 --- a/rlog/archive/index.html +++ b/rlog/archive/index.html @@ -10,8 +10,8 @@ <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/katex@0.13.24/dist/katex.min.css" integrity="sha384-odtC+0UGzzFL/6PNoE8rX/SPcQDXBJ+uRepguP4QkPCm2LBxH3FA3y+fKSiJ+AmM" crossorigin="anonymous"><link rel="stylesheet" href="/assets/css/styles.08d697e6.css"> -<link rel="preload" href="/assets/js/runtime~main.556fa6f5.js" as="script"> -<link rel="preload" href="/assets/js/main.ffc20c94.js" as="script"> +<link rel="preload" href="/assets/js/runtime~main.a9103199.js" as="script"> +<link rel="preload" href="/assets/js/main.5454aec3.js" as="script"> <meta property="og:image" content="https://vac.dev/_og/aca0aa4197ad1a1adebb40cd3e25f40f1f44a118.png"><meta name="twitter:image" content="https://vac.dev/_og/aca0aa4197ad1a1adebb40cd3e25f40f1f44a118.png"></head> <body class="navigation-with-keyboard"> <script>!function(){function e(e){document.documentElement.setAttribute("data-theme",e)}var t=function(){var e=null;try{e=new URLSearchParams(window.location.search).get("docusaurus-theme")}catch(e){}return e}()||function(){var e=null;try{e=localStorage.getItem("theme")}catch(e){}return e}();null!==t?e(t):window.matchMedia("(prefers-color-scheme: dark)").matches?e("dark"):window.matchMedia("(prefers-color-scheme: light)").matches?e("light"):e("dark")}()</script><div id="__docusaurus"> @@ -19,8 +19,8 @@ .lsd-dropdown--error ) .lsd-dropdown__trigger:hover .lsd-dropdown__option-label,.lsd-dropdown:not(.lsd-dropdown--disabled):not( .lsd-dropdown--error - ) .lsd-dropdown__trigger:focus .lsd-dropdown__option-label{-webkit-text-decoration:underline;text-decoration:underline;}.lsd-dropdown__label{display:block;}.lsd-dropdown__button-container{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-box-pack:justify;-webkit-justify-content:space-between;justify-content:space-between;}.lsd-dropdown__trigger{width:100%;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:row;-ms-flex-direction:row;flex-direction:row;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:justify;-webkit-justify-content:space-between;justify-content:space-between;border:none;cursor:pointer;background:none;}.lsd-dropdown__trigger:focus{outline:none;}.lsd-dropdown__option-label{cursor:inherit;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;}.lsd-dropdown__icons{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:row;-ms-flex-direction:row;flex-direction:row;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:center;-ms-flex-pack:center;-webkit-justify-content:center;justify-content:center;gap:8px;}.lsd-dropdown__icon{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;}.lsd-dropdown__supporting-text{margin:6px 14px;}.lsd-dropdown--error .lsd-dropdown__option-label{-webkit-text-decoration:line-through;text-decoration:line-through;}.lsd-dropdown--disabled{opacity:0.34;cursor:initial;}.lsd-dropdown--large{width:208px;}.lsd-dropdown--large.lsd-dropdown--error{width:230px;}.lsd-dropdown--large .lsd-dropdown__label{margin:0 0 6px 18px;}.lsd-dropdown--large .lsd-dropdown__button-container{height:40px;}.lsd-dropdown--large .lsd-dropdown__trigger{padding:10px 0px 10px 18px;}.lsd-dropdown--large .lsd-dropdown__icons{padding:0px 14px;}.lsd-dropdown--medium{width:188px;}.lsd-dropdown--medium.lsd-dropdown--error{width:210px;}.lsd-dropdown--medium .lsd-dropdown__label{margin:0 0 6px 14px;}.lsd-dropdown--medium .lsd-dropdown__button-container{height:32px;}.lsd-dropdown--medium .lsd-dropdown__trigger{padding:6px 0px 6px 14px;}.lsd-dropdown--medium .lsd-dropdown__icons{padding:0px 12px;}.lsd-dropdown--small{width:164px;}.lsd-dropdown--small.lsd-dropdown--error{width:186px;}.lsd-dropdown--small .lsd-dropdown__label{margin:0 0 6px 12px;}.lsd-dropdown--small .lsd-dropdown__button-container{height:28px;}.lsd-dropdown--small .lsd-dropdown__trigger{padding:6px 0px 6px 12px;}.lsd-dropdown--small .lsd-dropdown__icons{padding:0px 10px;}.lsd-dropdown--outlined .lsd-dropdown__button-container{border:1px solid rgb(var(--lsd-border-primary));}.lsd-dropdown--underlined .lsd-dropdown__button-container{border:1px solid transparent;border-bottom:1px solid rgb(var(--lsd-border-primary));}</style><style data-emotion="css-global w2g5fy">.lsd-dropdown-item{width:100%;box-sizing:border-box;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:row;-ms-flex-direction:row;flex-direction:row;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;border:1px solid rgb(var(--lsd-border-primary));}.lsd-dropdown-item:not(.lsd-dropdown-item--disabled){cursor:pointer;}.lsd-dropdown-item:not(.lsd-dropdown-item--disabled):hover,.lsd-dropdown-item:not(.lsd-dropdown-item--disabled):focus{outline:none;}.lsd-dropdown-item:not(.lsd-dropdown-item--disabled):hover .lsd-dropdown-item__label,.lsd-dropdown-item:not(.lsd-dropdown-item--disabled):focus .lsd-dropdown-item__label{-webkit-text-decoration:underline;text-decoration:underline;}.lsd-dropdown-item__label{display:block;overflow:hidden;white-space:nowrap;text-overflow:ellipsis;}.lsd-dropdown-item--disabled{opacity:0.34;}.lsd-dropdown-item__icon{margin-right:18px;-webkit-flex-shrink:0;-ms-flex-negative:0;flex-shrink:0;}.lsd-dropdown-item--small{padding:5px 9px;height:28px;}.lsd-dropdown-item--medium{padding:5px 11px;height:32px;}.lsd-dropdown-item--large{padding:5px 13px;height:40px;}</style><style data-emotion="css-global ww9kgc">.lsd-breadcrumb__list{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:row;-ms-flex-direction:row;flex-direction:row;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;list-style-type:none;margin:0;padding:0;}.lsd-breadcrumb--disabled .lsd-breadcrumb__list{opacity:0.34;cursor:initial;pointer-events:none;}.lsd-breadcrumb__dropdown-menu{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column;overflow:auto;border:1px solid rgb(var(--lsd-border-primary));margin-top:10px;position:absolute;width:auto!important;}.lsd-breadcrumb__dropdown-menu>li{cursor:pointer;}.lsd-breadcrumb__dropdown-menu>li:not(:last-child){border-bottom:1px solid rgb(var(--lsd-border-primary));}.lsd-breadcrumb__dropdown-menu>li:hover,.lsd-breadcrumb__dropdown-menu>li:focus{-webkit-text-decoration:underline;text-decoration:underline;text-decoration-color:rgb(var(--lsd-border-primary));}.lsd-breadcrumb__dropdown-menu li>a{width:164px;padding:5px 11px;}</style><style data-emotion="css-global 4gvini">.lsd-breadcrumb-item{list-style-type:none;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;}.lsd-breadcrumb__list>li:not(:last-child)::after{display:inline-block;margin-inline:12px;content:'/';}.lsd-breadcrumb-item__link{-webkit-text-decoration:none;text-decoration:none;cursor:pointer;}.lsd-breadcrumb-item--outlined{padding:3px 11px;border:1px solid rgb(var(--lsd-border-primary));}.lsd-breadcrumb:not(.lsd-breadcrumb--disabled) .lsd-breadcrumb-item__link:hover,.lsd-breadcrumb:not(.lsd-breadcrumb--disabled) .lsd-breadcrumb-item__link:focus{-webkit-text-decoration:underline;text-decoration:underline;text-decoration-color:rgb(var(--lsd-border-primary));}</style><style data-emotion="css-global 1cwg3oc">.lsd-card{box-sizing:border-box;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column;}.lsd-card>.lsd-card-header{margin-bottom:-1px;}</style><style data-emotion="css-global v7d76i">.lsd-card-header{box-sizing:border-box;padding:10px 18px;text-align:center;border:1px solid rgb(var(--lsd-border-primary));}.lsd-card-header__title{overflow:hidden;word-break:break-all;}.lsd-card-header--large{padding:10px 18px;}.lsd-card-header--medium{padding:6px 14px;}.lsd-card-header--small{padding:6px 12px;}</style><style data-emotion="css-global 1txgafh">.lsd-card-body{box-sizing:border-box;padding:14px 22px;border:1px solid rgb(var(--lsd-border-primary));}</style><style data-emotion="css-global kzy52c">.lsd-tag{width:-webkit-fit-content;width:-moz-fit-content;width:fit-content;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:row;-ms-flex-direction:row;flex-direction:row;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:center;-ms-flex-pack:center;-webkit-justify-content:center;justify-content:center;box-sizing:border-box;border:1px solid rgb(var(--lsd-icon-primary));}.lsd-tag:hover,.lsd-tag:focus{-webkit-text-decoration:underline;text-decoration:underline;cursor:pointer;}.lsd-badge--large{padding:3px 11px;gap:12px;height:28px;}.lsd-badge--small{padding:3px 7px;gap:8px;height:24px;}.lsd-tag--filled{background-color:rgb(var(--lsd-icon-primary));}.lsd-tag--filled .lsd-tag__label{color:rgb(var(--lsd-text-secondary));}.lsd-tag--filled svg{--lsd-icon-primary:var(--lsd-icon-secondary);}.lsd-tag--outlined{color:rgb(var(--lsd-text-primary));}.lsd-tag--disabled{opacity:0.3;cursor:initial;pointer-events:none;}</style><style data-emotion="css-global 4wy0ub">.lsd-text-field{box-sizing:border-box;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column;}.lsd-text-field__input-container{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:justify;-webkit-justify-content:space-between;justify-content:space-between;}.lsd-text-field--disabled{opacity:0.34;}.lsd-text-field__input{border:none;outline:none;font-size:14px;color:rgb(var(--lsd-text-primary));background:none;width:100%;}.lsd-text-field__input:hover{outline:none;}.lsd-text-field__input::-webkit-input-placeholder{color:rgb(var(--lsd-text-primary));opacity:0.3;}.lsd-text-field__input::-moz-placeholder{color:rgb(var(--lsd-text-primary));opacity:0.3;}.lsd-text-field__input:-ms-input-placeholder{color:rgb(var(--lsd-text-primary));opacity:0.3;}.lsd-text-field__input::placeholder{color:rgb(var(--lsd-text-primary));opacity:0.3;}.lsd-text-field--error .lsd-text-field__input{-webkit-text-decoration:line-through;text-decoration:line-through;}.lsd-text-field__supporting-text{width:-webkit-fit-content;width:-moz-fit-content;width:fit-content;}.lsd-text-field--large{width:208px;}.lsd-text-field--large>*{padding:10px 14px 10px 18px;}.lsd-text-field--medium{width:188px;}.lsd-text-field--medium>*{padding:6px 12px 6px 14px;}.lsd-text-field--small{width:164px;}.lsd-text-field--small>*{padding:6px 10px 6px 12px;}.lsd-text-field__label{padding-top:0;padding-bottom:6px;}.lsd-text-field__supporting-text{padding-bottom:0;padding-top:6px;}.lsd-text-field--outlined .lsd-text-field__input-container{border:1px solid rgb(var(--lsd-border-primary));}.lsd-text-field--underlined .lsd-text-field__input-container{border:1px solid transparent;border-bottom:1px solid rgb(var(--lsd-border-primary));}.lsd-text-field__clear-button{padding:0;width:auto;height:auto;margin:0;border:0;}</style><style data-emotion="css-global uhig7c">.lsd-checkbox{position:relative;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:row;-ms-flex-direction:row;flex-direction:row;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;}.lsd-checkbox__input{opacity:0;position:absolute;left:0;top:0;padding:0;margin:0;width:100%;height:100%;}.lsd-checkbox:not(.lsd-checkbox--disabled):hover,.lsd-checkbox:not(.lsd-checkbox--disabled).lsd-checkbox--focused{-webkit-text-decoration:underline;text-decoration:underline;}.lsd-checkbox:not(.lsd-checkbox--disabled) .lsd-checkbox__input{cursor:pointer;}.lsd-checkbox--disabled{opacity:0.34;}.lsd-checkbox__label{margin-left:18px;}.lsd-checkbox--large .lsd-checkbox__label{margin-left:18px;}.lsd-checkbox--medium .lsd-checkbox__label{margin-left:14px;}.lsd-checkbox--small .lsd-checkbox__label{margin-left:12px;}</style><style data-emotion="css-global txommo">.lsd-autocomplete{box-sizing:border-box;}.lsd-autocomplete__label{display:block;}.lsd-autocomplete__input-container{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-box-pack:justify;-webkit-justify-content:space-between;justify-content:space-between;}.lsd-autocomplete--disabled{opacity:0.34;}.lsd-autocomplete__input{border:none;outline:none;font-size:14px;color:rgb(var(--lsd-text-primary));background:none;width:100%;}.lsd-autocomplete__input:hover{outline:none;}.lsd-autocomplete__input::-webkit-input-placeholder{color:rgb(var(--lsd-text-primary));opacity:0.3;}.lsd-autocomplete__input::-moz-placeholder{color:rgb(var(--lsd-text-primary));opacity:0.3;}.lsd-autocomplete__input:-ms-input-placeholder{color:rgb(var(--lsd-text-primary));opacity:0.3;}.lsd-autocomplete__input::placeholder{color:rgb(var(--lsd-text-primary));opacity:0.3;}.lsd-autocomplete__icon{cursor:pointer;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;}.lsd-autocomplete--error{-webkit-text-decoration:line-through;text-decoration:line-through;}.lsd-autocomplete--large{width:208px;}.lsd-autocomplete--large .lsd-autocomplete__label{margin:0 0 6px 18px;}.lsd-autocomplete--large .lsd-autocomplete__input-container{height:40px;}.lsd-autocomplete--large .lsd-autocomplete__input{padding:9px 17px;}.lsd-autocomplete--large .lsd-autocomplete__icon{padding:12px 13px;}.lsd-autocomplete--medium{width:188px;}.lsd-autocomplete--medium .lsd-autocomplete__label{margin:0 0 6px 14px;}.lsd-autocomplete--medium .lsd-autocomplete__input-container{height:32px;}.lsd-autocomplete--medium .lsd-autocomplete__input{padding:5px 13px;}.lsd-autocomplete--medium .lsd-autocomplete__icon{padding:8px 11px;}.lsd-autocomplete--small{width:164px;}.lsd-autocomplete--small .lsd-autocomplete__label{margin:0 0 6px 12px;}.lsd-autocomplete--small .lsd-autocomplete__input-container{height:28px;}.lsd-autocomplete--small .lsd-autocomplete__input{padding:5px 11px;}.lsd-autocomplete--small .lsd-autocomplete__icon{padding:6px 9px;}.lsd-autocomplete--outlined .lsd-autocomplete__input-container{border:1px solid rgb(var(--lsd-border-primary));}.lsd-autocomplete--underlined .lsd-autocomplete__input-container{border:1px solid transparent;border-bottom:1px solid rgb(var(--lsd-border-primary));}.lsd-autocomplete__dropdown-item-placeholder{opacity:0.5;white-space:pre;}</style><style data-emotion="css-global quxxm6">.lsd-quote{color:rgb(var(--lsd-text-primary));white-space:pre-wrap;}.lsd-quote--indented-inline{border-left:1px solid rgb(var(--lsd-border-primary));padding:4px 8px 4px 28px;}.lsd-quote--parentheses{padding:0px;text-align:center;}.lsd-quote--parentheses::before{content:'***';}.lsd-quote--parentheses::after{content:'***';}</style><style data-emotion="css-global a49t4h">.lsd-collapse{box-sizing:border-box;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column;}.lsd-collapse--open .lsd-collapse__content{border-top:1px solid transparent;}.lsd-collapse__content{border:1px solid rgb(var(--lsd-border-primary));}</style><style data-emotion="css-global 12ppw0q">.lsd-collapse-header{box-sizing:border-box;}.lsd-collapse-header:not(.lsd-collapse-header--disabled) .lsd-collapse-header__trigger:hover .lsd-collapse-header__label{-webkit-text-decoration:underline;text-decoration:underline;}.lsd-collapse-header__trigger{width:100%;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:row;-ms-flex-direction:row;flex-direction:row;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:justify;-webkit-justify-content:space-between;justify-content:space-between;cursor:pointer;background:none;border:1px solid rgb(var(--lsd-border-primary));}.lsd-collapse-header__trigger:focus{outline:none;}.lsd-collapse-header__label{cursor:inherit;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;margin:auto;}.lsd-collapse-header__icons{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:row;-ms-flex-direction:row;flex-direction:row;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:end;-ms-flex-pack:end;-webkit-justify-content:flex-end;justify-content:flex-end;}.lsd-collapse-header__icon{margin-right:8px;}.lsd-collapse-header--disabled .lsd-collapse-header__trigger{opacity:0.34;cursor:initial;}.lsd-collapse-header--large .lsd-collapse-header__trigger{width:299px;height:40px;padding:9px 17px;}.lsd-collapse-header--medium .lsd-collapse-header__trigger{width:270px;height:32px;padding:5px 13px;}.lsd-collapse-header--small .lsd-collapse-header__trigger{width:235px;height:28px;padding:5px 11px;}</style><style data-emotion="css-global dixc0i">.lsd-checkbox-group{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column;gap:6px;width:-webkit-fit-content;width:-moz-fit-content;width:fit-content;}.lsd-checkbox-group__label{margin-bottom:6px;}</style><style data-emotion="css-global q2n2hz">.lsd-badge{width:-webkit-fit-content;width:-moz-fit-content;width:fit-content;box-sizing:border-box;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:row;-ms-flex-direction:row;flex-direction:row;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:center;-ms-flex-pack:center;-webkit-justify-content:center;justify-content:center;border:1px solid rgb(var(--lsd-icon-primary));border-radius:20px;}.lsd-badge:hover,.lsd-badge:focus{-webkit-text-decoration:underline;text-decoration:underline;cursor:pointer;}.lsd-badge--large{padding:3px 11px;gap:12px;height:28px;}.lsd-badge--small{padding:3px 7px;gap:8px;height:24px;}.lsd-badge--filled{background-color:rgb(var(--lsd-icon-primary));}.lsd-badge--filled .lsd-badge__label{color:rgb(var(--lsd-text-secondary));}.lsd-badge--filled svg{--lsd-icon-primary:var(--lsd-icon-secondary);}.lsd-badge--outlined{color:rgb(var(--lsd-text-primary));}.lsd-badge--disabled{opacity:0.3;cursor:initial;pointer-events:none;}</style><style data-emotion="css-global rlst54">.lsd-radio-button{position:relative;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:row;-ms-flex-direction:row;flex-direction:row;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;}.lsd-radio-button__input{opacity:0;position:absolute;left:0;top:0;padding:0;margin:0;width:100%;height:100%;}.lsd-radio-button:not(.lsd-radio-button--disabled):hover{-webkit-text-decoration:underline;text-decoration:underline;}.lsd-radio-button:not(.lsd-radio-button--disabled) .lsd-radio-button__input{cursor:pointer;}.lsd-radio-button--disabled{opacity:0.34;}.lsd-radio-button__label{margin-left:18px;}.lsd-radio-button--large .lsd-radio-button__label{margin-left:18px;}.lsd-radio-button--medium .lsd-radio-button__label{margin-left:14px;}.lsd-radio-button--small .lsd-radio-button__label{margin-left:12px;}</style><style data-emotion="css-global mo7h6o">.lsd-radio-button-group{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column;gap:6px;width:-webkit-fit-content;width:-moz-fit-content;width:fit-content;}.lsd-radio-button-group__label{margin-bottom:6px;}</style><style data-emotion="css-global amncrr">.lsd-table{box-sizing:border-box;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column;}.lsd-table>.lsd-table-header{margin-bottom:-1px;}</style><style data-emotion="css-global 1fkbozr">.lsd-table-header{box-sizing:border-box;border:1px solid rgb(var(--lsd-border-primary));}</style><style data-emotion="css-global 1fb1r54">.lsd-table-body table{border-collapse:collapse;text-align:center;table-layout:fixed;width:100%;height:auto;}.lsd-table-body table tr:first-of-type td label:has(input[type='radio']){display:none;}.lsd-table-body__toolbar{box-sizing:border-box;padding:10px;border:1px solid rgb(var(--lsd-border-primary));border-bottom:none;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-box-pack:justify;-webkit-justify-content:space-between;justify-content:space-between;}</style><style data-emotion="css-global 607rj8">.lsd-table-item{border:1px solid rgb(var(--lsd-border-primary));}.lsd-table-item:has(> label){width:40px;}.lsd-table-item:has(> label) input{position:relative;width:14px;height:14px;margin:auto;}.lsd-table-item:has(> label) span{margin-left:14px!important;}.lsd-table-item--large{padding:10px;}.lsd-table-item--medium{padding:6px 8px;}.lsd-table-item--small{padding:6px;}</style><style data-emotion="css-global 1vlh57l">.lsd-table-row{-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;}</style><style data-emotion="css-global 1fw5y3v">.lsd-number-input{width:auto;box-sizing:border-box;}.lsd-number-input__main-container:hover{-webkit-text-decoration:underline;text-decoration:underline;}.lsd-number-input--error .lsd-number-input__main-container{-webkit-text-decoration:line-through;text-decoration:line-through;}.lsd-number-input__label{display:block;}.lsd-number-input__plus-minus-icons{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-shrink:0;-ms-flex-negative:0;flex-shrink:0;}.lsd-number-input__input-container{box-sizing:border-box;border:1px solid rgb(var(--lsd-border-primary));border-left:0px;border-right:0px;}.lsd-number-input__error-icon{cursor:pointer;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;padding:10px 8px;}.lsd-number-input__input-container{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:justify;-webkit-justify-content:space-between;justify-content:space-between;}.lsd-number-input--disabled{opacity:0.34;}.lsd-number-input__main-container{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;}.lsd-number-input__input{border:none;outline:none;font-size:14px;color:rgb(var(--lsd-text-primary));background:none;text-align:center;padding:0 4px;}.lsd-number-input__input::-webkit-inner-spin-button{display:none;-webkit-appearance:none;}.lsd-number-input__input:hover{outline:none;}.lsd-number-input__supporting-text{position:absolute;}.lsd-number-input--large .lsd-number-input__label{margin:0 0 6px 18px;}.lsd-number-input--large .lsd-number-input__input-container{height:40px;}.lsd-number-input--large .lsd-number-input__input{width:62px;}.lsd-number-input--large .lsd-number-input__plus-minus-icons{height:40px;width:40px;}.lsd-number-input--large .lsd-number-input__supporting-text{margin:6px 18px 0 18px;}.lsd-number-input--medium .lsd-number-input__label{margin:0 0 6px 14px;}.lsd-number-input--medium .lsd-number-input__input-container{height:32px;}.lsd-number-input--medium .lsd-number-input__input{width:58px;}.lsd-number-input--medium .lsd-number-input__plus-minus-icons{height:32px;width:32px;}.lsd-number-input--medium .lsd-number-input__supporting-text{margin:6px 14px 0 14px;}.lsd-number-input--small .lsd-number-input__label{margin:0 0 6px 12px;}.lsd-number-input--small .lsd-number-input__input-container{height:28px;}.lsd-number-input--small .lsd-number-input__input{width:50px;}.lsd-number-input--small .lsd-number-input__plus-minus-icons{height:28px;width:28px;}.lsd-number-input--small .lsd-number-input__supporting-text{margin:6px 12px 0 12px;}</style><style data-emotion="css-global 12rmo7o">.lsd-modal{box-sizing:border-box;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column;position:fixed;top:0;left:0;right:0;bottom:0;background-color:rgba(0, 0, 0, 0.5);display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-box-pack:center;-ms-flex-pack:center;-webkit-justify-content:center;justify-content:center;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;z-index:9999;}.lsd-modal__container{position:relative;background:rgb(var(--lsd-surface-primary));padding:20px;max-width:90%;box-sizing:border-box;border:1px solid rgb(var(--lsd-border-primary));}.lsd-modal__header{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-box-pack:justify;-webkit-justify-content:space-between;justify-content:space-between;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;}.lsd-modal__close-icon{position:absolute;top:8px;right:8px;cursor:pointer;}.lsd-modal__title-and-subtitle-container{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column;}.lsd-modal--large .lsd-modal__container{min-width:960px;}.lsd-modal--medium .lsd-modal__container{min-width:768px;}.lsd-modal--small .lsd-modal__container{min-width:614px;}.lsd-modal--extra-small .lsd-modal__container{min-width:490px;}</style><style data-emotion="css-global 1k7gzc">.lsd-modal-footer{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;}</style><style data-emotion="css-global 1b9t8so">.lsd-modal-body{margin:18px 0;}</style><style data-emotion="css-global dyud2a">.lsd-date-picker{width:-webkit-fit-content;width:-moz-fit-content;width:fit-content;}.lsd-date-picker__calendar{border-top:none!important;}.lsd-date-picker--large .lsd-date-field--large{width:318px;}.lsd-date-picker--medium .lsd-date-field--medium{width:290px;}.lsd-date-picker--small .lsd-date-field--small{width:262px;}</style><style data-emotion="css-global olq3nk">.lsd-date-field{width:auto;box-sizing:border-box;}.lsd-date-field__label{display:block;}.lsd-date-field__input-container__icon{position:absolute;right:0;cursor:pointer;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;background-color:rgb(var(--lsd-surface-primary));}.lsd-date-field__input-container__icon:focus{background:blue;background-color:pink;border:1px solid rgb(var(--lsd-border-primary));}.lsd-date-field__input-container__no-icon{position:absolute;right:0;background-color:rgb(var(--lsd-surface-primary));padding:12px;}.lsd-date-field--outlined{border:1px solid rgb(var(--lsd-border-primary));}.lsd-date-field--underlined{border-bottom:1px solid rgb(var(--lsd-border-primary));}.lsd-date-field__input-container{position:relative;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:justify;-webkit-justify-content:space-between;justify-content:space-between;}.lsd-date-field--disabled{opacity:0.34;}.lsd-date-field__input-container__input{border:none;outline:none;font-size:14px;color:rgb(var(--lsd-text-primary));background:none;width:100%;opacity:0.4;-webkit-transition:opacity 0.2s ease-in-out;transition:opacity 0.2s ease-in-out;}.lsd-date-field__input-container__input::-webkit-inner-spin-button,.lsd-date-field__input-container__input::-webkit-calendar-picker-indicator{display:none;-webkit-appearance:none;}.lsd-date-field__input-container__input:hover{outline:none;}.lsd-date-field__supporting-text{position:absolute;}.lsd-date-field--large{width:208px;}.lsd-date-field--large .lsd-date-field__label{margin:0 0 6px 18px;}.lsd-date-field--large .lsd-date-field__input-container{height:40px;}.lsd-date-field--large .lsd-date-field__input-container__input{padding:9px 0px 9px 17px;}.lsd-date-field--large .lsd-date-field__input-container__icon{padding:12px 13px;}.lsd-date-field--large .lsd-date-field__supporting-text{margin:6px 18px 0 18px;}.lsd-date-field--medium{width:188px;}.lsd-date-field--medium .lsd-date-field__label{margin:0 0 6px 14px;}.lsd-date-field--medium .lsd-date-field__input-container{height:32px;}.lsd-date-field--medium .lsd-date-field__input-container__input{padding:5px 11px 5px 13px;}.lsd-date-field--medium .lsd-date-field__input-container__icon{padding:8px 11px;}.lsd-date-field--medium .lsd-date-field__supporting-text{margin:6px 14px 0 14px;}.lsd-date-field--small{width:164px;}.lsd-date-field--small .lsd-date-field__label{margin:0 0 6px 12px;}.lsd-date-field--small .lsd-date-field__input-container{height:28px;}.lsd-date-field--small .lsd-date-field__input-container__input{padding:5px 9px 5px 11px;font-size:12px;}.lsd-date-field--small .lsd-date-field__input-container__icon{padding:6px 9px;}.lsd-date-field--small .lsd-date-field__supporting-text{margin:6px 12px 0 12px;}.lsd-date-field__input-container__input:invalid,.lsd-date-field__input-container__input--filled{color:rgb(var(--lsd-border-primary));opacity:1;}.lsd-date-field--error .lsd-date-field__input-container__input::-webkit-datetime-edit-year-field,.lsd-date-field--error .lsd-date-field__input-container__input::-webkit-datetime-edit-month-field,.lsd-date-field--error .lsd-date-field__input-container__input::-webkit-datetime-edit-day-field{-webkit-text-decoration:line-through;text-decoration:line-through;}@supports not selector(::-webkit-datetime-edit-day-field){.lsd-date-field--error .lsd-date-field__input-container__input{-webkit-text-decoration:line-through;text-decoration:line-through;}}</style><style data-emotion="css-global 1gjtao4">.lsd-calendar{border:1px solid rgb(var(--lsd-border-primary));visibility:hidden;position:absolute!important;top:0;left:0;opacity:0;visibility:hidden;margin:0;padding:0;box-sizing:border-box;background:rgb(var(--lsd-surface-primary));-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;}.lsd-calendar-container{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column;padding:8px;}.lsd-calendar--open{opacity:1;visibility:visible;}.lsd-calendar-header{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-box-pack:center;-ms-flex-pack:center;-webkit-justify-content:center;justify-content:center;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;height:32px;margin-bottom:8px;}.lsd-calendar__week_day{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-box-pack:center;-ms-flex-pack:center;-webkit-justify-content:center;justify-content:center;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;aspect-ratio:1/1;margin-bottom:4px;}.lsd-calendar__change-year{position:relative;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-box-pack:center;-ms-flex-pack:center;-webkit-justify-content:center;justify-content:center;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;padding:2px 0xp 2px 8px;gap:6px;border:1px solid transparent;}.lsd-calendar__change-year--active .lsd-calendar__year-and-icon{border:1px solid rgb(var(--lsd-border-primary));}.lsd-calendar__change-year-icon-container{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-box-pack:center;-ms-flex-pack:center;-webkit-justify-content:center;justify-content:center;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;cursor:pointer;border:none;}.lsd-calendar-month{margin-right:8px;}.lsd-calendar__month-and-year{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:center;-ms-flex-pack:center;-webkit-justify-content:center;justify-content:center;}.lsd-calendar-day__container{cursor:pointer;background:transparent;position:relative;box-sizing:border-box;border:1px solid transparent;}.lsd-calendar-day{aspect-ratio:1/1;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-box-pack:center;-ms-flex-pack:center;-webkit-justify-content:center;justify-content:center;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;}.lsd-calendar-day:hover{cursor:pointer;-webkit-text-decoration:underline;text-decoration:underline;text-decoration-color:rgb(var(--lsd-border-primary));}.lsd-calendar-day label:hover{cursor:pointer;}.lsd-calendar-day--selected{border:1px solid rgb(var(--lsd-border-primary));}.lsd-calendar-day--disabled{opacity:0.3;cursor:default;}.lsd-calendar-day__today_indicator{position:absolute;left:50%;-webkit-transform:translateX(-50%);-moz-transform:translateX(-50%);-ms-transform:translateX(-50%);transform:translateX(-50%);bottom:2px;}.lsd-calendar--disabled{pointer-events:none;border:1px solid rgba(var(--lsd-border-primary), 0.3);}.lsd-calendar--disabled label{opacity:0.3;}.lsd-calendar--disabled .lsd-calendar__button{opacity:0.3;}.lsd-calendar--disabled .lsd-calendar-day--selected{opacity:0.3;}.lsd-calendar__button{border:1px solid rgb(var(--lsd-border-primary));cursor:pointer;background:transparent;width:32px;height:32px;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:center;-ms-flex-pack:center;-webkit-justify-content:center;justify-content:center;position:absolute;}.lsd-calendar__next-month-button{top:8px;right:8px;}.lsd-calendar__previous-month-button{top:8px;left:8px;}.lsd-calendar-day--border-left{border-left:1px double rgb(var(--lsd-border-primary));}.lsd-calendar-day--border-right{border-right:1px double rgb(var(--lsd-border-primary));}.lsd-calendar-day--border-left-and-right{border-left:1px double rgb(var(--lsd-border-primary));border-right:1px double rgb(var(--lsd-border-primary));}.lsd-calendar-day--border-top-and-bottom{border-top:1px double rgb(var(--lsd-border-primary));border-bottom:1px double rgb(var(--lsd-border-primary));}.lsd-calendar__month-table{border-collapse:collapse;}.lsd-calendar__year-dropdown{box-sizing:border-box;position:absolute;top:100%;left:0;max-height:200px;overflow-y:auto;width:100%;border:1px solid rgb(var(--lsd-border-primary));border-top:none;z-index:1;}.lsd-calendar__year-dropdown .lsd-calendar-year{border-bottom:1px solid rgb(var(--lsd-border-primary));}.lsd-calendar__year-dropdown--hidden{visibility:hidden;}.lsd-calendar-year{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;cursor:pointer;-webkit-transition:background-color 0.2s;transition:background-color 0.2s;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;background:rgb(var(--lsd-surface-primary));}.lsd-calendar-year:hover{-webkit-text-decoration:underline;text-decoration:underline;}.lsd-calendar__year-and-icon{border:1px solid rgb(var(--lsd-border-primary));}.lsd-calendar--large .lsd-calendar-year{padding:6px 0px 6px 14px;}.lsd-calendar--large .lsd-calendar__change-year-icon-container{width:32px;}.lsd-calendar--medium .lsd-calendar-year{padding:6px 0px 6px 12px;}.lsd-calendar--medium .lsd-calendar__change-year-icon-container{width:28px;}.lsd-calendar--small .lsd-calendar-year{padding:6px 0px 6px 12px;}.lsd-calendar--small .lsd-calendar__change-year-icon-container{width:28px;}</style><style data-emotion="css-global dlrd7d">.lsd-toast{box-sizing:border-box;display:-webkit-inline-box;display:-webkit-inline-flex;display:-ms-inline-flexbox;display:inline-flex;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;background:rgb(var(--lsd-surface-primary));border:1px solid rgb(var(--lsd-border-primary));padding:8px;height:-webkit-fit-content;height:-moz-fit-content;height:fit-content;}.lsd-toast__inline-button-container{-webkit-flex-shrink:0;-ms-flex-negative:0;flex-shrink:0;}.lsd-toast__column-button-container{margin-top:18px;margin-bottom:6px;}.lsd-toast__inline-container{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:justify;-webkit-justify-content:space-between;justify-content:space-between;-webkit-box-flex:1;-webkit-flex-grow:1;-ms-flex-positive:1;flex-grow:1;}.lsd-toast__column-container{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column;-webkit-box-pack:justify;-webkit-justify-content:space-between;justify-content:space-between;}.lsd-toast__text-container{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column;color:rgb(var(--lsd-text-secondary));padding-left:12px;}.lsd-toast__title{position:relative;}.lsd-toast__information{margin-top:4px;}.lsd-toast__button-container{min-height:28px;min-width:60px;width:-webkit-fit-content;width:-moz-fit-content;width:fit-content;padding:0px 12px;}.lsd-toast__close-button{margin-bottom:auto;-webkit-flex-shrink:0;-ms-flex-negative:0;flex-shrink:0;height:28px;width:28px;margin-left:auto;}.lsd-toast__column-icon-container{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-box-pack:center;-ms-flex-pack:center;-webkit-justify-content:center;justify-content:center;margin-bottom:auto;position:relative;top:4px;padding-left:4px;}.lsd-toast__inline-icon-container{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:center;-ms-flex-pack:center;-webkit-justify-content:center;justify-content:center;padding-left:4px;}.lsd-toast__icon{position:relative;}.lsd-toast--large{width:364px;}.lsd-toast--medium{width:336px;}.lsd-toast--small{width:296px;}.lsd-toast--small .lsd-toast__icon{top:0px;}</style><style data-emotion="css-global 5wlfwk">.lsd-toast-provider__toast-container{position:fixed;-webkit-transition:all 230ms cubic-bezier(0.21, 1.02, 0.73, 1);transition:all 230ms cubic-bezier(0.21, 1.02, 0.73, 1);z-index:9999;}.lsd-toast-provider__toast--top-left,.lsd-toast-provider__toast--top-center,.lsd-toast-provider__toast--top-right{top:0;}.lsd-toast-provider__toast--bottom-left,.lsd-toast-provider__toast--bottom-center,.lsd-toast-provider__toast--bottom-right{bottom:0;}.lsd-toast-provider__toast--top-center,.lsd-toast-provider__toast--bottom-center{left:50%;}.lsd-toast-provider__toast--top-right,.lsd-toast-provider__toast--bottom-right{right:0;}</style><style data-emotion="css-global 9yw6e1">.lsd-button-group{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:row;-ms-flex-direction:row;flex-direction:row;}.lsd-button-group >*:not(:last-child).lsd-button--outlined,.lsd-button-group >*:not(:last-child) .lsd-button--outlined{border-right:none;}</style><style data-emotion="css-global 17u9w7w">.lsd-date-range-picker{box-sizing:border-box;}.lsd-date-range-picker .lsd-date-field--outlined{border:none;}.lsd-date-range-picker .lsd-date-field__input-container__icon{padding:8px;}.lsd-date-range-picker__label{display:block;}.lsd-date-range-picker__input-container{box-sizing:border-box;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;border:1px solid transparent;}.lsd-date-picker__calendar{border-top:none!important;}.lsd-date-picker__calendar .lsd-tooltip-base__arrow-tip{-webkit-transition:left 0.2s ease-in-out;transition:left 0.2s ease-in-out;}.lsd-date-range-picker--calendar-open .lsd-date-range-picker__input-container{border-bottom:1px solid rgb(var(--lsd-border-primary));}.lsd-date-range-picker__icon{cursor:pointer;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:center;-ms-flex-pack:center;-webkit-justify-content:center;justify-content:center;-webkit-box-flex:1;-webkit-flex-grow:1;-ms-flex-positive:1;flex-grow:1;padding:0 10px;}.lsd-date-range-picker--disabled{opacity:0.3;}.lsd-date-range-picker__supporting-text{position:absolute;}.lsd-date-range-picker--large{width:318px;}.lsd-date-range-picker--large .lsd-date-field--large{width:156px;}.lsd-date-range-picker--large .lsd-date-field__input-container__input{padding-right:0;}.lsd-date-range-picker--large .lsd-date-field__input-container__icon{padding:11px 12px;}.lsd-date-range-picker--large .lsd-date-range-picker__label{margin:0 0 6px 18px;}.lsd-date-range-picker--large .lsd-date-range-picker__input-container{height:40px;}.lsd-date-range-picker--large .lsd-date-range-picker__supporting-text{margin:6px 18px 0 18px;}.lsd-date-range-picker--medium{width:290px;}.lsd-date-range-picker--medium .lsd-date-field--medium{width:142px;}.lsd-date-range-picker--medium .lsd-date-field__input-container__input{padding-right:0;}.lsd-date-range-picker--medium .lsd-date-field__input-container__icon{padding:7px 8px;}.lsd-date-range-picker--medium .lsd-date-range-picker__label{margin:0 0 6px 14px;}.lsd-date-range-picker--medium .lsd-date-range-picker__input-container{height:32px;}.lsd-date-range-picker--medium .lsd-date-range-picker__supporting-text{margin:6px 14px 0 14px;}.lsd-date-range-picker--small{width:262px;}.lsd-date-range-picker--small .lsd-date-field--small{width:128px;}.lsd-date-range-picker--small .lsd-date-field__input-container__input{padding-right:0;}.lsd-date-range-picker--small .lsd-date-field__input-container__icon{padding:5px 7px;}.lsd-date-range-picker--small .lsd-date-range-picker__label{margin:0 0 6px 12px;}.lsd-date-range-picker--small .lsd-date-range-picker__input-container{height:28px;}.lsd-date-range-picker--small .lsd-date-range-picker__supporting-text{margin:6px 12px 0 12px;}.lsd-date-range-picker__separator{margin-left:3px;width:1px;height:100%;}.lsd-date-range-picker__separator{border-left:1px solid transparent;}.lsd-date-range-picker--outlined{border:1px solid rgb(var(--lsd-border-primary));}.lsd-date-range-picker--outlined .lsd-date-range-picker__separator{border-left:1px solid rgb(var(--lsd-border-primary));}</style><style data-emotion="css-global 19d282h">.lsd-tooltip-base{border:1px solid rgb(var(--lsd-border-primary));position:relative;}.lsd-tooltip-base__arrow-tip{border:1px solid rgb(var(--lsd-border-primary));position:absolute;background:rgb(var(--lsd-surface-primary));}.lsd-tooltip-base__content{background:rgb(var(--lsd-surface-primary));width:100%;height:100%;position:relative;z-index:1;}</style><style data-emotion="css-global 1o77wkp">[data-theme=dark]{--lsd-display1-fontSize:5.5rem;--lsd-display1-fontWeight:normal;--lsd-display1-lineHeight:6rem;--lsd-display2-fontSize:4rem;--lsd-display2-fontWeight:normal;--lsd-display2-lineHeight:4.5rem;--lsd-display3-fontSize:3.5rem;--lsd-display3-fontWeight:normal;--lsd-display3-lineHeight:4rem;--lsd-display4-fontSize:3rem;--lsd-display4-fontWeight:normal;--lsd-display4-lineHeight:3.5rem;--lsd-h1-fontSize:2.5rem;--lsd-h1-fontWeight:normal;--lsd-h1-lineHeight:3rem;--lsd-h2-fontSize:2rem;--lsd-h2-fontWeight:normal;--lsd-h2-lineHeight:2.5rem;--lsd-h3-fontSize:1.75rem;--lsd-h3-fontWeight:normal;--lsd-h3-lineHeight:2.25rem;--lsd-h4-fontSize:1.5rem;--lsd-h4-fontWeight:normal;--lsd-h4-lineHeight:2rem;--lsd-h5-fontSize:1.25rem;--lsd-h5-fontWeight:normal;--lsd-h5-lineHeight:1.75rem;--lsd-h6-fontSize:1rem;--lsd-h6-fontWeight:normal;--lsd-h6-lineHeight:1.5rem;--lsd-subtitle1-fontSize:1.125rem;--lsd-subtitle1-fontWeight:normal;--lsd-subtitle1-lineHeight:1.5rem;--lsd-subtitle2-fontSize:1rem;--lsd-subtitle2-fontWeight:normal;--lsd-subtitle2-lineHeight:1.5rem;--lsd-subtitle3-fontSize:0.875rem;--lsd-subtitle3-fontWeight:normal;--lsd-subtitle3-lineHeight:1.25rem;--lsd-subtitle4-fontSize:0.75rem;--lsd-subtitle4-fontWeight:normal;--lsd-subtitle4-lineHeight:1rem;--lsd-body1-fontSize:1rem;--lsd-body1-fontWeight:normal;--lsd-body1-lineHeight:1.5rem;--lsd-body2-fontSize:0.875rem;--lsd-body2-fontWeight:normal;--lsd-body2-lineHeight:1.25rem;--lsd-body3-fontSize:0.75rem;--lsd-body3-fontWeight:normal;--lsd-body3-lineHeight:1rem;--lsd-label1-fontSize:0.875rem;--lsd-label1-fontWeight:normal;--lsd-label1-lineHeight:1.25rem;--lsd-label2-fontSize:0.75rem;--lsd-label2-fontWeight:normal;--lsd-label2-lineHeight:1rem;--lsd-typography-generic-font-family:sans-serif;--lsd-theme-primary:255,255,255;--lsd-theme-secondary:0,0,0;--lsd-surface-primary:0,0,0;--lsd-surface-secondary:255,255,255;--lsd-border-primary:255,255,255;--lsd-border-secondary:0,0,0;--lsd-icon-primary:255,255,255;--lsd-icon-secondary:0,0,0;--lsd-text-primary:255,255,255;--lsd-text-secondary:0,0,0;--lsd-text-tertiary:255,255,255,0.34;--lsd-spacing-4:4px;--lsd-spacing-8:8px;--lsd-spacing-16:16px;--lsd-spacing-24:24px;--lsd-spacing-32:32px;--lsd-spacing-40:40px;--lsd-spacing-64:64px;--lsd-spacing-80:80px;--lsd-spacing-96:96px;--lsd-spacing-120:120px;}</style><style data-emotion="css-global yon3n1">[data-theme=light]{--lsd-display1-fontSize:5.5rem;--lsd-display1-fontWeight:normal;--lsd-display1-lineHeight:6rem;--lsd-display2-fontSize:4rem;--lsd-display2-fontWeight:normal;--lsd-display2-lineHeight:4.5rem;--lsd-display3-fontSize:3.5rem;--lsd-display3-fontWeight:normal;--lsd-display3-lineHeight:4rem;--lsd-display4-fontSize:3rem;--lsd-display4-fontWeight:normal;--lsd-display4-lineHeight:3.5rem;--lsd-h1-fontSize:2.5rem;--lsd-h1-fontWeight:normal;--lsd-h1-lineHeight:3rem;--lsd-h2-fontSize:2rem;--lsd-h2-fontWeight:normal;--lsd-h2-lineHeight:2.5rem;--lsd-h3-fontSize:1.75rem;--lsd-h3-fontWeight:normal;--lsd-h3-lineHeight:2.25rem;--lsd-h4-fontSize:1.5rem;--lsd-h4-fontWeight:normal;--lsd-h4-lineHeight:2rem;--lsd-h5-fontSize:1.25rem;--lsd-h5-fontWeight:normal;--lsd-h5-lineHeight:1.75rem;--lsd-h6-fontSize:1rem;--lsd-h6-fontWeight:normal;--lsd-h6-lineHeight:1.5rem;--lsd-subtitle1-fontSize:1.125rem;--lsd-subtitle1-fontWeight:normal;--lsd-subtitle1-lineHeight:1.5rem;--lsd-subtitle2-fontSize:1rem;--lsd-subtitle2-fontWeight:normal;--lsd-subtitle2-lineHeight:1.5rem;--lsd-subtitle3-fontSize:0.875rem;--lsd-subtitle3-fontWeight:normal;--lsd-subtitle3-lineHeight:1.25rem;--lsd-subtitle4-fontSize:0.75rem;--lsd-subtitle4-fontWeight:normal;--lsd-subtitle4-lineHeight:1rem;--lsd-body1-fontSize:1rem;--lsd-body1-fontWeight:normal;--lsd-body1-lineHeight:1.5rem;--lsd-body2-fontSize:0.875rem;--lsd-body2-fontWeight:normal;--lsd-body2-lineHeight:1.25rem;--lsd-body3-fontSize:0.75rem;--lsd-body3-fontWeight:normal;--lsd-body3-lineHeight:1rem;--lsd-label1-fontSize:0.875rem;--lsd-label1-fontWeight:normal;--lsd-label1-lineHeight:1.25rem;--lsd-label2-fontSize:0.75rem;--lsd-label2-fontWeight:normal;--lsd-label2-lineHeight:1rem;--lsd-typography-generic-font-family:sans-serif;--lsd-theme-primary:0,0,0;--lsd-theme-secondary:255,255,255;--lsd-surface-primary:255,255,255;--lsd-surface-secondary:0,0,0;--lsd-border-primary:0,0,0;--lsd-border-secondary:255,255,255;--lsd-icon-primary:0,0,0;--lsd-icon-secondary:255,255,255;--lsd-text-primary:0,0,0;--lsd-text-secondary:255,255,255;--lsd-text-tertiary:0,0,0,0.34;--lsd-spacing-4:4px;--lsd-spacing-8:8px;--lsd-spacing-16:16px;--lsd-spacing-24:24px;--lsd-spacing-32:32px;--lsd-spacing-40:40px;--lsd-spacing-64:64px;--lsd-spacing-80:80px;--lsd-spacing-96:96px;--lsd-spacing-120:120px;}</style><div class="root_QACb"><div class="blog-archive-page"><div role="region" aria-label="Skip to main content"><a class="skipToContent_fXgn" href="#__docusaurus_skipToContent_fallback">Skip to main content</a></div><nav aria-label="Main" class="navbar navbar--fixed-top navbarHideable_OoEf"><div class="navbar__inner"><div class="navbar__left"><a class="navbar__brand" href="/"><div class="navbar__logo"><img src="/theme/image/logo.svg" alt="Vac Research" class="themedImage_ToTc themedImage--light_HNdA" height="26"><img src="/theme/image/logo.svg" alt="Vac Research" class="themedImage_ToTc themedImage--dark_i4oU" height="26"></div><b class="navbar__title text--truncate"></b></a></div><div class="navbar__left-items"><a class="navbar__item navbar__link" href="/"><div class="lsd-typography lsd-typography--body2 linkContent__x3v">About Vac</div></a><a class="navbar__item navbar__link" href="/community"><div class="lsd-typography lsd-typography--body2 linkContent__x3v">Community</div></a><a aria-current="page" class="navbar__item navbar__link navbar__link--active" href="/rlog"><div class="lsd-typography lsd-typography--body2 linkContent__x3v">Research Blog</div></a><a class="navbar__item navbar__link" href="/join-us"><div class="lsd-typography lsd-typography--body2 linkContent__x3v">Join Us</div></a></div><div class="navbar__right-items"><div class="iconButtonGroup_ktNv lsd-icon-button-group lsd-icon-button-group--medium lsd-icon-button-group--outlined"><button class="clean-btn toggle_K23S colorModeToggle_GSaI navbar__color-mode-toggle toggleButtonDisabled_AAS_ lsd-icon-button lsd-icon-button--medium lsd-icon-button--outlined lsd-icon-button--disabled" type="button" title="Switch between dark and light mode (currently dark mode)" aria-label="Switch between dark and light mode (currently dark mode)" aria-live="polite"><svg viewBox="0 0 24 24" width="24" height="24" class="lightToggleIcon_K4TL"><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"></path></svg><svg viewBox="0 0 24 24" width="24" height="24" class="darkToggleIcon_lKkA"><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"></path></svg></button><button aria-label="Toggle navigation bar" aria-expanded="false" class="navbar__toggle clean-btn" type="button"><svg width="30" height="30" viewBox="0 0 30 30" aria-hidden="true"><path stroke="currentColor" stroke-linecap="round" stroke-miterlimit="10" stroke-width="2" d="M4 7h22M4 15h22M4 23h22"></path></svg></button></div></div></div><div role="presentation" class="navbar-sidebar__backdrop"></div></nav><div id="__docusaurus_skipToContent_fallback" class="main-wrapper mainWrapper_z2l0"><header class="hero hero--primary"><div class="container"><h1 class="hero__title">Archive</h1><p class="hero__subtitle">Archive</p></div></header><main><section class="margin-vert--lg"><div class="container"><div class="row"><div class="col col--4 margin-vert--lg"><h3>2019</h3><ul><li><a href="/rlog/fixing-whisper-with-waku">December 3, 2019 - Fixing Whisper with Waku</a></li><li><a href="/rlog/feasibility-semaphore-rate-limiting-zksnarks">November 8, 2019 - Feasibility Study: Semaphore rate limiting through zkSNARKs</a></li><li><a href="/rlog/remote-log">October 4, 2019 - P2P Data Sync with a Remote Log</a></li><li><a href="/rlog/vac-overview">August 2, 2019 - Vac - A Rough Overview</a></li><li><a href="/rlog/p2p-data-sync-for-mobile">July 19, 2019 - P2P Data Sync for Mobile</a></li></ul></div><div class="col col--4 margin-vert--lg"><h3>2020</h3><ul><li><a href="/rlog/waku-v2-ethereum-messaging">November 10, 2020 - [Talk] Vac, Waku v2 and Ethereum Messaging</a></li><li><a href="/rlog/waku-v2-update">September 28, 2020 - Waku v2 Update</a></li><li><a href="/rlog/waku-v2-plan">July 1, 2020 - What's the Plan for Waku v2?</a></li><li><a href="/rlog/feasibility-discv5">April 27, 2020 - Feasibility Study: Discv5</a></li><li><a href="/rlog/wechat-replacement-need">April 16, 2020 - What Would a WeChat Replacement Need?</a></li><li><a href="/rlog/kademlia-to-discv5">April 9, 2020 - From Kademlia to Discv5</a></li><li><a href="/rlog/waku-update">February 14, 2020 - Waku Update</a></li><li><a href="/rlog/dns-based-discovery">February 7, 2020 - DNS Based Discovery</a></li></ul></div><div class="col col--4 margin-vert--lg"><h3>2021</h3><ul><li><a href="/rlog/ethics-surveillance-tech">December 3, 2021 - Opinion: Pseudo-ethics in the Surveillance Tech Industry</a></li><li><a href="/rlog/waku-v1-v2-bandwidth-comparison">November 3, 2021 - Waku v1 vs Waku v2: Bandwidth Comparison</a></li><li><a href="/rlog/waku-v2-ethereum-coscup">August 6, 2021 - [Talk at COSCUP] Vac, Waku v2 and Ethereum Messaging</a></li><li><a href="/rlog/presenting-js-waku">June 4, 2021 - Presenting JS-Waku: Waku v2 in the Browser</a></li><li><a href="/rlog/rln-relay">March 5, 2021 - Privacy-preserving p2p economic spam protection in Waku v2</a></li></ul></div><div class="col col--4 margin-vert--lg"><h3>2022</h3><ul><li><a href="/rlog/waku-for-all">November 8, 2022 - Waku for All Decentralized Applications and Infrastructures</a></li><li><a href="/rlog/building-privacy-protecting-infrastructure">November 4, 2022 - Building Privacy-Protecting Infrastructure</a></li><li><a href="/rlog/wakuv2-relay-anon">July 22, 2022 - Waku Privacy and Anonymity Analysis Part I: Definitions and Waku Relay</a></li><li><a href="/rlog/wakuv2-noise">May 17, 2022 - Noise handshakes as key-exchange mechanism for Waku</a></li><li><a href="/rlog/wakuv2-apd">May 9, 2022 - Waku v2 Ambient Peer Discovery</a></li><li><a href="/rlog/introducing-nwaku">April 12, 2022 - Introducing nwaku</a></li></ul></div><div class="col col--4 margin-vert--lg"><h3>2023</h3><ul><li><a href="/rlog/rln-anonymous-dos-prevention">November 7, 2023 - Strengthening Anonymous DoS Prevention with Rate Limiting Nullifiers in Waku</a></li><li><a href="/rlog/GossipSub Improvements">November 6, 2023 - GossipSub Improvements: Evolution of Overlay Design and Message Dissemination in Unstructured P2P Networks</a></li><li><a href="/rlog/Nescience-A-zkVM-leveraging-hiding-properties">August 28, 2023 - Nescience - A zkVM leveraging hiding properties</a></li><li><a href="/rlog/device-pairing-in-js-waku-and-go-waku">April 24, 2023 - Device Pairing in Js-waku and Go-waku</a></li><li><a href="/rlog/future-of-waku-network">April 3, 2023 - The Future of Waku Network: Scaling, Incentivization, and Heterogeneity</a></li></ul></div><div class="col col--4 margin-vert--lg"><h3>2024</h3><ul><li><a href="/rlog/zkVM-explorations">August 27, 2024 - Exploring zkVMs: Which Projects Truly Qualify as Zero-Knowledge Virtual Machines?</a></li><li><a href="/rlog/Nescience-state-separation-architecture">August 23, 2024 - Nescience: A User-Centric State-Separation Architecture</a></li><li><a href="/rlog/membership-with-bloom-filters-and-cuckoo-filters">July 19, 2024 - Membership with Bloom Filters and Cuckoo Filters</a></li><li><a href="/rlog/rln-v3">May 13, 2024 - RLN-v3: Towards a Flexible and Cost-Efficient Implementation</a></li><li><a href="/rlog/rln-light-verifiers">May 3, 2024 - Verifying RLN Proofs in Light Clients with Subtrees</a></li></ul></div></div></div></section></main></div><footer class="footer"><div class="container container-fluid firstRow_ar1q"><div class="footer__bottom text--center"><div class="margin-bottom--sm"><a class="footerLogoLink_BH7S" href="/"><img src="/theme/image/logo.svg" alt="Vac Research" class="themedImage_ToTc themedImage--light_HNdA footer__logo" width="22"><img src="/theme/image/logo.svg" alt="Vac Research" class="themedImage_ToTc themedImage--dark_i4oU footer__logo" width="22"></a></div><div class="footer__copyright">Vac Research © 2024<br>All rights reserved.</div></div><div class="row footer__links"><div class="col footer__col"><div class="footer__title"></div><ul class="footer__items clean-list"><li class="footer__item"><a href="https://twitter.com/vacp2p" target="_blank" rel="noopener noreferrer" class="footer__link-item">Twitter<svg width="13.5" height="13.5" aria-hidden="true" viewBox="0 0 24 24" class="iconExternalLink_nPIU"><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"></path></svg></a></li><li class="footer__item"><a href="https://discord.gg/PQFdubGt6d" target="_blank" rel="noopener noreferrer" class="footer__link-item">Discord<svg width="13.5" height="13.5" aria-hidden="true" viewBox="0 0 24 24" class="iconExternalLink_nPIU"><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"></path></svg></a></li><li class="footer__item"><a href="https://github.com/vacp2p" target="_blank" rel="noopener noreferrer" class="footer__link-item">Github<svg width="13.5" height="13.5" aria-hidden="true" viewBox="0 0 24 24" class="iconExternalLink_nPIU"><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"></path></svg></a></li></ul></div><div class="col footer__col"><div class="footer__title"></div><ul class="footer__items clean-list"><li class="footer__item"><a href="https://jobs.status.im/" target="_blank" rel="noopener noreferrer" class="footer__link-item">Work With Us<svg width="13.5" height="13.5" aria-hidden="true" viewBox="0 0 24 24" class="iconExternalLink_nPIU"><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"></path></svg></a></li><li class="footer__item"><a class="footer__link-item" href="/terms">Terms & Conditions</a></li><li class="footer__item"><a class="footer__link-item" href="/privacy-policy">Privacy Policy</a></li><li class="footer__item"><a class="footer__link-item" href="/security">Security</a></li></ul></div></div></div><div class="secondRow__ww3"><div class="footer__bottom text--center">Logos Collective</div><div class="row footer__links"><div class="col footer__col"><div class="footer__title">Research</div><ul class="footer__items clean-list"><li class="footer__item"><a href="https://vac.dev" target="_blank" rel="noopener noreferrer" class="footer__link-item">VacP2P<svg width="13.5" height="13.5" aria-hidden="true" viewBox="0 0 24 24" class="iconExternalLink_nPIU"><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"></path></svg></a></li><li class="footer__item"><a href="https://afaik.institute" target="_blank" rel="noopener noreferrer" class="footer__link-item">AFAIK<svg width="13.5" height="13.5" aria-hidden="true" viewBox="0 0 24 24" class="iconExternalLink_nPIU"><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"></path></svg></a></li></ul></div><div class="col footer__col"><div class="footer__title">Infrastructure</div><ul class="footer__items clean-list"><li class="footer__item"><a href="https://waku.org/" target="_blank" rel="noopener noreferrer" class="footer__link-item">Waku<svg width="13.5" height="13.5" aria-hidden="true" viewBox="0 0 24 24" class="iconExternalLink_nPIU"><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"></path></svg></a></li><li class="footer__item"><a href="https://nimbus.team/" target="_blank" rel="noopener noreferrer" class="footer__link-item">Nimbus<svg width="13.5" height="13.5" aria-hidden="true" viewBox="0 0 24 24" class="iconExternalLink_nPIU"><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"></path></svg></a></li><li class="footer__item"><a href="https://codex.storage" target="_blank" rel="noopener noreferrer" class="footer__link-item">Codex<svg width="13.5" height="13.5" aria-hidden="true" viewBox="0 0 24 24" class="iconExternalLink_nPIU"><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"></path></svg></a></li><li class="footer__item"><a href="https://nomos.tech" target="_blank" rel="noopener noreferrer" class="footer__link-item">Nomos<svg width="13.5" height="13.5" aria-hidden="true" viewBox="0 0 24 24" class="iconExternalLink_nPIU"><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"></path></svg></a></li></ul></div><div class="col footer__col"><div class="footer__title">Creative Studio</div><ul class="footer__items clean-list"><li class="footer__item"><a href="https://acid.info" target="_blank" rel="noopener noreferrer" class="footer__link-item">Acid.info<svg width="13.5" height="13.5" aria-hidden="true" viewBox="0 0 24 24" class="iconExternalLink_nPIU"><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"></path></svg></a></li></ul></div><div class="col footer__col"><div class="footer__title">Movement</div><ul class="footer__items clean-list"><li class="footer__item"><a href="https://logos.co" target="_blank" rel="noopener noreferrer" class="footer__link-item">Logos<svg width="13.5" height="13.5" aria-hidden="true" viewBox="0 0 24 24" class="iconExternalLink_nPIU"><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"></path></svg></a></li></ul></div><div class="col footer__col"><div class="footer__title">User-facing products</div><ul class="footer__items clean-list"><li class="footer__item"><a href="https://status.im" target="_blank" rel="noopener noreferrer" class="footer__link-item">Status<svg width="13.5" height="13.5" aria-hidden="true" viewBox="0 0 24 24" class="iconExternalLink_nPIU"><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"></path></svg></a></li><li class="footer__item"><a href="https://keycard.tech" target="_blank" rel="noopener noreferrer" class="footer__link-item">Keycard<svg width="13.5" height="13.5" aria-hidden="true" viewBox="0 0 24 24" class="iconExternalLink_nPIU"><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"></path></svg></a></li></ul></div></div></div><button class="backToTop_wDfN lsd-button lsd-button--small lsd-button--outlined"><span class="lsd-typography lsd-typography--label2 lsd-button__text">Back to top ↑</span></button></footer></div></div></div> -<script src="/assets/js/runtime~main.556fa6f5.js"></script> -<script src="/assets/js/main.ffc20c94.js"></script> + ) .lsd-dropdown__trigger:focus .lsd-dropdown__option-label{-webkit-text-decoration:underline;text-decoration:underline;}.lsd-dropdown__label{display:block;}.lsd-dropdown__button-container{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-box-pack:justify;-webkit-justify-content:space-between;justify-content:space-between;}.lsd-dropdown__trigger{width:100%;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:row;-ms-flex-direction:row;flex-direction:row;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:justify;-webkit-justify-content:space-between;justify-content:space-between;border:none;cursor:pointer;background:none;}.lsd-dropdown__trigger:focus{outline:none;}.lsd-dropdown__option-label{cursor:inherit;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;}.lsd-dropdown__icons{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:row;-ms-flex-direction:row;flex-direction:row;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:center;-ms-flex-pack:center;-webkit-justify-content:center;justify-content:center;gap:8px;}.lsd-dropdown__icon{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;}.lsd-dropdown__supporting-text{margin:6px 14px;}.lsd-dropdown--error .lsd-dropdown__option-label{-webkit-text-decoration:line-through;text-decoration:line-through;}.lsd-dropdown--disabled{opacity:0.34;cursor:initial;}.lsd-dropdown--large{width:208px;}.lsd-dropdown--large.lsd-dropdown--error{width:230px;}.lsd-dropdown--large .lsd-dropdown__label{margin:0 0 6px 18px;}.lsd-dropdown--large .lsd-dropdown__button-container{height:40px;}.lsd-dropdown--large .lsd-dropdown__trigger{padding:10px 0px 10px 18px;}.lsd-dropdown--large .lsd-dropdown__icons{padding:0px 14px;}.lsd-dropdown--medium{width:188px;}.lsd-dropdown--medium.lsd-dropdown--error{width:210px;}.lsd-dropdown--medium .lsd-dropdown__label{margin:0 0 6px 14px;}.lsd-dropdown--medium .lsd-dropdown__button-container{height:32px;}.lsd-dropdown--medium .lsd-dropdown__trigger{padding:6px 0px 6px 14px;}.lsd-dropdown--medium .lsd-dropdown__icons{padding:0px 12px;}.lsd-dropdown--small{width:164px;}.lsd-dropdown--small.lsd-dropdown--error{width:186px;}.lsd-dropdown--small .lsd-dropdown__label{margin:0 0 6px 12px;}.lsd-dropdown--small .lsd-dropdown__button-container{height:28px;}.lsd-dropdown--small .lsd-dropdown__trigger{padding:6px 0px 6px 12px;}.lsd-dropdown--small .lsd-dropdown__icons{padding:0px 10px;}.lsd-dropdown--outlined .lsd-dropdown__button-container{border:1px solid rgb(var(--lsd-border-primary));}.lsd-dropdown--underlined .lsd-dropdown__button-container{border:1px solid transparent;border-bottom:1px solid rgb(var(--lsd-border-primary));}</style><style data-emotion="css-global w2g5fy">.lsd-dropdown-item{width:100%;box-sizing:border-box;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:row;-ms-flex-direction:row;flex-direction:row;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;border:1px solid rgb(var(--lsd-border-primary));}.lsd-dropdown-item:not(.lsd-dropdown-item--disabled){cursor:pointer;}.lsd-dropdown-item:not(.lsd-dropdown-item--disabled):hover,.lsd-dropdown-item:not(.lsd-dropdown-item--disabled):focus{outline:none;}.lsd-dropdown-item:not(.lsd-dropdown-item--disabled):hover .lsd-dropdown-item__label,.lsd-dropdown-item:not(.lsd-dropdown-item--disabled):focus .lsd-dropdown-item__label{-webkit-text-decoration:underline;text-decoration:underline;}.lsd-dropdown-item__label{display:block;overflow:hidden;white-space:nowrap;text-overflow:ellipsis;}.lsd-dropdown-item--disabled{opacity:0.34;}.lsd-dropdown-item__icon{margin-right:18px;-webkit-flex-shrink:0;-ms-flex-negative:0;flex-shrink:0;}.lsd-dropdown-item--small{padding:5px 9px;height:28px;}.lsd-dropdown-item--medium{padding:5px 11px;height:32px;}.lsd-dropdown-item--large{padding:5px 13px;height:40px;}</style><style data-emotion="css-global ww9kgc">.lsd-breadcrumb__list{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:row;-ms-flex-direction:row;flex-direction:row;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;list-style-type:none;margin:0;padding:0;}.lsd-breadcrumb--disabled .lsd-breadcrumb__list{opacity:0.34;cursor:initial;pointer-events:none;}.lsd-breadcrumb__dropdown-menu{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column;overflow:auto;border:1px solid rgb(var(--lsd-border-primary));margin-top:10px;position:absolute;width:auto!important;}.lsd-breadcrumb__dropdown-menu>li{cursor:pointer;}.lsd-breadcrumb__dropdown-menu>li:not(:last-child){border-bottom:1px solid rgb(var(--lsd-border-primary));}.lsd-breadcrumb__dropdown-menu>li:hover,.lsd-breadcrumb__dropdown-menu>li:focus{-webkit-text-decoration:underline;text-decoration:underline;text-decoration-color:rgb(var(--lsd-border-primary));}.lsd-breadcrumb__dropdown-menu li>a{width:164px;padding:5px 11px;}</style><style data-emotion="css-global 4gvini">.lsd-breadcrumb-item{list-style-type:none;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;}.lsd-breadcrumb__list>li:not(:last-child)::after{display:inline-block;margin-inline:12px;content:'/';}.lsd-breadcrumb-item__link{-webkit-text-decoration:none;text-decoration:none;cursor:pointer;}.lsd-breadcrumb-item--outlined{padding:3px 11px;border:1px solid rgb(var(--lsd-border-primary));}.lsd-breadcrumb:not(.lsd-breadcrumb--disabled) .lsd-breadcrumb-item__link:hover,.lsd-breadcrumb:not(.lsd-breadcrumb--disabled) .lsd-breadcrumb-item__link:focus{-webkit-text-decoration:underline;text-decoration:underline;text-decoration-color:rgb(var(--lsd-border-primary));}</style><style data-emotion="css-global 1cwg3oc">.lsd-card{box-sizing:border-box;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column;}.lsd-card>.lsd-card-header{margin-bottom:-1px;}</style><style data-emotion="css-global v7d76i">.lsd-card-header{box-sizing:border-box;padding:10px 18px;text-align:center;border:1px solid rgb(var(--lsd-border-primary));}.lsd-card-header__title{overflow:hidden;word-break:break-all;}.lsd-card-header--large{padding:10px 18px;}.lsd-card-header--medium{padding:6px 14px;}.lsd-card-header--small{padding:6px 12px;}</style><style data-emotion="css-global 1txgafh">.lsd-card-body{box-sizing:border-box;padding:14px 22px;border:1px solid rgb(var(--lsd-border-primary));}</style><style data-emotion="css-global kzy52c">.lsd-tag{width:-webkit-fit-content;width:-moz-fit-content;width:fit-content;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:row;-ms-flex-direction:row;flex-direction:row;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:center;-ms-flex-pack:center;-webkit-justify-content:center;justify-content:center;box-sizing:border-box;border:1px solid rgb(var(--lsd-icon-primary));}.lsd-tag:hover,.lsd-tag:focus{-webkit-text-decoration:underline;text-decoration:underline;cursor:pointer;}.lsd-badge--large{padding:3px 11px;gap:12px;height:28px;}.lsd-badge--small{padding:3px 7px;gap:8px;height:24px;}.lsd-tag--filled{background-color:rgb(var(--lsd-icon-primary));}.lsd-tag--filled .lsd-tag__label{color:rgb(var(--lsd-text-secondary));}.lsd-tag--filled svg{--lsd-icon-primary:var(--lsd-icon-secondary);}.lsd-tag--outlined{color:rgb(var(--lsd-text-primary));}.lsd-tag--disabled{opacity:0.3;cursor:initial;pointer-events:none;}</style><style data-emotion="css-global 4wy0ub">.lsd-text-field{box-sizing:border-box;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column;}.lsd-text-field__input-container{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:justify;-webkit-justify-content:space-between;justify-content:space-between;}.lsd-text-field--disabled{opacity:0.34;}.lsd-text-field__input{border:none;outline:none;font-size:14px;color:rgb(var(--lsd-text-primary));background:none;width:100%;}.lsd-text-field__input:hover{outline:none;}.lsd-text-field__input::-webkit-input-placeholder{color:rgb(var(--lsd-text-primary));opacity:0.3;}.lsd-text-field__input::-moz-placeholder{color:rgb(var(--lsd-text-primary));opacity:0.3;}.lsd-text-field__input:-ms-input-placeholder{color:rgb(var(--lsd-text-primary));opacity:0.3;}.lsd-text-field__input::placeholder{color:rgb(var(--lsd-text-primary));opacity:0.3;}.lsd-text-field--error .lsd-text-field__input{-webkit-text-decoration:line-through;text-decoration:line-through;}.lsd-text-field__supporting-text{width:-webkit-fit-content;width:-moz-fit-content;width:fit-content;}.lsd-text-field--large{width:208px;}.lsd-text-field--large>*{padding:10px 14px 10px 18px;}.lsd-text-field--medium{width:188px;}.lsd-text-field--medium>*{padding:6px 12px 6px 14px;}.lsd-text-field--small{width:164px;}.lsd-text-field--small>*{padding:6px 10px 6px 12px;}.lsd-text-field__label{padding-top:0;padding-bottom:6px;}.lsd-text-field__supporting-text{padding-bottom:0;padding-top:6px;}.lsd-text-field--outlined .lsd-text-field__input-container{border:1px solid rgb(var(--lsd-border-primary));}.lsd-text-field--underlined .lsd-text-field__input-container{border:1px solid transparent;border-bottom:1px solid rgb(var(--lsd-border-primary));}.lsd-text-field__clear-button{padding:0;width:auto;height:auto;margin:0;border:0;}</style><style data-emotion="css-global uhig7c">.lsd-checkbox{position:relative;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:row;-ms-flex-direction:row;flex-direction:row;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;}.lsd-checkbox__input{opacity:0;position:absolute;left:0;top:0;padding:0;margin:0;width:100%;height:100%;}.lsd-checkbox:not(.lsd-checkbox--disabled):hover,.lsd-checkbox:not(.lsd-checkbox--disabled).lsd-checkbox--focused{-webkit-text-decoration:underline;text-decoration:underline;}.lsd-checkbox:not(.lsd-checkbox--disabled) .lsd-checkbox__input{cursor:pointer;}.lsd-checkbox--disabled{opacity:0.34;}.lsd-checkbox__label{margin-left:18px;}.lsd-checkbox--large .lsd-checkbox__label{margin-left:18px;}.lsd-checkbox--medium .lsd-checkbox__label{margin-left:14px;}.lsd-checkbox--small .lsd-checkbox__label{margin-left:12px;}</style><style data-emotion="css-global txommo">.lsd-autocomplete{box-sizing:border-box;}.lsd-autocomplete__label{display:block;}.lsd-autocomplete__input-container{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-box-pack:justify;-webkit-justify-content:space-between;justify-content:space-between;}.lsd-autocomplete--disabled{opacity:0.34;}.lsd-autocomplete__input{border:none;outline:none;font-size:14px;color:rgb(var(--lsd-text-primary));background:none;width:100%;}.lsd-autocomplete__input:hover{outline:none;}.lsd-autocomplete__input::-webkit-input-placeholder{color:rgb(var(--lsd-text-primary));opacity:0.3;}.lsd-autocomplete__input::-moz-placeholder{color:rgb(var(--lsd-text-primary));opacity:0.3;}.lsd-autocomplete__input:-ms-input-placeholder{color:rgb(var(--lsd-text-primary));opacity:0.3;}.lsd-autocomplete__input::placeholder{color:rgb(var(--lsd-text-primary));opacity:0.3;}.lsd-autocomplete__icon{cursor:pointer;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;}.lsd-autocomplete--error{-webkit-text-decoration:line-through;text-decoration:line-through;}.lsd-autocomplete--large{width:208px;}.lsd-autocomplete--large .lsd-autocomplete__label{margin:0 0 6px 18px;}.lsd-autocomplete--large .lsd-autocomplete__input-container{height:40px;}.lsd-autocomplete--large .lsd-autocomplete__input{padding:9px 17px;}.lsd-autocomplete--large .lsd-autocomplete__icon{padding:12px 13px;}.lsd-autocomplete--medium{width:188px;}.lsd-autocomplete--medium .lsd-autocomplete__label{margin:0 0 6px 14px;}.lsd-autocomplete--medium .lsd-autocomplete__input-container{height:32px;}.lsd-autocomplete--medium .lsd-autocomplete__input{padding:5px 13px;}.lsd-autocomplete--medium .lsd-autocomplete__icon{padding:8px 11px;}.lsd-autocomplete--small{width:164px;}.lsd-autocomplete--small .lsd-autocomplete__label{margin:0 0 6px 12px;}.lsd-autocomplete--small .lsd-autocomplete__input-container{height:28px;}.lsd-autocomplete--small .lsd-autocomplete__input{padding:5px 11px;}.lsd-autocomplete--small .lsd-autocomplete__icon{padding:6px 9px;}.lsd-autocomplete--outlined .lsd-autocomplete__input-container{border:1px solid rgb(var(--lsd-border-primary));}.lsd-autocomplete--underlined .lsd-autocomplete__input-container{border:1px solid transparent;border-bottom:1px solid rgb(var(--lsd-border-primary));}.lsd-autocomplete__dropdown-item-placeholder{opacity:0.5;white-space:pre;}</style><style data-emotion="css-global quxxm6">.lsd-quote{color:rgb(var(--lsd-text-primary));white-space:pre-wrap;}.lsd-quote--indented-inline{border-left:1px solid rgb(var(--lsd-border-primary));padding:4px 8px 4px 28px;}.lsd-quote--parentheses{padding:0px;text-align:center;}.lsd-quote--parentheses::before{content:'***';}.lsd-quote--parentheses::after{content:'***';}</style><style data-emotion="css-global a49t4h">.lsd-collapse{box-sizing:border-box;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column;}.lsd-collapse--open .lsd-collapse__content{border-top:1px solid transparent;}.lsd-collapse__content{border:1px solid rgb(var(--lsd-border-primary));}</style><style data-emotion="css-global 12ppw0q">.lsd-collapse-header{box-sizing:border-box;}.lsd-collapse-header:not(.lsd-collapse-header--disabled) .lsd-collapse-header__trigger:hover .lsd-collapse-header__label{-webkit-text-decoration:underline;text-decoration:underline;}.lsd-collapse-header__trigger{width:100%;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:row;-ms-flex-direction:row;flex-direction:row;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:justify;-webkit-justify-content:space-between;justify-content:space-between;cursor:pointer;background:none;border:1px solid rgb(var(--lsd-border-primary));}.lsd-collapse-header__trigger:focus{outline:none;}.lsd-collapse-header__label{cursor:inherit;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;margin:auto;}.lsd-collapse-header__icons{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:row;-ms-flex-direction:row;flex-direction:row;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:end;-ms-flex-pack:end;-webkit-justify-content:flex-end;justify-content:flex-end;}.lsd-collapse-header__icon{margin-right:8px;}.lsd-collapse-header--disabled .lsd-collapse-header__trigger{opacity:0.34;cursor:initial;}.lsd-collapse-header--large .lsd-collapse-header__trigger{width:299px;height:40px;padding:9px 17px;}.lsd-collapse-header--medium .lsd-collapse-header__trigger{width:270px;height:32px;padding:5px 13px;}.lsd-collapse-header--small .lsd-collapse-header__trigger{width:235px;height:28px;padding:5px 11px;}</style><style data-emotion="css-global dixc0i">.lsd-checkbox-group{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column;gap:6px;width:-webkit-fit-content;width:-moz-fit-content;width:fit-content;}.lsd-checkbox-group__label{margin-bottom:6px;}</style><style data-emotion="css-global q2n2hz">.lsd-badge{width:-webkit-fit-content;width:-moz-fit-content;width:fit-content;box-sizing:border-box;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:row;-ms-flex-direction:row;flex-direction:row;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:center;-ms-flex-pack:center;-webkit-justify-content:center;justify-content:center;border:1px solid rgb(var(--lsd-icon-primary));border-radius:20px;}.lsd-badge:hover,.lsd-badge:focus{-webkit-text-decoration:underline;text-decoration:underline;cursor:pointer;}.lsd-badge--large{padding:3px 11px;gap:12px;height:28px;}.lsd-badge--small{padding:3px 7px;gap:8px;height:24px;}.lsd-badge--filled{background-color:rgb(var(--lsd-icon-primary));}.lsd-badge--filled .lsd-badge__label{color:rgb(var(--lsd-text-secondary));}.lsd-badge--filled svg{--lsd-icon-primary:var(--lsd-icon-secondary);}.lsd-badge--outlined{color:rgb(var(--lsd-text-primary));}.lsd-badge--disabled{opacity:0.3;cursor:initial;pointer-events:none;}</style><style data-emotion="css-global rlst54">.lsd-radio-button{position:relative;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:row;-ms-flex-direction:row;flex-direction:row;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;}.lsd-radio-button__input{opacity:0;position:absolute;left:0;top:0;padding:0;margin:0;width:100%;height:100%;}.lsd-radio-button:not(.lsd-radio-button--disabled):hover{-webkit-text-decoration:underline;text-decoration:underline;}.lsd-radio-button:not(.lsd-radio-button--disabled) .lsd-radio-button__input{cursor:pointer;}.lsd-radio-button--disabled{opacity:0.34;}.lsd-radio-button__label{margin-left:18px;}.lsd-radio-button--large .lsd-radio-button__label{margin-left:18px;}.lsd-radio-button--medium .lsd-radio-button__label{margin-left:14px;}.lsd-radio-button--small .lsd-radio-button__label{margin-left:12px;}</style><style data-emotion="css-global mo7h6o">.lsd-radio-button-group{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column;gap:6px;width:-webkit-fit-content;width:-moz-fit-content;width:fit-content;}.lsd-radio-button-group__label{margin-bottom:6px;}</style><style data-emotion="css-global amncrr">.lsd-table{box-sizing:border-box;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column;}.lsd-table>.lsd-table-header{margin-bottom:-1px;}</style><style data-emotion="css-global 1fkbozr">.lsd-table-header{box-sizing:border-box;border:1px solid rgb(var(--lsd-border-primary));}</style><style data-emotion="css-global 1fb1r54">.lsd-table-body table{border-collapse:collapse;text-align:center;table-layout:fixed;width:100%;height:auto;}.lsd-table-body table tr:first-of-type td label:has(input[type='radio']){display:none;}.lsd-table-body__toolbar{box-sizing:border-box;padding:10px;border:1px solid rgb(var(--lsd-border-primary));border-bottom:none;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-box-pack:justify;-webkit-justify-content:space-between;justify-content:space-between;}</style><style data-emotion="css-global 607rj8">.lsd-table-item{border:1px solid rgb(var(--lsd-border-primary));}.lsd-table-item:has(> label){width:40px;}.lsd-table-item:has(> label) input{position:relative;width:14px;height:14px;margin:auto;}.lsd-table-item:has(> label) span{margin-left:14px!important;}.lsd-table-item--large{padding:10px;}.lsd-table-item--medium{padding:6px 8px;}.lsd-table-item--small{padding:6px;}</style><style data-emotion="css-global 1vlh57l">.lsd-table-row{-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;}</style><style data-emotion="css-global 1fw5y3v">.lsd-number-input{width:auto;box-sizing:border-box;}.lsd-number-input__main-container:hover{-webkit-text-decoration:underline;text-decoration:underline;}.lsd-number-input--error .lsd-number-input__main-container{-webkit-text-decoration:line-through;text-decoration:line-through;}.lsd-number-input__label{display:block;}.lsd-number-input__plus-minus-icons{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-shrink:0;-ms-flex-negative:0;flex-shrink:0;}.lsd-number-input__input-container{box-sizing:border-box;border:1px solid rgb(var(--lsd-border-primary));border-left:0px;border-right:0px;}.lsd-number-input__error-icon{cursor:pointer;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;padding:10px 8px;}.lsd-number-input__input-container{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:justify;-webkit-justify-content:space-between;justify-content:space-between;}.lsd-number-input--disabled{opacity:0.34;}.lsd-number-input__main-container{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;}.lsd-number-input__input{border:none;outline:none;font-size:14px;color:rgb(var(--lsd-text-primary));background:none;text-align:center;padding:0 4px;}.lsd-number-input__input::-webkit-inner-spin-button{display:none;-webkit-appearance:none;}.lsd-number-input__input:hover{outline:none;}.lsd-number-input__supporting-text{position:absolute;}.lsd-number-input--large .lsd-number-input__label{margin:0 0 6px 18px;}.lsd-number-input--large .lsd-number-input__input-container{height:40px;}.lsd-number-input--large .lsd-number-input__input{width:62px;}.lsd-number-input--large .lsd-number-input__plus-minus-icons{height:40px;width:40px;}.lsd-number-input--large .lsd-number-input__supporting-text{margin:6px 18px 0 18px;}.lsd-number-input--medium .lsd-number-input__label{margin:0 0 6px 14px;}.lsd-number-input--medium .lsd-number-input__input-container{height:32px;}.lsd-number-input--medium .lsd-number-input__input{width:58px;}.lsd-number-input--medium .lsd-number-input__plus-minus-icons{height:32px;width:32px;}.lsd-number-input--medium .lsd-number-input__supporting-text{margin:6px 14px 0 14px;}.lsd-number-input--small .lsd-number-input__label{margin:0 0 6px 12px;}.lsd-number-input--small .lsd-number-input__input-container{height:28px;}.lsd-number-input--small .lsd-number-input__input{width:50px;}.lsd-number-input--small .lsd-number-input__plus-minus-icons{height:28px;width:28px;}.lsd-number-input--small .lsd-number-input__supporting-text{margin:6px 12px 0 12px;}</style><style data-emotion="css-global 12rmo7o">.lsd-modal{box-sizing:border-box;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column;position:fixed;top:0;left:0;right:0;bottom:0;background-color:rgba(0, 0, 0, 0.5);display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-box-pack:center;-ms-flex-pack:center;-webkit-justify-content:center;justify-content:center;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;z-index:9999;}.lsd-modal__container{position:relative;background:rgb(var(--lsd-surface-primary));padding:20px;max-width:90%;box-sizing:border-box;border:1px solid rgb(var(--lsd-border-primary));}.lsd-modal__header{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-box-pack:justify;-webkit-justify-content:space-between;justify-content:space-between;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;}.lsd-modal__close-icon{position:absolute;top:8px;right:8px;cursor:pointer;}.lsd-modal__title-and-subtitle-container{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column;}.lsd-modal--large .lsd-modal__container{min-width:960px;}.lsd-modal--medium .lsd-modal__container{min-width:768px;}.lsd-modal--small .lsd-modal__container{min-width:614px;}.lsd-modal--extra-small .lsd-modal__container{min-width:490px;}</style><style data-emotion="css-global 1k7gzc">.lsd-modal-footer{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;}</style><style data-emotion="css-global 1b9t8so">.lsd-modal-body{margin:18px 0;}</style><style data-emotion="css-global dyud2a">.lsd-date-picker{width:-webkit-fit-content;width:-moz-fit-content;width:fit-content;}.lsd-date-picker__calendar{border-top:none!important;}.lsd-date-picker--large .lsd-date-field--large{width:318px;}.lsd-date-picker--medium .lsd-date-field--medium{width:290px;}.lsd-date-picker--small .lsd-date-field--small{width:262px;}</style><style data-emotion="css-global olq3nk">.lsd-date-field{width:auto;box-sizing:border-box;}.lsd-date-field__label{display:block;}.lsd-date-field__input-container__icon{position:absolute;right:0;cursor:pointer;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;background-color:rgb(var(--lsd-surface-primary));}.lsd-date-field__input-container__icon:focus{background:blue;background-color:pink;border:1px solid rgb(var(--lsd-border-primary));}.lsd-date-field__input-container__no-icon{position:absolute;right:0;background-color:rgb(var(--lsd-surface-primary));padding:12px;}.lsd-date-field--outlined{border:1px solid rgb(var(--lsd-border-primary));}.lsd-date-field--underlined{border-bottom:1px solid rgb(var(--lsd-border-primary));}.lsd-date-field__input-container{position:relative;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:justify;-webkit-justify-content:space-between;justify-content:space-between;}.lsd-date-field--disabled{opacity:0.34;}.lsd-date-field__input-container__input{border:none;outline:none;font-size:14px;color:rgb(var(--lsd-text-primary));background:none;width:100%;opacity:0.4;-webkit-transition:opacity 0.2s ease-in-out;transition:opacity 0.2s ease-in-out;}.lsd-date-field__input-container__input::-webkit-inner-spin-button,.lsd-date-field__input-container__input::-webkit-calendar-picker-indicator{display:none;-webkit-appearance:none;}.lsd-date-field__input-container__input:hover{outline:none;}.lsd-date-field__supporting-text{position:absolute;}.lsd-date-field--large{width:208px;}.lsd-date-field--large .lsd-date-field__label{margin:0 0 6px 18px;}.lsd-date-field--large .lsd-date-field__input-container{height:40px;}.lsd-date-field--large .lsd-date-field__input-container__input{padding:9px 0px 9px 17px;}.lsd-date-field--large .lsd-date-field__input-container__icon{padding:12px 13px;}.lsd-date-field--large .lsd-date-field__supporting-text{margin:6px 18px 0 18px;}.lsd-date-field--medium{width:188px;}.lsd-date-field--medium .lsd-date-field__label{margin:0 0 6px 14px;}.lsd-date-field--medium .lsd-date-field__input-container{height:32px;}.lsd-date-field--medium .lsd-date-field__input-container__input{padding:5px 11px 5px 13px;}.lsd-date-field--medium .lsd-date-field__input-container__icon{padding:8px 11px;}.lsd-date-field--medium .lsd-date-field__supporting-text{margin:6px 14px 0 14px;}.lsd-date-field--small{width:164px;}.lsd-date-field--small .lsd-date-field__label{margin:0 0 6px 12px;}.lsd-date-field--small .lsd-date-field__input-container{height:28px;}.lsd-date-field--small .lsd-date-field__input-container__input{padding:5px 9px 5px 11px;font-size:12px;}.lsd-date-field--small .lsd-date-field__input-container__icon{padding:6px 9px;}.lsd-date-field--small .lsd-date-field__supporting-text{margin:6px 12px 0 12px;}.lsd-date-field__input-container__input:invalid,.lsd-date-field__input-container__input--filled{color:rgb(var(--lsd-border-primary));opacity:1;}.lsd-date-field--error .lsd-date-field__input-container__input::-webkit-datetime-edit-year-field,.lsd-date-field--error .lsd-date-field__input-container__input::-webkit-datetime-edit-month-field,.lsd-date-field--error .lsd-date-field__input-container__input::-webkit-datetime-edit-day-field{-webkit-text-decoration:line-through;text-decoration:line-through;}@supports not selector(::-webkit-datetime-edit-day-field){.lsd-date-field--error .lsd-date-field__input-container__input{-webkit-text-decoration:line-through;text-decoration:line-through;}}</style><style data-emotion="css-global 1gjtao4">.lsd-calendar{border:1px solid rgb(var(--lsd-border-primary));visibility:hidden;position:absolute!important;top:0;left:0;opacity:0;visibility:hidden;margin:0;padding:0;box-sizing:border-box;background:rgb(var(--lsd-surface-primary));-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;}.lsd-calendar-container{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column;padding:8px;}.lsd-calendar--open{opacity:1;visibility:visible;}.lsd-calendar-header{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-box-pack:center;-ms-flex-pack:center;-webkit-justify-content:center;justify-content:center;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;height:32px;margin-bottom:8px;}.lsd-calendar__week_day{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-box-pack:center;-ms-flex-pack:center;-webkit-justify-content:center;justify-content:center;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;aspect-ratio:1/1;margin-bottom:4px;}.lsd-calendar__change-year{position:relative;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-box-pack:center;-ms-flex-pack:center;-webkit-justify-content:center;justify-content:center;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;padding:2px 0xp 2px 8px;gap:6px;border:1px solid transparent;}.lsd-calendar__change-year--active .lsd-calendar__year-and-icon{border:1px solid rgb(var(--lsd-border-primary));}.lsd-calendar__change-year-icon-container{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-box-pack:center;-ms-flex-pack:center;-webkit-justify-content:center;justify-content:center;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;cursor:pointer;border:none;}.lsd-calendar-month{margin-right:8px;}.lsd-calendar__month-and-year{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:center;-ms-flex-pack:center;-webkit-justify-content:center;justify-content:center;}.lsd-calendar-day__container{cursor:pointer;background:transparent;position:relative;box-sizing:border-box;border:1px solid transparent;}.lsd-calendar-day{aspect-ratio:1/1;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-box-pack:center;-ms-flex-pack:center;-webkit-justify-content:center;justify-content:center;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;}.lsd-calendar-day:hover{cursor:pointer;-webkit-text-decoration:underline;text-decoration:underline;text-decoration-color:rgb(var(--lsd-border-primary));}.lsd-calendar-day label:hover{cursor:pointer;}.lsd-calendar-day--selected{border:1px solid rgb(var(--lsd-border-primary));}.lsd-calendar-day--disabled{opacity:0.3;cursor:default;}.lsd-calendar-day__today_indicator{position:absolute;left:50%;-webkit-transform:translateX(-50%);-moz-transform:translateX(-50%);-ms-transform:translateX(-50%);transform:translateX(-50%);bottom:2px;}.lsd-calendar--disabled{pointer-events:none;border:1px solid rgba(var(--lsd-border-primary), 0.3);}.lsd-calendar--disabled label{opacity:0.3;}.lsd-calendar--disabled .lsd-calendar__button{opacity:0.3;}.lsd-calendar--disabled .lsd-calendar-day--selected{opacity:0.3;}.lsd-calendar__button{border:1px solid rgb(var(--lsd-border-primary));cursor:pointer;background:transparent;width:32px;height:32px;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:center;-ms-flex-pack:center;-webkit-justify-content:center;justify-content:center;position:absolute;}.lsd-calendar__next-month-button{top:8px;right:8px;}.lsd-calendar__previous-month-button{top:8px;left:8px;}.lsd-calendar-day--border-left{border-left:1px double rgb(var(--lsd-border-primary));}.lsd-calendar-day--border-right{border-right:1px double rgb(var(--lsd-border-primary));}.lsd-calendar-day--border-left-and-right{border-left:1px double rgb(var(--lsd-border-primary));border-right:1px double rgb(var(--lsd-border-primary));}.lsd-calendar-day--border-top-and-bottom{border-top:1px double rgb(var(--lsd-border-primary));border-bottom:1px double rgb(var(--lsd-border-primary));}.lsd-calendar__month-table{border-collapse:collapse;}.lsd-calendar__year-dropdown{box-sizing:border-box;position:absolute;top:100%;left:0;max-height:200px;overflow-y:auto;width:100%;border:1px solid rgb(var(--lsd-border-primary));border-top:none;z-index:1;}.lsd-calendar__year-dropdown .lsd-calendar-year{border-bottom:1px solid rgb(var(--lsd-border-primary));}.lsd-calendar__year-dropdown--hidden{visibility:hidden;}.lsd-calendar-year{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;cursor:pointer;-webkit-transition:background-color 0.2s;transition:background-color 0.2s;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;background:rgb(var(--lsd-surface-primary));}.lsd-calendar-year:hover{-webkit-text-decoration:underline;text-decoration:underline;}.lsd-calendar__year-and-icon{border:1px solid rgb(var(--lsd-border-primary));}.lsd-calendar--large .lsd-calendar-year{padding:6px 0px 6px 14px;}.lsd-calendar--large .lsd-calendar__change-year-icon-container{width:32px;}.lsd-calendar--medium .lsd-calendar-year{padding:6px 0px 6px 12px;}.lsd-calendar--medium .lsd-calendar__change-year-icon-container{width:28px;}.lsd-calendar--small .lsd-calendar-year{padding:6px 0px 6px 12px;}.lsd-calendar--small .lsd-calendar__change-year-icon-container{width:28px;}</style><style data-emotion="css-global dlrd7d">.lsd-toast{box-sizing:border-box;display:-webkit-inline-box;display:-webkit-inline-flex;display:-ms-inline-flexbox;display:inline-flex;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;background:rgb(var(--lsd-surface-primary));border:1px solid rgb(var(--lsd-border-primary));padding:8px;height:-webkit-fit-content;height:-moz-fit-content;height:fit-content;}.lsd-toast__inline-button-container{-webkit-flex-shrink:0;-ms-flex-negative:0;flex-shrink:0;}.lsd-toast__column-button-container{margin-top:18px;margin-bottom:6px;}.lsd-toast__inline-container{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:justify;-webkit-justify-content:space-between;justify-content:space-between;-webkit-box-flex:1;-webkit-flex-grow:1;-ms-flex-positive:1;flex-grow:1;}.lsd-toast__column-container{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column;-webkit-box-pack:justify;-webkit-justify-content:space-between;justify-content:space-between;}.lsd-toast__text-container{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column;color:rgb(var(--lsd-text-secondary));padding-left:12px;}.lsd-toast__title{position:relative;}.lsd-toast__information{margin-top:4px;}.lsd-toast__button-container{min-height:28px;min-width:60px;width:-webkit-fit-content;width:-moz-fit-content;width:fit-content;padding:0px 12px;}.lsd-toast__close-button{margin-bottom:auto;-webkit-flex-shrink:0;-ms-flex-negative:0;flex-shrink:0;height:28px;width:28px;margin-left:auto;}.lsd-toast__column-icon-container{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-box-pack:center;-ms-flex-pack:center;-webkit-justify-content:center;justify-content:center;margin-bottom:auto;position:relative;top:4px;padding-left:4px;}.lsd-toast__inline-icon-container{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:center;-ms-flex-pack:center;-webkit-justify-content:center;justify-content:center;padding-left:4px;}.lsd-toast__icon{position:relative;}.lsd-toast--large{width:364px;}.lsd-toast--medium{width:336px;}.lsd-toast--small{width:296px;}.lsd-toast--small .lsd-toast__icon{top:0px;}</style><style data-emotion="css-global 5wlfwk">.lsd-toast-provider__toast-container{position:fixed;-webkit-transition:all 230ms cubic-bezier(0.21, 1.02, 0.73, 1);transition:all 230ms cubic-bezier(0.21, 1.02, 0.73, 1);z-index:9999;}.lsd-toast-provider__toast--top-left,.lsd-toast-provider__toast--top-center,.lsd-toast-provider__toast--top-right{top:0;}.lsd-toast-provider__toast--bottom-left,.lsd-toast-provider__toast--bottom-center,.lsd-toast-provider__toast--bottom-right{bottom:0;}.lsd-toast-provider__toast--top-center,.lsd-toast-provider__toast--bottom-center{left:50%;}.lsd-toast-provider__toast--top-right,.lsd-toast-provider__toast--bottom-right{right:0;}</style><style data-emotion="css-global 9yw6e1">.lsd-button-group{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:row;-ms-flex-direction:row;flex-direction:row;}.lsd-button-group >*:not(:last-child).lsd-button--outlined,.lsd-button-group >*:not(:last-child) .lsd-button--outlined{border-right:none;}</style><style data-emotion="css-global 17u9w7w">.lsd-date-range-picker{box-sizing:border-box;}.lsd-date-range-picker .lsd-date-field--outlined{border:none;}.lsd-date-range-picker .lsd-date-field__input-container__icon{padding:8px;}.lsd-date-range-picker__label{display:block;}.lsd-date-range-picker__input-container{box-sizing:border-box;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;border:1px solid transparent;}.lsd-date-picker__calendar{border-top:none!important;}.lsd-date-picker__calendar .lsd-tooltip-base__arrow-tip{-webkit-transition:left 0.2s ease-in-out;transition:left 0.2s ease-in-out;}.lsd-date-range-picker--calendar-open .lsd-date-range-picker__input-container{border-bottom:1px solid rgb(var(--lsd-border-primary));}.lsd-date-range-picker__icon{cursor:pointer;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:center;-ms-flex-pack:center;-webkit-justify-content:center;justify-content:center;-webkit-box-flex:1;-webkit-flex-grow:1;-ms-flex-positive:1;flex-grow:1;padding:0 10px;}.lsd-date-range-picker--disabled{opacity:0.3;}.lsd-date-range-picker__supporting-text{position:absolute;}.lsd-date-range-picker--large{width:318px;}.lsd-date-range-picker--large .lsd-date-field--large{width:156px;}.lsd-date-range-picker--large .lsd-date-field__input-container__input{padding-right:0;}.lsd-date-range-picker--large .lsd-date-field__input-container__icon{padding:11px 12px;}.lsd-date-range-picker--large .lsd-date-range-picker__label{margin:0 0 6px 18px;}.lsd-date-range-picker--large .lsd-date-range-picker__input-container{height:40px;}.lsd-date-range-picker--large .lsd-date-range-picker__supporting-text{margin:6px 18px 0 18px;}.lsd-date-range-picker--medium{width:290px;}.lsd-date-range-picker--medium .lsd-date-field--medium{width:142px;}.lsd-date-range-picker--medium .lsd-date-field__input-container__input{padding-right:0;}.lsd-date-range-picker--medium .lsd-date-field__input-container__icon{padding:7px 8px;}.lsd-date-range-picker--medium .lsd-date-range-picker__label{margin:0 0 6px 14px;}.lsd-date-range-picker--medium .lsd-date-range-picker__input-container{height:32px;}.lsd-date-range-picker--medium .lsd-date-range-picker__supporting-text{margin:6px 14px 0 14px;}.lsd-date-range-picker--small{width:262px;}.lsd-date-range-picker--small .lsd-date-field--small{width:128px;}.lsd-date-range-picker--small .lsd-date-field__input-container__input{padding-right:0;}.lsd-date-range-picker--small .lsd-date-field__input-container__icon{padding:5px 7px;}.lsd-date-range-picker--small .lsd-date-range-picker__label{margin:0 0 6px 12px;}.lsd-date-range-picker--small .lsd-date-range-picker__input-container{height:28px;}.lsd-date-range-picker--small .lsd-date-range-picker__supporting-text{margin:6px 12px 0 12px;}.lsd-date-range-picker__separator{margin-left:3px;width:1px;height:100%;}.lsd-date-range-picker__separator{border-left:1px solid transparent;}.lsd-date-range-picker--outlined{border:1px solid rgb(var(--lsd-border-primary));}.lsd-date-range-picker--outlined .lsd-date-range-picker__separator{border-left:1px solid rgb(var(--lsd-border-primary));}</style><style data-emotion="css-global 19d282h">.lsd-tooltip-base{border:1px solid rgb(var(--lsd-border-primary));position:relative;}.lsd-tooltip-base__arrow-tip{border:1px solid rgb(var(--lsd-border-primary));position:absolute;background:rgb(var(--lsd-surface-primary));}.lsd-tooltip-base__content{background:rgb(var(--lsd-surface-primary));width:100%;height:100%;position:relative;z-index:1;}</style><style data-emotion="css-global 1o77wkp">[data-theme=dark]{--lsd-display1-fontSize:5.5rem;--lsd-display1-fontWeight:normal;--lsd-display1-lineHeight:6rem;--lsd-display2-fontSize:4rem;--lsd-display2-fontWeight:normal;--lsd-display2-lineHeight:4.5rem;--lsd-display3-fontSize:3.5rem;--lsd-display3-fontWeight:normal;--lsd-display3-lineHeight:4rem;--lsd-display4-fontSize:3rem;--lsd-display4-fontWeight:normal;--lsd-display4-lineHeight:3.5rem;--lsd-h1-fontSize:2.5rem;--lsd-h1-fontWeight:normal;--lsd-h1-lineHeight:3rem;--lsd-h2-fontSize:2rem;--lsd-h2-fontWeight:normal;--lsd-h2-lineHeight:2.5rem;--lsd-h3-fontSize:1.75rem;--lsd-h3-fontWeight:normal;--lsd-h3-lineHeight:2.25rem;--lsd-h4-fontSize:1.5rem;--lsd-h4-fontWeight:normal;--lsd-h4-lineHeight:2rem;--lsd-h5-fontSize:1.25rem;--lsd-h5-fontWeight:normal;--lsd-h5-lineHeight:1.75rem;--lsd-h6-fontSize:1rem;--lsd-h6-fontWeight:normal;--lsd-h6-lineHeight:1.5rem;--lsd-subtitle1-fontSize:1.125rem;--lsd-subtitle1-fontWeight:normal;--lsd-subtitle1-lineHeight:1.5rem;--lsd-subtitle2-fontSize:1rem;--lsd-subtitle2-fontWeight:normal;--lsd-subtitle2-lineHeight:1.5rem;--lsd-subtitle3-fontSize:0.875rem;--lsd-subtitle3-fontWeight:normal;--lsd-subtitle3-lineHeight:1.25rem;--lsd-subtitle4-fontSize:0.75rem;--lsd-subtitle4-fontWeight:normal;--lsd-subtitle4-lineHeight:1rem;--lsd-body1-fontSize:1rem;--lsd-body1-fontWeight:normal;--lsd-body1-lineHeight:1.5rem;--lsd-body2-fontSize:0.875rem;--lsd-body2-fontWeight:normal;--lsd-body2-lineHeight:1.25rem;--lsd-body3-fontSize:0.75rem;--lsd-body3-fontWeight:normal;--lsd-body3-lineHeight:1rem;--lsd-label1-fontSize:0.875rem;--lsd-label1-fontWeight:normal;--lsd-label1-lineHeight:1.25rem;--lsd-label2-fontSize:0.75rem;--lsd-label2-fontWeight:normal;--lsd-label2-lineHeight:1rem;--lsd-typography-generic-font-family:sans-serif;--lsd-theme-primary:255,255,255;--lsd-theme-secondary:0,0,0;--lsd-surface-primary:0,0,0;--lsd-surface-secondary:255,255,255;--lsd-border-primary:255,255,255;--lsd-border-secondary:0,0,0;--lsd-icon-primary:255,255,255;--lsd-icon-secondary:0,0,0;--lsd-text-primary:255,255,255;--lsd-text-secondary:0,0,0;--lsd-text-tertiary:255,255,255,0.34;--lsd-spacing-4:4px;--lsd-spacing-8:8px;--lsd-spacing-16:16px;--lsd-spacing-24:24px;--lsd-spacing-32:32px;--lsd-spacing-40:40px;--lsd-spacing-64:64px;--lsd-spacing-80:80px;--lsd-spacing-96:96px;--lsd-spacing-120:120px;}</style><style data-emotion="css-global yon3n1">[data-theme=light]{--lsd-display1-fontSize:5.5rem;--lsd-display1-fontWeight:normal;--lsd-display1-lineHeight:6rem;--lsd-display2-fontSize:4rem;--lsd-display2-fontWeight:normal;--lsd-display2-lineHeight:4.5rem;--lsd-display3-fontSize:3.5rem;--lsd-display3-fontWeight:normal;--lsd-display3-lineHeight:4rem;--lsd-display4-fontSize:3rem;--lsd-display4-fontWeight:normal;--lsd-display4-lineHeight:3.5rem;--lsd-h1-fontSize:2.5rem;--lsd-h1-fontWeight:normal;--lsd-h1-lineHeight:3rem;--lsd-h2-fontSize:2rem;--lsd-h2-fontWeight:normal;--lsd-h2-lineHeight:2.5rem;--lsd-h3-fontSize:1.75rem;--lsd-h3-fontWeight:normal;--lsd-h3-lineHeight:2.25rem;--lsd-h4-fontSize:1.5rem;--lsd-h4-fontWeight:normal;--lsd-h4-lineHeight:2rem;--lsd-h5-fontSize:1.25rem;--lsd-h5-fontWeight:normal;--lsd-h5-lineHeight:1.75rem;--lsd-h6-fontSize:1rem;--lsd-h6-fontWeight:normal;--lsd-h6-lineHeight:1.5rem;--lsd-subtitle1-fontSize:1.125rem;--lsd-subtitle1-fontWeight:normal;--lsd-subtitle1-lineHeight:1.5rem;--lsd-subtitle2-fontSize:1rem;--lsd-subtitle2-fontWeight:normal;--lsd-subtitle2-lineHeight:1.5rem;--lsd-subtitle3-fontSize:0.875rem;--lsd-subtitle3-fontWeight:normal;--lsd-subtitle3-lineHeight:1.25rem;--lsd-subtitle4-fontSize:0.75rem;--lsd-subtitle4-fontWeight:normal;--lsd-subtitle4-lineHeight:1rem;--lsd-body1-fontSize:1rem;--lsd-body1-fontWeight:normal;--lsd-body1-lineHeight:1.5rem;--lsd-body2-fontSize:0.875rem;--lsd-body2-fontWeight:normal;--lsd-body2-lineHeight:1.25rem;--lsd-body3-fontSize:0.75rem;--lsd-body3-fontWeight:normal;--lsd-body3-lineHeight:1rem;--lsd-label1-fontSize:0.875rem;--lsd-label1-fontWeight:normal;--lsd-label1-lineHeight:1.25rem;--lsd-label2-fontSize:0.75rem;--lsd-label2-fontWeight:normal;--lsd-label2-lineHeight:1rem;--lsd-typography-generic-font-family:sans-serif;--lsd-theme-primary:0,0,0;--lsd-theme-secondary:255,255,255;--lsd-surface-primary:255,255,255;--lsd-surface-secondary:0,0,0;--lsd-border-primary:0,0,0;--lsd-border-secondary:255,255,255;--lsd-icon-primary:0,0,0;--lsd-icon-secondary:255,255,255;--lsd-text-primary:0,0,0;--lsd-text-secondary:255,255,255;--lsd-text-tertiary:0,0,0,0.34;--lsd-spacing-4:4px;--lsd-spacing-8:8px;--lsd-spacing-16:16px;--lsd-spacing-24:24px;--lsd-spacing-32:32px;--lsd-spacing-40:40px;--lsd-spacing-64:64px;--lsd-spacing-80:80px;--lsd-spacing-96:96px;--lsd-spacing-120:120px;}</style><div class="root_QACb"><div class="blog-archive-page"><div role="region" aria-label="Skip to main content"><a class="skipToContent_fXgn" href="#__docusaurus_skipToContent_fallback">Skip to main content</a></div><nav aria-label="Main" class="navbar navbar--fixed-top navbarHideable_OoEf"><div class="navbar__inner"><div class="navbar__left"><a class="navbar__brand" href="/"><div class="navbar__logo"><img src="/theme/image/logo.svg" alt="Vac Research" class="themedImage_ToTc themedImage--light_HNdA" height="26"><img src="/theme/image/logo.svg" alt="Vac Research" class="themedImage_ToTc themedImage--dark_i4oU" height="26"></div><b class="navbar__title text--truncate"></b></a></div><div class="navbar__left-items"><a class="navbar__item navbar__link" href="/"><div class="lsd-typography lsd-typography--body2 linkContent__x3v">About Vac</div></a><a class="navbar__item navbar__link" href="/community"><div class="lsd-typography lsd-typography--body2 linkContent__x3v">Community</div></a><a aria-current="page" class="navbar__item navbar__link navbar__link--active" href="/rlog"><div class="lsd-typography lsd-typography--body2 linkContent__x3v">Research Blog</div></a><a class="navbar__item navbar__link" href="/join-us"><div class="lsd-typography lsd-typography--body2 linkContent__x3v">Join Us</div></a></div><div class="navbar__right-items"><div class="iconButtonGroup_ktNv lsd-icon-button-group lsd-icon-button-group--medium lsd-icon-button-group--outlined"><button class="clean-btn toggle_K23S colorModeToggle_GSaI navbar__color-mode-toggle toggleButtonDisabled_AAS_ lsd-icon-button lsd-icon-button--medium lsd-icon-button--outlined lsd-icon-button--disabled" type="button" title="Switch between dark and light mode (currently dark mode)" aria-label="Switch between dark and light mode (currently dark mode)" aria-live="polite"><svg viewBox="0 0 24 24" width="24" height="24" class="lightToggleIcon_K4TL"><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"></path></svg><svg viewBox="0 0 24 24" width="24" height="24" class="darkToggleIcon_lKkA"><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"></path></svg></button><button aria-label="Toggle navigation bar" aria-expanded="false" class="navbar__toggle clean-btn" type="button"><svg width="30" height="30" viewBox="0 0 30 30" aria-hidden="true"><path stroke="currentColor" stroke-linecap="round" stroke-miterlimit="10" stroke-width="2" d="M4 7h22M4 15h22M4 23h22"></path></svg></button></div></div></div><div role="presentation" class="navbar-sidebar__backdrop"></div></nav><div id="__docusaurus_skipToContent_fallback" class="main-wrapper mainWrapper_z2l0"><header class="hero hero--primary"><div class="container"><h1 class="hero__title">Archive</h1><p class="hero__subtitle">Archive</p></div></header><main><section class="margin-vert--lg"><div class="container"><div class="row"><div class="col col--4 margin-vert--lg"><h3>2019</h3><ul><li><a href="/rlog/fixing-whisper-with-waku">December 3, 2019 - Fixing Whisper with Waku</a></li><li><a href="/rlog/feasibility-semaphore-rate-limiting-zksnarks">November 8, 2019 - Feasibility Study: Semaphore rate limiting through zkSNARKs</a></li><li><a href="/rlog/remote-log">October 4, 2019 - P2P Data Sync with a Remote Log</a></li><li><a href="/rlog/vac-overview">August 2, 2019 - Vac - A Rough Overview</a></li><li><a href="/rlog/p2p-data-sync-for-mobile">July 19, 2019 - P2P Data Sync for Mobile</a></li></ul></div><div class="col col--4 margin-vert--lg"><h3>2020</h3><ul><li><a href="/rlog/waku-v2-ethereum-messaging">November 10, 2020 - [Talk] Vac, Waku v2 and Ethereum Messaging</a></li><li><a href="/rlog/waku-v2-update">September 28, 2020 - Waku v2 Update</a></li><li><a href="/rlog/waku-v2-plan">July 1, 2020 - What's the Plan for Waku v2?</a></li><li><a href="/rlog/feasibility-discv5">April 27, 2020 - Feasibility Study: Discv5</a></li><li><a href="/rlog/wechat-replacement-need">April 16, 2020 - What Would a WeChat Replacement Need?</a></li><li><a href="/rlog/kademlia-to-discv5">April 9, 2020 - From Kademlia to Discv5</a></li><li><a href="/rlog/waku-update">February 14, 2020 - Waku Update</a></li><li><a href="/rlog/dns-based-discovery">February 7, 2020 - DNS Based Discovery</a></li></ul></div><div class="col col--4 margin-vert--lg"><h3>2021</h3><ul><li><a href="/rlog/ethics-surveillance-tech">December 3, 2021 - Opinion: Pseudo-ethics in the Surveillance Tech Industry</a></li><li><a href="/rlog/waku-v1-v2-bandwidth-comparison">November 3, 2021 - Waku v1 vs Waku v2: Bandwidth Comparison</a></li><li><a href="/rlog/waku-v2-ethereum-coscup">August 6, 2021 - [Talk at COSCUP] Vac, Waku v2 and Ethereum Messaging</a></li><li><a href="/rlog/presenting-js-waku">June 4, 2021 - Presenting JS-Waku: Waku v2 in the Browser</a></li><li><a href="/rlog/rln-relay">March 5, 2021 - Privacy-preserving p2p economic spam protection in Waku v2</a></li></ul></div><div class="col col--4 margin-vert--lg"><h3>2022</h3><ul><li><a href="/rlog/waku-for-all">November 8, 2022 - Waku for All Decentralized Applications and Infrastructures</a></li><li><a href="/rlog/building-privacy-protecting-infrastructure">November 4, 2022 - Building Privacy-Protecting Infrastructure</a></li><li><a href="/rlog/wakuv2-relay-anon">July 22, 2022 - Waku Privacy and Anonymity Analysis Part I: Definitions and Waku Relay</a></li><li><a href="/rlog/wakuv2-noise">May 17, 2022 - Noise handshakes as key-exchange mechanism for Waku</a></li><li><a href="/rlog/wakuv2-apd">May 9, 2022 - Waku v2 Ambient Peer Discovery</a></li><li><a href="/rlog/introducing-nwaku">April 12, 2022 - Introducing nwaku</a></li></ul></div><div class="col col--4 margin-vert--lg"><h3>2023</h3><ul><li><a href="/rlog/rln-anonymous-dos-prevention">November 7, 2023 - Strengthening Anonymous DoS Prevention with Rate Limiting Nullifiers in Waku</a></li><li><a href="/rlog/GossipSub Improvements">November 6, 2023 - GossipSub Improvements: Evolution of Overlay Design and Message Dissemination in Unstructured P2P Networks</a></li><li><a href="/rlog/Nescience-A-zkVM-leveraging-hiding-properties">August 28, 2023 - Nescience - A zkVM leveraging hiding properties</a></li><li><a href="/rlog/device-pairing-in-js-waku-and-go-waku">April 24, 2023 - Device Pairing in Js-waku and Go-waku</a></li><li><a href="/rlog/future-of-waku-network">April 3, 2023 - The Future of Waku Network: Scaling, Incentivization, and Heterogeneity</a></li></ul></div><div class="col col--4 margin-vert--lg"><h3>2024</h3><ul><li><a href="/rlog/zkVM-testing">September 26, 2024 - zkVM Testing Report: Evaluating Zero-Knowledge Virtual Machines for Nescience</a></li><li><a href="/rlog/zkVM-explorations">August 27, 2024 - Exploring zkVMs: Which Projects Truly Qualify as Zero-Knowledge Virtual Machines?</a></li><li><a href="/rlog/Nescience-state-separation-architecture">August 23, 2024 - Nescience: A User-Centric State-Separation Architecture</a></li><li><a href="/rlog/membership-with-bloom-filters-and-cuckoo-filters">July 19, 2024 - Membership with Bloom Filters and Cuckoo Filters</a></li><li><a href="/rlog/rln-v3">May 13, 2024 - RLN-v3: Towards a Flexible and Cost-Efficient Implementation</a></li><li><a href="/rlog/rln-light-verifiers">May 3, 2024 - Verifying RLN Proofs in Light Clients with Subtrees</a></li></ul></div></div></div></section></main></div><footer class="footer"><div class="container container-fluid firstRow_ar1q"><div class="footer__bottom text--center"><div class="margin-bottom--sm"><a class="footerLogoLink_BH7S" href="/"><img src="/theme/image/logo.svg" alt="Vac Research" class="themedImage_ToTc themedImage--light_HNdA footer__logo" width="22"><img src="/theme/image/logo.svg" alt="Vac Research" class="themedImage_ToTc themedImage--dark_i4oU footer__logo" width="22"></a></div><div class="footer__copyright">Vac Research © 2024<br>All rights reserved.</div></div><div class="row footer__links"><div class="col footer__col"><div class="footer__title"></div><ul class="footer__items clean-list"><li class="footer__item"><a href="https://twitter.com/vacp2p" target="_blank" rel="noopener noreferrer" class="footer__link-item">Twitter<svg width="13.5" height="13.5" aria-hidden="true" viewBox="0 0 24 24" class="iconExternalLink_nPIU"><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"></path></svg></a></li><li class="footer__item"><a href="https://discord.gg/PQFdubGt6d" target="_blank" rel="noopener noreferrer" class="footer__link-item">Discord<svg width="13.5" height="13.5" aria-hidden="true" viewBox="0 0 24 24" class="iconExternalLink_nPIU"><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"></path></svg></a></li><li class="footer__item"><a href="https://github.com/vacp2p" target="_blank" rel="noopener noreferrer" class="footer__link-item">Github<svg width="13.5" height="13.5" aria-hidden="true" viewBox="0 0 24 24" class="iconExternalLink_nPIU"><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"></path></svg></a></li></ul></div><div class="col footer__col"><div class="footer__title"></div><ul class="footer__items clean-list"><li class="footer__item"><a href="https://jobs.status.im/" target="_blank" rel="noopener noreferrer" class="footer__link-item">Work With Us<svg width="13.5" height="13.5" aria-hidden="true" viewBox="0 0 24 24" class="iconExternalLink_nPIU"><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"></path></svg></a></li><li class="footer__item"><a class="footer__link-item" href="/terms">Terms & Conditions</a></li><li class="footer__item"><a class="footer__link-item" href="/privacy-policy">Privacy Policy</a></li><li class="footer__item"><a class="footer__link-item" href="/security">Security</a></li></ul></div></div></div><div class="secondRow__ww3"><div class="footer__bottom text--center">Logos Collective</div><div class="row footer__links"><div class="col footer__col"><div class="footer__title">Research</div><ul class="footer__items clean-list"><li class="footer__item"><a href="https://vac.dev" target="_blank" rel="noopener noreferrer" class="footer__link-item">VacP2P<svg width="13.5" height="13.5" aria-hidden="true" viewBox="0 0 24 24" class="iconExternalLink_nPIU"><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"></path></svg></a></li><li class="footer__item"><a href="https://afaik.institute" target="_blank" rel="noopener noreferrer" class="footer__link-item">AFAIK<svg width="13.5" height="13.5" aria-hidden="true" viewBox="0 0 24 24" class="iconExternalLink_nPIU"><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"></path></svg></a></li></ul></div><div class="col footer__col"><div class="footer__title">Infrastructure</div><ul class="footer__items clean-list"><li class="footer__item"><a href="https://waku.org/" target="_blank" rel="noopener noreferrer" class="footer__link-item">Waku<svg width="13.5" height="13.5" aria-hidden="true" viewBox="0 0 24 24" class="iconExternalLink_nPIU"><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"></path></svg></a></li><li class="footer__item"><a href="https://nimbus.team/" target="_blank" rel="noopener noreferrer" class="footer__link-item">Nimbus<svg width="13.5" height="13.5" aria-hidden="true" viewBox="0 0 24 24" class="iconExternalLink_nPIU"><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"></path></svg></a></li><li class="footer__item"><a href="https://codex.storage" target="_blank" rel="noopener noreferrer" class="footer__link-item">Codex<svg width="13.5" height="13.5" aria-hidden="true" viewBox="0 0 24 24" class="iconExternalLink_nPIU"><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"></path></svg></a></li><li class="footer__item"><a href="https://nomos.tech" target="_blank" rel="noopener noreferrer" class="footer__link-item">Nomos<svg width="13.5" height="13.5" aria-hidden="true" viewBox="0 0 24 24" class="iconExternalLink_nPIU"><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"></path></svg></a></li></ul></div><div class="col footer__col"><div class="footer__title">Creative Studio</div><ul class="footer__items clean-list"><li class="footer__item"><a href="https://acid.info" target="_blank" rel="noopener noreferrer" class="footer__link-item">Acid.info<svg width="13.5" height="13.5" aria-hidden="true" viewBox="0 0 24 24" class="iconExternalLink_nPIU"><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"></path></svg></a></li></ul></div><div class="col footer__col"><div class="footer__title">Movement</div><ul class="footer__items clean-list"><li class="footer__item"><a href="https://logos.co" target="_blank" rel="noopener noreferrer" class="footer__link-item">Logos<svg width="13.5" height="13.5" aria-hidden="true" viewBox="0 0 24 24" class="iconExternalLink_nPIU"><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"></path></svg></a></li></ul></div><div class="col footer__col"><div class="footer__title">User-facing products</div><ul class="footer__items clean-list"><li class="footer__item"><a href="https://status.im" target="_blank" rel="noopener noreferrer" class="footer__link-item">Status<svg width="13.5" height="13.5" aria-hidden="true" viewBox="0 0 24 24" class="iconExternalLink_nPIU"><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"></path></svg></a></li><li class="footer__item"><a href="https://keycard.tech" target="_blank" rel="noopener noreferrer" class="footer__link-item">Keycard<svg width="13.5" height="13.5" aria-hidden="true" viewBox="0 0 24 24" class="iconExternalLink_nPIU"><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"></path></svg></a></li></ul></div></div></div><button class="backToTop_wDfN lsd-button lsd-button--small lsd-button--outlined"><span class="lsd-typography lsd-typography--label2 lsd-button__text">Back to top ↑</span></button></footer></div></div></div> +<script src="/assets/js/runtime~main.a9103199.js"></script> +<script src="/assets/js/main.5454aec3.js"></script> </body> </html> \ No newline at end of file diff --git a/rlog/atom.xml b/rlog/atom.xml index 87ecd805..82dbe358 100644 --- a/rlog/atom.xml +++ b/rlog/atom.xml @@ -2,11 +2,72 @@ <feed xmlns="http://www.w3.org/2005/Atom"> <id>https://vac.dev/rlog</id> <title>Vac Research Blog - 2024-08-27T12:00:00.000Z + 2024-09-26T12:00:00.000Z https://github.com/jpmonette/feed Vac Research Blog https://vac.dev/theme/image/favicon.ico + + <![CDATA[zkVM Testing Report: Evaluating Zero-Knowledge Virtual Machines for Nescience]]> + https://vac.dev/rlog/zkVM-testing + + 2024-09-26T12:00:00.000Z + + Introduction

Following our initial exploration of zkVMs in our previous blog post [1], +we have conducted a series of tests to identify the most suitable zkVM for the Nescience architecture [2]. This post outlines the testing process, results, and conclusions. Additionally, +the full test suite and scripts can be found on our GitHub page [3], +allowing others to replicate the results or explore the candidates further.

We've shortlisted the following zkVMs for testing:

  • SP1 [4]
  • RISC0 [5]
  • Nexus [6]
  • ZkMIPS [7]
  • ZkWASM [8]
  • Valida [9]

Why these candidates?

When narrowing down the zkVMs, we focused on key factors:

  • True zero-knowledge functionality: The zkVMs had to demonstrate or be close to demonstrating the ability to generate and verify zero-knowledge proofs.
  • Performance baselines: We sought zkVMs with solid benchmarks in performance, particularly in speed and efficiency.
  • Specific functionalities: For Nescience, functionalities like lookup tables, precompiles, and recursive capabilities are critical.

We need a zkVM that supports these to enable robust project development.

Preliminary information on the candidates

  1. SP1 is a performant, open-source zkVM that verifies the execution of arbitrary Rust (or any LLVM-compiled language) programs. +SP1 utilizes Plonky3, enabling recursive proofs and supporting a wide range of cryptographic algorithms, including ECC-based ones like Groth16. +While it supports aggregation, it appears not to support zero knowledge in a conventional manner.

  2. RISC0 zkVM allows one to prove the correct execution of arbitrary Rust code. Built on a RISC-V architecture, it is inherently adaptable +for implementing standard cryptographic hash functions such as SHA-256 and ECDSA. RISC0 employs STARKs, providing a security level of 98 bits. +It supports multiple programming languages, including C and Rust, thanks to its compatibility with LLVM and WASM.

  3. Nexus is a modular, extensible, open-source, highly parallelized, prover-optimized, and contributor-friendly zkVM written in Rust. +It focuses on performance and security, using the Nova folding scheme, which is particularly effective for recursive proofs. +Nexus also supports precompiles and targeted compilation, and besides Rust, it offers C++ support.

  4. ZkMIPS is a general verifiable computing infrastructure based on Plonky2 and the MIPS microarchitecture, aiming to empower Ethereum +as a global settlement layer. It can run arbitrary Rust code as well. Notably, zkMIPS is the only zkVM in this list that utilizes the MIPS opcode set.

  5. ZkWASM adheres to and supports the unmodified standard WASM bytecode specification. Since Rust code can be compiled to WASM bytecode, +one could theoretically run any Rust code on a zkWASM machine, providing flexibility and broad language support.

  6. Valida is a STARK-based virtual machine aiming to improve upon the state of the art in several categories:

    • Code reuse: The VM has a RISC-inspired instruction set, simplifying the targeting of conventional programming languages. +A backend compiler is being developed to compile LLVM IR to the Valida ISA, enabling the proving of programs written in Rust, +Go, C++, and others with minimal to no changes in source code.
    • Prover performance: Engineered to maximize prover performance, Valida is compatible with a 31-bit field, restricted to degree 3 constraints, +and features minimal instruction decoding. It operates directly on memory without general-purpose registers or a dedicated stack, +utilizing newer lookup arguments to reduce trace overhead involved in cross-chip communication.
    • Extensibility: Designed to be customizable, Valida can easily be extended to include an arbitrary number of user-defined instructions. +Procedural macros are used to construct the desired machine at compile time, avoiding any runtime penalties.

Valida appears to be in the early stages of development but already showcases respectable performance metrics.

Testing plan

To thoroughly evaluate each zkVM, we devised a two-stage testing process:

  • Stage 1: Arithmetic operations

    The first phase focused on evaluating the zkVMs’ ability to handle basic arithmetic operations: addition, subtraction, multiplication, +division, modulus division, and square root calculations. We designed the test around heptagonal numbers, which required zkVMs to process +multiple arithmetic operations simultaneously. By using this method, we could measure efficiency and speed in handling complex mathematical calculations – +a crucial element for zkVM performance.

  • Stage 2: Memory consumption

    For the second phase, we evaluated each zkVM’s ability to manage memory under heavy loads. We tested several data structures, including lists, +hash maps, deques, queues, BTreeMaps, hash sets, and binary heaps. Each zkVM underwent tests for the following operations:

    • Insert: How quickly can the zkVM add data to structures?
    • Delete: Does the zkVM handle memory release effectively?
    • Append: Can the zkVM efficiently grow data structures?
    • Search: How fast and efficient is the zkVM when retrieving stored data?

The purpose of this stage was to identify any memory bottlenecks and to determine whether a zkVM could manage high-intensity tasks efficiently, +something vital for the Nescience project’s complex, data-heavy processes.

Machine specifications

The tests were conducted on the following hardware configuration:

  • CPU: AMD EPYC 7713 "Milan" 64-core processor (128 threads total)
  • RAM: 600GiB DDR4 3200MHz ECC RAM, distributed across 16 DIMMs
  • Host OS: Proxmox 8.3
  • Hypervisor: KVM
  • Network layer: Open vSwitch
  • Machine model: Supermicro AS-2024US-TRT

Results

1. SP1

SP1 does not provide zero-knowledge capability in its proofs but delivers respectable performance, though slightly behind its main competitor. +Memory leaks were minimal, staying below the 700 KB threshold. Interestingly, SP1 consumed more RAM during the basic arithmetic +test than in memory allocation tests, showcasing the team's effective handling of memory under load. In the basic test, +allocations were primarily in the 9-16 B, 33-64 B, and 65-128 B ranges. For memory allocations, most fell into the 129-256 B range.

  • Stage 1: Hept 100 test
    • Proof size: 3.108 MB
    • Proof time: 16.95 seconds
Image 1
Image 2
Image 3
Image 4
Image 5
  • Stage 2: Vec 10000 test
    • Proof size: 3.17 MB
    • Proof time: 20.85 seconds
Image 1
Image 2
Image 3
Image 4
Image 5

2. RISC0

RISC0 stands out with exceptional performance in proof size and generation time, ranking among the best +(with the exception of Valida and zkWASM's basic test). It also handles memory well, with minor leaks under 0.5 MB +and controlled RAM consumption staying below 2.2 GB. RISC0's memory allocations were consistent, primarily in the 17-32 B and 33-64 B ranges.

  • Stage 1: Hept 100 test
    • Proof size: 217.4 KB
    • Proof time: 9.73 seconds
Image 1
Image 2
Image 3
Image 4
Image 5
  • Stage 2: Vec 10000 test
    • Proof size: 217.4 KB
    • Proof time: 16.63 seconds
Image 1
Image 2
Image 3
Image 4
Image 5

Based on these results, RISC0 is a solid candidate for Nescience.


3. Nexus

Nexus' performance offers interesting insights into folding scheme-based zkVMs. Surprisingly, proof sizes remained consistent +regardless of workload, with no significant memory leaks (under 700 KB). However, while RAM consumption increased slightly with higher +workloads (up to 1.2 GB), Nexus performed poorly during memory allocation tests, making it unsuitable for our use case.

  • Allocation details:

    • Basic test: Most allocations concentrated in 65-128 B
    • Memory-heavy test: Allocations in the 129-256 B range
  • Stage 1: Hept 100 test

    • Proof size: 46 MB
    • Proof time: 12.06 seconds
Image 1
Image 2
Image 3
Image 4
Image 5
  • Stage 2: Vec 10000 test
    • Proof size: 46 MB
    • Proof time: 56 minutes
Image 1
Image 2
Image 3
Image 4
Image 5

4. ZkMIPS

ZkMIPS presents an intriguing case. While it shows good results in terms of proof size and generation time during the basic test, +these come at the cost of significant RAM usage and memory leaks. The memory allocation test revealed a concerning 6.7 GB memory leak, +with 0.5 GB leaked during the basic test. Despite this, RAM consumption (while high at 17+ GB) remains stable under higher workloads. +Allocation sizes are spread across several ranges, with notable concentrations in the 17-32 B, 65-128 B, and 257-512 B slots.

  • Stage 1: Hept 100 test
    • Proof size: 4.3 MB
    • Proof time: 9.32 seconds
Image 1
Image 2
Image 3
Image 4
Image 5
  • Stage 2: Vec 10000 test
    • Proof size: 4.898 MB
    • Proof time: 42.57 seconds
Image 1
Image 2
Image 3
Image 4
Image 5

This zkVM provides mixed results with strong proof generation but concerning memory management issues.


5. ZkWASM

ZkWASM, unfortunately, performed poorly in both stages regarding proof size and generation time. RAM consumption was particularly high, +exceeding 7 GB in the basic test, and an astounding 57 GB during memory allocation tests. Despite its impressive memory usage, +the proof sizes were relatively large at 18 KB and 334 KB respectively. Allocation sizes were mainly concentrated in the 33-64 B range, +with neighboring slots contributing small but notable amounts.

  • Stage 1: Hept 100 test
    • Proof size: 18 KB
    • Proof time: 42.7 seconds
Image 1
Image 2
Image 3
Image 4
Image 5
  • Stage 2: Vec 10000 test
    • Proof size: 334 KB
    • Proof time: 323 seconds
Image 1
Image 2
Image 3
Image 4
Image 5

6. Valida

Valida delivered impressive results in proof generation speed and size, with a proof size of 280 KB and a proof time of < 1 second. +However, profiling was not possible due to Valida's limited Rust support. Valida currently compiles Rust using the LLVM backend, +transpiling LLVM IR to leverage its C/C++ implementation, which leads to errors when handling Rust-specific data structures or dependencies. +As a result, complex memory interactions couldn't be tested, and using Valida with Rust code is currently not advisable. +A GitHub issue has been opened to address this.


Summary table

Stage 1

zkVMProof timeProof sizePeak RAM consumptionMemory leaked
SP116.95 s3.108 MB2.1 GB656.8 KB
RISC09.73 s217.4 KB1.9 GB470.5 KB
Nexus12.06 s46 MB9.7 MB646.5 KB
ZkMIPS9.32 s4.3 MB17.3 GB453.8 MB
ZkWASM42.7 s18 KB8.2 GB259.4 KB
Valida< 1 s280 KBN/AN/A

Stage 2

zkVMProof timeProof sizePeak RAM consumptionMemory leaked
SP120.85 s3.17 MB1.9 GB616 KB
RISC016.63 s217.4 KB2.3 GB485.3 KB
Nexus56 m46 MB1.9 GB616 KB
ZkMIPS42.57 s4.898 MB18.9 GB6.9 GB
ZkWASM323 s334 KB58.8 GB259.4 KB
ValidaN/AN/AN/AN/A

Summary

After an extensive evaluation of six zkVM candidates for the Nescience project, RISC0 emerged as the top choice. +It excels in both proof generation time and size while maintaining a reasonable memory footprint. With strong zero-knowledge +proof capabilities and support for multiple programming languages, it aligns well with our project's needs for privacy, +performance, and flexibility. Its overall balance between performance and efficiency makes it the most viable zkVM at this stage.

Valida, while promising with its potential for high prover performance, is still in early development and suffers from Rust integration issues. +The current LLVM IR transpilation limitations mean it cannot handle complex memory interactions, disqualifying it for now. +However, once its development matures, Valida could become a strong alternative, and we plan to revisit it as it evolves.

SP1, though initially interesting, failed to meet the zero-knowledge proof requirement. Its performance in arithmetic operations was +respectable but insufficient to justify further consideration given its lack of ZK functionality – critical for our privacy-first objectives.

Nexus demonstrated consistent proof sizes and manageable memory usage, but its lackluster performance during memory-intensive tasks and +its proof size (especially for larger workloads) disqualified it from being a top contender. While zkMIPS delivered solid proof times, +the memory issues were too significant to ignore, making it unsuitable.

Finally, zkWASM exhibited the poorest results, struggling both in proof size and generation time. Despite its potential for WASM bytecode support, +the excessive RAM consumption (up to 57 GB in the memory test) rendered it impractical for Nescience’s use case.

In conclusion, RISC0 is the best fit for Nescience at this stage, but Valida remains a future candidate as its development progresses.

We’d love to hear your thoughts on our zkVM testing process and results! Do you agree with our conclusions, or do you think we missed a promising zkVM? +We’re always open to feedback, insights, and suggestions from the community.

Join the discussion and share your perspectives on +our forum or try out the +tests yourself through our [GitHub page](https://github.com/vacp2p/nescience-zkvm-testing!

References

[1] Exploring zkVMs: Which Projects Truly Qualify as Zero-Knowledge Virtual Machines? Retrieved from https://vac.dev/rlog/zkVM-explorations/

[2] Nescience: A User-Centric State-Separation Architecture. Retrieved from https://vac.dev/rlog/Nescience-state-separation-architecture

[3] Our GitHub Page for zkVM Testing. Retrieved from https://github.com/vacp2p/nescience-zkvm-testing

[4] Introducing SP1: A performant, 100% open-source, contributor-friendly zkVM. Retrieved from https://blog.succinct.xyz/introducing-sp1/

[5] The first general purpose zkVM. Retrieved from https://www.risczero.com/zkvm

[6] The Nexus 2.0 zkVM. Retrieved from https://docs.nexus.xyz/

[7] ZKM Architecture. Retrieved from https://docs.zkm.io/zkm-architecture

[8] ZK-WASM. Retrieved from https://delphinuslab.com/zk-wasm/

[9] Valida zkVM Design. Retrieved from https://delendum.xyz/writings/2023-05-10-zkvm-design.html

]]>
+ + Moudy + +
<![CDATA[Exploring zkVMs: Which Projects Truly Qualify as Zero-Knowledge Virtual Machines?]]> https://vac.dev/rlog/zkVM-explorations diff --git a/rlog/building-privacy-protecting-infrastructure/index.html b/rlog/building-privacy-protecting-infrastructure/index.html index 03ba2650..1df57b4a 100644 --- a/rlog/building-privacy-protecting-infrastructure/index.html +++ b/rlog/building-privacy-protecting-infrastructure/index.html @@ -10,8 +10,8 @@ - - + +
@@ -261,7 +261,7 @@ discussions on our forum or hiring, and we have started expanding into other privacy infrastructure tech like private and provable computation with ZK-WASM.

- - + + \ No newline at end of file diff --git a/rlog/device-pairing-in-js-waku-and-go-waku/index.html b/rlog/device-pairing-in-js-waku-and-go-waku/index.html index c2b2b085..124b7a20 100644 --- a/rlog/device-pairing-in-js-waku-and-go-waku/index.html +++ b/rlog/device-pairing-in-js-waku-and-go-waku/index.html @@ -10,8 +10,8 @@ - - + +
@@ -20,7 +20,7 @@ ) .lsd-dropdown__trigger:hover .lsd-dropdown__option-label,.lsd-dropdown:not(.lsd-dropdown--disabled):not( .lsd-dropdown--error ) .lsd-dropdown__trigger:focus .lsd-dropdown__option-label{-webkit-text-decoration:underline;text-decoration:underline;}.lsd-dropdown__label{display:block;}.lsd-dropdown__button-container{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-box-pack:justify;-webkit-justify-content:space-between;justify-content:space-between;}.lsd-dropdown__trigger{width:100%;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:row;-ms-flex-direction:row;flex-direction:row;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:justify;-webkit-justify-content:space-between;justify-content:space-between;border:none;cursor:pointer;background:none;}.lsd-dropdown__trigger:focus{outline:none;}.lsd-dropdown__option-label{cursor:inherit;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;}.lsd-dropdown__icons{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:row;-ms-flex-direction:row;flex-direction:row;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:center;-ms-flex-pack:center;-webkit-justify-content:center;justify-content:center;gap:8px;}.lsd-dropdown__icon{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;}.lsd-dropdown__supporting-text{margin:6px 14px;}.lsd-dropdown--error .lsd-dropdown__option-label{-webkit-text-decoration:line-through;text-decoration:line-through;}.lsd-dropdown--disabled{opacity:0.34;cursor:initial;}.lsd-dropdown--large{width:208px;}.lsd-dropdown--large.lsd-dropdown--error{width:230px;}.lsd-dropdown--large .lsd-dropdown__label{margin:0 0 6px 18px;}.lsd-dropdown--large .lsd-dropdown__button-container{height:40px;}.lsd-dropdown--large .lsd-dropdown__trigger{padding:10px 0px 10px 18px;}.lsd-dropdown--large .lsd-dropdown__icons{padding:0px 14px;}.lsd-dropdown--medium{width:188px;}.lsd-dropdown--medium.lsd-dropdown--error{width:210px;}.lsd-dropdown--medium .lsd-dropdown__label{margin:0 0 6px 14px;}.lsd-dropdown--medium .lsd-dropdown__button-container{height:32px;}.lsd-dropdown--medium .lsd-dropdown__trigger{padding:6px 0px 6px 14px;}.lsd-dropdown--medium .lsd-dropdown__icons{padding:0px 12px;}.lsd-dropdown--small{width:164px;}.lsd-dropdown--small.lsd-dropdown--error{width:186px;}.lsd-dropdown--small .lsd-dropdown__label{margin:0 0 6px 12px;}.lsd-dropdown--small .lsd-dropdown__button-container{height:28px;}.lsd-dropdown--small .lsd-dropdown__trigger{padding:6px 0px 6px 12px;}.lsd-dropdown--small .lsd-dropdown__icons{padding:0px 10px;}.lsd-dropdown--outlined .lsd-dropdown__button-container{border:1px solid rgb(var(--lsd-border-primary));}.lsd-dropdown--underlined .lsd-dropdown__button-container{border:1px solid transparent;border-bottom:1px solid rgb(var(--lsd-border-primary));}

Device Pairing in Js-waku and Go-waku

by
5 min read

Device pairing and secure message exchange using Waku and noise protocol.

As the world becomes increasingly connected through the internet, the need for secure and reliable communication becomes paramount. In this article it is described how the Noise protocol can be used as a key-exchange mechanism for Waku.

Recently, this feature was introduced in js-waku and go-waku, providing a simple API for developers to implement secure communication protocols using the Noise Protocol framework. These open-source libraries provide a solid foundation for building secure and decentralized applications that prioritize data privacy and security.

This functionality is designed to be simple and easy to use, even for developers who are not experts in cryptography. The library offers a clear and concise API that abstracts away the complexity of the Noise Protocol framework and provides an straightforward interface for developers to use. Using this, developers can effortlessly implement secure communication protocols on top of their JavaScript and Go applications, without having to worry about the low-level details of cryptography.

One of the key benefits of using Noise is that it provides end-to-end encryption, which means that the communication between two parties is encrypted from start to finish. This is essential for ensuring the security and privacy of sensitive information

Device Pairing

In today's digital world, device pairing has become an integral part of our lives. Whether it's connecting our smartphones with other computers or web applications, the need for secure device pairing has become more crucial than ever. With the increasing threat of cyber-attacks and data breaches, it's essential to implement secure protocols for device pairing to ensure data privacy and prevent unauthorized access.

To demonstrate how device pairing can be achieved using Waku and Noise, we have examples available at https://examples.waku.org/noise-js/. You can try pairing different devices, such as mobile and desktop, via a web application. This can be done by scanning a QR code or opening a URL that contains the necessary data for a secure handshake.

The process works as follows:

Actors:

  • Alice the initiator
  • Bob the responder
  1. The first step in achieving secure device pairing using Noise and Waku is for Bob generate the pairing information which could be transmitted out-of-band. For this, Bob opens https://examples.waku.org/noise-js/ and a QR code is generated, containing the data required to do the handshake. This pairing QR code is timeboxed, meaning that after 2 minutes, it will become invalid and a new QR code must be generated
  2. Alice scans the QR code using a mobile phone. This will open the app with the QR code parameters initiating the handshake process which is described in 43/WAKU2-DEVICE-PAIRING. These messages are exchanged between two devices over Waku to establish a secure connection. The handshake messages consist of three main parts: the initiator's message, the responder's message, and the final message, which are exchanged to establish a secure connection. While using js-noise, the developer is abstracted of this process, since the messaging happens automatically depending on the actions performed by the actors in the pairing process.
  3. Both Alice and Bob will be asked to verify each other's identity. This is done by confirming if an 8-digits authorization code match in both devices. If both actors confirm that the authorization code is valid, the handshake concludes succesfully
  4. Alice and Bob receive a set of shared keys that can be used to start exchanging encrypted messages. The shared secret keys generated during the handshake process are used to encrypt and decrypt messages sent between the devices. This ensures that the messages exchanged between the devices are secure and cannot be intercepted or modified by an attacker.

The above example demonstrates device pairing using js-waku. Additionally, You can also try building and experimenting with other noise implementations like nwaku, or go-waku, with an example available at https://github.com/waku-org/go-waku/tree/master/examples/noise in which the same flow described before is done with Bob (the receiver) using go-waku instead of js-waku.

Conclusion

With its easy to use API built on top of the Noise Protocol framework and the LibP2P networking stack, if you are a developer looking to implement secure messaging in their applications that are both decentralized and censorship resistant, Waku is definitely an excellent choice worth checking out!

Waku is also Open source with a MIT and APACHEv2 licenses, which means that developers are encouraged to contribute code, report bugs, and suggest improvements to make it even better.

Don't hesitate to try the live example at https://examples.waku.org/noise-js and build your own webapp using https://github.com/waku-org/js-noise, https://github.com/waku-org/js-waku and https://github.com/waku-org/go-waku. This will give you a hands-on experience of implementing secure communication protocols using the Noise Protocol framework in a practical setting. Happy coding!

References

- - + + \ No newline at end of file diff --git a/rlog/dns-based-discovery/index.html b/rlog/dns-based-discovery/index.html index 4c966b41..c0942807 100644 --- a/rlog/dns-based-discovery/index.html +++ b/rlog/dns-based-discovery/index.html @@ -10,8 +10,8 @@ - - + +
@@ -20,7 +20,7 @@ ) .lsd-dropdown__trigger:hover .lsd-dropdown__option-label,.lsd-dropdown:not(.lsd-dropdown--disabled):not( .lsd-dropdown--error ) .lsd-dropdown__trigger:focus .lsd-dropdown__option-label{-webkit-text-decoration:underline;text-decoration:underline;}.lsd-dropdown__label{display:block;}.lsd-dropdown__button-container{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-box-pack:justify;-webkit-justify-content:space-between;justify-content:space-between;}.lsd-dropdown__trigger{width:100%;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:row;-ms-flex-direction:row;flex-direction:row;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:justify;-webkit-justify-content:space-between;justify-content:space-between;border:none;cursor:pointer;background:none;}.lsd-dropdown__trigger:focus{outline:none;}.lsd-dropdown__option-label{cursor:inherit;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;}.lsd-dropdown__icons{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:row;-ms-flex-direction:row;flex-direction:row;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:center;-ms-flex-pack:center;-webkit-justify-content:center;justify-content:center;gap:8px;}.lsd-dropdown__icon{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;}.lsd-dropdown__supporting-text{margin:6px 14px;}.lsd-dropdown--error .lsd-dropdown__option-label{-webkit-text-decoration:line-through;text-decoration:line-through;}.lsd-dropdown--disabled{opacity:0.34;cursor:initial;}.lsd-dropdown--large{width:208px;}.lsd-dropdown--large.lsd-dropdown--error{width:230px;}.lsd-dropdown--large .lsd-dropdown__label{margin:0 0 6px 18px;}.lsd-dropdown--large .lsd-dropdown__button-container{height:40px;}.lsd-dropdown--large .lsd-dropdown__trigger{padding:10px 0px 10px 18px;}.lsd-dropdown--large .lsd-dropdown__icons{padding:0px 14px;}.lsd-dropdown--medium{width:188px;}.lsd-dropdown--medium.lsd-dropdown--error{width:210px;}.lsd-dropdown--medium .lsd-dropdown__label{margin:0 0 6px 14px;}.lsd-dropdown--medium .lsd-dropdown__button-container{height:32px;}.lsd-dropdown--medium .lsd-dropdown__trigger{padding:6px 0px 6px 14px;}.lsd-dropdown--medium .lsd-dropdown__icons{padding:0px 12px;}.lsd-dropdown--small{width:164px;}.lsd-dropdown--small.lsd-dropdown--error{width:186px;}.lsd-dropdown--small .lsd-dropdown__label{margin:0 0 6px 12px;}.lsd-dropdown--small .lsd-dropdown__button-container{height:28px;}.lsd-dropdown--small .lsd-dropdown__trigger{padding:6px 0px 6px 12px;}.lsd-dropdown--small .lsd-dropdown__icons{padding:0px 10px;}.lsd-dropdown--outlined .lsd-dropdown__button-container{border:1px solid rgb(var(--lsd-border-primary));}.lsd-dropdown--underlined .lsd-dropdown__button-container{border:1px solid transparent;border-bottom:1px solid rgb(var(--lsd-border-primary));}

DNS Based Discovery

by
6 min read

A look at EIP-1459 and the benefits of DNS based discovery.

Discovery in p2p networks is the process of how nodes find each other and specific resources they are looking for. Popular discovery protocols, such as Kademlia which utilizes a distributed hash table or DHT, are highly inefficient for resource restricted devices. These methods use short connection windows, and it is quite battery intensive to keep establishing connections. Additionally, we cannot expect a mobile phone for example to synchronize an entire DHT using cellular data.

Another issue is how we do the initial bootstrapping. In other words, how does a client find its first node to then discover the rest of the network? In most applications, including Status right now, this is done with a static list of nodes that a client can connect to.

In summary, we have a static list that provides us with nodes we can connect to which then allows us to discover the rest of the network using something like Kademlia. But what we need is something that can easily be mutated, guarantees a certain amount of security, and is efficient for resource restricted devices. Ideally our solution would also be robust and scalable.

How do we do this?

EIP 1459: Node Discovery via DNS, which is one of the strategies we are using for discovering waku nodes. EIP-1459 is a DNS-based discovery protocol that stores merkle trees in DNS records which contain connection information for nodes.

Waku is our fork of Whisper. Oskar recently wrote an entire post explaining it. In short, Waku is our method of fixing the shortcomings of Whisper in a more iterative fashion. You can find the specification here

DNS-based methods for bootstrapping p2p networks are quite popular. Even Bitcoin uses it, but it uses a concept called DNS seeds, which are just DNS servers that are configured to return a list of randomly selected nodes from the network upon being queried. This means that although these seeds are hardcoded in the client, the IP addresses of actual nodes do not have to be.

> dig dnsseed.bluematt.me +short
129.226.73.12
107.180.78.111
169.255.56.123
91.216.149.28
85.209.240.91
66.232.124.232
207.55.53.96
86.149.241.168
193.219.38.57
190.198.210.139
74.213.232.234
158.181.226.33
176.99.2.207
202.55.87.45
37.205.10.3
90.133.4.73
176.191.182.3
109.207.166.232
45.5.117.59
178.211.170.2
160.16.0.30

The above displays the result of querying on of these DNS seeds. All the nodes are stored as A records for the given domain name. This is quite a simple solution which Bitcoin almost soley relies on since removing the IRC bootstrapping method in v0.8.2.

What makes this DNS based discovery useful? It allows us to have a mutable list of bootstrap nodes without needing to ship a new version of the client every time a list is mutated. It also allows for a more lightweight method of discovering nodes, something very important for resource restricted devices.

Additionally, DNS provides us with a robust and scalable infrastructure. This is due to its hierarchical architecture. This hierarchical architecture also already makes it distributed such that the failure of one DNS server does not result in us no longer being able to resolve our name.

As with every solution though, there is a trade-off. By storing the list in DNS name an adversary would simply need to censor the DNS records for a specific name. This would prevent any new client trying to join the network from being able to do so.

One thing you notice when looking at EIP-1459 is that it is a lot more technically complex than Bitcoin's way of doing this. So if Bitcoin uses this simple method and has proven that it works, why did we need a new method?

There are multiple reasons, but the main one is security. In the Bitcoin example, an attacker could create a new list and no one querying would be able to tell. This is however mitigated in EIP-1459 where we can verify the integrity of the entire returned list by storing an entire merkle tree in the DNS records.

Let's dive into this. Firstly, a client that is using these DNS records for discovery must know the public key corresponding to the private key controlled by the entity creating the list. This is because the entire list is signed using a secp256k1 private key, giving the client the ability to authenticate the list and know that it has not been tampered with by some external party.

So that already makes this a lot safer than the method Bitcoin uses. But how are these lists even stored? As previously stated they are stored using merkle trees as follows:

  • The root of the tree is stored in a TXT record, this record contains the tree's root hash, a sequence number which is incremented every time the tree is updated and a signature as stated above.

    Additionally, there is also a root hash to a second tree called a link tree, it contains the information to different lists. This link tree allows us to delegate trust and build a graph of multiple merkle trees stored across multiple DNS names.

    The sequence number ensures that an attacker cannot replace a tree with an older version because when a client reads the tree, they should ensure that the sequence number is greater than the last synchronized version.

  • Using the root hash for the tree, we can find the merkle tree's first branch, the branch is also stored in a TXT record. The branch record contains all the hashes of the branch's leafs.

  • Once a client starts reading all the leafs, they can find one of two things: either a new branch record leading them further down the tree or an Ethereum Name Records (ENR) which means they now have the address of a node to connect to! To learn more about ethereum node records you can have a look at EIP-778, or read a short blog post I wrote explaining them here.

Below is the zone file taken from the EIP-1459, displaying how this looks in practice.

; name                        ttl     class type  content
@ 60 IN TXT enrtree-root:v1 e=JWXYDBPXYWG6FX3GMDIBFA6CJ4 l=C7HRFPF3BLGF3YR4DY5KX3SMBE seq=1 sig=o908WmNp7LibOfPsr4btQwatZJ5URBr2ZAuxvK4UWHlsB9sUOTJQaGAlLPVAhM__XJesCHxLISo94z5Z2a463gA
C7HRFPF3BLGF3YR4DY5KX3SMBE 86900 IN TXT enrtree://AM5FCQLWIZX2QFPNJAP7VUERCCRNGRHWZG3YYHIUV7BVDQ5FDPRT2@morenodes.example.org
JWXYDBPXYWG6FX3GMDIBFA6CJ4 86900 IN TXT enrtree-branch:2XS2367YHAXJFGLZHVAWLQD4ZY,H4FHT4B454P6UXFD7JCYQ5PWDY,MHTDO6TMUBRIA2XWG5LUDACK24
2XS2367YHAXJFGLZHVAWLQD4ZY 86900 IN TXT enr:-HW4QOFzoVLaFJnNhbgMoDXPnOvcdVuj7pDpqRvh6BRDO68aVi5ZcjB3vzQRZH2IcLBGHzo8uUN3snqmgTiE56CH3AMBgmlkgnY0iXNlY3AyNTZrMaECC2_24YYkYHEgdzxlSNKQEnHhuNAbNlMlWJxrJxbAFvA
H4FHT4B454P6UXFD7JCYQ5PWDY 86900 IN TXT enr:-HW4QAggRauloj2SDLtIHN1XBkvhFZ1vtf1raYQp9TBW2RD5EEawDzbtSmlXUfnaHcvwOizhVYLtr7e6vw7NAf6mTuoCgmlkgnY0iXNlY3AyNTZrMaECjrXI8TLNXU0f8cthpAMxEshUyQlK-AM0PW2wfrnacNI
MHTDO6TMUBRIA2XWG5LUDACK24 86900 IN TXT enr:-HW4QLAYqmrwllBEnzWWs7I5Ev2IAs7x_dZlbYdRdMUx5EyKHDXp7AV5CkuPGUPdvbv1_Ms1CPfhcGCvSElSosZmyoqAgmlkgnY0iXNlY3AyNTZrMaECriawHKWdDRk2xeZkrOXBQ0dfMFLHY4eENZwdufn1S1o

All of this has already been introduced into go-ethereum with the pull request #20094, created by Felix Lange. There's a lot of tooling around it that already exists too which is really cool. So if your project is written in Golang and wants to use this, it's relatively simple! Additionally, here's a proof of concept that shows what this might look like with libp2p on github.

I hope this was a helpful explainer into DNS based discovery, and shows EIP-1459's benefits over more traditional DNS-based discovery schemes.

- - + + \ No newline at end of file diff --git a/rlog/ethics-surveillance-tech/index.html b/rlog/ethics-surveillance-tech/index.html index 9f60812a..0246a21a 100644 --- a/rlog/ethics-surveillance-tech/index.html +++ b/rlog/ethics-surveillance-tech/index.html @@ -10,8 +10,8 @@ - - + + - - + + \ No newline at end of file diff --git a/rlog/feasibility-discv5/index.html b/rlog/feasibility-discv5/index.html index 92ffde53..d8e5910e 100644 --- a/rlog/feasibility-discv5/index.html +++ b/rlog/feasibility-discv5/index.html @@ -10,8 +10,8 @@ - - + +
@@ -20,7 +20,7 @@ ) .lsd-dropdown__trigger:hover .lsd-dropdown__option-label,.lsd-dropdown:not(.lsd-dropdown--disabled):not( .lsd-dropdown--error ) .lsd-dropdown__trigger:focus .lsd-dropdown__option-label{-webkit-text-decoration:underline;text-decoration:underline;}.lsd-dropdown__label{display:block;}.lsd-dropdown__button-container{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-box-pack:justify;-webkit-justify-content:space-between;justify-content:space-between;}.lsd-dropdown__trigger{width:100%;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:row;-ms-flex-direction:row;flex-direction:row;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:justify;-webkit-justify-content:space-between;justify-content:space-between;border:none;cursor:pointer;background:none;}.lsd-dropdown__trigger:focus{outline:none;}.lsd-dropdown__option-label{cursor:inherit;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;}.lsd-dropdown__icons{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:row;-ms-flex-direction:row;flex-direction:row;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:center;-ms-flex-pack:center;-webkit-justify-content:center;justify-content:center;gap:8px;}.lsd-dropdown__icon{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;}.lsd-dropdown__supporting-text{margin:6px 14px;}.lsd-dropdown--error .lsd-dropdown__option-label{-webkit-text-decoration:line-through;text-decoration:line-through;}.lsd-dropdown--disabled{opacity:0.34;cursor:initial;}.lsd-dropdown--large{width:208px;}.lsd-dropdown--large.lsd-dropdown--error{width:230px;}.lsd-dropdown--large .lsd-dropdown__label{margin:0 0 6px 18px;}.lsd-dropdown--large .lsd-dropdown__button-container{height:40px;}.lsd-dropdown--large .lsd-dropdown__trigger{padding:10px 0px 10px 18px;}.lsd-dropdown--large .lsd-dropdown__icons{padding:0px 14px;}.lsd-dropdown--medium{width:188px;}.lsd-dropdown--medium.lsd-dropdown--error{width:210px;}.lsd-dropdown--medium .lsd-dropdown__label{margin:0 0 6px 14px;}.lsd-dropdown--medium .lsd-dropdown__button-container{height:32px;}.lsd-dropdown--medium .lsd-dropdown__trigger{padding:6px 0px 6px 14px;}.lsd-dropdown--medium .lsd-dropdown__icons{padding:0px 12px;}.lsd-dropdown--small{width:164px;}.lsd-dropdown--small.lsd-dropdown--error{width:186px;}.lsd-dropdown--small .lsd-dropdown__label{margin:0 0 6px 12px;}.lsd-dropdown--small .lsd-dropdown__button-container{height:28px;}.lsd-dropdown--small .lsd-dropdown__trigger{padding:6px 0px 6px 12px;}.lsd-dropdown--small .lsd-dropdown__icons{padding:0px 10px;}.lsd-dropdown--outlined .lsd-dropdown__button-container{border:1px solid rgb(var(--lsd-border-primary));}.lsd-dropdown--underlined .lsd-dropdown__button-container{border:1px solid transparent;border-bottom:1px solid rgb(var(--lsd-border-primary));}

Feasibility Study: Discv5

by
6 min read

Looking at discv5 and the theoretical numbers behind finding peers.

Disclaimer: some of the numbers found in this write-up could be inaccurate. They are based on the current understanding of theoretical parts of the protocol itself by the author and are meant to provide a rough overview rather than bindable numbers.

This post serves as a more authoritative overview of the discv5 study, for a discussionary post providing more context make sure to check out the corresponding discuss post. Additionally, if you are unfamiliar with discv5, check out my previous write-up: "From Kademlia to Discv5".

Motivating Problem

The discovery method currently used by Status, is made up of various components and grew over time to solve a mix of problems. We want to simplify this while maintaining some of the properties we currently have.

Namely, we want to ensure censorship resistance to state-level adversaries. One of the issues Status had which caused us them add to their discovery method was the fact that addresses from providers like AWS and GCP were blocked both in Russia and China. Additionally, one of the main factors required is the ability to function on resource restricted devices.

Considering we are talking about resource restricted devices, let's look at the implications and what we need to consider:

  • Battery consumption - constant connections like websockets consume a lot of battery life.
  • CPU usage - certain discovery methods may be CPU incentive, slowing an app down and making it unusable.
  • Bandwidth consumption - a lot of users will be using data plans, the discovery method needs to be efficient in order to accommodate those users without using up significant portions of their data plans.
  • Short connection windows - the discovery algorithm needs to be low latency, that means it needs to return results fast. This is because many users will only have the app open for a short amount of time.
  • Not publicly connectable - There is a good chance that most resource restricted devices are not publicly connectable.

For a node to be able to participate as both a provider, and a consumer in the discovery method. Meaning a node both reads from other nodes' stored DHTs and hosts the DHT for other nodes to read from, it needs to be publically connectable. This means another node must be able to connect to some public IP of the given node.

With devices that are behind a NAT, this is easier said than done. Especially mobile devices, that when connected to 4G LTE networks are often stuck behind a symmetric NAT, drastically reducing the the succeess rate of NAT traversal. Keeping this in mind, it becomes obvious that most resource restricted devices will be consumers rather than providers due to this technical limitation.

In order to answer our questions, we formulated the problem with a simple method for testing. The "needle in a haystack" problem was formulated to figure out how easily a specific node can be found within a given network. This issue was fully formulated in vacp2p/research#15.

Overview

The main things we wanted to investigate was the overhead on finding a peer. This means we wanted to look at both the bandwidth, latency and effectiveness of this. There are 2 methods which we can use to find a peer:

  • We can find a peer with a specific ID, using normal lookup methods as documented by Kademlia.
  • We can find a peer that advertises a capability, this is possible using either capabilities advertised in the ENR or through topic tables.

Feasbility

To be able to investigate the feasibility of discv5, we used various methods including rough calculations which can be found in the notebook, and a simulation isolated in vacp2p/research#19.

CPU & Memory Usage

The experimental discv5 has already been used within Status, however what was noticed was that the CPU and memory usage was rather high. It therefore should be investiaged if this is still the case, and if it is, it should be isolated where this stems from. Additionally it is worth looking at whether or not this is the case with both the go and nim implementation.

See details: vacp2p/research#31

NAT on Cellular Data

If a peer is not publically connectable it can not participate in the DHT both ways. A lot of mobile phones are behind symmetric NATs which UDP hole-punching close to impossible. It should be investigated whether or not mobile phones will be able to participate both ways and if there are good methods for doing hole-punching.

See details: vacp2p/research#29

Topic Tables

Topic Tables allow us the ability to efficiently find nodes given a specific topic. However, they are not implemented in the status-im/nim-eth implementation nor are they fully finalized in the spec. These are important if the network grows past a size where the concentration of specific nodes is relatively low making them hard to find.

See details: vacp2p/research#26

Finding a node

It is important to note, that given a network is relatively small sized, eg 100-500 nodes, then finding a node given a specific address is relatively managable. Additionally, if the concentration of a specific capability in a network is reasonable, then finding a node advertising its capabilities using an ENR rather than the topic table is also managable. A reasonable concentration for example would be 10%, which would give us an 80% chance of getting a node with that capability in the first lookup request. This can be explored more using our discv5 notebook.

Results

Research has shown that finding a node in the DHT has a relatively low effect on bandwidth, both inbound and outbound. For example when trying to find a node in a network of 100 nodes, it would take roughly 5668 bytes total. Additionally if we assume 100ms latency per request it would range at ≈ 300ms latency, translating to 3 requests to find a specific node.

General Thoughts

One of the main blockers right now is figuring out what the CPU and memory usage of discv5 is on mobile phones, this is a large blocker as it affects one of the core problems for us. We need to consider whether discv5 is an upgrade as it allows us to simplify our current discovery process or if it is too much of an overhead for resource restricted devices. The topic table feature could largely enhance discovery however it is not yet implemented. Given that CPU and memory isn't too high, discv5 could probably be used as the other issues are more "features" than large scale issues. Implementing it would already reduce the ability for state level adversaries to censor our nodes.

Acknowledgements

  • Oskar Thoren
  • Dmitry Shmatko
  • Kim De Mey
  • Corey Petty
- - + + \ No newline at end of file diff --git a/rlog/feasibility-semaphore-rate-limiting-zksnarks/index.html b/rlog/feasibility-semaphore-rate-limiting-zksnarks/index.html index ef09cfe1..16195e90 100644 --- a/rlog/feasibility-semaphore-rate-limiting-zksnarks/index.html +++ b/rlog/feasibility-semaphore-rate-limiting-zksnarks/index.html @@ -10,8 +10,8 @@ - - + +
@@ -20,7 +20,7 @@ ) .lsd-dropdown__trigger:hover .lsd-dropdown__option-label,.lsd-dropdown:not(.lsd-dropdown--disabled):not( .lsd-dropdown--error ) .lsd-dropdown__trigger:focus .lsd-dropdown__option-label{-webkit-text-decoration:underline;text-decoration:underline;}.lsd-dropdown__label{display:block;}.lsd-dropdown__button-container{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-box-pack:justify;-webkit-justify-content:space-between;justify-content:space-between;}.lsd-dropdown__trigger{width:100%;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:row;-ms-flex-direction:row;flex-direction:row;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:justify;-webkit-justify-content:space-between;justify-content:space-between;border:none;cursor:pointer;background:none;}.lsd-dropdown__trigger:focus{outline:none;}.lsd-dropdown__option-label{cursor:inherit;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;}.lsd-dropdown__icons{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:row;-ms-flex-direction:row;flex-direction:row;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:center;-ms-flex-pack:center;-webkit-justify-content:center;justify-content:center;gap:8px;}.lsd-dropdown__icon{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;}.lsd-dropdown__supporting-text{margin:6px 14px;}.lsd-dropdown--error .lsd-dropdown__option-label{-webkit-text-decoration:line-through;text-decoration:line-through;}.lsd-dropdown--disabled{opacity:0.34;cursor:initial;}.lsd-dropdown--large{width:208px;}.lsd-dropdown--large.lsd-dropdown--error{width:230px;}.lsd-dropdown--large .lsd-dropdown__label{margin:0 0 6px 18px;}.lsd-dropdown--large .lsd-dropdown__button-container{height:40px;}.lsd-dropdown--large .lsd-dropdown__trigger{padding:10px 0px 10px 18px;}.lsd-dropdown--large .lsd-dropdown__icons{padding:0px 14px;}.lsd-dropdown--medium{width:188px;}.lsd-dropdown--medium.lsd-dropdown--error{width:210px;}.lsd-dropdown--medium .lsd-dropdown__label{margin:0 0 6px 14px;}.lsd-dropdown--medium .lsd-dropdown__button-container{height:32px;}.lsd-dropdown--medium .lsd-dropdown__trigger{padding:6px 0px 6px 14px;}.lsd-dropdown--medium .lsd-dropdown__icons{padding:0px 12px;}.lsd-dropdown--small{width:164px;}.lsd-dropdown--small.lsd-dropdown--error{width:186px;}.lsd-dropdown--small .lsd-dropdown__label{margin:0 0 6px 12px;}.lsd-dropdown--small .lsd-dropdown__button-container{height:28px;}.lsd-dropdown--small .lsd-dropdown__trigger{padding:6px 0px 6px 12px;}.lsd-dropdown--small .lsd-dropdown__icons{padding:0px 10px;}.lsd-dropdown--outlined .lsd-dropdown__button-container{border:1px solid rgb(var(--lsd-border-primary));}.lsd-dropdown--underlined .lsd-dropdown__button-container{border:1px solid transparent;border-bottom:1px solid rgb(var(--lsd-border-primary));}

Feasibility Study: Semaphore rate limiting through zkSNARKs

by
8 min read

A research log. Zero knowledge signaling as a rate limiting mechanism to prevent spam in p2p networks.

tldr: Moon math promising for solving spam in Whisper, but to get there we need to invest more in performance work and technical upskilling.

Motivating problem

In open p2p networks for messaging, one big problem is spam-resistance. Existing solutions, such as Whisper's proof of work, are insufficient, especially for heterogeneous nodes. Other reputation-based approaches might not be desirable, due to issues around arbitrary exclusion and privacy.

One possible solution is to use a right-to-access staking-based method, where a node is only able to send a message, signal, at a certain rate, and otherwise they can be slashed. One problem with this is in terms of privacy-preservation, where we specifically don't want a user to be tied to a specific payment or unique fingerprint.

In addition to above, there are a lot of related problems that share similarities in terms of their structure and proposed solution.

  • Private transactions (Zcash, AZTEC)
  • Private voting (Semaphore)
  • Private group membership (Semaphore)
  • Layer 2 scaling, poss layer 1 (ZK Rollup; StarkWare/Eth2-3)

Overview

Basic terminology

A zero-knowledge proof allows a prover to show a verifier that they know something, without revealing what that something is. This means you can do trust-minimized computation that is also privacy preserving. As a basic example, instead of showing your ID when going to a bar you simply give them a proof that you are over 18, without showing the doorman your id.

zkSNARKs is a form of zero-knowledge proofs. There are many types of zero-knowledge proofs, and the field is evolving rapidly. They come with various trade-offs in terms of things such as: trusted setup, cryptographic assumptions, proof/verification key size, proof/verification time, proof size, etc. See section below for more.

Semaphore is a framework/library/construct on top of zkSNARks. It allows for zero-knowledge signaling, specifically on top of Ethereum. This means an approved user can broadcast some arbitrary string without revealing their identity, given some specific constraints. An approved user is someone who has been added to a certain merkle tree. See current Github home for more.

Circom is a DSL for writing arithmetic circuits that can be used in zkSNARKs, similar to how you might write a NAND gate. See Github for more.

Basic flow

We start with a private voting example, and then extend it to the slashable rate limiting example.

  1. A user registers an identity (arbitrary keypair), along with a small fee, to a smart contract. This adds them to a merkle tree and allows them to prove that they are member of that group, without revealing who they are.

  2. When a user wants to send a message, they compute a zero-knowledge proof. This ensures certain invariants, have some public outputs, and can be verified by anyone (including a smart contract).

  3. Any node can verify the proof, including smart contracts on chain (as of Byzantinum HF). Additionally, a node can have rules for the public output. In the case of voting, one such rule is that a specific output hash has to be equal to some predefined value, such as "2020-01-01 vote on Foo Bar for president".

  4. Because of how the proof is constructed, and the rules around output values, this ensures that: a user is part of the approved set of voters and that a user can only vote once.

  5. As a consequence of above, we have a system where registered users can only vote once, no one can see who voted for what, and this can all be proven and verified.

Rate limiting example

In the case of rate limiting, we do want nodes to send multiple messages. This changes step 3-5 above somewhat.

NOTE: It is a bit more involved than this, and if we precompute proofs the flow might look a bit different. But the general idea is the same.

  1. Instead of having a rule that you can only vote once, we have a rule that you can only send a message per epoch. Epoch here can be every second, as defined by UTC date time +-20s.

  2. Additionally, if a users sends more than one message per epoch, one of the public outputs is a random share of a private key. Using Shamir's Secret Sharing (similar to a multisig) and 2/3 key share as an example threshold: in the normal case only 1/3 private keys is revealed, which is insufficient to have access. In the case where two messages are sent in an epoch, probabilistically 2/3 shares is sufficient to have access to the key (unless you get the same random share of the key).

  3. This means any untrusted user who detects a spamming user, can use it to access their private key corresponding to funds in the contract, and thus slash them.

  4. As a consequence of above, we have a system where registered users can only messages X times per epoch, and no one can see who is sending what messages. Additionally, if a user is violating the above rate limit, they can be punished and any user can profit from it.

Briefly on scope of 'approved users'

In the case of an application like Status, this construct can either be a global StatusNetwork group, or one per chat, or network, etc. It can be applied both at the network and user level. There are no specific limitations on where or who deploys this, and it is thus more of a UX consideration.

Technical details

For a fairly self-contained set of examples above, see exploration in Vac research repo. Note that the Shamir secret sharing is not inside the SNARK, but out-of-band for now.

The current version of Semaphore is using NodeJS and Circom from Iden3 for Snarks.

For more on rate limiting idea, see ethresearch post.

Feasibility

The above repo was used to exercise the basic paths and to gain intution of feasibility. Based on it and related reading we outline a few blockers and things that require further study.

Technical feasibility

Proof time

Prove time for Semaphore (https://github.com/kobigurk/semaphore) zKSNARKs using circom, groth and snarkjs is currently way too long. It takes on the order of ~10m to generate a proof. With Websnark, it is likely to take 30s, which might still be too long. We should experiment with native code on mobile here.

See details.

Proving key size

Prover key size is ~110mb for Semaphore. Assuming this is embedded on mobile device, it bloats the APK a lot. Current APK size is ~30mb and even that might be high for people with limited bandwidth.

See details.

Trusted setup

Using zkSNARKs a trusted setup is required to generate prover and verifier keys. As part of this setup, a toxic parameter lambda is generated. If a party gets access to this lambda, they can prove anything. This means people using zKSNARKs usually have an elaborate MPC ceremony to ensure this parameter doesn't get discovered.

See details.

Shamir logic in SNARK

For Semaphore RLN we need to embed the Shamir logic inside the SNARK in order to do slashing for spam. Currently the implementation is trusted and very hacky.

See details.

End to end integation

Currently is standalone and doesn't touch multiple users, deployed contract with merkle tree and verification, actual transactions, a mocked network, add/remove members, etc. There are bound to be edge cases and unknown unknowns here.

See details.

Licensing issues

Currently Circom uses a GPL license, which can get tricky when it comes to the App Store etc.

See details.

Alternative ZKPs?

Some of the isolated blockers for zKSNARKs (#7, #8, #9) might be mitigated by the use of other ZKP technology. However, they likely have their own issues.

See details.

Social feasibility

Technical skill

zkSNARKs and related technologies are quite new. To learn how they work and get an intuition for them requires individuals to dedicate a lot of time to studying them. This means we must make getting competence in these technologies if we wish to use them to our advantage.

Time and resources

In order for this and related projects (such as private transaction) to get anywhere, it must be made an explicit area of focus for an extend period of time.

General thoughts

Similar to Whisper, and in line with moving towards protocol and infrastructure, we need to upskill and invest resources into this. This doesn't mean developing all of the technologies ourselves, but gaining enough competence to leverage and extend existing solutions by the growing ZKP community.

For example, this might also include leveraging largely ready made solutions such as AZTEC for private transaction; more fundamental research into ZK rollup and similar; using Semaphore for private group membership and private voting; Nim based wrapper aronud Bellman, etc.

Acknowledgement

Thanks to Barry Whitehat for patient explanation and pointers. Thanks to WJ for helping with runtime issues.

Peacock header image from [Tonos](<https://en.wikipedia.org/wiki/File:Flickr-lo.tangelini-Tonos(1).jpg>)._

- - + + \ No newline at end of file diff --git a/rlog/fixing-whisper-with-waku/index.html b/rlog/fixing-whisper-with-waku/index.html index 754f6544..e5529df1 100644 --- a/rlog/fixing-whisper-with-waku/index.html +++ b/rlog/fixing-whisper-with-waku/index.html @@ -10,8 +10,8 @@ - - + +
@@ -41,7 +41,7 @@ approaches. It is likely that Waku will either converge to those, or Waku will lay the groundwork (clear specs, common issues/components) necessary to make switching to another protocol easier. In this project we want to emphasize iterative work with results on the order of weeks.

Briefly on Waku mode

  • Doesn’t impact existing clients, it’s just a separate node and capability.
  • Other nodes can still use Whisper as is, like a full node.
  • Sacrifices metadata protection and incurs higher connectivity/availability requirements for scalbility

Requirements:

  • Exposes API to get messages from a set of list of topics (no bloom filter)
  • Way of being identified as a Waku node (e.g. through version string)
  • Option to statically encode this node in app, e.g. similar to custom bootnodes/mailserver
  • Only node that needs to be connected to, possibly as Whisper relay / mailserver hybrid

Provides:

  • likely provides scalability of up to 10k users and beyond
  • with some enhancements to partition topic logic, can possibly scale up to 1m users (app/network specific)

Caveats:

  • hasn’t been tested in a large-scale simulation
  • other network and intermediate node bottlenecks might become apparent (e.g. full bloom filter and private cluster capacity; can likely be dealt with in isolation using known techniques, e.g. load balancing) (deployment specific)

Progress so far

In short, we have a Waku version 0 spec up as well as a PoC for backwards compatibility. In the coming weeks, we are going to solidify the specs, get a more fully featured PoC for Waku mode. See rough roadmap, project board [link deprecated] and progress thread on the Vac forum.

The spec has been rewrittten for clarity, with ABNF grammar and less ambiguous language. The spec also incorporates several previously ad hoc implemented features, such as light nodes and mailserver/client support. This has already caught a few incompatibilities between the geth (Go), status/whisper (Go) and nim-eth (Nim) versions, specifically around light node usage and the handshake.

If you are interested in this effort, please check out our forum for questions, comments and proposals. We already have some discussion for better spam protection (see previous post for a more complex but privacy-preserving proposal), something that is likely going to be addressed in future versions of Waku, along with many other fixes and enhancement.

- - + + \ No newline at end of file diff --git a/rlog/future-of-waku-network/index.html b/rlog/future-of-waku-network/index.html index 4ac1382b..5088e7fd 100644 --- a/rlog/future-of-waku-network/index.html +++ b/rlog/future-of-waku-network/index.html @@ -10,8 +10,8 @@ - - + +
@@ -57,7 +57,7 @@ and allow various payment models to coexist within the Waku ecosystem.

In maintaining its core principles. As Waku continues to evolve, we expect it to accommodate a diverse range of use cases and business models, all while preserving privacy, resisting censorship, avoiding surveillance, and remaining accessible to devices with limited resources.

References

  1. 51/WAKU2-RELAY-SHARDING
  2. 57/STATUS-Simple-Scaling
  3. 58/RLN-V2
  4. Scaling Status Communities: Potential Problems
  5. Waku Network Testing
  6. 51/WAKU2-RELAY-SHARDING: Control Message Shards
- - + + \ No newline at end of file diff --git a/rlog/index.html b/rlog/index.html index 9eda6a40..4e64a0e1 100644 --- a/rlog/index.html +++ b/rlog/index.html @@ -10,8 +10,8 @@ - - + +
@@ -19,8 +19,8 @@ .lsd-dropdown--error ) .lsd-dropdown__trigger:hover .lsd-dropdown__option-label,.lsd-dropdown:not(.lsd-dropdown--disabled):not( .lsd-dropdown--error - ) .lsd-dropdown__trigger:focus .lsd-dropdown__option-label{-webkit-text-decoration:underline;text-decoration:underline;}.lsd-dropdown__label{display:block;}.lsd-dropdown__button-container{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-box-pack:justify;-webkit-justify-content:space-between;justify-content:space-between;}.lsd-dropdown__trigger{width:100%;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:row;-ms-flex-direction:row;flex-direction:row;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:justify;-webkit-justify-content:space-between;justify-content:space-between;border:none;cursor:pointer;background:none;}.lsd-dropdown__trigger:focus{outline:none;}.lsd-dropdown__option-label{cursor:inherit;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;}.lsd-dropdown__icons{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:row;-ms-flex-direction:row;flex-direction:row;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:center;-ms-flex-pack:center;-webkit-justify-content:center;justify-content:center;gap:8px;}.lsd-dropdown__icon{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;}.lsd-dropdown__supporting-text{margin:6px 14px;}.lsd-dropdown--error .lsd-dropdown__option-label{-webkit-text-decoration:line-through;text-decoration:line-through;}.lsd-dropdown--disabled{opacity:0.34;cursor:initial;}.lsd-dropdown--large{width:208px;}.lsd-dropdown--large.lsd-dropdown--error{width:230px;}.lsd-dropdown--large .lsd-dropdown__label{margin:0 0 6px 18px;}.lsd-dropdown--large .lsd-dropdown__button-container{height:40px;}.lsd-dropdown--large .lsd-dropdown__trigger{padding:10px 0px 10px 18px;}.lsd-dropdown--large .lsd-dropdown__icons{padding:0px 14px;}.lsd-dropdown--medium{width:188px;}.lsd-dropdown--medium.lsd-dropdown--error{width:210px;}.lsd-dropdown--medium .lsd-dropdown__label{margin:0 0 6px 14px;}.lsd-dropdown--medium .lsd-dropdown__button-container{height:32px;}.lsd-dropdown--medium .lsd-dropdown__trigger{padding:6px 0px 6px 14px;}.lsd-dropdown--medium .lsd-dropdown__icons{padding:0px 12px;}.lsd-dropdown--small{width:164px;}.lsd-dropdown--small.lsd-dropdown--error{width:186px;}.lsd-dropdown--small .lsd-dropdown__label{margin:0 0 6px 12px;}.lsd-dropdown--small .lsd-dropdown__button-container{height:28px;}.lsd-dropdown--small .lsd-dropdown__trigger{padding:6px 0px 6px 12px;}.lsd-dropdown--small .lsd-dropdown__icons{padding:0px 10px;}.lsd-dropdown--outlined .lsd-dropdown__button-container{border:1px solid rgb(var(--lsd-border-primary));}.lsd-dropdown--underlined .lsd-dropdown__button-container{border:1px solid transparent;border-bottom:1px solid rgb(var(--lsd-border-primary));}

Research Blog

Blog
- - + ) .lsd-dropdown__trigger:focus .lsd-dropdown__option-label{-webkit-text-decoration:underline;text-decoration:underline;}.lsd-dropdown__label{display:block;}.lsd-dropdown__button-container{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-box-pack:justify;-webkit-justify-content:space-between;justify-content:space-between;}.lsd-dropdown__trigger{width:100%;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:row;-ms-flex-direction:row;flex-direction:row;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:justify;-webkit-justify-content:space-between;justify-content:space-between;border:none;cursor:pointer;background:none;}.lsd-dropdown__trigger:focus{outline:none;}.lsd-dropdown__option-label{cursor:inherit;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;}.lsd-dropdown__icons{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:row;-ms-flex-direction:row;flex-direction:row;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:center;-ms-flex-pack:center;-webkit-justify-content:center;justify-content:center;gap:8px;}.lsd-dropdown__icon{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;}.lsd-dropdown__supporting-text{margin:6px 14px;}.lsd-dropdown--error .lsd-dropdown__option-label{-webkit-text-decoration:line-through;text-decoration:line-through;}.lsd-dropdown--disabled{opacity:0.34;cursor:initial;}.lsd-dropdown--large{width:208px;}.lsd-dropdown--large.lsd-dropdown--error{width:230px;}.lsd-dropdown--large .lsd-dropdown__label{margin:0 0 6px 18px;}.lsd-dropdown--large .lsd-dropdown__button-container{height:40px;}.lsd-dropdown--large .lsd-dropdown__trigger{padding:10px 0px 10px 18px;}.lsd-dropdown--large .lsd-dropdown__icons{padding:0px 14px;}.lsd-dropdown--medium{width:188px;}.lsd-dropdown--medium.lsd-dropdown--error{width:210px;}.lsd-dropdown--medium .lsd-dropdown__label{margin:0 0 6px 14px;}.lsd-dropdown--medium .lsd-dropdown__button-container{height:32px;}.lsd-dropdown--medium .lsd-dropdown__trigger{padding:6px 0px 6px 14px;}.lsd-dropdown--medium .lsd-dropdown__icons{padding:0px 12px;}.lsd-dropdown--small{width:164px;}.lsd-dropdown--small.lsd-dropdown--error{width:186px;}.lsd-dropdown--small .lsd-dropdown__label{margin:0 0 6px 12px;}.lsd-dropdown--small .lsd-dropdown__button-container{height:28px;}.lsd-dropdown--small .lsd-dropdown__trigger{padding:6px 0px 6px 12px;}.lsd-dropdown--small .lsd-dropdown__icons{padding:0px 10px;}.lsd-dropdown--outlined .lsd-dropdown__button-container{border:1px solid rgb(var(--lsd-border-primary));}.lsd-dropdown--underlined .lsd-dropdown__button-container{border:1px solid transparent;border-bottom:1px solid rgb(var(--lsd-border-primary));}

Research Blog

Blog
+ + \ No newline at end of file diff --git a/rlog/introducing-nwaku/index.html b/rlog/introducing-nwaku/index.html index 43578a28..637e0534 100644 --- a/rlog/introducing-nwaku/index.html +++ b/rlog/introducing-nwaku/index.html @@ -10,8 +10,8 @@ - - + + - - + + \ No newline at end of file diff --git a/rlog/kademlia-to-discv5/index.html b/rlog/kademlia-to-discv5/index.html index 362c199b..ce061f93 100644 --- a/rlog/kademlia-to-discv5/index.html +++ b/rlog/kademlia-to-discv5/index.html @@ -10,8 +10,8 @@ - - + +
@@ -20,7 +20,7 @@ ) .lsd-dropdown__trigger:hover .lsd-dropdown__option-label,.lsd-dropdown:not(.lsd-dropdown--disabled):not( .lsd-dropdown--error ) .lsd-dropdown__trigger:focus .lsd-dropdown__option-label{-webkit-text-decoration:underline;text-decoration:underline;}.lsd-dropdown__label{display:block;}.lsd-dropdown__button-container{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-box-pack:justify;-webkit-justify-content:space-between;justify-content:space-between;}.lsd-dropdown__trigger{width:100%;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:row;-ms-flex-direction:row;flex-direction:row;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:justify;-webkit-justify-content:space-between;justify-content:space-between;border:none;cursor:pointer;background:none;}.lsd-dropdown__trigger:focus{outline:none;}.lsd-dropdown__option-label{cursor:inherit;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;}.lsd-dropdown__icons{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:row;-ms-flex-direction:row;flex-direction:row;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:center;-ms-flex-pack:center;-webkit-justify-content:center;justify-content:center;gap:8px;}.lsd-dropdown__icon{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;}.lsd-dropdown__supporting-text{margin:6px 14px;}.lsd-dropdown--error .lsd-dropdown__option-label{-webkit-text-decoration:line-through;text-decoration:line-through;}.lsd-dropdown--disabled{opacity:0.34;cursor:initial;}.lsd-dropdown--large{width:208px;}.lsd-dropdown--large.lsd-dropdown--error{width:230px;}.lsd-dropdown--large .lsd-dropdown__label{margin:0 0 6px 18px;}.lsd-dropdown--large .lsd-dropdown__button-container{height:40px;}.lsd-dropdown--large .lsd-dropdown__trigger{padding:10px 0px 10px 18px;}.lsd-dropdown--large .lsd-dropdown__icons{padding:0px 14px;}.lsd-dropdown--medium{width:188px;}.lsd-dropdown--medium.lsd-dropdown--error{width:210px;}.lsd-dropdown--medium .lsd-dropdown__label{margin:0 0 6px 14px;}.lsd-dropdown--medium .lsd-dropdown__button-container{height:32px;}.lsd-dropdown--medium .lsd-dropdown__trigger{padding:6px 0px 6px 14px;}.lsd-dropdown--medium .lsd-dropdown__icons{padding:0px 12px;}.lsd-dropdown--small{width:164px;}.lsd-dropdown--small.lsd-dropdown--error{width:186px;}.lsd-dropdown--small .lsd-dropdown__label{margin:0 0 6px 12px;}.lsd-dropdown--small .lsd-dropdown__button-container{height:28px;}.lsd-dropdown--small .lsd-dropdown__trigger{padding:6px 0px 6px 12px;}.lsd-dropdown--small .lsd-dropdown__icons{padding:0px 10px;}.lsd-dropdown--outlined .lsd-dropdown__button-container{border:1px solid rgb(var(--lsd-border-primary));}.lsd-dropdown--underlined .lsd-dropdown__button-container{border:1px solid transparent;border-bottom:1px solid rgb(var(--lsd-border-primary));}

From Kademlia to Discv5

by
9 min read

A quick history of discovery in peer-to-peer networks, along with a look into discv4 and discv5, detailing what they are, how they work and where they differ.

If you've been working on Ethereum or adjacent technologies you've probably heard of discv4 or discv5. But what are they actually? How do they work and what makes them different? To answer these questions, we need to start at the beginning, so this post will assume that there is little knowledge on the subject so the post should be accessible for anyone.

The Beginning

Let's start right at the beginning: the problem of discovery and organization of nodes in peer-to-peer networks.

Early P2P file sharing technologies, such as Napster, would share information about who holds what file using a single server. A node would connect to the central server and give it a list of the files it owns. Another node would then connect to that central server, find a node that has the file it is looking for and contact that node. This however was a flawed system -- it was vulnerable to attacks and left a single party open to lawsuits.

It became clear that another solution was needed, and after years of research and experimentation, we were given the distributed hash table or DHT.

Distributed Hash Tables

In 2001 4 new protocols for such DHTs were conceived, Tapestry, Chord, CAN and Pastry, all of which made various trade-offs and changes in their core functionality, giving them unique characteristics.

But as said, they're all DHTs. So what is a DHT?

A distributed hash table (DHT) is essentially a distributed key-value list. Nodes participating in the DHT can easily retrieve the value for a key.

If we have a network with 9 key-value pairs and 3 nodes, ideally each node would store 3 (optimally 6 for redundancy) of those key-value pairs, meaning that if a key-value pair were to be updated, only part of the network would responsible for ensuring that it is. The idea is that any node in the network would know where to find the specific key-value pair it is looking for based on how things are distributed amongst the nodes.

Kademlia

So now that we know what DHTs are, let's get to Kademlia, the predecessor of discv4. Kademlia was created by Petar Maymounkov and David Mazières in 2002. I will naively say that this is probably one of the most popular and most used DHT protocols. It's quite simple in how it works, so let's look at it.

In Kademlia, nodes and values are arranged by distance (in a very mathematical definition). This distance is not a geographical one, but rather based on identifiers. It is calculated how far 2 identifiers are from eachother using some distance function.

Kademlia uses an XOR as its distance function. An XOR is a function that outputs true only when inputs differ. Here is an example with some binary identifiers:

XOR 10011001
00110010
--------
10101011

The top in decimal numbers means that the distance between 153 and 50 is 171.

There are several reasons why XOR was taken:

  1. The distance from one ID to itself will be 0.
  2. Distance is symmetric, A to B is the same as B to A.
  3. Follows triangle inequality, if A, B and C are points on a triangle then the distance A to B is closer or equal to that of A to C plus the one from B to C.

In summary, this distance function allows a node to decide what is "close" to it and make decisions based on that "closeness".

Kademlia nodes store a routing table. This table contains multiple lists. Each subsequent list contains nodes which are a little further distanced than the ones included in the previous list. Nodes maintain detailed knowledge about nodes closest to them, and the further away a node is, the less knowledge the node maintains about it.

So let's say I want to find a specific node. What I would do is go to any node which I already know and ask them for all their neighbours closest to my target. I repeat this process for the returned neighbours until I find my target.

The same thing happens for values. Values have a certain distance from nodes and their IDs are structured the same way so we can calculate this distance. If I want to find a value, I simply look for the neighbours closest to that value's key until I find the one storing said value.

For Kademlia nodes to support these functions, there are several messages with which the protocol communicates.

  • PING - Used to check whether a node is still running.
  • STORE - Stores a value with a given key on a node.
  • FINDNODE - Returns the closest nodes requested to a given ID.
  • FINDVALUE - The same as FINDNODE, except if a node stores the specific value it will return it directly.

This is a very simplified explanation of Kademlia and skips various important details. For the full description, make sure to check out the paper or a more in-depth design specification

Discv4

Now after that history lesson, we finally get to discv4 (which stands for discovery v4), Ethereum's current node discovery protocol. The protocol itself is essentially based off of Kademlia, however it does away with certain aspects of it. For example, it does away with any usage of the value part of the DHT.

Kademlia is mainly used for the organisation of the network, so we only use the routing table to locate other nodes. Due to the fact that discv4 doesn't use the value portion of the DHT at all, we can throw away the FINDVALUE and STORE commands described by Kademlia.

The lookup method previously described by Kademlia describes how a node gets its peers. A node contacts some node and asks it for the nodes closest to itself. It does so until it can no longer find any new nodes.

Additionally, discv4 adds mutual endpoint verification. This is meant to ensure that a peer calling FINDNODE also participates in the discovery protocol.

Finally, all discv4 nodes are expected to maintain up-to-date ENR records. These contain information about a node. They can be requested from any node using a discv4-specific packet called ENRRequest.

If you want some more details on ENRs, check out one of my posts "Network Addresses in Ethereum"

Discv4 comes with its own range of problems however. Let's look at a few of them.

Firstly, the way discv4 works right now, there is no way to differentiate between node sub-protocols. This means for example that an Ethereum node could add an Ethereum Classic Node, Swarm or Whisper node to its DHT without realizing that it is invalid until more communication has happened. This inability to differentiate sub-protocols makes it harder to find specific nodes, such as Ethereum nodes with light-client support.

Next, in order to prevent replay attacks, discv4 uses timestamps. This however can lead to various issues when a host's clock is wrong. For more details, see the "Known Issues" section of the discv4 specification.

Finally, we have an issue with the way mutual endpoint verification works. Messages can get dropped and there is no way to tell if both peers have verified eachother. This means that we could consider our peer verified while it does not consider us so making them drop the FINDNODE packet.

Discv5

Finally, let's look at discv5. The next iteration of discv4 and the discovery protocol which will be used by Eth 2.0. It aims at fixing various issues present in discv4.

The first change is the way FINDNODE works. In traditional Kademlia as well as in discv5, we pass an identifier. However, in discv5 we instead pass the logarithmic distance, meaning that a FINDNODE request gets a response containing all nodes at the specified logarithmic distance from the called node.

Logarithmic distance means we first calculate the distance and then run it through our log base 2 function. See:

log2(A xor B)

And the second, more important change, is that discv5 aims at solving one of the biggest issues of discv4: the differentiation of sub-protocols. It does this by adding topic tables. Topic tables are first in first out lists that contain nodes which have advertised that they provide a specific service. Nodes get themselves added to this list by registering ads on their peers.

As of writing, there is still an issue with this proposal. There is currently no efficient way for a node to place ads on multiple peers, since it would require separate requests for every peer which is inefficient in a large-scale network.

Additionally, it is unclear how many peers a node should place these ads on and exactly which peers to place them on. For more details, check out the issue devp2p#136.

There are a bunch more smaller changes to the protocol, but they are less important hence they were ommitted from this summary.

Nevertheless, discv5 still does not resolve a couple issues present in discv4, such as unreliable endpoint verification. As of writing this post, there is currently no new method in discv5 to improve the endpoint verification process.

As you can see discv5 is still a work in progress and has a few large challenges to overcome. However if it does, it will most likely be a large improvement to a more naive Kademlia implementations.


Hopefully this article helped explain what these discovery protocols are and how they work. If you're interested in their full specifications you can find them on github.

- - + + \ No newline at end of file diff --git a/rlog/membership-with-bloom-filters-and-cuckoo-filters/index.html b/rlog/membership-with-bloom-filters-and-cuckoo-filters/index.html index 57788303..0774c519 100644 --- a/rlog/membership-with-bloom-filters-and-cuckoo-filters/index.html +++ b/rlog/membership-with-bloom-filters-and-cuckoo-filters/index.html @@ -10,8 +10,8 @@ - - + +
@@ -116,7 +116,7 @@ Unfortunately, Bloom filters do not support the deletion of members. Luckily, Cuckoo filters allow for deletions that can performed in constant time.

Cuckoo filter that use Sliding-Window could be used so that light clients are able to verify proofs of membership in the RLN. These proofs are not a substitute to the usual proofs that a heavy client can verify due to the allowance of false positives. However, with the allowance of false positives, a light client can participate in verification RLN proofs in an efficient manner.

References

- - + + \ No newline at end of file diff --git a/rlog/p2p-data-sync-for-mobile/index.html b/rlog/p2p-data-sync-for-mobile/index.html index d5e09996..0c351b8a 100644 --- a/rlog/p2p-data-sync-for-mobile/index.html +++ b/rlog/p2p-data-sync-for-mobile/index.html @@ -10,8 +10,8 @@ - - + +
@@ -22,7 +22,7 @@ ) .lsd-dropdown__trigger:focus .lsd-dropdown__option-label{-webkit-text-decoration:underline;text-decoration:underline;}.lsd-dropdown__label{display:block;}.lsd-dropdown__button-container{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-box-pack:justify;-webkit-justify-content:space-between;justify-content:space-between;}.lsd-dropdown__trigger{width:100%;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:row;-ms-flex-direction:row;flex-direction:row;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:justify;-webkit-justify-content:space-between;justify-content:space-between;border:none;cursor:pointer;background:none;}.lsd-dropdown__trigger:focus{outline:none;}.lsd-dropdown__option-label{cursor:inherit;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;}.lsd-dropdown__icons{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:row;-ms-flex-direction:row;flex-direction:row;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:center;-ms-flex-pack:center;-webkit-justify-content:center;justify-content:center;gap:8px;}.lsd-dropdown__icon{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;}.lsd-dropdown__supporting-text{margin:6px 14px;}.lsd-dropdown--error .lsd-dropdown__option-label{-webkit-text-decoration:line-through;text-decoration:line-through;}.lsd-dropdown--disabled{opacity:0.34;cursor:initial;}.lsd-dropdown--large{width:208px;}.lsd-dropdown--large.lsd-dropdown--error{width:230px;}.lsd-dropdown--large .lsd-dropdown__label{margin:0 0 6px 18px;}.lsd-dropdown--large .lsd-dropdown__button-container{height:40px;}.lsd-dropdown--large .lsd-dropdown__trigger{padding:10px 0px 10px 18px;}.lsd-dropdown--large .lsd-dropdown__icons{padding:0px 14px;}.lsd-dropdown--medium{width:188px;}.lsd-dropdown--medium.lsd-dropdown--error{width:210px;}.lsd-dropdown--medium .lsd-dropdown__label{margin:0 0 6px 14px;}.lsd-dropdown--medium .lsd-dropdown__button-container{height:32px;}.lsd-dropdown--medium .lsd-dropdown__trigger{padding:6px 0px 6px 14px;}.lsd-dropdown--medium .lsd-dropdown__icons{padding:0px 12px;}.lsd-dropdown--small{width:164px;}.lsd-dropdown--small.lsd-dropdown--error{width:186px;}.lsd-dropdown--small .lsd-dropdown__label{margin:0 0 6px 12px;}.lsd-dropdown--small .lsd-dropdown__button-container{height:28px;}.lsd-dropdown--small .lsd-dropdown__trigger{padding:6px 0px 6px 12px;}.lsd-dropdown--small .lsd-dropdown__icons{padding:0px 10px;}.lsd-dropdown--outlined .lsd-dropdown__button-container{border:1px solid rgb(var(--lsd-border-primary));}.lsd-dropdown--underlined .lsd-dropdown__button-container{border:1px solid transparent;border-bottom:1px solid rgb(var(--lsd-border-primary));}

P2P Data Sync for Mobile

by
12 min read

A research log. Reliable and decentralized, pick two.

Together with decanus, I've been working on the problem of data sync lately.

In building p2p messaging systems, one problem you quickly come across is the problem of reliably transmitting data. If there's no central server with high availability guarantees, you can't meaningfully guarantee that data has been transmitted. One way of solving this problem is through a synchronization protocol.

There are many synchronization protocols out there and I won't go into detail of how they differ with our approach here. Some common examples are Git and Bittorrent, but there are also projects like IPFS, Swarm, Dispersy, Matrix, Briar, SSB, etc.

Problem motivation

Why do we want to do p2p sync for mobilephones in the first place? There are three components to that question. One is on the value of decentralization and peer-to-peer, the second is on why we'd want to reliably sync data at all, and finally why mobilephones and other resource restricted devices.

Why p2p?

For decentralization and p2p, there are both technical and social/philosophical reasons. Technically, having a user-run network means it can scale with the number of users. Data locality is also improved if you query data that's close to you, similar to distributed CDNs. The throughput is also improved if there are more places to get data from.

Socially and philosophically, there are several ways to think about it. Open and decentralized networks also relate to the idea of open standards, i.e. compare the longevity of AOL with IRC or Bittorrent. One is run by a company and is shut down as soon as it stops being profitable, the others live on. Additionally increasingly control of data and infrastructure is becoming a liability. By having a network with no one in control, everyone is. It's ultimately a form of democratization, more similar to organic social structures pre Big Internet companies. This leads to properties such as censorship resistance and coercion resistance, where we limit the impact a 3rd party might have a voluntary interaction between individuals or a group of people. Examples of this are plentiful in the world of Facebook, Youtube, Twitter and WeChat.

Why reliably sync data?

At risk of stating the obvious, reliably syncing data is a requirement for many problem domains. You don't get this by default in a p2p world, as it is unreliable with nodes permissionslessly join and leave the network. In some cases you can get away with only ephemeral data, but usually you want some kind of guarantees. This is a must for reliable group chat experience, for example, where messages are expected to arrive in a timely fashion and in some reasonable order. The same is true for messages there represent financial transactions, and so on.

Why mobilephones?

Most devices people use daily are mobile phones. It's important to provide the same or at least similar guarantees to more traditional p2p nodes that might run on a desktop computer or computer. The alternative is to rely on gateways, which shares many of the drawbacks of centralized control and prone to censorship, control and surveillence.

More generally, resource restricted devices can differ in their capabilities. One example is smartphones, but others are: desktop, routers, Raspberry PIs, POS systems, and so on. The number and diversity of devices are exploding, and it's useful to be able to leverage this for various types of infrastructure. The alternative is to centralize on big cloud providers, which also lends itself to lack of democratization and censorship, etc.

Minimal Requirements

For requirements or design goals for a solution, here's what we came up with.

  1. MUST sync data reliably between devices. By reliably we mean having the ability to deal with messages being out of order, dropped, duplicated, or delayed.

  2. MUST NOT rely on any centralized services for reliability. By centralized services we mean any single point of failure that isn’t one of the endpoint devices.

  3. MUST allow for mobile-friendly usage. By mobile-friendly we mean devices that are resource restricted, mostly-offline and often changing network.

  4. MAY use helper services in order to be more mobile-friendly. Examples of helper services are decentralized file storage solutions such as IPFS and Swarm. These help with availability and latency of data for mostly-offline devices.

  5. MUST have the ability to provide casual consistency. By casual consistency we mean the commonly accepted definition in distributed systems literature. This means messages that are casually related can achieve a partial ordering.

  6. MUST support ephemeral messages that don’t need replication. That is, allow for messages that don’t need to be reliabily transmitted but still needs to be transmitted between devices.

  7. MUST allow for privacy-preserving messages and extreme data loss. By privacy-preserving we mean things such as exploding messages (self-destructing messages). By extreme data loss we mean the ability for two trusted devices to recover from a, deliberate or accidental, removal of data.

  8. MUST be agnostic to whatever transport it is running on. It should not rely on specific semantics of the transport it is running on, nor be tightly coupled with it. This means a transport can be swapped out without loss of reliability between devices.

MVDS - a minimium viable version

The first minimum viable version is in an alpha stage, and it has a specification, implementation and we have deployed it in a console client for end to end functionality. It's heavily inspired by Bramble Sync Protocol.

The spec is fairly minimal. You have nodes that exchange records over some secure transport. These records are of different types, such as OFFER, MESSAGE, REQUEST, and ACK. A peer keep tracks of the state of message for each node it is interacting with. There's also logic for message retransmission with exponential delay. The positive ACK and retransmission model is quite similar to how TCP is designed.

There are two different modes of syncing, interactive and batch mode. See sequence diagrams below.

Interactive mode:

Interactive mode

Batch mode:

Batch mode

Which mode should you choose? It's a tradeoff of latency and bandwidth. If you want to minimize latency, batch mode is better. If you care about preserving bandwidth interactive mode is better. The choice is up to each node.

Basic simulation

Initial ad hoc bandwidth and latency testing shows some issues with a naive approach. Running with the default simulation settings:

  • communicating nodes: 2
  • nodes using interactive mode: 2
  • interval between messages: 5s
  • time node is offine: 90%
  • nodes each node is sharing with: 2

we notice a huge overhead. More specifically, we see a ~5 minute latency overhead and a bandwidth multiplier of x100-1000, i.e. 2-3 orders of magnitude just for receiving a message with interactive mode, without acks.

Now, that seems terrible. A moment of reflection will reveal why that is. If each node is offline uniformly 90% of the time, that means that each record will be lost 90% of the time. Since interactive mode requires offer, request, payload (and then ack), that's three links just for Bob to receive the actual message.

Each failed attempt implies another retransmission. That means we have (1/0.1)^3 = 1000 expected overhead to receive a message in interactive mode. The latency follows naturally from that, with the retransmission logic.

Mostly-offline devices

The problem above hints at the requirements 3 and 4 above. While we did get reliable syncing (requirement 1), it came at a big cost.

There are a few ways of getting around this issue. One is having a store and forward model, where some intermediary node picks up (encrypted) messages and forwards them to the recipient. This is what we have in production right now at Status.

Another, arguably more pure and robust, way is having a remote log, where the actual data is spread over some decentralized storage layer, and you have a mutable reference to find the latest messages, similar to DNS.

What they both have in common is that they act as a sort of highly-available cache to smooth over the non-overlapping connection windows between two endpoints. Neither of them are required to get reliable data transmission.

Basic calculations for bandwidth multiplier

While we do want better simulations, and this is a work in progress, we can also look at the above scenarios using some basic calculations. This allows us to build a better intuition and reason about the problem without having to write code. Let's start with some assumptions:

  • two nodes exchanging a single message in batch mode
  • 10% uniformly random uptime for each node
  • in HA cache case, 100% uptime of a piece of infrastructure C
  • retransmission every epoch (with constant or exponential backoff)
  • only looking at average (p50) case

First case, no helper services

A sends a message to B, and B acks it.

A message -> B (10% chance of arrival)
A <- ack B (10% chance of arrival)

With a constant backoff, A will send messages at epoch 1, 2, 3, .... With exponential backoff and a multiplier of 2, this would be 1, 2, 4, 8, .... Let's assume constant backoff for now, as this is what will influence the success rate and thus the bandwidth multiplier.

There's a difference between time to receive and time to stop sending. Assuming each send attempt is independent, it takes on average 10 epochs for A's message to arrive with B. Furthermore:

  1. A will send messages until it receives an ACK.
  2. B will send ACK if it receives a message.

To get an average of one ack through, A needs to send 100 messages, and B send on average 10 acks. That's a multiplier of roughly a 100. That's roughly what we saw with the simulation above for receiving a message in interactive mode.

Second case, high-availability caching layer

Let's introduce a helper node or piece of infrastructure, C. Whenever A or B sends a message, it also sends it to C. Whenever A or B comes online, it queries for messages with C.

A message    -> B (10% chance of arrival)
A message -> C (100% chance of arrival)
B <- req/res -> C (100% chance of arrival)
A <- ack B (10% chance of arrival)
C <- ack B (100% chance of arrival)
A <- req/res -> C (100% chance of arrival)

What's the probability that A's messages will arrive at B? Directly, it's still 10%. But we can assume it's 100% that C picks up the message. (Giving C a 90% chance success rate doesn't materially change the numbers).

B will pick up A's message from C after an average of 10 epochs. Then B will send ack to A, which will also be picked up by C 100% of the time. Once A comes online again, it'll query C and receive B's ack.

Assuming we use exponential backoff with a multiplier of 2, A will send a message directly to B at epoch 1, 2, 4, 8 (assuming it is online). At this point, epoch 10, B will be online in the average case. These direct sends will likely fail, but B will pick the message up from C and send one ack, both directly to A and to be picked up by C. Once A comes online, it'll query C and receive the ack from B, which means it won't do any more retransmits.

How many messages have been sent? Not counting interactions with C, A sends 4 (at most) and B 1. Depending on if the interaction with C is direct or indirect (i.e. multicast), the factor for interaction with C will be ~2. This means the total bandwidth multiplier is likely to be <10, which is a lot more acceptable.

Since the syncing semantics are end-to-end, this is without relying on the reliablity of C.

Caveat

Note that both of these are probabilistic argument. They are also based on heuristics. More formal analysis would be desirable, as well as better simulations to experimentally verify them. In fact, the calculations could very well be wrong!

Future work

There are many enhancements that can be made and are desirable. Let's outline a few.

  1. Data sync clients. Examples of actual usage of data sync, with more interesting domain semantics. This also includes usage of sequence numbers and DAGs to know what content is missing and ought to be synced.

  2. Remote log. As alluded to above, this is necessary. It needs a more clear specification and solid proof of concepts.

  3. More efficient ways of syncing with large number of nodes. When the number of nodes goes up, the algorithmic complexity doesn't look great. This also touches on things such as ambient content discovery.

  4. More robust simulations and real-world deployments. Exisiting simulation is ad hoc, and there are many improvements that can be made to gain more confidence and identify issues. Additionally, better formal analysis.

  5. Example usage over multiple transports. Including things like sneakernet and meshnets. The described protocol is designed to work over unstructured, structured and private p2p networks. In some cases it can leverage differences in topology, such as multicast, or direct connections.

- - + + \ No newline at end of file diff --git a/rlog/page/2/index.html b/rlog/page/2/index.html index 9525af1e..ed80ec62 100644 --- a/rlog/page/2/index.html +++ b/rlog/page/2/index.html @@ -10,8 +10,8 @@ - - + +
@@ -19,12 +19,12 @@ .lsd-dropdown--error ) .lsd-dropdown__trigger:hover .lsd-dropdown__option-label,.lsd-dropdown:not(.lsd-dropdown--disabled):not( .lsd-dropdown--error - ) .lsd-dropdown__trigger:focus .lsd-dropdown__option-label{-webkit-text-decoration:underline;text-decoration:underline;}.lsd-dropdown__label{display:block;}.lsd-dropdown__button-container{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-box-pack:justify;-webkit-justify-content:space-between;justify-content:space-between;}.lsd-dropdown__trigger{width:100%;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:row;-ms-flex-direction:row;flex-direction:row;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:justify;-webkit-justify-content:space-between;justify-content:space-between;border:none;cursor:pointer;background:none;}.lsd-dropdown__trigger:focus{outline:none;}.lsd-dropdown__option-label{cursor:inherit;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;}.lsd-dropdown__icons{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:row;-ms-flex-direction:row;flex-direction:row;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:center;-ms-flex-pack:center;-webkit-justify-content:center;justify-content:center;gap:8px;}.lsd-dropdown__icon{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;}.lsd-dropdown__supporting-text{margin:6px 14px;}.lsd-dropdown--error .lsd-dropdown__option-label{-webkit-text-decoration:line-through;text-decoration:line-through;}.lsd-dropdown--disabled{opacity:0.34;cursor:initial;}.lsd-dropdown--large{width:208px;}.lsd-dropdown--large.lsd-dropdown--error{width:230px;}.lsd-dropdown--large .lsd-dropdown__label{margin:0 0 6px 18px;}.lsd-dropdown--large .lsd-dropdown__button-container{height:40px;}.lsd-dropdown--large .lsd-dropdown__trigger{padding:10px 0px 10px 18px;}.lsd-dropdown--large .lsd-dropdown__icons{padding:0px 14px;}.lsd-dropdown--medium{width:188px;}.lsd-dropdown--medium.lsd-dropdown--error{width:210px;}.lsd-dropdown--medium .lsd-dropdown__label{margin:0 0 6px 14px;}.lsd-dropdown--medium .lsd-dropdown__button-container{height:32px;}.lsd-dropdown--medium .lsd-dropdown__trigger{padding:6px 0px 6px 14px;}.lsd-dropdown--medium .lsd-dropdown__icons{padding:0px 12px;}.lsd-dropdown--small{width:164px;}.lsd-dropdown--small.lsd-dropdown--error{width:186px;}.lsd-dropdown--small .lsd-dropdown__label{margin:0 0 6px 12px;}.lsd-dropdown--small .lsd-dropdown__button-container{height:28px;}.lsd-dropdown--small .lsd-dropdown__trigger{padding:6px 0px 6px 12px;}.lsd-dropdown--small .lsd-dropdown__icons{padding:0px 10px;}.lsd-dropdown--outlined .lsd-dropdown__button-container{border:1px solid rgb(var(--lsd-border-primary));}.lsd-dropdown--underlined .lsd-dropdown__button-container{border:1px solid transparent;border-bottom:1px solid rgb(var(--lsd-border-primary));}

Research Blog

Blog

by
7 min read

Waku is an open communication protocol and network. Decentralized apps and infrastructure can use Waku for their + ) .lsd-dropdown__trigger:focus .lsd-dropdown__option-label{-webkit-text-decoration:underline;text-decoration:underline;}.lsd-dropdown__label{display:block;}.lsd-dropdown__button-container{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-box-pack:justify;-webkit-justify-content:space-between;justify-content:space-between;}.lsd-dropdown__trigger{width:100%;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:row;-ms-flex-direction:row;flex-direction:row;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:justify;-webkit-justify-content:space-between;justify-content:space-between;border:none;cursor:pointer;background:none;}.lsd-dropdown__trigger:focus{outline:none;}.lsd-dropdown__option-label{cursor:inherit;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;}.lsd-dropdown__icons{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:row;-ms-flex-direction:row;flex-direction:row;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:center;-ms-flex-pack:center;-webkit-justify-content:center;justify-content:center;gap:8px;}.lsd-dropdown__icon{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;}.lsd-dropdown__supporting-text{margin:6px 14px;}.lsd-dropdown--error .lsd-dropdown__option-label{-webkit-text-decoration:line-through;text-decoration:line-through;}.lsd-dropdown--disabled{opacity:0.34;cursor:initial;}.lsd-dropdown--large{width:208px;}.lsd-dropdown--large.lsd-dropdown--error{width:230px;}.lsd-dropdown--large .lsd-dropdown__label{margin:0 0 6px 18px;}.lsd-dropdown--large .lsd-dropdown__button-container{height:40px;}.lsd-dropdown--large .lsd-dropdown__trigger{padding:10px 0px 10px 18px;}.lsd-dropdown--large .lsd-dropdown__icons{padding:0px 14px;}.lsd-dropdown--medium{width:188px;}.lsd-dropdown--medium.lsd-dropdown--error{width:210px;}.lsd-dropdown--medium .lsd-dropdown__label{margin:0 0 6px 14px;}.lsd-dropdown--medium .lsd-dropdown__button-container{height:32px;}.lsd-dropdown--medium .lsd-dropdown__trigger{padding:6px 0px 6px 14px;}.lsd-dropdown--medium .lsd-dropdown__icons{padding:0px 12px;}.lsd-dropdown--small{width:164px;}.lsd-dropdown--small.lsd-dropdown--error{width:186px;}.lsd-dropdown--small .lsd-dropdown__label{margin:0 0 6px 12px;}.lsd-dropdown--small .lsd-dropdown__button-container{height:28px;}.lsd-dropdown--small .lsd-dropdown__trigger{padding:6px 0px 6px 12px;}.lsd-dropdown--small .lsd-dropdown__icons{padding:0px 10px;}.lsd-dropdown--outlined .lsd-dropdown__button-container{border:1px solid rgb(var(--lsd-border-primary));}.lsd-dropdown--underlined .lsd-dropdown__button-container{border:1px solid transparent;border-bottom:1px solid rgb(var(--lsd-border-primary));}

Research Blog

Blog

by
7 min read

Waku is an open communication protocol and network. Decentralized apps and infrastructure can use Waku for their communication needs. It is designed to enable dApps and decentralized infrastructure projects to have secure, private, scalable communication. Waku is available in several languages and platforms, from Web to mobile to desktop to cloud. Initially, We pushed Waku adoption to the Web ecosystem, we learned that Waku is usable in a variety of complex applications -and infrastructure projects. We have prioritized our effort to make Waku usable on various platforms and environments.

by
19 min read

What is privacy-protecting infrastructure? Why do we need it and how we can build it? We'll look at Waku, the communication layer for Web3. We'll see how it uses ZKPs to incentivize and protect the Waku network. We'll also look at Zerokit, a library that makes it easier to use ZKPs in different environments. After reading this, I hope you'll better understand the importance of privacy-protecting infrastructure and how we can build it.

by
11 min read

Introducing nwaku, a Nim-based Waku v2 client, including a summary of recent developments and preview of current and future focus areas.

- - +and infrastructure projects. We have prioritized our effort to make Waku usable on various platforms and environments.

by
19 min read

What is privacy-protecting infrastructure? Why do we need it and how we can build it? We'll look at Waku, the communication layer for Web3. We'll see how it uses ZKPs to incentivize and protect the Waku network. We'll also look at Zerokit, a library that makes it easier to use ZKPs in different environments. After reading this, I hope you'll better understand the importance of privacy-protecting infrastructure and how we can build it.

by
11 min read

Introducing nwaku, a Nim-based Waku v2 client, including a summary of recent developments and preview of current and future focus areas.

+ + \ No newline at end of file diff --git a/rlog/page/3/index.html b/rlog/page/3/index.html index ccbe12bf..d8c5ff94 100644 --- a/rlog/page/3/index.html +++ b/rlog/page/3/index.html @@ -10,8 +10,8 @@ - - + +
@@ -19,8 +19,8 @@ .lsd-dropdown--error ) .lsd-dropdown__trigger:hover .lsd-dropdown__option-label,.lsd-dropdown:not(.lsd-dropdown--disabled):not( .lsd-dropdown--error - ) .lsd-dropdown__trigger:focus .lsd-dropdown__option-label{-webkit-text-decoration:underline;text-decoration:underline;}.lsd-dropdown__label{display:block;}.lsd-dropdown__button-container{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-box-pack:justify;-webkit-justify-content:space-between;justify-content:space-between;}.lsd-dropdown__trigger{width:100%;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:row;-ms-flex-direction:row;flex-direction:row;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:justify;-webkit-justify-content:space-between;justify-content:space-between;border:none;cursor:pointer;background:none;}.lsd-dropdown__trigger:focus{outline:none;}.lsd-dropdown__option-label{cursor:inherit;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;}.lsd-dropdown__icons{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:row;-ms-flex-direction:row;flex-direction:row;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:center;-ms-flex-pack:center;-webkit-justify-content:center;justify-content:center;gap:8px;}.lsd-dropdown__icon{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;}.lsd-dropdown__supporting-text{margin:6px 14px;}.lsd-dropdown--error .lsd-dropdown__option-label{-webkit-text-decoration:line-through;text-decoration:line-through;}.lsd-dropdown--disabled{opacity:0.34;cursor:initial;}.lsd-dropdown--large{width:208px;}.lsd-dropdown--large.lsd-dropdown--error{width:230px;}.lsd-dropdown--large .lsd-dropdown__label{margin:0 0 6px 18px;}.lsd-dropdown--large .lsd-dropdown__button-container{height:40px;}.lsd-dropdown--large .lsd-dropdown__trigger{padding:10px 0px 10px 18px;}.lsd-dropdown--large .lsd-dropdown__icons{padding:0px 14px;}.lsd-dropdown--medium{width:188px;}.lsd-dropdown--medium.lsd-dropdown--error{width:210px;}.lsd-dropdown--medium .lsd-dropdown__label{margin:0 0 6px 14px;}.lsd-dropdown--medium .lsd-dropdown__button-container{height:32px;}.lsd-dropdown--medium .lsd-dropdown__trigger{padding:6px 0px 6px 14px;}.lsd-dropdown--medium .lsd-dropdown__icons{padding:0px 12px;}.lsd-dropdown--small{width:164px;}.lsd-dropdown--small.lsd-dropdown--error{width:186px;}.lsd-dropdown--small .lsd-dropdown__label{margin:0 0 6px 12px;}.lsd-dropdown--small .lsd-dropdown__button-container{height:28px;}.lsd-dropdown--small .lsd-dropdown__trigger{padding:6px 0px 6px 12px;}.lsd-dropdown--small .lsd-dropdown__icons{padding:0px 10px;}.lsd-dropdown--outlined .lsd-dropdown__button-container{border:1px solid rgb(var(--lsd-border-primary));}.lsd-dropdown--underlined .lsd-dropdown__button-container{border:1px solid transparent;border-bottom:1px solid rgb(var(--lsd-border-primary));}

Research Blog

Blog

by
21 min read

This post is going to give you an overview of how spam protection can be achieved in Waku Relay through rate-limiting nullifiers. We will cover a summary of spam-protection methods in centralized and p2p systems, and the solution overview and details of the economic spam-protection method. The open issues and future steps are discussed in the end.

by
8 min read

A research log. Read on to find out what is going on with Waku v2, a messaging protocol. What has been happening? What is coming up next?

by
9 min read

A quick history of discovery in peer-to-peer networks, along with a look into discv4 and discv5, detailing what they are, how they work and where they differ.

by
6 min read

A research log. What's the current state of Waku? How many users does it support? What are the bottlenecks? What's next?

- - + ) .lsd-dropdown__trigger:focus .lsd-dropdown__option-label{-webkit-text-decoration:underline;text-decoration:underline;}.lsd-dropdown__label{display:block;}.lsd-dropdown__button-container{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-box-pack:justify;-webkit-justify-content:space-between;justify-content:space-between;}.lsd-dropdown__trigger{width:100%;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:row;-ms-flex-direction:row;flex-direction:row;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:justify;-webkit-justify-content:space-between;justify-content:space-between;border:none;cursor:pointer;background:none;}.lsd-dropdown__trigger:focus{outline:none;}.lsd-dropdown__option-label{cursor:inherit;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;}.lsd-dropdown__icons{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:row;-ms-flex-direction:row;flex-direction:row;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:center;-ms-flex-pack:center;-webkit-justify-content:center;justify-content:center;gap:8px;}.lsd-dropdown__icon{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;}.lsd-dropdown__supporting-text{margin:6px 14px;}.lsd-dropdown--error .lsd-dropdown__option-label{-webkit-text-decoration:line-through;text-decoration:line-through;}.lsd-dropdown--disabled{opacity:0.34;cursor:initial;}.lsd-dropdown--large{width:208px;}.lsd-dropdown--large.lsd-dropdown--error{width:230px;}.lsd-dropdown--large .lsd-dropdown__label{margin:0 0 6px 18px;}.lsd-dropdown--large .lsd-dropdown__button-container{height:40px;}.lsd-dropdown--large .lsd-dropdown__trigger{padding:10px 0px 10px 18px;}.lsd-dropdown--large .lsd-dropdown__icons{padding:0px 14px;}.lsd-dropdown--medium{width:188px;}.lsd-dropdown--medium.lsd-dropdown--error{width:210px;}.lsd-dropdown--medium .lsd-dropdown__label{margin:0 0 6px 14px;}.lsd-dropdown--medium .lsd-dropdown__button-container{height:32px;}.lsd-dropdown--medium .lsd-dropdown__trigger{padding:6px 0px 6px 14px;}.lsd-dropdown--medium .lsd-dropdown__icons{padding:0px 12px;}.lsd-dropdown--small{width:164px;}.lsd-dropdown--small.lsd-dropdown--error{width:186px;}.lsd-dropdown--small .lsd-dropdown__label{margin:0 0 6px 12px;}.lsd-dropdown--small .lsd-dropdown__button-container{height:28px;}.lsd-dropdown--small .lsd-dropdown__trigger{padding:6px 0px 6px 12px;}.lsd-dropdown--small .lsd-dropdown__icons{padding:0px 10px;}.lsd-dropdown--outlined .lsd-dropdown__button-container{border:1px solid rgb(var(--lsd-border-primary));}.lsd-dropdown--underlined .lsd-dropdown__button-container{border:1px solid transparent;border-bottom:1px solid rgb(var(--lsd-border-primary));}

Research Blog

Blog

by
21 min read

This post is going to give you an overview of how spam protection can be achieved in Waku Relay through rate-limiting nullifiers. We will cover a summary of spam-protection methods in centralized and p2p systems, and the solution overview and details of the economic spam-protection method. The open issues and future steps are discussed in the end.

by
8 min read

A research log. Read on to find out what is going on with Waku v2, a messaging protocol. What has been happening? What is coming up next?

by
9 min read

A quick history of discovery in peer-to-peer networks, along with a look into discv4 and discv5, detailing what they are, how they work and where they differ.

by
6 min read

A research log. What's the current state of Waku? How many users does it support? What are the bottlenecks? What's next?

+ + \ No newline at end of file diff --git a/rlog/page/4/index.html b/rlog/page/4/index.html index 19004aa1..64b11903 100644 --- a/rlog/page/4/index.html +++ b/rlog/page/4/index.html @@ -10,8 +10,8 @@ - - + +
@@ -19,8 +19,8 @@ .lsd-dropdown--error ) .lsd-dropdown__trigger:hover .lsd-dropdown__option-label,.lsd-dropdown:not(.lsd-dropdown--disabled):not( .lsd-dropdown--error - ) .lsd-dropdown__trigger:focus .lsd-dropdown__option-label{-webkit-text-decoration:underline;text-decoration:underline;}.lsd-dropdown__label{display:block;}.lsd-dropdown__button-container{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-box-pack:justify;-webkit-justify-content:space-between;justify-content:space-between;}.lsd-dropdown__trigger{width:100%;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:row;-ms-flex-direction:row;flex-direction:row;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:justify;-webkit-justify-content:space-between;justify-content:space-between;border:none;cursor:pointer;background:none;}.lsd-dropdown__trigger:focus{outline:none;}.lsd-dropdown__option-label{cursor:inherit;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;}.lsd-dropdown__icons{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:row;-ms-flex-direction:row;flex-direction:row;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:center;-ms-flex-pack:center;-webkit-justify-content:center;justify-content:center;gap:8px;}.lsd-dropdown__icon{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;}.lsd-dropdown__supporting-text{margin:6px 14px;}.lsd-dropdown--error .lsd-dropdown__option-label{-webkit-text-decoration:line-through;text-decoration:line-through;}.lsd-dropdown--disabled{opacity:0.34;cursor:initial;}.lsd-dropdown--large{width:208px;}.lsd-dropdown--large.lsd-dropdown--error{width:230px;}.lsd-dropdown--large .lsd-dropdown__label{margin:0 0 6px 18px;}.lsd-dropdown--large .lsd-dropdown__button-container{height:40px;}.lsd-dropdown--large .lsd-dropdown__trigger{padding:10px 0px 10px 18px;}.lsd-dropdown--large .lsd-dropdown__icons{padding:0px 14px;}.lsd-dropdown--medium{width:188px;}.lsd-dropdown--medium.lsd-dropdown--error{width:210px;}.lsd-dropdown--medium .lsd-dropdown__label{margin:0 0 6px 14px;}.lsd-dropdown--medium .lsd-dropdown__button-container{height:32px;}.lsd-dropdown--medium .lsd-dropdown__trigger{padding:6px 0px 6px 14px;}.lsd-dropdown--medium .lsd-dropdown__icons{padding:0px 12px;}.lsd-dropdown--small{width:164px;}.lsd-dropdown--small.lsd-dropdown--error{width:186px;}.lsd-dropdown--small .lsd-dropdown__label{margin:0 0 6px 12px;}.lsd-dropdown--small .lsd-dropdown__button-container{height:28px;}.lsd-dropdown--small .lsd-dropdown__trigger{padding:6px 0px 6px 12px;}.lsd-dropdown--small .lsd-dropdown__icons{padding:0px 10px;}.lsd-dropdown--outlined .lsd-dropdown__button-container{border:1px solid rgb(var(--lsd-border-primary));}.lsd-dropdown--underlined .lsd-dropdown__button-container{border:1px solid transparent;border-bottom:1px solid rgb(var(--lsd-border-primary));}

Research Blog

Blog

by
6 min read

Vac is a modular peer-to-peer messaging stack, with a focus on secure messaging. Overview of terms, stack and open problems.

- - + ) .lsd-dropdown__trigger:focus .lsd-dropdown__option-label{-webkit-text-decoration:underline;text-decoration:underline;}.lsd-dropdown__label{display:block;}.lsd-dropdown__button-container{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-box-pack:justify;-webkit-justify-content:space-between;justify-content:space-between;}.lsd-dropdown__trigger{width:100%;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:row;-ms-flex-direction:row;flex-direction:row;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:justify;-webkit-justify-content:space-between;justify-content:space-between;border:none;cursor:pointer;background:none;}.lsd-dropdown__trigger:focus{outline:none;}.lsd-dropdown__option-label{cursor:inherit;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;}.lsd-dropdown__icons{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:row;-ms-flex-direction:row;flex-direction:row;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:center;-ms-flex-pack:center;-webkit-justify-content:center;justify-content:center;gap:8px;}.lsd-dropdown__icon{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;}.lsd-dropdown__supporting-text{margin:6px 14px;}.lsd-dropdown--error .lsd-dropdown__option-label{-webkit-text-decoration:line-through;text-decoration:line-through;}.lsd-dropdown--disabled{opacity:0.34;cursor:initial;}.lsd-dropdown--large{width:208px;}.lsd-dropdown--large.lsd-dropdown--error{width:230px;}.lsd-dropdown--large .lsd-dropdown__label{margin:0 0 6px 18px;}.lsd-dropdown--large .lsd-dropdown__button-container{height:40px;}.lsd-dropdown--large .lsd-dropdown__trigger{padding:10px 0px 10px 18px;}.lsd-dropdown--large .lsd-dropdown__icons{padding:0px 14px;}.lsd-dropdown--medium{width:188px;}.lsd-dropdown--medium.lsd-dropdown--error{width:210px;}.lsd-dropdown--medium .lsd-dropdown__label{margin:0 0 6px 14px;}.lsd-dropdown--medium .lsd-dropdown__button-container{height:32px;}.lsd-dropdown--medium .lsd-dropdown__trigger{padding:6px 0px 6px 14px;}.lsd-dropdown--medium .lsd-dropdown__icons{padding:0px 12px;}.lsd-dropdown--small{width:164px;}.lsd-dropdown--small.lsd-dropdown--error{width:186px;}.lsd-dropdown--small .lsd-dropdown__label{margin:0 0 6px 12px;}.lsd-dropdown--small .lsd-dropdown__button-container{height:28px;}.lsd-dropdown--small .lsd-dropdown__trigger{padding:6px 0px 6px 12px;}.lsd-dropdown--small .lsd-dropdown__icons{padding:0px 10px;}.lsd-dropdown--outlined .lsd-dropdown__button-container{border:1px solid rgb(var(--lsd-border-primary));}.lsd-dropdown--underlined .lsd-dropdown__button-container{border:1px solid transparent;border-bottom:1px solid rgb(var(--lsd-border-primary));}

Research Blog

Blog

by
6 min read

Vac is a modular peer-to-peer messaging stack, with a focus on secure messaging. Overview of terms, stack and open problems.

+ + \ No newline at end of file diff --git a/rlog/presenting-js-waku/index.html b/rlog/presenting-js-waku/index.html index 7cec8530..f69d9856 100644 --- a/rlog/presenting-js-waku/index.html +++ b/rlog/presenting-js-waku/index.html @@ -10,8 +10,8 @@ - - + +
@@ -100,7 +100,7 @@ You can find documentation on the chat2. You can get support in #dappconnect-support on Vac Discord or Telegram. If you have any ideas on how Waku could enable a specific dapp or use case, do share, we are always keen to hear it.

- - + + \ No newline at end of file diff --git a/rlog/remote-log/index.html b/rlog/remote-log/index.html index 26e0b31d..00e86c6e 100644 --- a/rlog/remote-log/index.html +++ b/rlog/remote-log/index.html @@ -10,8 +10,8 @@ - - + +
@@ -24,7 +24,7 @@ that are resource restricted, mostly-offline and often changing network.

Remote log

A remote log is a replication of a local log. This means a node can read data from a node that is offline.

The spec is in an early draft stage and can be found here. A very basic spike / proof-of-concept can be found here.

Definitions

TermDefinition
CASContent-addressed storage. Stores data that can be addressed by its hash.
NSName system. Associates mutable data to a name.
Remote logReplication of a local log at a different location.

Roles

There are four fundamental roles:

  1. Alice
  2. Bob
  3. Name system (NS)
  4. Content-addressed storage (CAS)

The remote log is the data format of what is stored in the name system.

"Bob" can represent anything from 0 to N participants. Unlike Alice, Bob only needs read-only access to NS and CAS.

Flow

Figure 1: Remote log data synchronization.

Data format

The remote log lets receiving nodes know what data they are missing. Depending on the specific requirements and capabilities of the nodes and name system, the information can be referred to differently. We distinguish between three rough modes:

  1. Fully replicated log
  2. Normal sized page with CAS mapping
  3. "Linked list" mode - minimally sized page with CAS mapping

A remote log is simply a mapping from message identifiers to their corresponding address in a CAS:

Message Identifier (H1)CAS Hash (H2)
H1_3H2_3
H1_2H2_2
H1_1H2_1
address to next page

The numbers here corresponds to messages. Optionally, the content itself can be included, just like it normally would be sent over the wire. This bypasses the need for a dedicated CAS and additional round-trips, with a trade-off in bandwidth usage.

Message Identifier (H1)Content
H1_3C3
H1_2C2
H1_1C1
address to next page

Both patterns can be used in parallel, e,g. by storing the last k messages directly and use CAS pointers for the rest. Together with the next_page page semantics, this gives users flexibility in terms of bandwidth and latency/indirection, all the way from a simple linked list to a fully replicated log. The latter is useful for things like backups on durable storage.

Interaction with MVDS

vac.mvds.Message payloads are the only payloads that MUST be uploaded. Other messages types MAY be uploaded, depending on the implementation.

Future work

The spec is still in an early draft stage, so it is expected to change. Same with the proof of concept. More work is needed on getting a fully featured proof of concept with specific CAS and NAS instances. E.g. Swarm and Swarm Feeds, or IPFS and IPNS, or something else.

For data sync in general:

  • Make consistency guarantees more explicit for app developers with support for sequence numbers and DAGs, as well as the ability to send non-synced messages. E.g. ephemeral typing notifications, linear/sequential history and casual consistency/DAG history
  • Better semantics and scalability for multi-user sync contexts, e.g. CRDTs and joining multiple logs together
  • Better usability in terms of application layer usage (data sync clients) and supporting more transports

PS1. Thanks everyone who submitted great logo proposals for Vac!

PPS2. Next week on October 10th decanus and I will be presenting Vac at Devcon, come say hi :)

- - + + \ No newline at end of file diff --git a/rlog/rln-anonymous-dos-prevention/index.html b/rlog/rln-anonymous-dos-prevention/index.html index a67f277f..c404c414 100644 --- a/rlog/rln-anonymous-dos-prevention/index.html +++ b/rlog/rln-anonymous-dos-prevention/index.html @@ -10,8 +10,8 @@ - - + +
@@ -64,7 +64,7 @@ which is documented here. The usage of RLN in Waku is detailed in our RLN Implementers guide, which provides step-by-step instructions on how to run Waku-RLN-Relay.

Following is a diagram that will help understand the dependency tree -

rln-dep-tree

Future work

  • Optimizations to zerokit for proof generation time.
  • Incrementing tree depth from 20 to 32, to allow more memberships.
  • Optimizations to the smart contract.
  • An ability to signal validity of a message in different time windows.
  • Usage of proving systems other than Groth16.

References

- - + + \ No newline at end of file diff --git a/rlog/rln-light-verifiers/index.html b/rlog/rln-light-verifiers/index.html index c115f8c9..42cf6955 100644 --- a/rlog/rln-light-verifiers/index.html +++ b/rlog/rln-light-verifiers/index.html @@ -10,8 +10,8 @@ - - + +
@@ -52,7 +52,7 @@ which requires fetching all the memberships from the smart contract.

shardIndex of the commitment.

Proof of concept

A proof of concept implementation of the tiered commitment tree is available here, and is deployed on Sepolia at 0xE7987c70B54Ff32f0D5CBbAA8c8Fc1cAf632b9A5.

It is compatible with the current implementation of the RLN verifier.

Future work

  1. Optimize the gas costs of the tiered commitment tree.
  2. Explore using different number of leaves under a given node in the tree (currently set to 2).

Conclusion

The tiered commitment tree is a promising approach to reduce the number of RPC calls required to sync the tree and reduce the gas costs associated with computing the root of the tree. Consequently, it allows for a more scalable and efficient RLN verifier.

References

- - + + \ No newline at end of file diff --git a/rlog/rln-relay/index.html b/rlog/rln-relay/index.html index 6cf2afc5..d4e6bdf3 100644 --- a/rlog/rln-relay/index.html +++ b/rlog/rln-relay/index.html @@ -10,8 +10,8 @@ - - + +
@@ -29,7 +29,7 @@ If the preceding checks are passed successfully, then the message is relayed. In

Figure 3: Publishing, Routing and Slashing workflow.

Feasibility and Open Issues

We've come a long way since a year ago, blockers resolved, now we have implemented it end-to-end. We learned lot and could identify further issues and unknowns some of which are blocking getting to production. The summary of the identified issues are presented below.

Storage overhead per peer

Currently, peers are supposed to maintain the entire tree locally and it imposes storage overhead which is linear in the size of the group (see this issue11 for more details). One way to cope with this is to use the light-node and full-node paradigm in which only a subset of peers who are more resourceful retain the tree whereas the light nodes obtain the necessary information by interacting with the full nodes. Another way to approach this problem is through a more storage efficient method (as described in this research issue12) where peers store a partial view of the tree instead of the entire tree. Keeping the partial view lowers the storage complexity to O(log(N)) where N is the size of the group. There are still unknown unknowns to this solution, as such, it must be studied further to become fully functional.

Cost-effective way of member insertion and deletion

Currently, the cost associated with RLN-Relay membership is around 30 USD10. We aim at finding a more cost-effective approach. Please feel free to share with us your solution ideas in this regard in this issue.

Exceeding the messaging rate via multiple registrations

While the economic-incentive solution has an economic incentive to discourage spamming, we should note that there is still expensive attack(s)23 that a spammer can launch to break the messaging rate limit. That is, the attacker can pay for multiple legit registrations e.g., k, hence being able to publish k messages per epoch. We believe that the higher the membership fee is, the less probable would be such an attack, hence a stronger level of spam-protection can be achieved. Following this argument, the high fee associated with the membership (which we listed above as an open problem) can indeed be contributing to a better protection level.

Conclusion and Future Steps

As discussed in this post, Waku RLN Relay can achieve a privacy-preserving economic spam protection through rate-limiting nullifiers. The idea is to financially discourage peers from publishing more than one message per epoch. In specific, exceeding the messaging rate results in a financial charge. Those who violate this rule are called spammers and their messages are spam. The identification of spammers does not rely on any central entity. Also, the financial punishment of spammers is cryptographically guaranteed. In this solution, privacy is guaranteed since: 1) Peers do not have to disclose any piece of personally identifiable information in any phase i.e., neither in the registration nor in the messaging phase 2) Peers can prove that they have not exceeded the messaging rate in a zero-knowledge manner and without leaving any trace to their membership accounts. Furthermore, all the computations are light hence this solution fits the heterogenous p2p messaging system. Note that the zero-knowledge proof parts are handled through zkSNARKs and the benchmarking result can be found in the RLN benchmark report5.

Future steps:

We are still at the PoC level, and the development is in progress. As our future steps,

  • we would like to evaluate the running time associated with the Merkle tree operations. Indeed, the need to locally store Merkle tree on each peer was one of the unknowns discovered during this PoC and yet the concrete benchmarking result in this regard is not available.
  • We would also like to pursue our storage-efficient Merkle Tree maintenance solution in order to lower the storage overhead of peers.
  • In line with the storage optimization, the full-node light-node structure is another path to follow.
  • Another possible improvement is to replace the membership contract with a distributed group management scheme e.g., through distributed hash tables. This is to address possible performance issues that the interaction with the Ethereum blockchain may cause. For example, the registration transactions are subject to delay as they have to be mined before being visible in the state of the membership contract. This means peers have to wait for some time before being able to publish any message.

Acknowledgement

Thanks to Onur Kılıç for his explanation and pointers and for assisting with development and runtime issues. Also thanks to Barry Whitehat for his time and insightful comments. Special thanks to Oskar Thoren for his constructive comments and his guides during the development of this PoC and the writeup of this post.

References


  1. RLN-Relay specification: https://rfc.vac.dev/spec/17/
  2. RLN documentation: https://hackmd.io/tMTLMYmTR5eynw2lwK9n1w?both
  3. RLN repositories: https://github.com/kilic/RLN and https://github.com/kilic/rlnapp
  4. Waku v2: https://rfc.vac.dev/spec/10/
  5. GossipSub: https://docs.libp2p.io/concepts/publish-subscribe/
  6. Waku Relay: https://rfc.vac.dev/spec/11/
  7. Proof of work: http://www.infosecon.net/workshop/downloads/2004/pdf/clayton.pdf and https://link.springer.com/content/pdf/10.1007/3-540-48071-4_10.pdf
  8. EIP-627 Whisper: https://eips.ethereum.org/EIPS/eip-627
  9. Peer Scoring: https://github.com/libp2p/specs/blob/master/pubsub/gossipsub/gossipsub-v1.1.md#peer-scoring
  10. Peer scoring security issues: https://github.com/vacp2p/research/issues/44
  11. Zero Knowledge Proof: https://dl.acm.org/doi/abs/10.1145/3335741.3335750 and https://en.wikipedia.org/wiki/Zero-knowledge_proof
  12. zkSNARKs: https://link.springer.com/chapter/10.1007/978-3-662-49896-5_11 and https://coinpare.io/whitepaper/zcash.pdf
  13. Shamir Secret Sharing Scheme: https://en.wikipedia.org/wiki/Shamir%27s_Secret_Sharing
  14. zkSNARKs proof time: https://github.com/vacp2p/research/issues/7
  15. Prover key size: https://github.com/vacp2p/research/issues/8
  16. The lack of Shamir secret sharing in zkSNARKs: https://github.com/vacp2p/research/issues/10
  17. The MPC required for zkSNARKs trusted setup: https://github.com/vacp2p/research/issues/9
  18. Storage overhead per peer: https://github.com/vacp2p/research/issues/57
  19. Storage-efficient Merkle Tree maintenance: https://github.com/vacp2p/research/pull/54
  20. Cost-effective way of member insertion and deletion: https://github.com/vacp2p/research/issues/56
  21. Attack on the messaging rate: https://github.com/vacp2p/specs/issues/251
  22. RLN Benchmark: https://hackmd.io/tMTLMYmTR5eynw2lwK9n1w?view#Benchmarks
- - + + \ No newline at end of file diff --git a/rlog/rln-v3/index.html b/rlog/rln-v3/index.html index 036c2e73..8ae85338 100644 --- a/rlog/rln-v3/index.html +++ b/rlog/rln-v3/index.html @@ -10,8 +10,8 @@ - - + +
@@ -67,7 +67,7 @@ we need to increase the size of the nullifier log used, which previously cleared itself every second to the higher bound of the user_epoch_limit, which is 3600. Now, the RLN proof verifier must clear the nullifier log every 3600 seconds to satisfactorily detect double signaling.

The implementation

An implementation of the RLN-v3 scheme in gnark can be found here.

Comments on performance

  • Hardware: Macbook Air M2, 16GB RAM
  • Circuit: RLN-v3
  • Proving system: Groth16
  • Framework: gnark
  • Elliptic curve: bn254 (aka bn128) (not to be confused with the 254-bit Weierstrass curve)
  • Finite field: Prime-order subgroup of the group of points on the bn254 curve
  • Default Merkle tree height: 20
  • Hashing algorithm: Poseidon
  • Merkle tree: Sparse Indexed Merkle Tree

Proving

The proving time for the RLN-v3 circuit is 90ms for a single proof.

Verification

The verification time for the RLN-v3 circuit is 1.7ms for a single proof.

Conclusion

The RLN-v3 scheme introduces a new epoch-based message rate-limiting scheme to the RLN protocol. It enhances the user's flexibility in setting their message limits and cost-optimizes their stake.

Future work

  • Implementing the RLN-v3 scheme in Zerokit
  • Implementing the RLN-v3 scheme in Waku
  • Formal security analysis of the RLN-v3 scheme

References

- - + + \ No newline at end of file diff --git a/rlog/rss.xml b/rlog/rss.xml index b2636a14..12130279 100644 --- a/rlog/rss.xml +++ b/rlog/rss.xml @@ -4,10 +4,68 @@ Vac Research Blog https://vac.dev/rlog Vac Research Blog - Tue, 27 Aug 2024 12:00:00 GMT + Thu, 26 Sep 2024 12:00:00 GMT https://validator.w3.org/feed/docs/rss2.html https://github.com/jpmonette/feed en + + <![CDATA[zkVM Testing Report: Evaluating Zero-Knowledge Virtual Machines for Nescience]]> + https://vac.dev/rlog/zkVM-testing + https://vac.dev/rlog/zkVM-testing + Thu, 26 Sep 2024 12:00:00 GMT + + Introduction

Following our initial exploration of zkVMs in our previous blog post [1], +we have conducted a series of tests to identify the most suitable zkVM for the Nescience architecture [2]. This post outlines the testing process, results, and conclusions. Additionally, +the full test suite and scripts can be found on our GitHub page [3], +allowing others to replicate the results or explore the candidates further.

We've shortlisted the following zkVMs for testing:

  • SP1 [4]
  • RISC0 [5]
  • Nexus [6]
  • ZkMIPS [7]
  • ZkWASM [8]
  • Valida [9]

Why these candidates?

When narrowing down the zkVMs, we focused on key factors:

  • True zero-knowledge functionality: The zkVMs had to demonstrate or be close to demonstrating the ability to generate and verify zero-knowledge proofs.
  • Performance baselines: We sought zkVMs with solid benchmarks in performance, particularly in speed and efficiency.
  • Specific functionalities: For Nescience, functionalities like lookup tables, precompiles, and recursive capabilities are critical.

We need a zkVM that supports these to enable robust project development.

Preliminary information on the candidates

  1. SP1 is a performant, open-source zkVM that verifies the execution of arbitrary Rust (or any LLVM-compiled language) programs. +SP1 utilizes Plonky3, enabling recursive proofs and supporting a wide range of cryptographic algorithms, including ECC-based ones like Groth16. +While it supports aggregation, it appears not to support zero knowledge in a conventional manner.

  2. RISC0 zkVM allows one to prove the correct execution of arbitrary Rust code. Built on a RISC-V architecture, it is inherently adaptable +for implementing standard cryptographic hash functions such as SHA-256 and ECDSA. RISC0 employs STARKs, providing a security level of 98 bits. +It supports multiple programming languages, including C and Rust, thanks to its compatibility with LLVM and WASM.

  3. Nexus is a modular, extensible, open-source, highly parallelized, prover-optimized, and contributor-friendly zkVM written in Rust. +It focuses on performance and security, using the Nova folding scheme, which is particularly effective for recursive proofs. +Nexus also supports precompiles and targeted compilation, and besides Rust, it offers C++ support.

  4. ZkMIPS is a general verifiable computing infrastructure based on Plonky2 and the MIPS microarchitecture, aiming to empower Ethereum +as a global settlement layer. It can run arbitrary Rust code as well. Notably, zkMIPS is the only zkVM in this list that utilizes the MIPS opcode set.

  5. ZkWASM adheres to and supports the unmodified standard WASM bytecode specification. Since Rust code can be compiled to WASM bytecode, +one could theoretically run any Rust code on a zkWASM machine, providing flexibility and broad language support.

  6. Valida is a STARK-based virtual machine aiming to improve upon the state of the art in several categories:

    • Code reuse: The VM has a RISC-inspired instruction set, simplifying the targeting of conventional programming languages. +A backend compiler is being developed to compile LLVM IR to the Valida ISA, enabling the proving of programs written in Rust, +Go, C++, and others with minimal to no changes in source code.
    • Prover performance: Engineered to maximize prover performance, Valida is compatible with a 31-bit field, restricted to degree 3 constraints, +and features minimal instruction decoding. It operates directly on memory without general-purpose registers or a dedicated stack, +utilizing newer lookup arguments to reduce trace overhead involved in cross-chip communication.
    • Extensibility: Designed to be customizable, Valida can easily be extended to include an arbitrary number of user-defined instructions. +Procedural macros are used to construct the desired machine at compile time, avoiding any runtime penalties.

Valida appears to be in the early stages of development but already showcases respectable performance metrics.

Testing plan

To thoroughly evaluate each zkVM, we devised a two-stage testing process:

  • Stage 1: Arithmetic operations

    The first phase focused on evaluating the zkVMs’ ability to handle basic arithmetic operations: addition, subtraction, multiplication, +division, modulus division, and square root calculations. We designed the test around heptagonal numbers, which required zkVMs to process +multiple arithmetic operations simultaneously. By using this method, we could measure efficiency and speed in handling complex mathematical calculations – +a crucial element for zkVM performance.

  • Stage 2: Memory consumption

    For the second phase, we evaluated each zkVM’s ability to manage memory under heavy loads. We tested several data structures, including lists, +hash maps, deques, queues, BTreeMaps, hash sets, and binary heaps. Each zkVM underwent tests for the following operations:

    • Insert: How quickly can the zkVM add data to structures?
    • Delete: Does the zkVM handle memory release effectively?
    • Append: Can the zkVM efficiently grow data structures?
    • Search: How fast and efficient is the zkVM when retrieving stored data?

The purpose of this stage was to identify any memory bottlenecks and to determine whether a zkVM could manage high-intensity tasks efficiently, +something vital for the Nescience project’s complex, data-heavy processes.

Machine specifications

The tests were conducted on the following hardware configuration:

  • CPU: AMD EPYC 7713 "Milan" 64-core processor (128 threads total)
  • RAM: 600GiB DDR4 3200MHz ECC RAM, distributed across 16 DIMMs
  • Host OS: Proxmox 8.3
  • Hypervisor: KVM
  • Network layer: Open vSwitch
  • Machine model: Supermicro AS-2024US-TRT

Results

1. SP1

SP1 does not provide zero-knowledge capability in its proofs but delivers respectable performance, though slightly behind its main competitor. +Memory leaks were minimal, staying below the 700 KB threshold. Interestingly, SP1 consumed more RAM during the basic arithmetic +test than in memory allocation tests, showcasing the team's effective handling of memory under load. In the basic test, +allocations were primarily in the 9-16 B, 33-64 B, and 65-128 B ranges. For memory allocations, most fell into the 129-256 B range.

  • Stage 1: Hept 100 test
    • Proof size: 3.108 MB
    • Proof time: 16.95 seconds
Image 1
Image 2
Image 3
Image 4
Image 5
  • Stage 2: Vec 10000 test
    • Proof size: 3.17 MB
    • Proof time: 20.85 seconds
Image 1
Image 2
Image 3
Image 4
Image 5

2. RISC0

RISC0 stands out with exceptional performance in proof size and generation time, ranking among the best +(with the exception of Valida and zkWASM's basic test). It also handles memory well, with minor leaks under 0.5 MB +and controlled RAM consumption staying below 2.2 GB. RISC0's memory allocations were consistent, primarily in the 17-32 B and 33-64 B ranges.

  • Stage 1: Hept 100 test
    • Proof size: 217.4 KB
    • Proof time: 9.73 seconds
Image 1
Image 2
Image 3
Image 4
Image 5
  • Stage 2: Vec 10000 test
    • Proof size: 217.4 KB
    • Proof time: 16.63 seconds
Image 1
Image 2
Image 3
Image 4
Image 5

Based on these results, RISC0 is a solid candidate for Nescience.


3. Nexus

Nexus' performance offers interesting insights into folding scheme-based zkVMs. Surprisingly, proof sizes remained consistent +regardless of workload, with no significant memory leaks (under 700 KB). However, while RAM consumption increased slightly with higher +workloads (up to 1.2 GB), Nexus performed poorly during memory allocation tests, making it unsuitable for our use case.

  • Allocation details:

    • Basic test: Most allocations concentrated in 65-128 B
    • Memory-heavy test: Allocations in the 129-256 B range
  • Stage 1: Hept 100 test

    • Proof size: 46 MB
    • Proof time: 12.06 seconds
Image 1
Image 2
Image 3
Image 4
Image 5
  • Stage 2: Vec 10000 test
    • Proof size: 46 MB
    • Proof time: 56 minutes
Image 1
Image 2
Image 3
Image 4
Image 5

4. ZkMIPS

ZkMIPS presents an intriguing case. While it shows good results in terms of proof size and generation time during the basic test, +these come at the cost of significant RAM usage and memory leaks. The memory allocation test revealed a concerning 6.7 GB memory leak, +with 0.5 GB leaked during the basic test. Despite this, RAM consumption (while high at 17+ GB) remains stable under higher workloads. +Allocation sizes are spread across several ranges, with notable concentrations in the 17-32 B, 65-128 B, and 257-512 B slots.

  • Stage 1: Hept 100 test
    • Proof size: 4.3 MB
    • Proof time: 9.32 seconds
Image 1
Image 2
Image 3
Image 4
Image 5
  • Stage 2: Vec 10000 test
    • Proof size: 4.898 MB
    • Proof time: 42.57 seconds
Image 1
Image 2
Image 3
Image 4
Image 5

This zkVM provides mixed results with strong proof generation but concerning memory management issues.


5. ZkWASM

ZkWASM, unfortunately, performed poorly in both stages regarding proof size and generation time. RAM consumption was particularly high, +exceeding 7 GB in the basic test, and an astounding 57 GB during memory allocation tests. Despite its impressive memory usage, +the proof sizes were relatively large at 18 KB and 334 KB respectively. Allocation sizes were mainly concentrated in the 33-64 B range, +with neighboring slots contributing small but notable amounts.

  • Stage 1: Hept 100 test
    • Proof size: 18 KB
    • Proof time: 42.7 seconds
Image 1
Image 2
Image 3
Image 4
Image 5
  • Stage 2: Vec 10000 test
    • Proof size: 334 KB
    • Proof time: 323 seconds
Image 1
Image 2
Image 3
Image 4
Image 5

6. Valida

Valida delivered impressive results in proof generation speed and size, with a proof size of 280 KB and a proof time of < 1 second. +However, profiling was not possible due to Valida's limited Rust support. Valida currently compiles Rust using the LLVM backend, +transpiling LLVM IR to leverage its C/C++ implementation, which leads to errors when handling Rust-specific data structures or dependencies. +As a result, complex memory interactions couldn't be tested, and using Valida with Rust code is currently not advisable. +A GitHub issue has been opened to address this.


Summary table

Stage 1

zkVMProof timeProof sizePeak RAM consumptionMemory leaked
SP116.95 s3.108 MB2.1 GB656.8 KB
RISC09.73 s217.4 KB1.9 GB470.5 KB
Nexus12.06 s46 MB9.7 MB646.5 KB
ZkMIPS9.32 s4.3 MB17.3 GB453.8 MB
ZkWASM42.7 s18 KB8.2 GB259.4 KB
Valida< 1 s280 KBN/AN/A

Stage 2

zkVMProof timeProof sizePeak RAM consumptionMemory leaked
SP120.85 s3.17 MB1.9 GB616 KB
RISC016.63 s217.4 KB2.3 GB485.3 KB
Nexus56 m46 MB1.9 GB616 KB
ZkMIPS42.57 s4.898 MB18.9 GB6.9 GB
ZkWASM323 s334 KB58.8 GB259.4 KB
ValidaN/AN/AN/AN/A

Summary

After an extensive evaluation of six zkVM candidates for the Nescience project, RISC0 emerged as the top choice. +It excels in both proof generation time and size while maintaining a reasonable memory footprint. With strong zero-knowledge +proof capabilities and support for multiple programming languages, it aligns well with our project's needs for privacy, +performance, and flexibility. Its overall balance between performance and efficiency makes it the most viable zkVM at this stage.

Valida, while promising with its potential for high prover performance, is still in early development and suffers from Rust integration issues. +The current LLVM IR transpilation limitations mean it cannot handle complex memory interactions, disqualifying it for now. +However, once its development matures, Valida could become a strong alternative, and we plan to revisit it as it evolves.

SP1, though initially interesting, failed to meet the zero-knowledge proof requirement. Its performance in arithmetic operations was +respectable but insufficient to justify further consideration given its lack of ZK functionality – critical for our privacy-first objectives.

Nexus demonstrated consistent proof sizes and manageable memory usage, but its lackluster performance during memory-intensive tasks and +its proof size (especially for larger workloads) disqualified it from being a top contender. While zkMIPS delivered solid proof times, +the memory issues were too significant to ignore, making it unsuitable.

Finally, zkWASM exhibited the poorest results, struggling both in proof size and generation time. Despite its potential for WASM bytecode support, +the excessive RAM consumption (up to 57 GB in the memory test) rendered it impractical for Nescience’s use case.

In conclusion, RISC0 is the best fit for Nescience at this stage, but Valida remains a future candidate as its development progresses.

We’d love to hear your thoughts on our zkVM testing process and results! Do you agree with our conclusions, or do you think we missed a promising zkVM? +We’re always open to feedback, insights, and suggestions from the community.

Join the discussion and share your perspectives on +our forum or try out the +tests yourself through our [GitHub page](https://github.com/vacp2p/nescience-zkvm-testing!

References

[1] Exploring zkVMs: Which Projects Truly Qualify as Zero-Knowledge Virtual Machines? Retrieved from https://vac.dev/rlog/zkVM-explorations/

[2] Nescience: A User-Centric State-Separation Architecture. Retrieved from https://vac.dev/rlog/Nescience-state-separation-architecture

[3] Our GitHub Page for zkVM Testing. Retrieved from https://github.com/vacp2p/nescience-zkvm-testing

[4] Introducing SP1: A performant, 100% open-source, contributor-friendly zkVM. Retrieved from https://blog.succinct.xyz/introducing-sp1/

[5] The first general purpose zkVM. Retrieved from https://www.risczero.com/zkvm

[6] The Nexus 2.0 zkVM. Retrieved from https://docs.nexus.xyz/

[7] ZKM Architecture. Retrieved from https://docs.zkm.io/zkm-architecture

[8] ZK-WASM. Retrieved from https://delphinuslab.com/zk-wasm/

[9] Valida zkVM Design. Retrieved from https://delendum.xyz/writings/2023-05-10-zkvm-design.html

]]>
+
<![CDATA[Exploring zkVMs: Which Projects Truly Qualify as Zero-Knowledge Virtual Machines?]]> https://vac.dev/rlog/zkVM-explorations diff --git a/rlog/vac-overview/index.html b/rlog/vac-overview/index.html index aa9aeab9..71175d20 100644 --- a/rlog/vac-overview/index.html +++ b/rlog/vac-overview/index.html @@ -10,8 +10,8 @@ - - + +
@@ -20,7 +20,7 @@ ) .lsd-dropdown__trigger:hover .lsd-dropdown__option-label,.lsd-dropdown:not(.lsd-dropdown--disabled):not( .lsd-dropdown--error ) .lsd-dropdown__trigger:focus .lsd-dropdown__option-label{-webkit-text-decoration:underline;text-decoration:underline;}.lsd-dropdown__label{display:block;}.lsd-dropdown__button-container{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-box-pack:justify;-webkit-justify-content:space-between;justify-content:space-between;}.lsd-dropdown__trigger{width:100%;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:row;-ms-flex-direction:row;flex-direction:row;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:justify;-webkit-justify-content:space-between;justify-content:space-between;border:none;cursor:pointer;background:none;}.lsd-dropdown__trigger:focus{outline:none;}.lsd-dropdown__option-label{cursor:inherit;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;}.lsd-dropdown__icons{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:row;-ms-flex-direction:row;flex-direction:row;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:center;-ms-flex-pack:center;-webkit-justify-content:center;justify-content:center;gap:8px;}.lsd-dropdown__icon{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;}.lsd-dropdown__supporting-text{margin:6px 14px;}.lsd-dropdown--error .lsd-dropdown__option-label{-webkit-text-decoration:line-through;text-decoration:line-through;}.lsd-dropdown--disabled{opacity:0.34;cursor:initial;}.lsd-dropdown--large{width:208px;}.lsd-dropdown--large.lsd-dropdown--error{width:230px;}.lsd-dropdown--large .lsd-dropdown__label{margin:0 0 6px 18px;}.lsd-dropdown--large .lsd-dropdown__button-container{height:40px;}.lsd-dropdown--large .lsd-dropdown__trigger{padding:10px 0px 10px 18px;}.lsd-dropdown--large .lsd-dropdown__icons{padding:0px 14px;}.lsd-dropdown--medium{width:188px;}.lsd-dropdown--medium.lsd-dropdown--error{width:210px;}.lsd-dropdown--medium .lsd-dropdown__label{margin:0 0 6px 14px;}.lsd-dropdown--medium .lsd-dropdown__button-container{height:32px;}.lsd-dropdown--medium .lsd-dropdown__trigger{padding:6px 0px 6px 14px;}.lsd-dropdown--medium .lsd-dropdown__icons{padding:0px 12px;}.lsd-dropdown--small{width:164px;}.lsd-dropdown--small.lsd-dropdown--error{width:186px;}.lsd-dropdown--small .lsd-dropdown__label{margin:0 0 6px 12px;}.lsd-dropdown--small .lsd-dropdown__button-container{height:28px;}.lsd-dropdown--small .lsd-dropdown__trigger{padding:6px 0px 6px 12px;}.lsd-dropdown--small .lsd-dropdown__icons{padding:0px 10px;}.lsd-dropdown--outlined .lsd-dropdown__button-container{border:1px solid rgb(var(--lsd-border-primary));}.lsd-dropdown--underlined .lsd-dropdown__button-container{border:1px solid transparent;border-bottom:1px solid rgb(var(--lsd-border-primary));}

Vac - A Rough Overview

by
6 min read

Vac is a modular peer-to-peer messaging stack, with a focus on secure messaging. Overview of terms, stack and open problems.

Vac is a modular peer-to-peer messaging stack, with a focus on secure messaging. What does that mean? Let's unpack it a bit.

Basic terms

messaging stack. While the initial focus is on data sync, we are concerned with all layers in the stack. That means all the way from underlying transports, p2p overlays and routing, to initial trust establishment and semantics for things like group chat. The ultimate goal is to give application developers the tools they need to provide secure messaging for their users, so they can focus on their domain expertise.

modular. Unlike many other secure messaging applications, our goal is not to have a tightly coupled set of protocols, nor is it to reinvent the wheel. Instead, we aim to provide options at each layer in the stack, and build on the shoulders of giants, putting a premimum on interoperability. It's similar in philosophy to projects such as libp2p or Substrate in that regard. Each choice comes with different trade-offs, and these look different for different applications.

peer-to-peer. The protocols we work on are pure p2p, and aim to minimize centralization. This too is in opposition to many initiatives in the secure messaging space.

messaging. By messaging we mean messaging in a generalized sense. This includes both human to human communication, as well machine to machine communication. By messaging we also mean something more fundamental than text messages, we also include things like transactions (state channels, etc) under this moniker.

secure messaging. Outside of traditional notions of secure messaging, such as ensuring end to end encryption, forward secrecy, avoiding MITM-attacks, etc, we are also concerned with two other forms of secure messaging. We call these private messaging and censorship-resistance. Private messaging means viewing privacy as a security property, with all that entails. Censorship resistance ties into being p2p, but also in terms of allowing for transports and overlays that can't easily be censored by port blocking, traffic analysis, and similar.

Vāc. Is a Vedic goddess of speech. It also hints at being a vaccine.

Protocol stack

What does this stack look like? We take inspiration from core internet architecture, existing survey work and other efforts that have been done to decompose the problem into orthogonal pieces. Each layer provides their own set of properties and only interact with the layers it is adjacent to. Note that this is a rough sketch.

Layer / ProtocolPurposeExamples
Application layerEnd user semantics1:1 chat, group chat
Data SyncData consistencyMVDS, BSP
Secure TransportConfidentiality, PFS, etcDouble Ratchet, MLS
Transport PrivacyTransport and metadata protectionWhisper, Tor, Mixnet
P2P OverlayOverlay routing, NAT traversaldevp2p, libp2p
Trust EstablishmentEstablishing end-to-end trustTOFU, web of trust

As an example, end user semantics such as group chat or moderation capabilities can largely work regardless of specific choices further down the stack. Similarly, using a mesh network or Tor doesn't impact the use of Double Ratchet at the Secure Transport layer.

Data Sync plays a similar role to what TCP does at the transport layer in a traditional Internet architecture, and for some applications something more like UDP is likely to be desirable.

In terms of specific properties and trade-offs at each layer, we'll go deeper down into them as we study them. For now, this is best treated as a rough sketch or mental map.

Problems and rough priorities

With all the pieces involved, this is quite an undertaking. Luckily, a lot of pieces are already in place and can be either incorporated as-is or iterated on. In terms of medium and long term, here's a rough sketch of priorities and open problems.

  1. Better data sync. While the current MVDS works, it is lacking in a few areas:
  • Lack of remote log for mostly-offline offline devices
  • Better scalability for multi-user chat contexts
  • Better usability in terms of application layer usage and supporting more transports
  1. Better transport layer support. Currently MVDS runs primarily over Whisper, which has a few issues:
  • scalability, being able to run with many nodes
  • spam-resistance, proof of work is a poor mechanism for heterogeneous devices
  • no incentivized infrastructure, leading to centralized choke points

In addition to these most immediate concerns, there are other open problems. Some of these are overlapping with the above.

  1. Adaptive nodes. Better support for resource restricted devices and nodes of varying capabilities. Light connection strategy for resources and guarantees. Security games to outsource processing with guarantees.

  2. Incentivized and spam-resistant messaging. Reasons to run infrastructure and not relying on altruistic nodes. For spam resistance, in p2p multicast spam is a big attack vector due to amplification. There are a few interesting directions here, such as EigenTrust, proof of burn with micropayments, and leveraging zero-knowledge proofs.

  3. Strong privacy guarantees at transport privacy layer. More rigorous privacy guarantees and explicit trade-offs for metadata protection. Includes Mixnet.

  4. Censorship-resistant and robust P2P overlay. NAT traversal; running in the browser; mesh networks; pluggable transports for traffic obfuscation.

  5. Scalable and decentralized secure conversational security. Strong security guarantees such as forward secrecy, post compromise security, for large group chats. Includes projects such MLS and extending Double Ratchet.

  6. Better trust establishment and key handling. Avoiding MITM attacks while still enabling a good user experience. Protecting against ghost users in group chat and providing better ways to do key handling.

There is also a set of more general problems, that touch multiple layers:

  1. Ensuring modularity and interoperability. Providing interfaces that allow for existing and new protocols to be at each layer of the stack.

  2. Better specifications. Machine-readable and formally verified specifications. More rigorous analysis of exact guarantees and behaviors. Exposing work in such a way that it can be analyzed by academics.

  3. Better simulations. Providing infrastructure and tooling to be able to test protocols in adverse environments and at scale.

  4. Enabling excellent user experience. A big reason for the lack of widespread adoption of secure messaging is the fact that more centralized, insecure methods provide a better user experience. Given that incentives can align better for users interested in secure messaging, providing an even better user experience should be doable.


We got some work to do. Come help us if you want. See you in the next update!

- - + + \ No newline at end of file diff --git a/rlog/waku-for-all/index.html b/rlog/waku-for-all/index.html index 0d7c5f05..58df7a6b 100644 --- a/rlog/waku-for-all/index.html +++ b/rlog/waku-for-all/index.html @@ -10,8 +10,8 @@ - - + +
@@ -66,7 +66,7 @@ These two devices could be:

  • Ethereum node and mobile phone to access Raspberry Pi Zero and other restricted-resource environments,
  • More communication & marketing effort around Waku and the Waku developer community.

References

  • [1] Waku is modular; it is a suite of protocols; hence some Waku protocols may be mature, while new protocols are still being designed. Which means that research continues to be ongoing while Waku is already used in production.
  • [2] The Optimism Foundation runs the only block produce on the Optimism network.
  • [3] Top 10 L2s are documented has having a centralized operator.
- - + + \ No newline at end of file diff --git a/rlog/waku-update/index.html b/rlog/waku-update/index.html index 9ac28b29..ffe2a242 100644 --- a/rlog/waku-update/index.html +++ b/rlog/waku-update/index.html @@ -10,8 +10,8 @@ - - + +
@@ -21,7 +21,7 @@ .lsd-dropdown--error ) .lsd-dropdown__trigger:focus .lsd-dropdown__option-label{-webkit-text-decoration:underline;text-decoration:underline;}.lsd-dropdown__label{display:block;}.lsd-dropdown__button-container{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-box-pack:justify;-webkit-justify-content:space-between;justify-content:space-between;}.lsd-dropdown__trigger{width:100%;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:row;-ms-flex-direction:row;flex-direction:row;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:justify;-webkit-justify-content:space-between;justify-content:space-between;border:none;cursor:pointer;background:none;}.lsd-dropdown__trigger:focus{outline:none;}.lsd-dropdown__option-label{cursor:inherit;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;}.lsd-dropdown__icons{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:row;-ms-flex-direction:row;flex-direction:row;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:center;-ms-flex-pack:center;-webkit-justify-content:center;justify-content:center;gap:8px;}.lsd-dropdown__icon{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;}.lsd-dropdown__supporting-text{margin:6px 14px;}.lsd-dropdown--error .lsd-dropdown__option-label{-webkit-text-decoration:line-through;text-decoration:line-through;}.lsd-dropdown--disabled{opacity:0.34;cursor:initial;}.lsd-dropdown--large{width:208px;}.lsd-dropdown--large.lsd-dropdown--error{width:230px;}.lsd-dropdown--large .lsd-dropdown__label{margin:0 0 6px 18px;}.lsd-dropdown--large .lsd-dropdown__button-container{height:40px;}.lsd-dropdown--large .lsd-dropdown__trigger{padding:10px 0px 10px 18px;}.lsd-dropdown--large .lsd-dropdown__icons{padding:0px 14px;}.lsd-dropdown--medium{width:188px;}.lsd-dropdown--medium.lsd-dropdown--error{width:210px;}.lsd-dropdown--medium .lsd-dropdown__label{margin:0 0 6px 14px;}.lsd-dropdown--medium .lsd-dropdown__button-container{height:32px;}.lsd-dropdown--medium .lsd-dropdown__trigger{padding:6px 0px 6px 14px;}.lsd-dropdown--medium .lsd-dropdown__icons{padding:0px 12px;}.lsd-dropdown--small{width:164px;}.lsd-dropdown--small.lsd-dropdown--error{width:186px;}.lsd-dropdown--small .lsd-dropdown__label{margin:0 0 6px 12px;}.lsd-dropdown--small .lsd-dropdown__button-container{height:28px;}.lsd-dropdown--small .lsd-dropdown__trigger{padding:6px 0px 6px 12px;}.lsd-dropdown--small .lsd-dropdown__icons{padding:0px 10px;}.lsd-dropdown--outlined .lsd-dropdown__button-container{border:1px solid rgb(var(--lsd-border-primary));}.lsd-dropdown--underlined .lsd-dropdown__button-container{border:1px solid transparent;border-bottom:1px solid rgb(var(--lsd-border-primary));}

Waku Update

by
6 min read

A research log. What's the current state of Waku? How many users does it support? What are the bottlenecks? What's next?

Waku is our fork of Whisper where we address the shortcomings of Whisper in an iterative manner. We've seen a in previous post that Whisper doesn't scale, and why. In this post we'll talk about what the current state of Waku is, how many users it can support, and future plans.

Current state

Specs:

We released Waku spec v0.3 this week! You can see the full changelog here.

The main change from 0.2 is making the handshake more flexible. This enables us to communicate topic interest immediately without ambiguity. We also did the following:

  • added recommendation for DNS based discovery
  • added an upgradability and compatibility policy
  • cut the spec up into several components

We cut the spec up in several components to make Vac as modular as possible. The components right now are:

We can probably factor these out further as the main spec is getting quite big, but this is good enough for now.

Clients:

There are currently two clients that implement Waku v0.3, these are Nimbus (Update: now nim-waku) in Nim and status-go in Go.

For more details on what each client support and don't, you can follow the work in progress checklist.

Work is currently in progress to integrate it into the Status core app. Waku is expected to be part of their upcoming 1.1 release (see Status app roadmap (link deprecated)).

Simulation:

We have a simulation that verifies - or rather, fails to falsify - our scalability model. More on the simulation and what it shows below.

How many users does Waku support?

This is our current understanding of how many users a network running Waku can support. Specifically in the context of the Status chat app, since that's the most immediate consumer of Waku. It should generalize fairly well to most deployments.

tl;dr (for Status app):

  • beta: 100 DAU
  • v1: 1k DAU
  • v1.1 (waku only): 10k DAU (up to x10 with deployment hotfixes)
  • v1.2 (waku+dns): 100k DAU (can optionally be folded into v1.1)

Assuming 10 concurrent users = 100 DAU. Estimate uncertainty increases for each order of magnitude until real-world data is observed.

As far as we know right now, these are the bottlenecks we have:

  • Immediate bottleneck - Receive bandwidth for end user clients (aka ‘Fixing Whisper with Waku’)
  • Very likely bottleneck - Nodes and cluster capacity (aka ‘DNS based node discovery’)
  • Conjecture but not unlikely to appear- Full node traffic (aka ‘the routing / partition problem’)

We've already seen the first bottleneck being discussed in the initial post. Dean wrote a post on DNS based discovery which explains how we will address the likely second bottleneck. More on the third one in future posts.

For more details on these bottlenecks, see Scalability estimate: How many users can Waku and the Status app support?.

Simulation

The ultimate test is real-world usage. Until then, we have a simulation thanks to Kim De Mey from the Nimbus team!

We have two network topologies, Star and full mesh. Both networks have 6 full nodes, one traditional light node with bloom filter, and one Waku light node.

One of the full nodes sends 1 envelope over 1 of the 100 topics that the two light nodes subscribe to. After that, it sends 10000 envelopes over random topics.

For light node, bloom filter is set to almost 10% false positive (bloom filter: n=100, k=3, m=512). It shows the number of valid and invalid envelopes received for the different nodes.

Star network:

DescriptionPeersValidInvalid
Master node7100010
Full node 13100010
Full node 21100010
Full node 31100010
Full node 41100010
Full node 51100010
Light node28150
Waku light node210

Full mesh:

DescriptionPeersValidInvalid
Full node 071000120676
Full node 17100019554
Full node 251000123304
Full node 351000111983
Full node 451000124425
Full node 551000123472
Light node2803803
Waku light node211

Things to note:

  • Whisper light node with ~10% false positive gets ~10% of total traffic
  • Waku light node gets ~1000x less envelopes than Whisper light node
  • Full mesh results in a lot more duplicate messages, expect for Waku light node

Run the simulation yourself here. The parameters are configurable, and it is integrated with Prometheus and Grafana.

Difference between Waku and Whisper

Summary of main differences between Waku v0 spec and Whisper v6, as described in EIP-627:

  • Handshake/Status message not compatible with shh/6 nodes; specifying options as association list
  • Include topic-interest in Status handshake
  • Upgradability policy
  • topic-interest packet code
  • RLPx subprotocol is changed from shh/6 to waku/0.
  • Light node capability is added.
  • Optional rate limiting is added.
  • Status packet has following additional parameters: light-node, confirmations-enabled and rate-limits
  • Mail Server and Mail Client functionality is now part of the specification.
  • P2P Message packet contains a list of envelopes instead of a single envelope.

Next steps and future plans

Several challenges remain to make Waku a robust and suitable base communication protocol. Here we outline a few challenges that we are addressing and will continue to work on:

  • scalability of the network
  • incentived infrastructure and spam-resistance
  • build with resource restricted devices in mind, including nodes being mostly offline

For the third bottleneck, a likely candidate for fixing this is Kademlia routing. This is similar to what is done in Swarm's PSS. We are in the early stages of experimenting with this over libp2p in nim-libp2p. More on this in a future post!

Acknowledgements

Image from "caged sky" by mh.xbhd.org is licensed under CC BY 2.0 (https://ccsearch.creativecommons.org/photos/a9168311-78de-4cb7-a6ad-f92be8361d0e)

- - + + \ No newline at end of file diff --git a/rlog/waku-v1-v2-bandwidth-comparison/index.html b/rlog/waku-v1-v2-bandwidth-comparison/index.html index 0a7e6cff..7fa60fae 100644 --- a/rlog/waku-v1-v2-bandwidth-comparison/index.html +++ b/rlog/waku-v1-v2-bandwidth-comparison/index.html @@ -10,8 +10,8 @@ - - + +
@@ -109,7 +109,7 @@ we can proceed to a more in-depth characterisation of Waku v2's resource us Some questions that we want to answer include:

  • What proportion of Waku v2's bandwidth usage is used to propagate payload versus bandwidth spent on control messaging to maintain the mesh?
  • To what extent is message latency (time until a message is delivered to its destination) affected by network size and message rate?
  • How reliable is message delivery in Waku v2 for different network sizes and message rates?
  • What are the resource usage profiles of other Waku v2 protocols (e.g.12/WAKU2-FILTER and 19/WAKU2-LIGHTPUSH)?

Our aim is to get ever closer to a "real world" understanding of Waku v2's performance characteristics, identify and fix vulnerabilities and continually improve the efficiency of our suite of protocols.

References

- - + + \ No newline at end of file diff --git a/rlog/waku-v2-ethereum-coscup/index.html b/rlog/waku-v2-ethereum-coscup/index.html index 95df06e7..6dc37fbd 100644 --- a/rlog/waku-v2-ethereum-coscup/index.html +++ b/rlog/waku-v2-ethereum-coscup/index.html @@ -10,8 +10,8 @@ - - + +
@@ -72,7 +72,7 @@ Status uses it with different topics. Then we looked at how it can be useful for messaging in Ethereum, including for things like WalletConnect.

I hope this talk gives you a better idea of what Waku is, why it exists, and that it inspires you to contribute, either to Waku itself or by using it in your own project!

- - + + \ No newline at end of file diff --git a/rlog/waku-v2-ethereum-messaging/index.html b/rlog/waku-v2-ethereum-messaging/index.html index a12956b7..8a1a5deb 100644 --- a/rlog/waku-v2-ethereum-messaging/index.html +++ b/rlog/waku-v2-ethereum-messaging/index.html @@ -10,8 +10,8 @@ - - + +
@@ -24,7 +24,7 @@ This is a work in progress. What we talked about in part 1.
  • Expose messa Currently wallets connect ot dapps with centralized service. Great UX.
  • Solve DAO/Multi-Sig coordination problem. E.g. send message to wallet-derived key when it is time to sign a transaction.
  • Extend dapp-to-user and user-to-dapp communication to more dapps. Use lessons learned and examples to drive adoptation for wallets/dapps.
  • And then build up from there.

    10. We are hiring!

    A lot of this will happen in Javascript and browsers, since that's the primarily environment for a lot of wallets and dapps. We are currently hiring for a Waku JS Wallet integration lead to help push this effort further.

    Come talk to me after or apply here.

    That's it! You can find us on Status, Telegram, vac.dev. I'm on twitter here.

    Questions?


    - - + + \ No newline at end of file diff --git a/rlog/waku-v2-plan/index.html b/rlog/waku-v2-plan/index.html index 5345b5b9..5fdc76ce 100644 --- a/rlog/waku-v2-plan/index.html +++ b/rlog/waku-v2-plan/index.html @@ -10,8 +10,8 @@ - - + +
    @@ -29,7 +29,7 @@ the primary bottleneck for full nodes, and the bottleneck is still bandwidth. To

    While we technically could implement this over existing Waku, we'd have to re-implement it, and we'd lose out on all the other benefits libp2p would provide, as well as the ecosystem of people and projects working on improving the scalability and security of these protocols.

    2. Topic sharding

    This one is slightly more speculative in terms of its ultimate impact. The basic idea is to split the application topic into N shards, say 10, and then each full node can choose which shards to listen to. This can reduce amplification factors by another factor of 10.

    Note that this means a light node that listens to several topics would have to be connected to more full nodes to get connectivity. For a more exotic version of this, see https://forum.vac.dev/t/rfc-topic-propagation-extension-to-libp2p-pubsub/47

    This is orthogonal from the choice of FloodSub or GossipSub, but due to GossipSub's more dynamic nature it is likely best combined with it.

    3. Other factors

    Not a primary focus, but worth a look. Looking at the scaling model, there might be other easy wins to improve overall bandwidth consumption between full nodes. For example, can we reduce envelope size by a significant factor?

    Track 3 - Accounting and user-run nodes

    This is where we make sure the network isn't fragile, become a true p2p app, get our users excited and engaged, and allow us to scale the network without creating an even bigger cluster.

    To work in practice, this has a soft dependency on node discovery such as DNS based discovery (https://eips.ethereum.org/EIPS/eip-1459) or Discovery v5 (https://vac.dev/feasibility-discv5).

    1. Adaptive nodes and capabilities

    We want to make the gradation between light nodes, full nodes, storing (partial set of) historical messages, only acting for a specific shard, etc more flexible and explicit. This is required to identify and discover the nodes you want. See https://github.com/vacp2p/specs/issues/87

    Depending on how the other tracks come together, this design should allow for a desktop node to identify as a full relaying node for some some app topic shard, but also express waku topic interest and retrieve historical messages itself.

    E.g. Disc v5 can be used to supply node properties through ENR.

    2. Accounting

    This is based on a few principles:

    1. Some nodes contribute a lot more than other nodes in the network
    2. We can account for the difference in contribution in some fashion
    3. We want to incentivize nodes to tell the true, and be incentivized not to lie

    Accounting here is a stepping stone, where accounting is the raw data upon which some settlement later occurs. It can have various forms of granularity. See https://forum.vac.dev/t/accounting-for-resources-in-waku-and-beyond/31 for discussion.

    We also note that in GossipSub, the mesh is bidrectional. Additionally, it doesn't appears to be a high priority issue in terms of nodes misreporting. What is an issue is having people run full nodes in the first place. There are a few points to that. It has to be possible in the end-user UX, nodes have to be discovered, and it has to be profitable/visible that you are contributing. UX and discovery are out of scope for this work, whereas visibility/accounting is part of this scope. Settlement is a stretch goal here.

    The general shape of the solution is inspired by the Swarm model, where we do accounting separate from settlement. It doesn't require any specific proofs, but nodes are incentivized to tell the truth in the following way:

    1. Both full node and light node do accounting in a pairwise, local fashion
    2. If a light node doesn't ultimately pay or lie about reporting, they get disconnected (e.g.)
    3. If a full node doesn't provide its service the light node may pick another full node (e.g.)

    While accounting for individual resource usage is useful, for the ultimate end user experience we can ideally account for other things such as:

    • end to end delivery
    • online time
    • completeness of storage

    This can be gradually enhanced and strengthened, for example with proofs, consistency checks, Quality of Service, reputation systems. See https://discuss.status.im/t/network-incentivisation-first-draft/1037 for one attempt to provide stronger guarantees with periodic consistency checks and a shared fund mechanism. And https://forum.vac.dev/t/incentivized-messaging-using-validity-proofs/51 for using validity proofs and removing liveness requirement for settlement.

    All of this is optional at this stage, because our goal here is to improve the status quo for user run nodes. Accounting at this stage should be visible and correspond to the net benefit a node provides to another.

    As a concrete example: a light node has some topic interest and cares about historical messages on some topic. A full node communicates envelopes as they come in, communicates their high availability (online time) and stores/forward stored messages. Both nodes have this information, and if they agree settlement (initially just a mock message) can be sending a payment to an address at some time interval / over some defined volume. See future sections for how this can be improved upon.

    Also see below in section 4, using constructs such as eigentrust as a local reputation mechanism.

    3. Relax high availability requirement

    If we want desktop nodes to participate in the storing of historical messages, high availability is a problem. It is a problem for any node, especially if they lie about it, but assuming they are honest it is still an issue.

    By being connected to multiple nodes, we can get an overlapping online window. Then these can be combined together to get consistency. This is obviously experimental and would need to be tested before being deployed, but if it works it'd be very useful.

    Additionally or alternatively, instead of putting a high requirement on message availability, focus on detection of missing information. This likely requires re-thinking how we do data sync / replication.

    4. Incentivize light and full nodes to tell the truth (policy, etc)

    In accounting phase it is largely assumed nodes are honest. What happens when they lie, and how do we incentivize them to be honest? In the case of Bittorrent this is done with tit-for-tat, however this is a different kind of relationship. What follows are some examples of how this can be done.

    For light nodes:

    • if they don't, they get disconnected
    • prepayment (especially to "high value" nodes)

    For full nodes:

    • multiple nodes reporting to agree, where truth becomes a shelling point
    • use eigentrust
    • staking for discovery visibility with slashing

    5. Settlement PoC

    Can be done after phase 2 if so desired. Basically integrate payments based on accounting and policy.

    Out of scope

    1. We assume the Status Base model requirements are accurate.
    2. We assume Core will improve retention rates.
    3. We assume the Stimbus production team will enable integration of nim-waku.
    4. We assume Discovery mechanisms such as DNS and Discovery v5 will be worked on separately.
    5. We assume Core will, at some point, provide an UX for integrating payment of services.
    6. We assume the desktop client is sufficiently usable.
    7. We assume Core and Infra will investigate ways of improving MaxPeers.
    - - + + \ No newline at end of file diff --git a/rlog/waku-v2-update/index.html b/rlog/waku-v2-update/index.html index 5a0ce58a..9ae3ba99 100644 --- a/rlog/waku-v2-update/index.html +++ b/rlog/waku-v2-update/index.html @@ -10,8 +10,8 @@ - - + +
    @@ -22,7 +22,7 @@ ) .lsd-dropdown__trigger:focus .lsd-dropdown__option-label{-webkit-text-decoration:underline;text-decoration:underline;}.lsd-dropdown__label{display:block;}.lsd-dropdown__button-container{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-box-pack:justify;-webkit-justify-content:space-between;justify-content:space-between;}.lsd-dropdown__trigger{width:100%;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:row;-ms-flex-direction:row;flex-direction:row;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:justify;-webkit-justify-content:space-between;justify-content:space-between;border:none;cursor:pointer;background:none;}.lsd-dropdown__trigger:focus{outline:none;}.lsd-dropdown__option-label{cursor:inherit;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;}.lsd-dropdown__icons{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:row;-ms-flex-direction:row;flex-direction:row;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:center;-ms-flex-pack:center;-webkit-justify-content:center;justify-content:center;gap:8px;}.lsd-dropdown__icon{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;}.lsd-dropdown__supporting-text{margin:6px 14px;}.lsd-dropdown--error .lsd-dropdown__option-label{-webkit-text-decoration:line-through;text-decoration:line-through;}.lsd-dropdown--disabled{opacity:0.34;cursor:initial;}.lsd-dropdown--large{width:208px;}.lsd-dropdown--large.lsd-dropdown--error{width:230px;}.lsd-dropdown--large .lsd-dropdown__label{margin:0 0 6px 18px;}.lsd-dropdown--large .lsd-dropdown__button-container{height:40px;}.lsd-dropdown--large .lsd-dropdown__trigger{padding:10px 0px 10px 18px;}.lsd-dropdown--large .lsd-dropdown__icons{padding:0px 14px;}.lsd-dropdown--medium{width:188px;}.lsd-dropdown--medium.lsd-dropdown--error{width:210px;}.lsd-dropdown--medium .lsd-dropdown__label{margin:0 0 6px 14px;}.lsd-dropdown--medium .lsd-dropdown__button-container{height:32px;}.lsd-dropdown--medium .lsd-dropdown__trigger{padding:6px 0px 6px 14px;}.lsd-dropdown--medium .lsd-dropdown__icons{padding:0px 12px;}.lsd-dropdown--small{width:164px;}.lsd-dropdown--small.lsd-dropdown--error{width:186px;}.lsd-dropdown--small .lsd-dropdown__label{margin:0 0 6px 12px;}.lsd-dropdown--small .lsd-dropdown__button-container{height:28px;}.lsd-dropdown--small .lsd-dropdown__trigger{padding:6px 0px 6px 12px;}.lsd-dropdown--small .lsd-dropdown__icons{padding:0px 10px;}.lsd-dropdown--outlined .lsd-dropdown__button-container{border:1px solid rgb(var(--lsd-border-primary));}.lsd-dropdown--underlined .lsd-dropdown__button-container{border:1px solid transparent;border-bottom:1px solid rgb(var(--lsd-border-primary));}

    Waku v2 Update

    by
    8 min read

    A research log. Read on to find out what is going on with Waku v2, a messaging protocol. What has been happening? What is coming up next?

    It has been a while since the last post. It is time for an update on Waku v2. Aside from getting more familiar with libp2p (specifically nim-libp2p) and some vacation, what have we been up to? In this post we'll talk about what we've gotten done since last time, and briefly talk about immediate next steps and future. But first, a recap.

    Recap

    In the last post (Waku v2 plan) we explained the rationale of Waku v2 - the current Waku network is fragile and doesn't scale. To solve this, Waku v2 aims to reduce amplification factors and get more user run nodes. We broke the work down into three separate tracks.

    1. Track 1 - Move to libp2p
    2. Track 2 - Better routing
    3. Track 3 - Accounting and user-run nodes

    As well as various rough components for each track. The primary initial focus is track 1. This means things like: moving to FloodSub, simplify the protocol, core integration, topic interest behavior, historical message caching, and Waku v1<>v2 bridge.

    Current state

    Let's talk about the state of specs and our main implementation nim-waku. Then we'll go over our recent testnet, Nangang, and finish off with a Web PoC.

    Specs

    After some back and forth on how to best structure things, we ended up breaking down the specs into a few pieces. While Waku v2 is best thought of as a cohesive whole in terms of its capabilities, it is made up of several protocols. Here's a list of the current specs and their status:

    Raw means there is not yet an implementation that corresponds fully to the spec, and draft means there is an implementation that corresponds to the spec. In the interest of space, we won't go into too much detail on the specs here except to note a few things:

    • The relay spec is essentially a thin wrapper on top of PubSub/FloodSub/GossipSub
    • The filter protocol corresponds to previous light client mode in Waku v1
    • The store protocol corresponds to the previous mailserver construct in Waku v1

    The filter and store protocol allow for adaptive nodes, i.e. nodes that have various capabilities. For example, a node being mostly offline, or having limited bandwidth capacity. The bridge spec outlines how to bridge the Waku v1 and v2 networks.

    Implementation

    The main implementation we are working on is nim-waku. This builds on top of libraries such as nim-libp2p and others that the Nimbus team have been working on as part of their Ethereum 2.0 client.

    Currently nim-waku implements the relay protocol, and is close to implementing filter and store protocol. It also exposes a Nim Node API that allows libraries such as nim-status to use it. Additionally, there is also a rudimentary JSON RPC API for command line scripting.

    Nangang testnet

    Last week we launched a very rudimentary internal testnet called Nangang. The goal was to test basic connectivity and make sure things work end to end. It didn't have things like: client integration, encryption, bridging, multiple clients, store/filter protocol, or even a real interface. What it did do is allow Waku developers to "chat" via RPC calls and looking in the log output. Doing this meant we exposed and fixed a few blockers, such as connection issues, deployment, topic subscription management, protocol and node integration, and basic scripting/API usage. After this, we felt confident enough to upgrade the main and relay spec to "draft" status.

    Waku Web PoC

    As a bonus, we wanted to see what it'd take to get Waku running in a browser. This is a very powerful capability that enables a lot of use cases, and something that libp2p enables with its multiple transport support.

    Using the current stack, with nim-waku, would require quite a lot of ground work with WASM, WebRTC, Websockets support etc. Instead, we decided to take a shortcut and hack together a JS implementation called Waku Web Chat. This quick hack wouldn't be possible without the people behind js-libp2p-examples and js-libp2p and all its libraries. These are people like Jacob Heun, Vasco Santos, and Cayman Nava. Thanks!

    It consists of a brower implementation, a NodeJS implementation and a bootstrap server that acts as a signaling server for WebRTC. It is largely a bastardized version of GossipSub, and while it isn't completely to spec, it does allow messages originating from a browser to eventually end up at a nim-waku node, and vice versa. Which is pretty cool.

    Coming up

    Now that we know what the current state is, what is still missing? what are the next steps?

    Things that are missing

    While we are getting closer to closing out work for track 1, there are still a few things missing from the initial scope:

    1. Store and filter protocols need to be finished. This means basic spec, implementation, API integration and proven to work in a testnet. All of these are work in progress and expected to be done very soon. Once the store protocol is done in a basic form, it needs further improvements to make it production ready, at least on a spec/basic implementation level.

    2. Core integration was mentioned in scope for track 1 initially. This work has stalled a bit, largely due to organizational bandwidth and priorities. While there is a Nim Node API that in theory is ready to be used, having it be used in e.g. Status desktop or mobile app is a different matter. The team responsible for this at Status (status-nim has been making progress on getting nim-waku v1 integrated, and is expected to look into nim-waku v2 integration soon. One thing that makes this a especially tricky is the difference in interface between Waku v1 and v2, which brings us too...

    3. Companion spec for encryption. As part of simplifying the protocol, the routing is decoupled from the encryption in v2 (1, 2). There are multiple layers of encryption at play here, and we need to figure out a design that makes sense for various use cases (dapps using Waku on their own, Status app, etc).

    4. Bridge implementation. The spec is done and we know how it should work, but it needs to be implemented.

    5. General tightening up of specs and implementation.

    While this might seem like a lot, a lot has been done already, and the majority of the remaining tasks are more amendable to be pursued in parallel with other efforts. It is also worth mentioning that part of track 2 and 3 have been started, in the form of moving to GossipSub (amplification factors) and basics of adaptive nodes (multiple protocols). This is in addition to things like Waku Web which were not part of the initial scope.

    Upcoming

    Aside from the things mentioned above, what is coming up next? There are a few areas of interest, mentioned in no particular order. For track 2 and 3, see previous post for more details.

    1. Better routing (track 2). While we are already building on top of GossipSub, we still need to explore things like topic sharding in more detail to further reduce amplification factors.

    2. Accounting and user-run nodes (track 3). With store and filter protocol getting ready, we can start to implement accounting and light connection game for incentivization in a bottom up and iterative manner.

    3. Privacy research. Study better and more rigorous privacy guarantees. E.g. how FloodSub/GossipSub behaves for common threat models, and how custom packet format can improve things like unlinkability.

    4. zkSnarks RLN for spam protection and incentivization. We studied this last year and recent developments have made this relevant to study again. Create an experimental spec/PoC as an extension to the relay protocol. Kudos to Barry Whitehat and others like Kobi Gurkan and Koh Wei Jie for pushing this!

    5. Ethereum M2M messaging. Being able to run in the browser opens up a lot of doors, and there is an opportunity here to enable things like a decentralized WalletConnect, multi-sig transactions, voting and similar use cases. This was the original goal of Whisper, and we'd like to deliver on that.

    As you can tell, quite a lot of thing! Luckily, we have two people joining as protocol engineers soon, which will bring much needed support for the current team of ~2-2.5 people. More details to come in further updates.


    If you are feeling adventurous and want to use early stage alpha software, check out the docs. If you want to read the specs, head over to Waku spec. If you want to talk with us, join us on Status or on Telegram (they are bridged).

    - - + + \ No newline at end of file diff --git a/rlog/wakuv2-apd/index.html b/rlog/wakuv2-apd/index.html index 927dbdd5..ced065f8 100644 --- a/rlog/wakuv2-apd/index.html +++ b/rlog/wakuv2-apd/index.html @@ -10,8 +10,8 @@ - - + +
    @@ -159,7 +159,7 @@ As an outlook we can already state that DHT approaches typically allow inferring Further, sending peer lists allows inferring the position of a node within the mesh, and by extension information about the node. Waku v2 already provides some mitigation, because the mesh for transmitting actual messages, and the peer discovery network are separate. To mitigate information leakage by transmitting peer lists, we plan to only reply with lists of peers that nodes do not use in their active meshes.


    References

    - - + + \ No newline at end of file diff --git a/rlog/wakuv2-noise/index.html b/rlog/wakuv2-noise/index.html index b4c1ca0a..91f9101b 100644 --- a/rlog/wakuv2-noise/index.html +++ b/rlog/wakuv2-noise/index.html @@ -10,8 +10,8 @@ - - + +
    @@ -22,7 +22,7 @@ ) .lsd-dropdown__trigger:focus .lsd-dropdown__option-label{-webkit-text-decoration:underline;text-decoration:underline;}.lsd-dropdown__label{display:block;}.lsd-dropdown__button-container{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-box-pack:justify;-webkit-justify-content:space-between;justify-content:space-between;}.lsd-dropdown__trigger{width:100%;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:row;-ms-flex-direction:row;flex-direction:row;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:justify;-webkit-justify-content:space-between;justify-content:space-between;border:none;cursor:pointer;background:none;}.lsd-dropdown__trigger:focus{outline:none;}.lsd-dropdown__option-label{cursor:inherit;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;}.lsd-dropdown__icons{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:row;-ms-flex-direction:row;flex-direction:row;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:center;-ms-flex-pack:center;-webkit-justify-content:center;justify-content:center;gap:8px;}.lsd-dropdown__icon{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;}.lsd-dropdown__supporting-text{margin:6px 14px;}.lsd-dropdown--error .lsd-dropdown__option-label{-webkit-text-decoration:line-through;text-decoration:line-through;}.lsd-dropdown--disabled{opacity:0.34;cursor:initial;}.lsd-dropdown--large{width:208px;}.lsd-dropdown--large.lsd-dropdown--error{width:230px;}.lsd-dropdown--large .lsd-dropdown__label{margin:0 0 6px 18px;}.lsd-dropdown--large .lsd-dropdown__button-container{height:40px;}.lsd-dropdown--large .lsd-dropdown__trigger{padding:10px 0px 10px 18px;}.lsd-dropdown--large .lsd-dropdown__icons{padding:0px 14px;}.lsd-dropdown--medium{width:188px;}.lsd-dropdown--medium.lsd-dropdown--error{width:210px;}.lsd-dropdown--medium .lsd-dropdown__label{margin:0 0 6px 14px;}.lsd-dropdown--medium .lsd-dropdown__button-container{height:32px;}.lsd-dropdown--medium .lsd-dropdown__trigger{padding:6px 0px 6px 14px;}.lsd-dropdown--medium .lsd-dropdown__icons{padding:0px 12px;}.lsd-dropdown--small{width:164px;}.lsd-dropdown--small.lsd-dropdown--error{width:186px;}.lsd-dropdown--small .lsd-dropdown__label{margin:0 0 6px 12px;}.lsd-dropdown--small .lsd-dropdown__button-container{height:28px;}.lsd-dropdown--small .lsd-dropdown__trigger{padding:6px 0px 6px 12px;}.lsd-dropdown--small .lsd-dropdown__icons{padding:0px 10px;}.lsd-dropdown--outlined .lsd-dropdown__button-container{border:1px solid rgb(var(--lsd-border-primary));}.lsd-dropdown--underlined .lsd-dropdown__button-container{border:1px solid transparent;border-bottom:1px solid rgb(var(--lsd-border-primary));}

    Noise handshakes as key-exchange mechanism for Waku

    by
    22 min read

    We provide an overview of the Noise Protocol Framework as a tool to design efficient and secure key-exchange mechanisms in Waku2.

    Introduction

    In this post we will provide an overview of how Waku v2 users can adopt Noise handshakes to agree on cryptographic keys used to securely encrypt messages.

    This process belongs to the class of key-exchange mechanisms, consisting of all those protocols that, with different levels of complexity and security guarantees, allow two parties to publicly agree on a secret without letting anyone else know what this secret is.

    But why do we need key-exchange mechanisms in the first place?

    With the advent of public-key cryptography, it become possible to decouple encryption from decryption through use of two distinct cryptographic keys: one public, used to encrypt information and that can be made available to anyone, and one private (kept secret), which enables decryption of messages encrypted with its corresponding public key. The same does not happen in the case of symmetric encryption schemes where, instead, the same key is used for both encryption and decryption operations and hence cannot be publicly revealed as for public keys.

    In order to address specific application needs, many different public, symmetric and hybrid cryptographic schemes were designed: Waku v1 and Waku v2, which inherits part of their design from the Ethereum messaging protocol Whisper, provide support to both public-key primitives (ECIES, ECDSA) and symmetric primitives (AES-256-GCM, KECCAK-256), used to sign, hash, encrypt and decrypt exchanged messages.

    In principle, when communications employ public-key based encryption schemes (ECIES, in the case of Waku), there is no need for a key-agreement among parties: messages can be directly encrypted using the recipient's public-key before being sent over the network. However, public-key encryption and decryption primitives are usually very inefficient in processing large amount of data, and this may constitute a bottleneck for many of today's applications. Symmetric encryption schemes such as AES-256-GCM, on the other hand, are much more efficient, but the encryption/decryption key needs to be shared among users beforehand any encrypted messages is exchanged.

    To counter the downsides given by each of these two approaches while taking advantage of their strengths, hybrid constructions were designed. In these, public-key primitives are employed to securely agree on a secret key which, in turn, is used with a symmetric cipher for encrypting messages. In other words, such constructions specify a (public-key based) key-agreement mechanism!

    Waku, up to payload version 1, does not implement nor recommend any protocol for exchanging symmetric ciphers' keys, leaving such task to the application layer. It is important to note that the kind of key-agreement employed has a direct impact on the security properties that can be granted on later encrypted messages, while security requirements usually depend on the specific application for which encryption is needed in the first place.

    In this regard, Status, which builds on top of Waku, implements a custom version of the X3DH key-agreement protocol, in order to allow users to instantiate end-to-end encrypted communication channels. However, although such a solution is optimal when applied to (distributed) E2E encrypted chats, it is not flexible enough to fit or simplify the variety of applications Waku aims to address. Hence, proposing and implementing one or few key-agreements which provide certain (presumably strong) security guarantees, would inevitably degrade performances of all those applications for which, given their security requirements, more tailored and efficient key-exchange mechanisms can be employed.

    Guided by different examples, in the following sections we will overview Noise, a protocol framework we are currently integrating in Waku, for building secure key-agreements between two parties. One of the great advantage of using Noise is that it is possible to add support to new key-exchanges by just specifying users' actions from a predefined list, requiring none to minimal modifications to existing implementations. Furthermore, Noise provides a framework to systematically analyze protocols' security properties and the corresponding attacker threat models. This allows not only to easily design new key-agreements eventually optimized for specific applications we want to address, but also to easily analyze or even formally verify any of such custom protocol!

    We believe that with its enormous flexibility and features, Noise represents a perfect candidate for bringing key-exchange mechanisms in Waku.

    The Diffie-Hellman Key-exchange

    The formalization of modern public-key cryptography started with the pioneering work of Whitefield Diffie and Martin Hellman, who detailed one of the earliest known key-agreement protocols: the famous Diffie-Hellman Key-Exchange.

    Diffie-Hellman (DH) key-exchange is largely used today and represents the main cryptographic building block on which Noise handshakes' security is based.

    In turn, the security of DH is based on a mathematical problem called discrete logarithm which is believed to be hard when the agreement is practically instantiated using certain elliptic curves EE defined over finite fields Fp\mathbb{F}_p.

    Informally, a DH exchange between Alice and Bob proceeds as follows:

    • Alice picks a secret scalar sAFps_A\in\mathbb{F}_p and computes, using the underlying curve's arithmetic, the point PA=sAPE(Fp)P_A = s_A\cdot P\in E(\mathbb{F}_p) for a certain pre-agreed public generator PP of the elliptic curve E(Fp)E(\mathbb{F}_p). She then sends PAP_A to Bob.
    • Similarly, Bob picks a secret scalar sBFps_B\in\mathbb{F}_p, computes PB=sBPE(Fp)P_B = s_B\cdot P\in E(\mathbb{F}_p) and sends PBP_B to Alice.
    • By commutativity of scalar multiplication, both Alice and Bob can now compute the point PAB=sAsBPP_{AB} = s_As_B\cdot P, using the elliptic curve point received from the other party and their secret scalar.

    The assumed hardness of computing discrete logarithms in the elliptic curve, ensures that it is not possible to compute sAs_A or sBs_B from PAP_A and PBP_B, respectively. Another security assumption (named Computational Diffie-Hellman assumption) ensures that it is not possible to compute PABP_{AB} from PP, PAP_A and PBP_B. Hence the point PABP_{AB} shared by Alice and Bob at the end of the above protocol cannot be efficiently computed by an attacker intercepting PAP_A and PBP_B, and can then be used to generate a secret to be later employed, for example, as a symmetric encryption key.

    On a side note, this protocol shows the interplay between two components typical to public-key based schemes: the scalars sAs_A and sBs_B can be seen as private keys associated to the public keys PAP_A and PBP_B, respectively, which allow Alice and Bob only to compute the shared secret point PABP_{AB}.

    Ephemeral and Static Public Keys

    Although we assumed that it is practically impossible for an attacker to compute the randomly picked secret scalar from the corresponding public elliptic curve point, it may happen that such scalar gets compromised or can be guessed due to a faulty employed random number generator. In such cases, an attacker will be able to recover the final shared secret and all encryption keys eventually derived from that, with clear catastrophic consequences for the privacy of exchanged messages.

    To mitigate such issues, multiple DH operations can be combined using two different types of exchanged elliptic curve points or, better, public keys: ephemeral keys, that is random keys used only once in a DH operation, and long-term static keys, used mainly for authentication purposes since employed multiple times.

    Just to provide an example, let us suppose Alice and Bob perform the following custom DH-based key-exchange protocol:

    • Alice generates an ephemeral key EA=eAPE_A=e_A\cdot P by picking a random scalar eAe_A and sends EAE_A to Bob;
    • Similarly, Bob generates an ephemeral key EB=eBPE_B=e_B\cdot P and sends EBE_B to Alice;
    • Alice and Bob computes EAB=eAeBPE_{AB} = e_Ae_B \cdot P and from it derive a secret encryption key kk.
    • Bob sends to Alice his static key SB=sBPS_B = s_B\cdot P encrypted with kk.
    • Alice encrypts with kk her static key SA=sAPS_A = s_A\cdot P and sends it to Bob.
    • Alice and Bob decrypt the received static keys, compute the secret SAB=sAsBPS_{AB} = s_As_B \cdot P and use it together with EABE_{AB} to derive a new encryption key k~\tilde{k} to be later used with a symmetric cipher.

    In this protocol, if Alice's and/or Bob's static keys get compromised, it would not possible to derive the final secret key k~\tilde{k}, since at least one ephemeral key among EAE_A and EBE_B has to be compromised too in order to recover the secret EABE_{AB}. Furthermore, since Alice's and Bob's long-term static keys are encrypted, an attacker intercepting exchanged (encrypted) public keys will not be able to link such communication to Alice or Bob, unless one of the ephemeral key is compromised (and, even in such case, none of the messages encrypted under the key k~\tilde{k} can be decrypted).

    The Noise Protocol Framework

    In previous section we gave a small intuition on how multiple DH operations over ephemeral and static users' public keys can be combined to create different key-exchange protocols.

    The Noise Protocol Framework, defines various rules for building custom key-exchange protocols while allowing easy analysis of the security properties and threat models provided given the type and order of the DH operations employed.

    In Noise terminology, a key-agreement or Noise protocol consists of one or more Noise handshakes. During a Noise handshake, Alice and Bob exchange multiple (handshake) messages containing their ephemeral keys and/or static keys. These public keys are then used to perform a handshake-dependent sequence of Diffie-Hellman operations, whose results are all hashed into a shared secret key. Similarly as we have seen above, after a handshake is complete, each party will use the derived secret key to send and receive authenticated encrypted data by employing a symmetric cipher.

    Depending on the handshake pattern adopted, different security guarantees can be provided on messages encrypted using a handshake-derived key.

    The Noise handshakes we support in Waku all provide the following security properties:

    • Confidentiality: the adversary should not be able to learn what data is being sent between Alice and Bob.
    • Strong forward secrecy: an active adversary cannot decrypt messages nor infer any information on the employed encryption key, even in the case he has access to Alice's and Bob's long-term private keys (during or after their communication).
    • Authenticity: the adversary should not be able to cause either Alice or Bob to accept messages coming from a party different than their original senders.
    • Integrity: the adversary should not be able to cause Alice or Bob to accept data that has been tampered with.
    • Identity-hiding: once a secure communication channel is established, a passive adversary should not be able to link exchanged encrypted messages to their corresponding sender and recipient by knowing their long-term static keys.

    We refer to Noise specification for more formal security definitions and precise threat models relative to Waku supported Noise Handshake patterns.

    Message patterns

    Noise handshakes involving DH operations over ephemeral and static keys can be succinctly sketched using the following set of handshake message tokens: e,s,ee,se,es,ss.

    Tokens employing single letters denote (the type of) users' public keys: e refers to randomly generated ephemeral key(s), while s indicates the users' long-term static key(s).

    Two letters tokens, instead, denotes DH operations over the two users' public keys the token refers to, given that the left token letter refers to the handshake initiator's public key, while the right token letter indicates the used responder's public key. Thus, if Alice started a handshake with Bob, the es token will shortly represent a DH operation among Alice's ephemeral key e and Bob's static key s.

    Since, in order to perform any DH operations users need to share (or pre-share) the corresponding public keys, Noise compactly represents messages' exchanges using the two direction -> and <-, where the -> denotes a message (arbitrary and/or DH public key) from the initiator to the responder, while <- the opposite.

    Hence a message pattern consisting of a direction and one or multiple tokens such as <- e, s, es has to be interpreted one token at a time: in this example, the responder is sending his ephemeral and static key to the initiator and is then executing a DH operation over the initiator's ephemeral key e (shared in a previously exchanged message pattern) and his static key s. On the other hand, such message indicates also that the initiator received the responder's ephemeral and static keys e and s, respectively, and performed a DH operation over his ephemeral key and the responder's just received static key s. In this way, both parties will be able to derive at the end of each message pattern processed the same shared secret, which is eventually used to update any derived symmetric encryption keys computed so far.

    In some cases, DH public keys employed in a handshake are pre-shared before the handshake itself starts. In order to chronologically separate exchanged keys and DH operations performed before and during a handshake, Noise employs the ... delimiter.

    For example, the following message patterns

    <- e
    ...
    -> e, ee

    indicates that the initiator knew the responder's ephemeral key before he sends his own ephemeral key and executes a DH operation between both parties ephemeral keys (similarly, the responder receives the initiator's ephemeral key and does a ee DH operation).

    At this point it should be clear how such notation is able to compactly represent a large variety of DH based key-agreements. Nevertheless, we can easily define additional tokens and processing rules in order to address specific applications and security requirements, such as the psk token used to process arbitrary pre-shared key material.

    As an example of Noise flexibility, the custom protocol we detailed above can be shortly represented as (Alice is on the left):

    -> e
    <- e, ee, s
    -> s, ss

    where after each DH operation an encryption key is derived (along with the secrets computed by all previously executed DH operations) in order to encrypt/decrypt any subsequent sent/received message.

    Another example is given by the possibility to replicate within Noise the well established Signal's X3DH key-agreement protocols, thus making the latter a general framework to design and study security of many practical and widespread DH-based key-exchange protocols.

    The Noise State Objects

    We mentioned multiple times that parties derive an encryption key each time they perform a DH operation, but how does this work in more details?

    Noise defines three state object: a Handshake State, a Symmetric State and a Cipher State, each encapsulated into each other and instantiated during the execution of a handshake.

    The Handshake State object stores the user's and other party's received ephemeral and static keys (if any) and embeds a Symmetric State object.

    The Symmetric State, instead, stores a handshake hash value h, iteratively updated with any message read/received and DH secret computed, and a chaining key ck, updated using a key derivation function every time a DH secret is computed. This object further embeds a Cipher State.

    Lastly, the Cipher State stores a symmetric encryption k key and a counter n used to encrypt and decrypt messages exchanged during the handshake (not only static keys, but also arbitrary payloads). These key and counter are refreshed every time the chaining key is updated.

    While processing each handshake's message pattern token, all these objects are updated according to some specific processing rules which employ a combination of public-key primitives, hash and key-derivation functions and symmetric ciphers. It is important to note, however, that at the end of each processed message pattern, the two users will share the same Symmetric and Cipher State embedded in their respective Handshake States.

    Once a handshake is complete, users derive two new Cipher States and can then discard the Handshake State object (and, thus, the embedded Symmetric State and Cipher State objects) employed during the handshake.

    These two Cipher states are used to encrypt and decrypt all outbound and inbound after-handshake messages, respectively, and only to these will be granted the confidentiality, authenticity, integrity and identity-hiding properties we detailed above.

    For more details on processing rules, we refer to Noise specifications.

    Supported Noise Handshakes in Waku

    The Noise handshakes we provided support to in Waku address four typical scenarios occurring when an encrypted communication channel between Alice and Bob is going to be created:

    • Alice and Bob know each others' static key.
    • Alice knows Bob's static key;
    • Alice and Bob share no key material and they don't know each others' static key.
    • Alice and Bob share some key material, but they don't know each others' static key.

    The possibility to have handshakes based on the reciprocal knowledge parties have of each other, allows designing Noise handshakes that can quickly reach the desired level of security on exchanged encrypted messages while keeping the number of interactions between Alice and Bob minimum.

    Nonetheless, due to the pure token-based nature of handshake processing rules, implementations can easily add support to any custom handshake pattern with minor modifications, in case more specific application use-cases need to be addressed.

    On a side note, we already mentioned that identity-hiding properties can be guaranteed against a passive attacker that only reads the communication occurring between Alice and Bob. However, an active attacker who compromised one party's static key and actively interferes with the parties' exchanged messages, may lower the identity-hiding security guarantees provided by some handshake patterns. In our security model we exclude such adversary, but, for completeness, in the following we report a summary of possible de-anonymization attacks that can be performed by such an active attacker.

    For more details on supported handshakes and on how these are implemented in Waku, we refer to 35/WAKU2-NOISE RFC.

    The K1K1 Handshake

    If Alice and Bob know each others' static key (e.g., these are public or were already exchanged in a previous handshake) , they MAY execute a K1K1 handshake. In Noise notation (Alice is on the left) this can be sketched as:

     K1K1:
    -> s
    <- s
    ...
    -> e
    <- e, ee, es
    -> se

    We note that here only ephemeral keys are exchanged. This handshake is useful in case Alice needs to instantiate a new separate encrypted communication channel with Bob, e.g. opening multiple parallel connections, file transfers, etc.

    Security considerations on identity-hiding (active attacker): no static key is transmitted, but an active attacker impersonating Alice can check candidates for Bob's static key.

    The XK1 Handshake

    Here, Alice knows how to initiate a communication with Bob and she knows his public static key: such discovery can be achieved, for example, through a publicly accessible register of users' static keys, smart contracts, or through a previous public/private advertisement of Bob's static key.

    A Noise handshake pattern that suits this scenario is XK1:

     XK1:
    <- s
    ...
    -> e
    <- e, ee, es
    -> s, se

    Within this handshake, Alice and Bob reciprocally authenticate their static keys s using ephemeral keys e. We note that while Bob's static key is assumed to be known to Alice (and hence is not transmitted), Alice's static key is sent to Bob encrypted with a key derived from both parties ephemeral keys and Bob's static key.

    Security considerations on identity-hiding (active attacker): Alice's static key is encrypted with forward secrecy to an authenticated party. An active attacker initiating the handshake can check candidates for Bob's static key against recorded/accepted exchanged handshake messages.

    The XX and XXpsk0 Handshakes

    If Alice is not aware of any static key belonging to Bob (and neither Bob knows anything about Alice), she can execute an XX handshake, where each party tranXmits to the other its own static key.

    The handshake goes as follows:

     XX:
    -> e
    <- e, ee, s, es
    -> s, se

    We note that the main difference with XK1 is that in second step Bob sends to Alice his own static key encrypted with a key obtained from an ephemeral-ephemeral Diffie-Hellman exchange.

    This handshake can be slightly changed in case both Alice and Bob pre-shares some secret psk which can be used to strengthen their mutual authentication during the handshake execution. One of the resulting protocol, called XXpsk0, goes as follow:

     XXpsk0:
    -> psk, e
    <- e, ee, s, es
    -> s, se

    The main difference with XX is that Alice's and Bob's static keys, when transmitted, would be encrypted with a key derived from psk as well.

    Security considerations on identity-hiding (active attacker): Alice's static key is encrypted with forward secrecy to an authenticated party for both XX and XXpsk0 handshakes. In XX, Bob's static key is encrypted with forward secrecy but is transmitted to a non-authenticated user which can then be an active attacker. In XXpsk0, instead, Bob's secret key is protected by forward secrecy to a partially authenticated party (through the pre-shared secret psk but not through any static key), provided that psk was not previously compromised (in such case identity-hiding properties provided by the XX handshake applies).

    Session Management and Multi-Device Support

    When two users complete a Noise handshake, an encryption/decryption session - or Noise session - consisting of two Cipher States is instantiated.

    By identifying Noise session with a session-id derived from the handshake's cryptographic material, we can take advantage of the PubSub/GossipSub protocols used by Waku for relaying messages in order to manage instantiated Noise sessions.

    The core idea is to exchange after-handshake messages (encrypted with a Cipher State specific to the Noise session), over a content topic derived from the (secret) session-id the corresponding session refers to.

    This allows to decouple the handshaking phase from the actual encrypted communication, thus improving users' identity-hiding capabilities.

    Furthermore, by publicly revealing a value derived from session-id on the corresponding session content topic, a Noise session can be marked as stale, enabling peers to save resources by discarding any eventually stored message sent to such content topic.

    One relevant aspect in today's applications is the possibility for users to employ different devices in their communications. In some cases, this is non-trivial to achieve since, for example, encrypted messages might be required to be synced on different devices which do not necessarily share the necessary key material for decryption and may be temporarily offline.

    We address this by requiring each user's device to instantiate multiple Noise sessions either with all user's other devices which, in turn, all together share a Noise session with the other party, or by directly instantiating a Noise session with all other party's devices.

    We named these two approaches N11MN11M and NMNM, respectively, which are in turn loosely based on the paper “Multi-Device for Signal” and Signal’s Sesame Algorithm.

    Informally, in the N11MN11M session management scheme, once the first Noise session between any of Alice’s and Bob’s device is instantiated, its session information is securely propagated to all other devices using previously instantiated Noise sessions. Hence, all devices are able to send and receive new messages on the content topic associated to such session.

    In the NMNM session management scheme, instead, all pairs of Alice's and Bob's devices have a distinct Noise session: a message is then sent from the currently-in-use sender’s device to all recipient’s devices, by properly encrypting and sending it to the content topics of each corresponding Noise session. If sent messages should be available on all sender’s devices as well, we require each pair of sender’s devices to instantiate a Noise session used for syncing purposes.

    For more technical details on how Noise sessions are instantiated and managed within these two mechanisms and the different trade-offs provided by the latter, we refer to 37/WAKU2-NOISE-SESSIONS.

    Conclusions

    In this post we provided an overview of Noise, a protocol framework for designing Diffie-Hellman based key-exchange mechanisms allowing systematic security and threat model analysis.

    The flexibility provided by Noise components allows not only to fully replicate with same security guarantees well established key-exchange primitives such as X3DH, currently employed by Status 5/TRANSPORT-SECURITY, but enables also optimizations based on the reciprocal knowledge parties have of each other while allowing easier protocols' security analysis and (formal) verification.

    Furthermore, different handshakes can be combined and executed one after each other, a particularly useful feature to authenticate multiple static keys employed by different applications but also to ease keys revocation.

    The possibility to manage Noise sessions over multiple devices and the fact that handshakes can be concretely instantiated using modern, fast and secure cryptographic primitives such as ChaChaPoly and BLAKE2b, make Noise one of the best candidates for efficiently and securely address the many different needs of applications built on top of Waku requiring key-agreement.

    Future steps

    The available implementation of Noise in nwaku, although mostly complete, is still in its testing phase. As future steps we would like to:

    • have an extensively tested and robust Noise implementation;
    • formalize, implement and test performances of the two proposed N11MN11M and NMNM session management mechanisms and their suitability for common use-case scenarios;
    • provide Waku network nodes a native protocol to readily support key-exchanges, strongly-encrypted communication and multi-device session management mechanisms with none-to-little interaction besides applications' connection requests.

    References

    - - + + \ No newline at end of file diff --git a/rlog/wakuv2-relay-anon/index.html b/rlog/wakuv2-relay-anon/index.html index ca1d82dc..caff5f75 100644 --- a/rlog/wakuv2-relay-anon/index.html +++ b/rlog/wakuv2-relay-anon/index.html @@ -10,8 +10,8 @@ - - + +
    @@ -146,7 +146,7 @@ As an intermediate step, we might directly employ Tor for onion-routing, and
    • 13/WAKU2-STORE, which can violate receiver anonymity as it allows filtering by content topic. A countermeasure is using the content topic exclusively for local filters.
    • 12/WAKU2-FILTER, which discloses nodes' interest in topics;
    • 19/WAKU2-LIGHTPUSH, which also discloses nodes' interest in topics and links the lightpush client as the sender of a message to the lightpush service node;
    • 21/WAKU2-FTSTORE, which discloses nodes' interest in specific time ranges allowing to infer information like online times.

    While these protocols are not necessary for the operation of Waku v2, and can be seen as pluggable features, we aim to provide alternatives without the cost of lowering the anonymity level.

    References

    - - + + \ No newline at end of file diff --git a/rlog/wechat-replacement-need/index.html b/rlog/wechat-replacement-need/index.html index 9669e841..44feea9d 100644 --- a/rlog/wechat-replacement-need/index.html +++ b/rlog/wechat-replacement-need/index.html @@ -10,8 +10,8 @@ - - + +
    @@ -20,7 +20,7 @@ ) .lsd-dropdown__trigger:hover .lsd-dropdown__option-label,.lsd-dropdown:not(.lsd-dropdown--disabled):not( .lsd-dropdown--error ) .lsd-dropdown__trigger:focus .lsd-dropdown__option-label{-webkit-text-decoration:underline;text-decoration:underline;}.lsd-dropdown__label{display:block;}.lsd-dropdown__button-container{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-box-pack:justify;-webkit-justify-content:space-between;justify-content:space-between;}.lsd-dropdown__trigger{width:100%;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:row;-ms-flex-direction:row;flex-direction:row;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:justify;-webkit-justify-content:space-between;justify-content:space-between;border:none;cursor:pointer;background:none;}.lsd-dropdown__trigger:focus{outline:none;}.lsd-dropdown__option-label{cursor:inherit;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;}.lsd-dropdown__icons{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:row;-ms-flex-direction:row;flex-direction:row;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:center;-ms-flex-pack:center;-webkit-justify-content:center;justify-content:center;gap:8px;}.lsd-dropdown__icon{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;}.lsd-dropdown__supporting-text{margin:6px 14px;}.lsd-dropdown--error .lsd-dropdown__option-label{-webkit-text-decoration:line-through;text-decoration:line-through;}.lsd-dropdown--disabled{opacity:0.34;cursor:initial;}.lsd-dropdown--large{width:208px;}.lsd-dropdown--large.lsd-dropdown--error{width:230px;}.lsd-dropdown--large .lsd-dropdown__label{margin:0 0 6px 18px;}.lsd-dropdown--large .lsd-dropdown__button-container{height:40px;}.lsd-dropdown--large .lsd-dropdown__trigger{padding:10px 0px 10px 18px;}.lsd-dropdown--large .lsd-dropdown__icons{padding:0px 14px;}.lsd-dropdown--medium{width:188px;}.lsd-dropdown--medium.lsd-dropdown--error{width:210px;}.lsd-dropdown--medium .lsd-dropdown__label{margin:0 0 6px 14px;}.lsd-dropdown--medium .lsd-dropdown__button-container{height:32px;}.lsd-dropdown--medium .lsd-dropdown__trigger{padding:6px 0px 6px 14px;}.lsd-dropdown--medium .lsd-dropdown__icons{padding:0px 12px;}.lsd-dropdown--small{width:164px;}.lsd-dropdown--small.lsd-dropdown--error{width:186px;}.lsd-dropdown--small .lsd-dropdown__label{margin:0 0 6px 12px;}.lsd-dropdown--small .lsd-dropdown__button-container{height:28px;}.lsd-dropdown--small .lsd-dropdown__trigger{padding:6px 0px 6px 12px;}.lsd-dropdown--small .lsd-dropdown__icons{padding:0px 10px;}.lsd-dropdown--outlined .lsd-dropdown__button-container{border:1px solid rgb(var(--lsd-border-primary));}.lsd-dropdown--underlined .lsd-dropdown__button-container{border:1px solid transparent;border-bottom:1px solid rgb(var(--lsd-border-primary));}

    What Would a WeChat Replacement Need?

    by
    26 min read

    What would a self-sovereign, private, censorship-resistant and open alternative to WeChat look like?

    What would it take to replace WeChat? More specifically, what would a self-sovereign, private, censorship-resistant and open alternative look like? One that allows people to communicate, coordinate and transact freely.

    Background

    What WeChat provides to the end-user

    Let's first look at some of the things that WeChat providers. It is a lot:

    • Messaging: 1:1 and group chat. Text, as well as voice and video. Post gifs. Share location.
    • Group chat: Limited to 500 people; above 100 people people need to verify with a bank account. Also has group video chat and QR code to join a group.
    • Timeline/Moments: Post comments with attachments and have people like/comment on it.
    • Location Discovery: See WeChat users that are nearby.
    • Profile: Nickname and profile picture; can alias people.
    • "Broadcast" messages: Send one message to many contacts, up to 200 people (spam limited).
    • Contacts: Max 5000 contacts (people get around it with multiple accounts and sim cards).
    • App reach: Many diferent web apps, extensions, native apps, etc. Scan QR code to access web app from phone.
    • Selective posting: Decide who can view your posts and who can view your comments on other people's post.
    • Transact: Send money gifts through red envelopes.
    • Transact: Use WeChat pay to transfer money to friends and businesses; linked account with Alipay that is connected to your bank account.
    • Services: Find taxis and get notifications; book flights, train tickets, hotels etc.
    • Mini apps: API for all kinds of apps that allow you to provide services etc.
    • Picture in picture: allowing you to have a video call while using the app.

    And much more. Not going to through it all in detail, and there are probably many things I don't know about WeChat since I'm not a heavy user living in mainland China.

    How WeChat works - a toy model

    This is an overly simplistic model of how WeChat works, but it is sufficient for our purposes. This general design applies to most traditional client-server apps today.

    To sign up for account you need a phone number or equivalent. To get access to some features you need to verify your identity further, for example with official ID and/or bank account.

    When you signup this creates an entry in the WeChat server, from now on treated as a black box. You authenticate with that box, and thats where you get your messages from. If you go online the app asks that box for messages you have received while you were offline. If you login from a different app your contacts and conversations are synced from that box.

    The box gives you an account, it deals with routing to your contacts, it stores messages and attachments and gives access to mini apps that people have uploaded. For transacting money, there is a partnership with a different company that has a different box which talks to your bank account.

    This is done in a such a way that they can support a billion users with the features above, no sweat.

    Whoever controls that box can sees who you are talking with and what the content of those messages are. There is no end to end encryption. If WeChat/Tencent disagrees with you for some reason they can ban you. This means you can't interact with the box under that name anymore.

    What do we want?

    We want something that is self-sovereign, private, censorship-resistant and open that allows individuals and groups of people to communicate and transact freely. To explore what this means in more detail, without getting lost in the weeds, we provide the following list of properties. A lot of these are tied together, and some fall out of the other requirements. Some of them stand in slight opposition to each other.

    Self-sovereignity identity. Exercises authority within your own sphere. If you aren't harming anyone, you should be able to have an account and communicate with other people.

    Pseudonymity, and ideally total anonymity. Not having your identity tied to your real name (e.g. through phone number, bank account, ID, etc). This allows people to act more freely without being overly worried about censorship and coercion in the real world. While total anonymity is even more desirable - especially to break multiple hops to a true-name action - real-world constraints sometimes makes this more challenging.

    Private and secure communication. Your communication and who you transact with should be for your eyes only. This includes transactions (transfer of value) as a form of communication.

    Censorship-resistance. Not being able to easily censor individuals on the platform. Both at an individual, group and collective level. Not having single points of failure that allow service to be disrupted.

    Decentralization. Partly falls out of censorship-resistance and other properties. If infrastructure isn't decentralized it means there's a single point of failure that can be disrupted. This is more of a tool than a goal on its own, but it is an important tool.

    Built for mass adoption. Includes scalabiltiy, UX (latency, reliability, bandwidth consumption, UI etc), and allowing for people to stick around. One way of doing this is to allow users to discover people they want to talk to.

    Scalability. Infrastructure needs to support a lot of users to be a viabile alternative. Like, a billion of them (eventually).

    Fundamentals in place to support great user experience. To be a viable alternative, aside from good UI and distribution, fundamentals such as latency, bandwidth usage, consistency etc must support great UX to be a viable alternative.

    Works for resource restricted devices, including smartphones. Most people will use a smartphone to use this. This means it has to work well on them and similar devices, without becoming a second-class citizen where we ignore properties such as censorship-resistance and privacy. Some concession to reality will be necessary due to additional constraints, which leads us to...

    Adaptive nodes. Nodes will have different capabilities, and perhaps at different times. To maintain a lot of the properties described here it is desirable if as many participants as possible are first-class citizens. If a phone is switching from a limited data plan to a WiFi network or from battery to AC power it can do more useful work, and so on. Likewise for a laptop with a lot of free disk space and spare compute power, etc.

    Sustainable. If there's no centralized, top down ad-driven model, this means all the infrastructure has to be sustainable somehow. Since these are individual entitites, this means it has to be paid for. While altruistic modes and similar can be used, this likely requires some form of incentivization scheme for useful services provided in the network. Related: free rider problem.

    Spam resistant. Relates to sustainability, scalability and built for mass adoption. Made more difficult by pseudonymous identity due to whitewashing attacks.

    Trust-minimized. To know that properties are provided for and aren't compromised, various ways of minimizing trust requirements are useful. This also related to mass adoption and social cohesion. Examples include: open and audited protocols, open source, reproducible builds, etc. This also relates to how mini apps are provided for, since we may not know their source but want to be able to use them anyway.

    Open source. Related to above, where we must be able to inspect the software to know that it functions as advertised and hasn't been compromised, e.g. by uploading private data to a third party.

    Some of these are graded and a bit subtle, i.e.:

    • Censorship resistance would ideally be able to absorb Internet shutdowns. This would require an extensive MANET/meshnet infrastructure, which while desirable, requires a lot of challenges to be overcome to be feasible.
    • Privacy would ideally make all actions (optionally) totally anoymous, though this may incur undue costs on bandwidth and latency, which impacts user experience.
    • Decentralization, certain topologies, such as DHTs, are efficient and quite decentralized but still have some centralized aspects, which makes it attackable in various ways. Ditto for blockchains compared with bearer instruments which requires some coordinating infrastructure, compared with naturally occuring assets such as precious metals.
    • "Discover people" and striving for "total anonymity" might initially seem incompatible. The idea is to provide for sane defaults, and then allow people to decide how much information they want to disclose. This is the essence of privacy.
    • Users often want some form of moderation to get a good user experience, which can be seen as a form of censorship. The idea to raise the bar on the basics, the fundamental infrastructure. If individuals or specific communities want certain moderation mechanisms, that is still a compatible requirement.

    Counterpoint 1

    We could refute the above by saying that the design goals are undesirable. We want a system where people can censor others, and where everyone is tied to their real identity. Or we could say something like, freedom of speech is a general concept, and it doesn't apply to Internet companies, even if they provide a vital service. You can survive without it and you should've read the terms of service. This roughly charactericizes the mainstream view.

    Additional factor here is the idea that a group of people know more about what's good for you then you do, so they are protecting you.

    Counterpoint 2

    We could agree with all these design goals, but think they are too extreme in terms of their requirements. For example, we could operate as a non profit, take donations and volunteers, and then host the whole infrastructure ourselves. We could say we are in a friendly legislation, so we won't be a single point of failure. Since we are working on this and maybe even our designs are open, you can trust us and we'll provide service and infrastructure that gives you what you want without having to pay for it or solve all these complex decentralized computation and so on problems. If you don't trust us for some reason, you shouldn't use us regardless. Also, this is better than status quo. And we are more likely to survive by doing this, either by taking shortcuts or by being less ambituous in terms of scope.

    Principal components

    There are many ways to skin a cat, but this is one way of breaking down the problem. We have a general direction with the properties listed above, together with some understanding of how WeChat works for the everday user. Now the question is, what infrastructure do we need to support this? How do we achieve the above properties, or at least get closer to them? We want to figure out the necessary building blocks, and one of doing this is to map out likely necessary components.

    Background: Ethereum and Web3 stack

    It is worth noting that a lot of the required infrastructure has been developed, at least as concepts, in the original Ethereum / Web3 vision. In it there is Ethereum for consensus/compute/transact, storage through Swarm, and communication through Whisper. That said, the main focus has been on the Ethereum blockchain itself, and a lot of things have happened in the last 5y+ with respect to technology around privacy and scalabilty. It is worth revisiting things from a fresh point of view, with the WeChat alternative in mind as a clear use case.

    Account - self-sovereign identity and the perils of phone numbers

    Starting from the most basic: what is an account and how do you get one? With most internet services today, WeChat and almost all popular messaging apps included, you need to signup with some centralized authority. Usually you also have to verify this with some data that ties this account to you as an individual. E.g. by requiring a phone number, which in most jurisdictions 1 means giving out your real ID. This also means you can be banned from using the service by a somewhat arbitrary process, with no due process.

    Now, we could argue these app providers can do what they want. And they are right, in a very narrow sense. As apps like WeChat (and Google) become general-purpose platforms, they become more and more ingrained in our everyday lives. They start to provide utilities that we absolutely require to work to go about our day, such as paying for food or transportation. This means we need higher standard than this.

    Justifications for requiring phone numbers are usually centered around three claims:

    1. Avoiding spam
    2. Tying your account to your real name, for various reasons
    3. Using as a commonly shared identifier as a social network discovery mechanism

    Of course, many services require more than phone numbers. E.g. email, other forms of personal data such as voice recording, linking a bank account, and so on.

    In contrast, a self-sovereign system would allow you to "create an account" completely on your own. This can easily be done with public key cryptograpy, and it also paves the way for end-to-end encryption to make your messages private.

    The main issue with this that you need to get more creative about avoiding spam (e.g. through white washing attacks), and ideally there is some other form of social discovery mechanism.

    Just having a public key as an account isn't enough though. If it goes through a central server, then nothing is stopping that server from arbitrarly blocking requests related to that public key. Of course, this also depends on how transparent such requests are. Fundamentally, lest we rely completely on goodwill, there needs to be multiple actors by which you can use the service. This naturally points to decentralization as a requirement. See counterpoint.

    Even so, if the system is closed source we don't know what it is doing. Perhaps the app communicating is also uploading data to another place, or somehow making it possible to see who is who and act accordingly.

    You might notice that just one simple property, self-sovereign identity, leads to a slew of other requirements and properties. You might also notice that WeChat is far from alone in this, even if their identity requirements might be a bit stringent than, say, Telegram. Their control aspects are also a bit more extreme, at least for someone with western sensibilities 2.

    Most user facing applications have similar issues, Google Apps/FB/Twitter etc. For popular tools that have this built in, we can look at git - which is truly decentralized and have keypair at the bottom. It is for a very specific technical domain, and even then people rely on Github. Key management is fairly difficult even for technical people, and for normal people even more so. Banks are generally far behind on this tech, relying on arcane procedures and special purpose hardware for 2FA. That's another big issue.

    Let's shift gears a bit and talk about some other functional requirements.

    Routing - packets from A to B

    In order to get a lot of the features WeChat provides, we need the ability to do three things: communicate, store data, and transact with people. We need a bit more than that, but let's focus on this for now.

    To communicate with people, in the base case, we need to go from one phone to another phone that is separated by a large distance. This requires some form of routing. The most natural platform to build this on is the existing Internet, though not the only one. Most phones are resource restricted, and are only "on" for brief periods of time. This is needed to preserve battery and bandwidth. Additionally, Internet uses IPs as endpoints, which change as a phones move through space. NAT punching etc isn't always perfect either. This means we need a way to get a message from one public key to another, and through some intermediate nodes. We can think of these nodes as a form of service network. Similar to how a power grid works, or phone lines, or collection of ISPs.

    One important property here is to ensure we don't end up in a situation like the centralized capture scenario above, something we've seen with centralized ISPs 3 4 where they can choose which traffic is good and which is bad. We want to allow the use of different service nodes, just like if a restaurant gives you food poisioning you can go to the one next door and then the first one goes out of business after a while. And the circle of life continues.

    We shouldn't be naive though, and think that this is something nodes are likely to do for free. They need to be adequately compensated for their services, in some of incentivization scheme. That can either be monetary, or as in the case of Bittorrent, more of a barter situation where you use game theory to coordinate with strangers 5, and some form of reputation attached to it (for private trackers).

    There are many ways of doing routing, and we won't go into too much technical detail here. Suffice to say is that you likely want both a structured and unstructured alternative, and that these comes with several trade-offs when it comes to efficiency, metadata protection, ability to incentivize, compatibility with existing topologies, and suitability for mobilephones (mostly offline, bandwidth restricted, not directly connectable). Expect more on this in a future article.

    Some of these considerations naturally leads us into the storage and transaction components.

    Storage - available and persistant for later

    If mobile phones are mostly offline, we need some way to store these messages so they can be retrieved when online again. The same goes for various kinds attachments as well, and for when people are switching devices. A user might control their timeline, but in the WeChat case that timeline is stored on Tencent's servers, and queried from there as well. This naturally needs to happen by some other service nodes. In the WeChat case, and for most IMs, the way these servers are paid for is through some indirect ad mechanism. The entity controlling these ads and so on is the same one as the one operating the servers for storage. A more direct model with different entities would see these services being compensated for their work.

    We also need storage for attachments, mini-apps, as well as a way of understanding the current state of consensus when it comes to the compute/transact module. In the WeChat case, this state is completely handled by the bank institution or one of their partners, such as Alibaba. When it comes to bearer instruments like cash, no state needs to be kept as that's a direct exchange in the physical world. This isn't directly compatible with transfering value over a distance.

    All of this state requires availability and persistance. It should be done in a trust minimized fashion and decentralized, which requires some form of incentivization for keeping data around. If it isn't, you are relying on social cohesion which breaks down at very large scales.

    Since data will be spread out across multiple nodes, you need a way to sync data and transfer it in the network. As well as being able to add and query data from it. All of this requires a routing component.

    To make it more censorship resistant it might be better to keep it as a general-purpose store, i.e. individuals don't need to know what they storing. Otherwise, you naturally end up in a situation where individual nodes can be pressured to not store certain content.

    Messaging - from me to you to all of us (not them)

    This builds on top of routing, but it has a slightly different focus. The goal is to allow for individuals and groups to communicate in a private, secure and censorship-resistant manner.

    It also needs to provide a decent interface to the end user, in terms of dealing seamlessly with offline messages, providing reliable and timely messaging.

    In order to get closer to the ideal of total anonymity, it is useful to be able to hide metadata of who is talking to whom. This applies to both normal communication as well as for transactions. Ideally, no one but the parties involved can see who is taking part in a conversation. This can be achieved through various techniques such as mixnets, anonymous credentials, private information retrieval, and so on. Many of these techniques have a fundamental trade-off with latency and bandwidth, something that is a big concern for mobilephones. Being able to do some form of tuning, in an adaptive node manner, depending on your threat model and current capabilities is useful here.

    The baseline here is pseudonymity, and having tools to allow individuals to "cut off" ties to their real world identity and transactions. People act different in different circles in the real world, and this should be mimicked online as well. Your company, family or government shouldn't be able to know what exactly you use your paycheck for, and who you are talking to.

    Compute - transact, contract and settle

    The most immediate need here is transaction from A to B. Direct exchange. There is also a more indirect need for private lawmaking and contracting.

    We talked about routing and storage and how they likely need to be incentivized to work properly. How are they going to be compensated? While this could in theory work via existing banking system and so on, this would be rather heavy. It'd also very likely require tying your identifier to your legal name, something that goes against what we want to achieve. What we want is something that acts more as right-to-access, similar to the way cash functions in a society 6. I pay for a fruit with something that is valuable to you and then I'm on my way.

    While there might be other candidates, such as pre-paid debit cards and so on, this transaction mode pretty much requires a cryptocurrency component. The alternative is to do it on a reputation basis, which might work for small communities, due to social cohesion, but quickly detoriates for large ones 7. Ad hoc models like private Bittorrent trackers are centralized and easy to censor.

    Now, none of the existing cryptocurrency models are ideal. They also all suffer from lack of widespread use, and it is difficult to get onboarded to them in the first place. Transactions in Bitcoin are slow. Ethereum is faster and has more capabilities, but it still suffers from linking payments over time, which makes the privacy part of this more difficult. Zcash, Monero and similar are interesting, but also require more use. For Zcash, shielded transactions appear to only account for less than 2% of all transactions in 2019 8 9.

    Another dimension is what sets general purpose cryptocurrencies like Ethereum apart. Aside from just paying from A to B, you can encode rules about when something should be paid out and not. This is very useful for doing a form of private lawmaking, contracting, for setting up service agreements with these nodes. If there's no trivial recourse as in the meatspace world, where you know someone's name and you can sue them, you need a different kind of model.

    What makes something like Zcash interesting is that it works more like digital cash. Instead of leaving a public trail for everyone, where someone can see where you got the initial money from and then trace you across various usage, for Zcash every hop is privacy preserving.

    To fulfill the general goals of being censorship resistance and secure, it is also vital that the system being used stays online and can't be easily disrupted. That points to disintermediation, as opposed to using gateways and exchanges. This is a case where something like cash, or gold, is more direct, since no one can censor this transaction without being physically present where this direct exchange is taking place. However, like before, this doesn't work over distance.

    Secure chat - just our business

    Similar to the messaging module above. The distinction here is that we assume the network part has already taken place. Here we are interested in keeping the contents of messages private, so that means confidentiality/end-to-end encryption, integrity, authentication, as well as forward secrecy and plausible deniability. This means that even if there's some actor that gets some private key material, or confiscated your phone, there is some level of...ephemerality to your conversations. Another issue here in terms of scalable private group chat.

    Extensible mini apps

    This relates to the compute and storage module above. Essentially we want to provide mini apps as in WeChat, but to do so in a way that is compatible with what we want to achieve more generally. This allows individuals and small businesses to create small tools for various purposes, and coordinate with strangers. E.g. booking a cab or getting an insurance, and so on.

    This has a higher dependency on the contracting/general computation aspect. I.e. often it isn't only a transaction, but you might want to encode some specific rules here that strangers can abide by without having too high trust requirements. As a simple example: escrows.

    This also needs an open API that anyone can use. It should be properly secured, so using one doesn't compromise the rest of the system it is operating in. To be censorship resistant it requires the routing and storage component to work properly.

    Where are we now?

    Let's look back at some of desirable properties we set out in the beginning and see how close we are to building out the necessary components. Is it realistic at all or just a pipe dream? We'll see that there are many building blocks in place, and there's reason for hope.

    Self-sovereignity identity. Public key crypto and web of trust like constructs makes this possible.

    Pseudonymity, and ideally total anonymity. Pseudonymity can largely be achieved with public key crypto and open systems that allow for permissionless participation. For transactions, pseudonymity exists in most cryptocurrencies. The challenge is linkage across time, especially when interfacing with other "legacy" system. There are stronger constructs that are actively being worked on and are promising here, such as mixnets (Nym), mixers (Wasabi Wallet, Tornado.Cash) and zero knowledge proofs (Zcash, Ethereum, Starkware). This area of applied research has exploded over the last few years.

    Private and secure communication. Signal has pioneered a lot of this, following OTR. Double Ratchet, X3DH. E2EE is minimum these days, and properties like PFS and PD are getting better. For metadata protection, you have Tor, with its faults, and more active research on mixnets and private information retrieval, etc.

    Censorship-resistance. This covers a lot of ground across the spectrum. You have technologies like Bittorrent, Bitcoin/Ethereum, Tor obfuscated transports, E2EE by default, partial mesh networks in production, abilit to move/replicate host machines more quickly have all made this more of a reality than it used to be. this easier. Of course, techniques such as deep packet inspection and internet shutdowns have increased.

    Decentralization. Cryptocurrencies, projects like libp2p and IPFS. Need to be mindful here of many projects that claim decentralization but are still vulnerable to single points of failures, such as relying on gateways.

    Built for mass adoption. This one is more subjective. There's definitely a lot of work to be done here, both when it comes to fundamental performance, key management and things like social discoverability. Directionally these things are improving and becoming easier for the average person but there is a lot ot be done here.

    Scalability. With projects like Ethereum 2.0 and IPFS more and more resources are a being put into this, both at the consensus/compute layer as well as networking (gossip, scalable Kademlia) layer. Also various layer 2 solutions for transactions.

    Fundamentals in place to support great user experience. Similar to built for mass adoption. As scalability becomes more important, more applied research is being done in the p2p area to improve things like latency, bandwidth.

    Works for resource restricted devices, including smartphones. Work in progress and not enough focus here, generally an after thought. Also have stateless clients etc.

    Adaptive nodes. See above. With subprotocols and capabilities in Ethereum and libp2p, this is getting easier.

    Sustainable. Token economics is a thing. While a lot of it won't stay around, there are many more projects working on making themselves dispensable. Being open source, having an engaged community and enabling users run their own infrastructure. Users as stakeholders.

    Spam resistant. Tricky problem if you want to be pseudonymous, but some signs of hope with incentivization mechanisms, zero knowledge based signaling, etc. Together with various forms of rate limiting and better controlling of topology and network amplification. And just generally being battle-tested by real world attacks, such as historical Ethereum DDoS attacks.

    Trust minimized. Bitcoin. Zero knowledge provable computation. Open source. Reproducible builds. Signed binaries. Incentive compatible structures. Independent audits. Still a lot of work, but getting better.

    Open source. Big and only getting bigger. Including mainstream companies.

    What's next?

    We've look at what WeChat provides and what we'd like an alternative to look like. We've also seen a few principal modules that are necessary to achieve those goals. To achieve all of this is a daunting task, and one might call it overly ambitiuous. We've also seen how far we've come with some of the goals, and how a lot of the pieces are there, in one form or another. Then it is a question of putting them all together in the right mix.

    The good news is that a lot of people are working all these building blocks and thinking about these problems. Compared to a few years ago we've come quite far when it comes to p2p infrastructure, privacy, security, scalability, and general developer mass and mindshare. If you want to join us in building some of these building blocks, and assembling them, check out our forum.

    PS. We are hiring protocol engineers. DS

    Acknowledgements

    Corey, Dean, Jacek.

    References

    - - + + \ No newline at end of file diff --git a/rlog/zkVM-explorations/index.html b/rlog/zkVM-explorations/index.html index 585dd2a1..35cd3635 100644 --- a/rlog/zkVM-explorations/index.html +++ b/rlog/zkVM-explorations/index.html @@ -10,8 +10,8 @@ - - + +
    @@ -69,8 +69,8 @@ that balance proof generation, privacy, and scalability, offering strong platfor scenarios where proof generation and scalability are paramount, but privacy is not a primary concern.

    As zkVM technology continues to evolve, we expect to see more projects integrating enhanced privacy-preserving mechanisms while simultaneously improving performance and scalability. This ongoing development will likely broaden the application of zkVMs across the blockchain ecosystem, particularly in privacy-sensitive sectors such as finance, data security, and decentralized applications.

    What are your thoughts on our zkVM analysis? Do you agree with our findings, or do you know of other zkVM projects that should be on our radar? We would love to hear your insights, questions, -or suggestions! Feel free to join the discussion on our forum.

    References

    [1] Introducing SP1: A performant, 100% open-source, contributor-friendly zkVM. Retrieved from https://blog.succinct.xyz/introducing-sp1/

    [2] The Nexus 2.0 zkVM. Retrieved from https://docs.nexus.xyz/

    [3] The first general purpose zkVM. Retrieved from https://www.risczero.com/zkvm

    [4] Powdr. Retrieved from https://docs.powdr.org/

    [5] ZKM Architecture. Retrieved from https://docs.zkm.io/zkm-architecture

    [6] Valida zkVM Design. Retrieved from https://delendum.xyz/writings/2023-05-10-zkvm-design.html

    [7] Building Jolt: A fast, easy-to-use zkVM. Retrieved from https://a16zcrypto.com/posts/article/building-jolt/

    [8] ZK-WASM. Retrieved from https://delphinuslab.com/zk-wasm/

    [9] Aleo. Retrieved from https://aleo.org/blog/

    [10] OlaVM Whitepaper V2. Retrieved from https://github.com/Sin7Y/olavm-whitepaper-v2/tree/master

    [11] Polygon Miden VM. Retrieved from https://0xpolygonmiden.github.io/miden-vm/intro/main.html

    [12] The Adventures of OS: Making a RISC-V Operating System using Rust. Retrieved from https://osblog.stephenmarz.com/index.html

    [13] Triton VM. Retrieved from https://triton-vm.org/spec/

    [14] How does the original Cairo VM work?. Retrieved from https://github.com/lambdaclass/cairo-vm/blob/main/docs/python_vm/README.md

    [15] Aleo completes security audits of snarkOS & snarkVM. Retrieved from https://aleo.org/post/aleo-completes-security-audits-of-snarkos-and-snarkvm/

    [16] Lurk zkVM. Retrieved from https://github.com/lurk-lab

    [17] Piecrust VM. Retrieved from https://docs.rs/piecrust/latest/piecrust/

    [18] Ceno: Non-uniform, Segment and Parallel Zero-knowledge Virtual Machine. Retrieved from https://eprint.iacr.org/2024/387

    [19] ZkVM: a new design for fast, confidential smart contracts. Retrieved from https://stellar.org/blog/developers/zkvm-a-new-design-for-fast-confidential-smart-contracts

    [20] Novanet. Retrieved from https://www.novanet.xyz/blog

    [21] ZKLLVM. Retrieved from https://github.com/NilFoundation/zkLLVM

    [22] zkMove 0.2.0 - Achieving Full Bytecode Compatibility with Move. Retrieved from https://www.zkmove.net/2023-06-20-zkMove-0.2.0-Achieving-Full-Bytecode-Compatibility-with-Move/

    [23] O1VM. Retrieved from https://github.com/o1-labs/proof-systems/tree/master/o1vm

    - - +or suggestions! Feel free to join the discussion on our forum.

    References

    [1] Introducing SP1: A performant, 100% open-source, contributor-friendly zkVM. Retrieved from https://blog.succinct.xyz/introducing-sp1/

    [2] The Nexus 2.0 zkVM. Retrieved from https://docs.nexus.xyz/

    [3] The first general purpose zkVM. Retrieved from https://www.risczero.com/zkvm

    [4] Powdr. Retrieved from https://docs.powdr.org/

    [5] ZKM Architecture. Retrieved from https://docs.zkm.io/zkm-architecture

    [6] Valida zkVM Design. Retrieved from https://delendum.xyz/writings/2023-05-10-zkvm-design.html

    [7] Building Jolt: A fast, easy-to-use zkVM. Retrieved from https://a16zcrypto.com/posts/article/building-jolt/

    [8] ZK-WASM. Retrieved from https://delphinuslab.com/zk-wasm/

    [9] Aleo. Retrieved from https://aleo.org/blog/

    [10] OlaVM Whitepaper V2. Retrieved from https://github.com/Sin7Y/olavm-whitepaper-v2/tree/master

    [11] Polygon Miden VM. Retrieved from https://0xpolygonmiden.github.io/miden-vm/intro/main.html

    [12] The Adventures of OS: Making a RISC-V Operating System using Rust. Retrieved from https://osblog.stephenmarz.com/index.html

    [13] Triton VM. Retrieved from https://triton-vm.org/spec/

    [14] How does the original Cairo VM work?. Retrieved from https://github.com/lambdaclass/cairo-vm/blob/main/docs/python_vm/README.md

    [15] Aleo completes security audits of snarkOS & snarkVM. Retrieved from https://aleo.org/post/aleo-completes-security-audits-of-snarkos-and-snarkvm/

    [16] Lurk zkVM. Retrieved from https://github.com/lurk-lab

    [17] Piecrust VM. Retrieved from https://docs.rs/piecrust/latest/piecrust/

    [18] Ceno: Non-uniform, Segment and Parallel Zero-knowledge Virtual Machine. Retrieved from https://eprint.iacr.org/2024/387

    [19] ZkVM: a new design for fast, confidential smart contracts. Retrieved from https://stellar.org/blog/developers/zkvm-a-new-design-for-fast-confidential-smart-contracts

    [20] Novanet. Retrieved from https://www.novanet.xyz/blog

    [21] ZKLLVM. Retrieved from https://github.com/NilFoundation/zkLLVM

    [22] zkMove 0.2.0 - Achieving Full Bytecode Compatibility with Move. Retrieved from https://www.zkmove.net/2023-06-20-zkMove-0.2.0-Achieving-Full-Bytecode-Compatibility-with-Move/

    [23] O1VM. Retrieved from https://github.com/o1-labs/proof-systems/tree/master/o1vm

    + + \ No newline at end of file diff --git a/rlog/zkVM-testing/index.html b/rlog/zkVM-testing/index.html new file mode 100644 index 00000000..ffb3dab1 --- /dev/null +++ b/rlog/zkVM-testing/index.html @@ -0,0 +1,76 @@ + + + + + +zkVM Testing Report: Evaluating Zero-Knowledge Virtual Machines for Nescience | Vac Research + + + + + + + + + + +
    +

    zkVM Testing Report: Evaluating Zero-Knowledge Virtual Machines for Nescience

    by
    12 min read

    Introduction

    Following our initial exploration of zkVMs in our previous blog post [1], +we have conducted a series of tests to identify the most suitable zkVM for the Nescience architecture [2]. This post outlines the testing process, results, and conclusions. Additionally, +the full test suite and scripts can be found on our GitHub page [3], +allowing others to replicate the results or explore the candidates further.

    We've shortlisted the following zkVMs for testing:

    • SP1 [4]
    • RISC0 [5]
    • Nexus [6]
    • ZkMIPS [7]
    • ZkWASM [8]
    • Valida [9]

    Why these candidates?

    When narrowing down the zkVMs, we focused on key factors:

    • True zero-knowledge functionality: The zkVMs had to demonstrate or be close to demonstrating the ability to generate and verify zero-knowledge proofs.
    • Performance baselines: We sought zkVMs with solid benchmarks in performance, particularly in speed and efficiency.
    • Specific functionalities: For Nescience, functionalities like lookup tables, precompiles, and recursive capabilities are critical.

    We need a zkVM that supports these to enable robust project development.

    Preliminary information on the candidates

    1. SP1 is a performant, open-source zkVM that verifies the execution of arbitrary Rust (or any LLVM-compiled language) programs. +SP1 utilizes Plonky3, enabling recursive proofs and supporting a wide range of cryptographic algorithms, including ECC-based ones like Groth16. +While it supports aggregation, it appears not to support zero knowledge in a conventional manner.

    2. RISC0 zkVM allows one to prove the correct execution of arbitrary Rust code. Built on a RISC-V architecture, it is inherently adaptable +for implementing standard cryptographic hash functions such as SHA-256 and ECDSA. RISC0 employs STARKs, providing a security level of 98 bits. +It supports multiple programming languages, including C and Rust, thanks to its compatibility with LLVM and WASM.

    3. Nexus is a modular, extensible, open-source, highly parallelized, prover-optimized, and contributor-friendly zkVM written in Rust. +It focuses on performance and security, using the Nova folding scheme, which is particularly effective for recursive proofs. +Nexus also supports precompiles and targeted compilation, and besides Rust, it offers C++ support.

    4. ZkMIPS is a general verifiable computing infrastructure based on Plonky2 and the MIPS microarchitecture, aiming to empower Ethereum +as a global settlement layer. It can run arbitrary Rust code as well. Notably, zkMIPS is the only zkVM in this list that utilizes the MIPS opcode set.

    5. ZkWASM adheres to and supports the unmodified standard WASM bytecode specification. Since Rust code can be compiled to WASM bytecode, +one could theoretically run any Rust code on a zkWASM machine, providing flexibility and broad language support.

    6. Valida is a STARK-based virtual machine aiming to improve upon the state of the art in several categories:

      • Code reuse: The VM has a RISC-inspired instruction set, simplifying the targeting of conventional programming languages. +A backend compiler is being developed to compile LLVM IR to the Valida ISA, enabling the proving of programs written in Rust, +Go, C++, and others with minimal to no changes in source code.
      • Prover performance: Engineered to maximize prover performance, Valida is compatible with a 31-bit field, restricted to degree 3 constraints, +and features minimal instruction decoding. It operates directly on memory without general-purpose registers or a dedicated stack, +utilizing newer lookup arguments to reduce trace overhead involved in cross-chip communication.
      • Extensibility: Designed to be customizable, Valida can easily be extended to include an arbitrary number of user-defined instructions. +Procedural macros are used to construct the desired machine at compile time, avoiding any runtime penalties.

    Valida appears to be in the early stages of development but already showcases respectable performance metrics.

    Testing plan

    To thoroughly evaluate each zkVM, we devised a two-stage testing process:

    • Stage 1: Arithmetic operations

      The first phase focused on evaluating the zkVMs’ ability to handle basic arithmetic operations: addition, subtraction, multiplication, +division, modulus division, and square root calculations. We designed the test around heptagonal numbers, which required zkVMs to process +multiple arithmetic operations simultaneously. By using this method, we could measure efficiency and speed in handling complex mathematical calculations – +a crucial element for zkVM performance.

    • Stage 2: Memory consumption

      For the second phase, we evaluated each zkVM’s ability to manage memory under heavy loads. We tested several data structures, including lists, +hash maps, deques, queues, BTreeMaps, hash sets, and binary heaps. Each zkVM underwent tests for the following operations:

      • Insert: How quickly can the zkVM add data to structures?
      • Delete: Does the zkVM handle memory release effectively?
      • Append: Can the zkVM efficiently grow data structures?
      • Search: How fast and efficient is the zkVM when retrieving stored data?

    The purpose of this stage was to identify any memory bottlenecks and to determine whether a zkVM could manage high-intensity tasks efficiently, +something vital for the Nescience project’s complex, data-heavy processes.

    Machine specifications

    The tests were conducted on the following hardware configuration:

    • CPU: AMD EPYC 7713 "Milan" 64-core processor (128 threads total)
    • RAM: 600GiB DDR4 3200MHz ECC RAM, distributed across 16 DIMMs
    • Host OS: Proxmox 8.3
    • Hypervisor: KVM
    • Network layer: Open vSwitch
    • Machine model: Supermicro AS-2024US-TRT

    Results

    1. SP1

    SP1 does not provide zero-knowledge capability in its proofs but delivers respectable performance, though slightly behind its main competitor. +Memory leaks were minimal, staying below the 700 KB threshold. Interestingly, SP1 consumed more RAM during the basic arithmetic +test than in memory allocation tests, showcasing the team's effective handling of memory under load. In the basic test, +allocations were primarily in the 9-16 B, 33-64 B, and 65-128 B ranges. For memory allocations, most fell into the 129-256 B range.

    • Stage 1: Hept 100 test
      • Proof size: 3.108 MB
      • Proof time: 16.95 seconds
    Image 1
    Image 2
    Image 3
    Image 4
    Image 5
    • Stage 2: Vec 10000 test
      • Proof size: 3.17 MB
      • Proof time: 20.85 seconds
    Image 1
    Image 2
    Image 3
    Image 4
    Image 5

    2. RISC0

    RISC0 stands out with exceptional performance in proof size and generation time, ranking among the best +(with the exception of Valida and zkWASM's basic test). It also handles memory well, with minor leaks under 0.5 MB +and controlled RAM consumption staying below 2.2 GB. RISC0's memory allocations were consistent, primarily in the 17-32 B and 33-64 B ranges.

    • Stage 1: Hept 100 test
      • Proof size: 217.4 KB
      • Proof time: 9.73 seconds
    Image 1
    Image 2
    Image 3
    Image 4
    Image 5
    • Stage 2: Vec 10000 test
      • Proof size: 217.4 KB
      • Proof time: 16.63 seconds
    Image 1
    Image 2
    Image 3
    Image 4
    Image 5

    Based on these results, RISC0 is a solid candidate for Nescience.


    3. Nexus

    Nexus' performance offers interesting insights into folding scheme-based zkVMs. Surprisingly, proof sizes remained consistent +regardless of workload, with no significant memory leaks (under 700 KB). However, while RAM consumption increased slightly with higher +workloads (up to 1.2 GB), Nexus performed poorly during memory allocation tests, making it unsuitable for our use case.

    • Allocation details:

      • Basic test: Most allocations concentrated in 65-128 B
      • Memory-heavy test: Allocations in the 129-256 B range
    • Stage 1: Hept 100 test

      • Proof size: 46 MB
      • Proof time: 12.06 seconds
    Image 1
    Image 2
    Image 3
    Image 4
    Image 5
    • Stage 2: Vec 10000 test
      • Proof size: 46 MB
      • Proof time: 56 minutes
    Image 1
    Image 2
    Image 3
    Image 4
    Image 5

    4. ZkMIPS

    ZkMIPS presents an intriguing case. While it shows good results in terms of proof size and generation time during the basic test, +these come at the cost of significant RAM usage and memory leaks. The memory allocation test revealed a concerning 6.7 GB memory leak, +with 0.5 GB leaked during the basic test. Despite this, RAM consumption (while high at 17+ GB) remains stable under higher workloads. +Allocation sizes are spread across several ranges, with notable concentrations in the 17-32 B, 65-128 B, and 257-512 B slots.

    • Stage 1: Hept 100 test
      • Proof size: 4.3 MB
      • Proof time: 9.32 seconds
    Image 1
    Image 2
    Image 3
    Image 4
    Image 5
    • Stage 2: Vec 10000 test
      • Proof size: 4.898 MB
      • Proof time: 42.57 seconds
    Image 1
    Image 2
    Image 3
    Image 4
    Image 5

    This zkVM provides mixed results with strong proof generation but concerning memory management issues.


    5. ZkWASM

    ZkWASM, unfortunately, performed poorly in both stages regarding proof size and generation time. RAM consumption was particularly high, +exceeding 7 GB in the basic test, and an astounding 57 GB during memory allocation tests. Despite its impressive memory usage, +the proof sizes were relatively large at 18 KB and 334 KB respectively. Allocation sizes were mainly concentrated in the 33-64 B range, +with neighboring slots contributing small but notable amounts.

    • Stage 1: Hept 100 test
      • Proof size: 18 KB
      • Proof time: 42.7 seconds
    Image 1
    Image 2
    Image 3
    Image 4
    Image 5
    • Stage 2: Vec 10000 test
      • Proof size: 334 KB
      • Proof time: 323 seconds
    Image 1
    Image 2
    Image 3
    Image 4
    Image 5

    6. Valida

    Valida delivered impressive results in proof generation speed and size, with a proof size of 280 KB and a proof time of < 1 second. +However, profiling was not possible due to Valida's limited Rust support. Valida currently compiles Rust using the LLVM backend, +transpiling LLVM IR to leverage its C/C++ implementation, which leads to errors when handling Rust-specific data structures or dependencies. +As a result, complex memory interactions couldn't be tested, and using Valida with Rust code is currently not advisable. +A GitHub issue has been opened to address this.


    Summary table

    Stage 1

    zkVMProof timeProof sizePeak RAM consumptionMemory leaked
    SP116.95 s3.108 MB2.1 GB656.8 KB
    RISC09.73 s217.4 KB1.9 GB470.5 KB
    Nexus12.06 s46 MB9.7 MB646.5 KB
    ZkMIPS9.32 s4.3 MB17.3 GB453.8 MB
    ZkWASM42.7 s18 KB8.2 GB259.4 KB
    Valida< 1 s280 KBN/AN/A

    Stage 2

    zkVMProof timeProof sizePeak RAM consumptionMemory leaked
    SP120.85 s3.17 MB1.9 GB616 KB
    RISC016.63 s217.4 KB2.3 GB485.3 KB
    Nexus56 m46 MB1.9 GB616 KB
    ZkMIPS42.57 s4.898 MB18.9 GB6.9 GB
    ZkWASM323 s334 KB58.8 GB259.4 KB
    ValidaN/AN/AN/AN/A

    Summary

    After an extensive evaluation of six zkVM candidates for the Nescience project, RISC0 emerged as the top choice. +It excels in both proof generation time and size while maintaining a reasonable memory footprint. With strong zero-knowledge +proof capabilities and support for multiple programming languages, it aligns well with our project's needs for privacy, +performance, and flexibility. Its overall balance between performance and efficiency makes it the most viable zkVM at this stage.

    Valida, while promising with its potential for high prover performance, is still in early development and suffers from Rust integration issues. +The current LLVM IR transpilation limitations mean it cannot handle complex memory interactions, disqualifying it for now. +However, once its development matures, Valida could become a strong alternative, and we plan to revisit it as it evolves.

    SP1, though initially interesting, failed to meet the zero-knowledge proof requirement. Its performance in arithmetic operations was +respectable but insufficient to justify further consideration given its lack of ZK functionality – critical for our privacy-first objectives.

    Nexus demonstrated consistent proof sizes and manageable memory usage, but its lackluster performance during memory-intensive tasks and +its proof size (especially for larger workloads) disqualified it from being a top contender. While zkMIPS delivered solid proof times, +the memory issues were too significant to ignore, making it unsuitable.

    Finally, zkWASM exhibited the poorest results, struggling both in proof size and generation time. Despite its potential for WASM bytecode support, +the excessive RAM consumption (up to 57 GB in the memory test) rendered it impractical for Nescience’s use case.

    In conclusion, RISC0 is the best fit for Nescience at this stage, but Valida remains a future candidate as its development progresses.

    We’d love to hear your thoughts on our zkVM testing process and results! Do you agree with our conclusions, or do you think we missed a promising zkVM? +We’re always open to feedback, insights, and suggestions from the community.

    Join the discussion and share your perspectives on +our forum or try out the +tests yourself through our [GitHub page](https://github.com/vacp2p/nescience-zkvm-testing!

    References

    [1] Exploring zkVMs: Which Projects Truly Qualify as Zero-Knowledge Virtual Machines? Retrieved from https://vac.dev/rlog/zkVM-explorations/

    [2] Nescience: A User-Centric State-Separation Architecture. Retrieved from https://vac.dev/rlog/Nescience-state-separation-architecture

    [3] Our GitHub Page for zkVM Testing. Retrieved from https://github.com/vacp2p/nescience-zkvm-testing

    [4] Introducing SP1: A performant, 100% open-source, contributor-friendly zkVM. Retrieved from https://blog.succinct.xyz/introducing-sp1/

    [5] The first general purpose zkVM. Retrieved from https://www.risczero.com/zkvm

    [6] The Nexus 2.0 zkVM. Retrieved from https://docs.nexus.xyz/

    [7] ZKM Architecture. Retrieved from https://docs.zkm.io/zkm-architecture

    [8] ZK-WASM. Retrieved from https://delphinuslab.com/zk-wasm/

    [9] Valida zkVM Design. Retrieved from https://delendum.xyz/writings/2023-05-10-zkvm-design.html

    + + + + \ No newline at end of file diff --git a/search-index.json b/search-index.json index 12e62a07..d5188f90 100644 --- a/search-index.json +++ b/search-index.json @@ -1 +1 @@ -[{"documents":[{"i":1,"t":"Vac Deep Research","u":"/deepresearch","b":[]},{"i":9,"t":"","u":"/media","b":[]},{"i":11,"t":"Current job openings","u":"/join-us","b":["Join Us"]},{"i":13,"t":"","u":"/principles","b":[]},{"i":37,"t":"About Vac","u":"/","b":["About Vac"]},{"i":39,"t":"Join the community","u":"/community","b":["Community"]},{"i":41,"t":"Privacy Policy","u":"/privacy-policy","b":[]},{"i":61,"t":"Contribute","u":"/contribute","b":[]},{"i":66,"t":"Security","u":"/security","b":[]},{"i":68,"t":"Vac R&D Service Units","u":"/vsus","b":[]},{"i":86,"t":"Vac RFC Process","u":"/rfcprocess","b":[]},{"i":88,"t":"Publications","u":"/publications","b":[]},{"i":93,"t":"Terms of Use","u":"/terms","b":[]},{"i":117,"t":"Vac Incubator Projects","u":"/vips","b":[]}],"index":{"version":"2.3.9","fields":["t"],"fieldVectors":[["t/1",[0,0.802,1,1.839,2,1.839]],["t/9",[]],["t/11",[3,1.839,4,1.839,5,1.839]],["t/13",[]],["t/37",[0,1.237]],["t/39",[6,2.232,7,2.232]],["t/41",[8,2.232,9,2.232]],["t/61",[10,2.839]],["t/66",[11,2.839]],["t/68",[0,0.682,12,1.564,13,1.564,14,1.564]],["t/86",[0,0.802,15,1.839,16,1.839]],["t/88",[17,2.839]],["t/93",[18,2.232,19,2.232]],["t/117",[0,0.802,20,1.839,21,1.839]]],"invertedIndex":[["commun",{"_index":7,"t":{"39":{"position":[[9,9]]}}}],["contribut",{"_index":10,"t":{"61":{"position":[[0,10]]}}}],["current",{"_index":3,"t":{"11":{"position":[[0,7]]}}}],["deep",{"_index":1,"t":{"1":{"position":[[4,4]]}}}],["incub",{"_index":20,"t":{"117":{"position":[[4,9]]}}}],["job",{"_index":4,"t":{"11":{"position":[[8,3]]}}}],["join",{"_index":6,"t":{"39":{"position":[[0,4]]}}}],["open",{"_index":5,"t":{"11":{"position":[[12,8]]}}}],["polici",{"_index":9,"t":{"41":{"position":[[8,6]]}}}],["privaci",{"_index":8,"t":{"41":{"position":[[0,7]]}}}],["process",{"_index":16,"t":{"86":{"position":[[8,7]]}}}],["project",{"_index":21,"t":{"117":{"position":[[14,8]]}}}],["public",{"_index":17,"t":{"88":{"position":[[0,12]]}}}],["r&d",{"_index":12,"t":{"68":{"position":[[4,3]]}}}],["research",{"_index":2,"t":{"1":{"position":[[9,8]]}}}],["rfc",{"_index":15,"t":{"86":{"position":[[4,3]]}}}],["secur",{"_index":11,"t":{"66":{"position":[[0,8]]}}}],["servic",{"_index":13,"t":{"68":{"position":[[8,7]]}}}],["term",{"_index":18,"t":{"93":{"position":[[0,5]]}}}],["unit",{"_index":14,"t":{"68":{"position":[[16,5]]}}}],["us",{"_index":19,"t":{"93":{"position":[[9,3]]}}}],["vac",{"_index":0,"t":{"1":{"position":[[0,3]]},"37":{"position":[[6,3]]},"68":{"position":[[0,3]]},"86":{"position":[[0,3]]},"117":{"position":[[0,3]]}}}]],"pipeline":["stemmer"]}},{"documents":[{"i":3,"t":"Zero-Knowledge Proofs","u":"/deepresearch","h":"#zero-knowledge-proofs","p":1},{"i":5,"t":"Libp2p Gossipsub Improvements","u":"/deepresearch","h":"#libp2p-gossipsub-improvements","p":1},{"i":7,"t":"Anonymisation Networks","u":"/deepresearch","h":"#anonymisation-networks","p":1},{"i":15,"t":"Principles","u":"/principles","h":"","p":13},{"i":17,"t":"I. Liberty","u":"/principles","h":"#i-liberty","p":13},{"i":19,"t":"II. Censorship resistance","u":"/principles","h":"#ii-censorship-resistance","p":13},{"i":21,"t":"III. Security","u":"/principles","h":"#iii-security","p":13},{"i":23,"t":"IV. Privacy","u":"/principles","h":"#iv-privacy","p":13},{"i":25,"t":"V. Transparency","u":"/principles","h":"#v-transparency","p":13},{"i":27,"t":"VI. Openness","u":"/principles","h":"#vi-openness","p":13},{"i":29,"t":"VII. Decentralisation","u":"/principles","h":"#vii-decentralisation","p":13},{"i":31,"t":"VIII. Inclusivity","u":"/principles","h":"#viii-inclusivity","p":13},{"i":33,"t":"IX. Continuance","u":"/principles","h":"#ix-continuance","p":13},{"i":35,"t":"X. Resourcefulness","u":"/principles","h":"#x-resourcefulness","p":13},{"i":43,"t":"1) Who we are","u":"/privacy-policy","h":"#1-who-we-are","p":41},{"i":45,"t":"2) We limit the collection and processing of personal data from your use of the Website","u":"/privacy-policy","h":"#2-we-limit-the-collection-and-processing-of-personal-data-from-your-use-of-the-website","p":41},{"i":47,"t":"3) Third party processing of personal data","u":"/privacy-policy","h":"#3-third-party-processing-of-personal-data","p":41},{"i":49,"t":"4) Security measures we take in respect of the Website","u":"/privacy-policy","h":"#4-security-measures-we-take-in-respect-of-the-website","p":41},{"i":51,"t":"5) Exporting data outside the European Union and Switzerland","u":"/privacy-policy","h":"#5-exporting-data-outside-the-european-union-and-switzerland","p":41},{"i":53,"t":"6) Your choices and rights","u":"/privacy-policy","h":"#6-your-choices-and-rights","p":41},{"i":55,"t":"7) Third party links","u":"/privacy-policy","h":"#7-third-party-links","p":41},{"i":57,"t":"8) This Privacy Policy might change","u":"/privacy-policy","h":"#8-this-privacy-policy-might-change","p":41},{"i":59,"t":"9) Contact information","u":"/privacy-policy","h":"#9-contact-information","p":41},{"i":62,"t":"How to Contribute","u":"/contribute","h":"#how-to-contribute","p":61},{"i":64,"t":"What to Contribute","u":"/contribute","h":"#what-to-contribute","p":61},{"i":70,"t":"P2P","u":"/vsus","h":"#p2p","p":68},{"i":72,"t":"Token Economics (TKE)","u":"/vsus","h":"#token-economics-tke","p":68},{"i":74,"t":"Distributed Systems Testing (DST)","u":"/vsus","h":"#distributed-systems-testing-dst","p":68},{"i":76,"t":"Quality Assurance (QA)","u":"/vsus","h":"#quality-assurance-qa","p":68},{"i":78,"t":"Smart Contracts (SC)","u":"/vsus","h":"#smart-contracts-sc","p":68},{"i":80,"t":"Nim","u":"/vsus","h":"#nim","p":68},{"i":82,"t":"Applied Cryptography & ZK (ACZ)","u":"/vsus","h":"#applied-cryptography--zk-acz","p":68},{"i":84,"t":"RFC","u":"/vsus","h":"#rfc","p":68},{"i":89,"t":"Papers","u":"/publications","h":"#papers","p":88},{"i":91,"t":"Write-ups","u":"/publications","h":"#write-ups","p":88},{"i":95,"t":"1) Who we are","u":"/terms","h":"#1-who-we-are","p":93},{"i":97,"t":"2) Disclaimers","u":"/terms","h":"#2-disclaimers","p":93},{"i":99,"t":"3) Forward looking statements","u":"/terms","h":"#3-forward-looking-statements","p":93},{"i":101,"t":"4) Intellectual property rights","u":"/terms","h":"#4-intellectual-property-rights","p":93},{"i":103,"t":"5) Third-party website links","u":"/terms","h":"#5-third-party-website-links","p":93},{"i":105,"t":"6) Limitation of liability","u":"/terms","h":"#6-limitation-of-liability","p":93},{"i":107,"t":"7) Indemnity","u":"/terms","h":"#7-indemnity","p":93},{"i":109,"t":"8) Modifications","u":"/terms","h":"#8-modifications","p":93},{"i":111,"t":"9) Governing law","u":"/terms","h":"#9-governing-law","p":93},{"i":113,"t":"10) Disputes","u":"/terms","h":"#10-disputes","p":93},{"i":115,"t":"11) About these Website Terms of Use","u":"/terms","h":"#11-about-these-website-terms-of-use","p":93},{"i":119,"t":"Nescience","u":"/vips","h":"#nescience","p":117}],"index":{"version":"2.3.9","fields":["t"],"fieldVectors":[["t/3",[0,3.35,1,3.35,2,3.35]],["t/5",[3,3.35,4,3.35,5,3.35]],["t/7",[6,3.909,7,3.909]],["t/15",[8,4.691]],["t/17",[9,4.691]],["t/19",[10,3.35,11,3.35,12,3.35]],["t/21",[13,3.909,14,3.332]],["t/23",[15,3.909,16,3.332]],["t/25",[17,3.909,18,3.909]],["t/27",[19,3.909,20,3.909]],["t/29",[21,3.909,22,3.909]],["t/31",[23,3.909,24,3.909]],["t/33",[25,3.909,26,3.909]],["t/35",[27,3.909,28,3.909]],["t/43",[29,4]],["t/45",[30,1.666,31,1.666,32,1.953,33,1.666,34,1.666,35,1.476,36,1.666,37,1.334]],["t/47",[33,1.999,34,1.999,35,1.771,38,1.999,39,1.771,40,1.771]],["t/49",[14,1.999,37,1.601,41,1.999,42,2.344,43,2.344,44,2.344]],["t/51",[35,1.61,45,1.817,46,2.131,47,2.131,48,2.131,49,2.131,50,2.131]],["t/53",[51,2.856,52,3.35,53,2.856]],["t/55",[39,2.214,40,2.214,54,2.499,55,2.499]],["t/57",[16,2.499,56,2.499,57,2.931,58,2.931]],["t/59",[59,2.856,60,3.35,61,3.35]],["t/62",[62,4]],["t/64",[62,4]],["t/70",[63,4.691]],["t/72",[64,3.35,65,3.35,66,3.35]],["t/74",[67,2.931,68,2.931,69,2.931,70,2.931]],["t/76",[71,3.35,72,3.35,73,3.35]],["t/78",[74,3.35,75,3.35,76,3.35]],["t/80",[77,4.691]],["t/82",[78,2.605,79,2.605,80,2.605,81,2.605,82,2.605]],["t/84",[83,4.691]],["t/89",[84,4.691]],["t/91",[85,3.909,86,3.909]],["t/95",[29,4]],["t/97",[30,3.332,87,3.909]],["t/99",[38,2.499,88,2.931,89,2.931,90,2.931]],["t/101",[41,2.499,53,2.499,91,2.931,92,2.931]],["t/103",[37,1.779,39,1.968,40,1.968,45,2.221,55,2.221]],["t/105",[31,2.856,51,2.856,93,3.35]],["t/107",[54,3.332,94,3.909]],["t/109",[56,3.332,95,3.909]],["t/111",[59,2.856,96,3.35,97,3.35]],["t/113",[98,3.909,99,3.909]],["t/115",[36,2.499,37,2.002,100,2.931,101,2.931]],["t/119",[102,4.691]]],"invertedIndex":[["",{"_index":80,"t":{"82":{"position":[[21,1]]}}}],["1",{"_index":29,"t":{"43":{"position":[[0,2]]},"95":{"position":[[0,2]]}}}],["10",{"_index":98,"t":{"113":{"position":[[0,3]]}}}],["11",{"_index":100,"t":{"115":{"position":[[0,3]]}}}],["2",{"_index":30,"t":{"45":{"position":[[0,2]]},"97":{"position":[[0,2]]}}}],["3",{"_index":38,"t":{"47":{"position":[[0,2]]},"99":{"position":[[0,2]]}}}],["4",{"_index":41,"t":{"49":{"position":[[0,2]]},"101":{"position":[[0,2]]}}}],["5",{"_index":45,"t":{"51":{"position":[[0,2]]},"103":{"position":[[0,2]]}}}],["6",{"_index":51,"t":{"53":{"position":[[0,2]]},"105":{"position":[[0,2]]}}}],["7",{"_index":54,"t":{"55":{"position":[[0,2]]},"107":{"position":[[0,2]]}}}],["8",{"_index":56,"t":{"57":{"position":[[0,2]]},"109":{"position":[[0,2]]}}}],["9",{"_index":59,"t":{"59":{"position":[[0,2]]},"111":{"position":[[0,2]]}}}],["acz",{"_index":82,"t":{"82":{"position":[[26,5]]}}}],["anonymis",{"_index":6,"t":{"7":{"position":[[0,13]]}}}],["appli",{"_index":78,"t":{"82":{"position":[[0,7]]}}}],["assur",{"_index":72,"t":{"76":{"position":[[8,9]]}}}],["censorship",{"_index":11,"t":{"19":{"position":[[4,10]]}}}],["chang",{"_index":58,"t":{"57":{"position":[[29,6]]}}}],["choic",{"_index":52,"t":{"53":{"position":[[8,7]]}}}],["collect",{"_index":32,"t":{"45":{"position":[[16,10]]}}}],["contact",{"_index":60,"t":{"59":{"position":[[3,7]]}}}],["continu",{"_index":26,"t":{"33":{"position":[[4,11]]}}}],["contract",{"_index":75,"t":{"78":{"position":[[6,9]]}}}],["contribut",{"_index":62,"t":{"62":{"position":[[7,10]]},"64":{"position":[[8,10]]}}}],["cryptographi",{"_index":79,"t":{"82":{"position":[[8,12]]}}}],["data",{"_index":35,"t":{"45":{"position":[[54,4]]},"47":{"position":[[38,4]]},"51":{"position":[[13,4]]}}}],["decentralis",{"_index":22,"t":{"29":{"position":[[5,16]]}}}],["disclaim",{"_index":87,"t":{"97":{"position":[[3,11]]}}}],["disput",{"_index":99,"t":{"113":{"position":[[4,8]]}}}],["distribut",{"_index":67,"t":{"74":{"position":[[0,11]]}}}],["dst",{"_index":70,"t":{"74":{"position":[[28,5]]}}}],["econom",{"_index":65,"t":{"72":{"position":[[6,9]]}}}],["european",{"_index":48,"t":{"51":{"position":[[30,8]]}}}],["export",{"_index":46,"t":{"51":{"position":[[3,9]]}}}],["forward",{"_index":88,"t":{"99":{"position":[[3,7]]}}}],["gossipsub",{"_index":4,"t":{"5":{"position":[[7,9]]}}}],["govern",{"_index":96,"t":{"111":{"position":[[3,9]]}}}],["ii",{"_index":10,"t":{"19":{"position":[[0,3]]}}}],["iii",{"_index":13,"t":{"21":{"position":[[0,4]]}}}],["improv",{"_index":5,"t":{"5":{"position":[[17,12]]}}}],["inclus",{"_index":24,"t":{"31":{"position":[[6,11]]}}}],["indemn",{"_index":94,"t":{"107":{"position":[[3,9]]}}}],["inform",{"_index":61,"t":{"59":{"position":[[11,11]]}}}],["intellectu",{"_index":91,"t":{"101":{"position":[[3,12]]}}}],["iv",{"_index":15,"t":{"23":{"position":[[0,3]]}}}],["ix",{"_index":25,"t":{"33":{"position":[[0,3]]}}}],["knowledg",{"_index":1,"t":{"3":{"position":[[5,9]]}}}],["law",{"_index":97,"t":{"111":{"position":[[13,3]]}}}],["liabil",{"_index":93,"t":{"105":{"position":[[17,9]]}}}],["liberti",{"_index":9,"t":{"17":{"position":[[3,7]]}}}],["libp2p",{"_index":3,"t":{"5":{"position":[[0,6]]}}}],["limit",{"_index":31,"t":{"45":{"position":[[6,5]]},"105":{"position":[[3,10]]}}}],["link",{"_index":55,"t":{"55":{"position":[[15,5]]},"103":{"position":[[23,5]]}}}],["look",{"_index":89,"t":{"99":{"position":[[11,7]]}}}],["measur",{"_index":42,"t":{"49":{"position":[[12,8]]}}}],["modif",{"_index":95,"t":{"109":{"position":[[3,13]]}}}],["nescienc",{"_index":102,"t":{"119":{"position":[[0,9]]}}}],["network",{"_index":7,"t":{"7":{"position":[[14,8]]}}}],["nim",{"_index":77,"t":{"80":{"position":[[0,3]]}}}],["open",{"_index":20,"t":{"27":{"position":[[4,8]]}}}],["outsid",{"_index":47,"t":{"51":{"position":[[18,7]]}}}],["p2p",{"_index":63,"t":{"70":{"position":[[0,3]]}}}],["paper",{"_index":84,"t":{"89":{"position":[[0,6]]}}}],["parti",{"_index":40,"t":{"47":{"position":[[9,5]]},"55":{"position":[[9,5]]},"103":{"position":[[9,5]]}}}],["person",{"_index":34,"t":{"45":{"position":[[45,8]]},"47":{"position":[[29,8]]}}}],["polici",{"_index":57,"t":{"57":{"position":[[16,6]]}}}],["principl",{"_index":8,"t":{"15":{"position":[[0,10]]}}}],["privaci",{"_index":16,"t":{"23":{"position":[[4,7]]},"57":{"position":[[8,7]]}}}],["process",{"_index":33,"t":{"45":{"position":[[31,10]]},"47":{"position":[[15,10]]}}}],["proof",{"_index":2,"t":{"3":{"position":[[15,6]]}}}],["properti",{"_index":92,"t":{"101":{"position":[[16,8]]}}}],["qa",{"_index":73,"t":{"76":{"position":[[18,4]]}}}],["qualiti",{"_index":71,"t":{"76":{"position":[[0,7]]}}}],["resist",{"_index":12,"t":{"19":{"position":[[15,10]]}}}],["resourc",{"_index":28,"t":{"35":{"position":[[3,15]]}}}],["respect",{"_index":44,"t":{"49":{"position":[[32,7]]}}}],["rfc",{"_index":83,"t":{"84":{"position":[[0,3]]}}}],["right",{"_index":53,"t":{"53":{"position":[[20,6]]},"101":{"position":[[25,6]]}}}],["sc",{"_index":76,"t":{"78":{"position":[[16,4]]}}}],["secur",{"_index":14,"t":{"21":{"position":[[5,8]]},"49":{"position":[[3,8]]}}}],["smart",{"_index":74,"t":{"78":{"position":[[0,5]]}}}],["statement",{"_index":90,"t":{"99":{"position":[[19,10]]}}}],["switzerland",{"_index":50,"t":{"51":{"position":[[49,11]]}}}],["system",{"_index":68,"t":{"74":{"position":[[12,7]]}}}],["take",{"_index":43,"t":{"49":{"position":[[24,4]]}}}],["term",{"_index":101,"t":{"115":{"position":[[24,5]]}}}],["test",{"_index":69,"t":{"74":{"position":[[20,7]]}}}],["third",{"_index":39,"t":{"47":{"position":[[3,5]]},"55":{"position":[[3,5]]},"103":{"position":[[3,5]]}}}],["tke",{"_index":66,"t":{"72":{"position":[[16,5]]}}}],["token",{"_index":64,"t":{"72":{"position":[[0,5]]}}}],["transpar",{"_index":18,"t":{"25":{"position":[[3,12]]}}}],["union",{"_index":49,"t":{"51":{"position":[[39,5]]}}}],["up",{"_index":86,"t":{"91":{"position":[[6,3]]}}}],["us",{"_index":36,"t":{"45":{"position":[[69,3]]},"115":{"position":[[33,3]]}}}],["v",{"_index":17,"t":{"25":{"position":[[0,2]]}}}],["vi",{"_index":19,"t":{"27":{"position":[[0,3]]}}}],["vii",{"_index":21,"t":{"29":{"position":[[0,4]]}}}],["viii",{"_index":23,"t":{"31":{"position":[[0,5]]}}}],["websit",{"_index":37,"t":{"45":{"position":[[80,7]]},"49":{"position":[[47,7]]},"103":{"position":[[15,7]]},"115":{"position":[[16,7]]}}}],["write",{"_index":85,"t":{"91":{"position":[[0,5]]}}}],["x",{"_index":27,"t":{"35":{"position":[[0,2]]}}}],["zero",{"_index":0,"t":{"3":{"position":[[0,4]]}}}],["zk",{"_index":81,"t":{"82":{"position":[[23,2]]}}}]],"pipeline":["stemmer"]}},{"documents":[{"i":2,"t":"Vac Deep Research is at the forefront of exploration and cutting-edge innovation within the IFT. Their work extends beyond scientific publications, actively bridging the gap between theory and practice. The team collaborates with various entities, such as Vac R&D units, incubator projects, and IFT projects, to bring their research findings to fruition. Part of this effort includes identifying opportunities for and spawning new incubator projects, allowing Vac Deep Research to translate their research findings into practical applications within the IFT. Deep Research encompasses several key areas, including zero knowledge (ZK), decentralised privacy-preserving node provider networks, validator privacy, and libp2p gossipsub improvements.","s":"Vac Deep Research","u":"/deepresearch","h":"","p":1},{"i":4,"t":"In the realm of ZKP, Vac Deep Research has made contributions that have given rise to the incubator project Nescience. The team delved into the intricacies of zero-knowledge proofs, exploring their applications and pushing the boundaries of privacy-preserving technologies. By advancing the field of ZK, Vac Deep Research strengthens the foundation for secure and confidential interactions within decentralised networks.","s":"Zero-Knowledge Proofs","u":"/deepresearch","h":"#zero-knowledge-proofs","p":1},{"i":6,"t":"Another area of focus for Vac Deep Research is \"libp2p gossipsub improvements\". The team explores ways to enhance the performance, efficiency, and reliability of the libp2p gossipsub protocol. By conducting in-depth research and proposing improvements, Vac Deep Research aims to optimise information sharing and communication within decentralised networks, contributing to the overall robustness and scalability of the P2P layers of IFT projects.","s":"Libp2p Gossipsub Improvements","u":"/deepresearch","h":"#libp2p-gossipsub-improvements","p":1},{"i":8,"t":"Vac also researches anonymisation networks, with the main goal of a libp2p gossipsub anonymisation layer with pluggable project-specific components.","s":"Anonymisation Networks","u":"/deepresearch","h":"#anonymisation-networks","p":1},{"i":10,"t":"Waku v2 training session Waku: Enabling a New Dimension for dApps Vac, Waku v2 and Ethereum Messaging ZKPodcast: ZKPs for Spam Protection & Decentralized Messaging with Status Franck Royer : DappConnect: Enabling decentralised communications using Waku Oskar Thoren | Vac, Waku v2 and Ethereum Messaging Dean Eigenman & Oskar Thoren: From Whisper to Waku Private and Reliable Data Sync for Messaging Over Whisper by Dean Eigenmann & Oskar Thoren (Devcon5)","s":"","u":"/media","h":"","p":9},{"i":12,"t":"Vac Libp2p Networking Engineer Remote (Worldwide) Software Developer in Test (Low Level Programming) Remote (Worldwide) Zero Knowledge Research Engineer (ACZ) Remote (Worldwide) Zero Knowledge Researcher (Nescience) Remote (Worldwide)","s":"Current job openings","u":"/join-us","h":"","p":11},{"i":14,"t":"These principles have been inherited from https://our.status.im/our-principles/. Only minor stylistic changes have been made to them.","s":"","u":"/principles","h":"","p":13},{"i":16,"t":"The goal of Vac is widespread adoption of the decentralised web. Our challenge is achieving mass adoption while staying true to the principles outlined below.","s":"Principles","u":"/principles","h":"","p":13},{"i":18,"t":"We believe in the sovereignty of individuals. As a research organisation that stands for the cause of personal liberty, we aim to maximise social, political, and economic freedoms. This includes being coercion resistant.","s":"I. Liberty","u":"/principles","h":"#i-liberty","p":13},{"i":20,"t":"We enable the free flow of information. No content is under surveillance. We abide by the cryptoeconomic design principle of censorship resistance. Even stronger, we design agnostic infrastructures for information.","s":"II. Censorship resistance","u":"/principles","h":"#ii-censorship-resistance","p":13},{"i":22,"t":"We don't compromise on security when building features. We use state-of-the-art technologies, and research new security methods and technologies to make strong security guarantees.","s":"III. Security","u":"/principles","h":"#iii-security","p":13},{"i":24,"t":"Privacy is the power to selectively reveal oneself to the world. For us, it's essential to protect privacy in both communications and transactions, as well as pseudo-anonymity. Additionally, we strive to provide the right of total anonymity.","s":"IV. Privacy","u":"/principles","h":"#iv-privacy","p":13},{"i":26,"t":"We strive for complete openness and symmetry of information within the organisation, and have no border between our core contributors and our community. We are frank about our shortcomings, especially when making short-term tradeoffs in service of our long-term goals.","s":"V. Transparency","u":"/principles","h":"#v-transparency","p":13},{"i":28,"t":"The software we create is a public good. It is made available via a free and open-source licence, for anyone to share, modify, and benefit from. We believe in permissionless participation.","s":"VI. Openness","u":"/principles","h":"#vi-openness","p":13},{"i":30,"t":"We minimise centralisation across both the software and the organisation itself. In other words, we maximise the number of physical computers composing the network, and maximise the number of individuals who have control over the system(s) we are building.","s":"VII. Decentralisation","u":"/principles","h":"#vii-decentralisation","p":13},{"i":32,"t":"We believe in fair and widespread access to our software, with an emphasis on ease of use. This also extends to social inclusivity, permissionless participation, interoperability, and investing in educational efforts.","s":"VIII. Inclusivity","u":"/principles","h":"#viii-inclusivity","p":13},{"i":34,"t":"We create software incentivised to continue to exist and improve without the stewardship of a single entity or any of the current team members.","s":"IX. Continuance","u":"/principles","h":"#ix-continuance","p":13},{"i":36,"t":"We are relentlessly resourceful. As we grow and have ready access to capital, it is our obligation to token holders to fight bureaucracy and inefficiencies within the organisation. This means solving problems in the most effective way possible at lower economic costs (in terms of capital, time, and resources).","s":"X. Resourcefulness","u":"/principles","h":"#x-resourcefulness","p":13},{"i":38,"t":"Vac is a principle-driven research and development group that provides technical support to each IFT startup. Vac comprises R&D Service Units, Deep Research, and Incubator Projects. We do applied research based on which we build protocols, libraries, specifications, and publications. As custodians of these protocols, our aim is to adhere to a set of principles that ensure their alignment with our core values and objectives.","s":"About Vac","u":"/","h":"","p":37},{"i":40,"t":"Join the Vac Community! Keep up to date with our latest research by connecting with us on our communities channels. Follow us on X Join the community on Discord Share your thoughts on the latest research on the Vac research forum","s":"Join the community","u":"/community","h":"","p":39},{"i":42,"t":"On this page Last updated: 9 February 2024 This Privacy Policy is intended to inform users of our approach to privacy in respect of this website (\"Website\"). In this regard, if you are visiting our Website, this Privacy Policy applies to you.","s":"Privacy Policy","u":"/privacy-policy","h":"","p":41},{"i":44,"t":"For the purposes of this Privacy Policy and the collection and processing of personal data as a controller, the relevant entity is the Logos Collective Association, which has its registered office in Zug and its legal domicile address at Logos Collective Association c/o PST Consulting GmbH Baarerstrasse 10 6300 Zug Switzerland Whenever we refer to “Logos”, “we” or other similar references, we are referring to the Logos Collective Association.","s":"1) Who we are","u":"/privacy-policy","h":"#1-who-we-are","p":41},{"i":46,"t":"We aim to limit the collection and collection and processing of personal data from users of the Website. We only collect and process certain personal data for specific purposes and where we have the legal basis to do so under applicable privacy legislation. We will not collect or process any personal data that we don’t need and where we do store any personal data, we will only store it for the least amount of time needed for the indicated purpose. In this regard, we collect and process the following personal data from your use of the Website: IP address: As part of such use of the Website we briefly process your IP address but we have no way of identifying you. We however have a legitimate interest in processing such IP addresses to ensure the technical functionality and enhance the security measures of the Website. This IP address is not stored by us over time.","s":"2) We limit the collection and processing of personal data from your use of the Website","u":"/privacy-policy","h":"#2-we-limit-the-collection-and-processing-of-personal-data-from-your-use-of-the-website","p":41},{"i":48,"t":"In addition to our limited and collection of personal data, third parties may collect or process personal data as a result of the Website making use of certain features or to provide certain content. To the extent you interact with such third party content or features, their respective privacy policies will apply.","s":"3) Third party processing of personal data","u":"/privacy-policy","h":"#3-third-party-processing-of-personal-data","p":41},{"i":50,"t":"As a general approach, we take data security seriously and we have implemented a variety of security measures on the Website to maintain the safety of your personal data when you submit such information to us.","s":"4) Security measures we take in respect of the Website","u":"/privacy-policy","h":"#4-security-measures-we-take-in-respect-of-the-website","p":41},{"i":52,"t":"We are obliged to protect the privacy of personal data that you may have submitted in the unlikely event that we export your personal data to places outside the European Union or Switzerland. This means that personal data will only be processed in countries or by parties that provide an adequate level of protection as deemed by Switzerland or the European Commission. Otherwise, we will use other forms of protections, such as specific forms of contractual clauses to ensure such personal data is provided the same protection as required in Switzerland or Europe. In any event, the transmission of personal data outside the European Union and Switzerland will always occur in conformity with applicable privacy legislation.","s":"5) Exporting data outside the European Union and Switzerland","u":"/privacy-policy","h":"#5-exporting-data-outside-the-european-union-and-switzerland","p":41},{"i":54,"t":"As explained in this Privacy Policy, we limit our collection and processing of your personal data wherever possible. Nonetheless, you still have certain choices and rights in respect of the personal data which we do collect and process. As laid out in relevant privacy legislation, you have the right to: Ask us to correct or update your personal data (where reasonably possible); Ask us to remove your personal data from our systems; Ask us for a copy of your personal data, which may also be transferred to another data controller at your request; Withdraw your consent to process your personal data (only if consent was asked for a processing activity), which only affects processing activities that are based on your consent and doesn’t affect the validity of such processing activities before you have withdrawn your consent; Object to the processing of your personal data; and File a complaint with the Federal Data Protection and Information Commissioner (FDPIC), if you believe that your personal data has been processed unlawfully.","s":"6) Your choices and rights","u":"/privacy-policy","h":"#6-your-choices-and-rights","p":41},{"i":56,"t":"On this Website, you may come across links to third party websites. These third party sites have separate and independent privacy policies. We therefore have no responsibility or liability for the content and activities of these third party websites.","s":"7) Third party links","u":"/privacy-policy","h":"#7-third-party-links","p":41},{"i":58,"t":"We may modify or replace any part of this Privacy Policy at any time and without notice. Please check the Website periodically for any changes. The new Privacy Policy will be effective immediately upon its posting on our Website.","s":"8) This Privacy Policy might change","u":"/privacy-policy","h":"#8-this-privacy-policy-might-change","p":41},{"i":60,"t":"To the extent that you have any questions about the Privacy Policy, please contact us at legal@free.technology. This document is licensed under CC-BY-SA.","s":"9) Contact information","u":"/privacy-policy","h":"#9-contact-information","p":41},{"i":63,"t":"Get in touch with us by joining our Discord, opening a thread in our forum, or opening issues / PRs on GitHub. Also, see our current job openings.","s":"How to Contribute","u":"/contribute","h":"#how-to-contribute","p":61},{"i":65,"t":"We are interested in both research and code contributions. For code contributions, see our \"good first issue\" lists for various Vac-related code bases: nim-libp2p zerokit stealth-address-kit","s":"What to Contribute","u":"/contribute","h":"#what-to-contribute","p":61},{"i":67,"t":"We take security seriously at Vac and across the Institute of Free Technology and its affiliates. Please report any security incidents via security@free.technology. Please report any discovered vulnerabilities in our bounty programme at HackenProof to help ensure our protocols and software remain secure.","s":"Security","u":"/security","h":"","p":66},{"i":69,"t":"Vac's R&D Service Units play a crucial role in supporting IFT projects. In addition to providing expertise, resources, and technical guidance, they also develop software artefacts, such as nim-libp2p and zerokit.","s":"Vac R&D Service Units","u":"/vsus","h":"","p":68},{"i":71,"t":"The P2P R&D Service Unit is a vital part of Vac, specialising in peer-to-peer (P2P) technologies. The P2P unit develops nim-libp2p, works on improving the libp2p gossipsub protocol, and assists projects with the integration of P2P network layers. The P2P unit collaborates closely with Vac Deep Research to conduct research aimed at enhancing libp2p gossipsub. By focusing on advancing P2P technologies, the P2P unit contributes to the overall improvement and efficiency of decentralised networks, enabling seamless decentralised communication within IFT projects and beyond.","s":"P2P","u":"/vsus","h":"#p2p","p":68},{"i":73,"t":"The Vac Token Economics Unit is dedicated to assisting IFT projects in designing their token economies, incentives, and markets. TKE's collaboration with IFT project teams is intensive and occurs on a day-to-day basis, where TKE not only responds to their needs but also proactively drives the conversation forward by suggesting new ideas and strategies based on TKE's research. The team brings together a broad spectrum of skills and knowledge, ranging from the modelling of dynamic systems to theoretical modelling and general cryptoeconomics.","s":"Token Economics (TKE)","u":"/vsus","h":"#token-economics-tke","p":68},{"i":75,"t":"The Distributed Systems Testing (DST) R&D Service Unit is responsible for developing distributed systems testing software. DST's primary objective is to assist IFT projects in understanding the scaling behaviour of their nodes within larger networks. By conducting thorough regression testing, the DST unit helps identify potential bottlenecks and performance issues, ensuring the reliability and stability of the projects. The DST unit's expertise in distributed systems testing enables IFT projects to deliver scalable and resilient solutions that can withstand the demands of real-world decentralised applications.","s":"Distributed Systems Testing (DST)","u":"/vsus","h":"#distributed-systems-testing-dst","p":68},{"i":77,"t":"The QA Service Unit is dedicated to supporting IFT projects through the development and execution of comprehensive test plans. Primary responsibilities include implementing unit tests and interoperability tests to ensure seamless integration and functionality across systems. The QA unit plays a crucial role in the verification of project implementations. By rigorously testing project implementations against defined specifications, QA ensures that all functionalities align with the project's requirements. QA's proactive approach to identifying and reporting bugs ensures that any issues are addressed promptly, enhancing the overall quality and reliability of the software. Through meticulous testing and quality assurance processes, the QA Service Unit ensures that IFT projects deliver robust and high-performing software solutions.","s":"Quality Assurance (QA)","u":"/vsus","h":"#quality-assurance-qa","p":68},{"i":79,"t":"Vac's Smart Contracts Service Unit specialises in the development, maintenance, and auditing of smart contracts for IFT projects. The SC unit ensures that all smart contracts are robust, secure, and aligned with project requirements. SC designs and develops smart contracts tailored to the specific needs of IFT projects, ensuring they function as intended and are up-to-date with any project changes or requirements. The unit's thorough auditing process involves meticulously reviewing smart contracts to identify and rectify potential vulnerabilities, ensuring the highest standards of security and reliability.","s":"Smart Contracts (SC)","u":"/vsus","h":"#smart-contracts-sc","p":68},{"i":81,"t":"With the IFT's extensive use of the Nim ecosystem, the Nim Service Unit focuses on the development and maintenance of Nim tooling and core libraries essential for IFT projects. The Nim unit works on critical tools in the Nim ecosystem, including the Nim compiler, Nimble (package manager), and nim-suggest, ensuring they are efficient, reliable, and up-to-date. The Nim unit further plans to maintain core libraries developed by IFT, such as Chronos. The mandate of the Nim unit also includes providing support to IFT projects regarding the use of Nim, identifying and addressing specific project needs and demands related to the Nim ecosystem.","s":"Nim","u":"/vsus","h":"#nim","p":68},{"i":83,"t":"The Applied Cryptography & ZK R&D Service Unit focuses on cryptographic solutions and zero-knowledge (ZK) proofs. ACZ provides valuable assistance to IFT projects by offering expertise in employing ZK proofs and implementing cryptographic techniques. The ACZ unit specialises in areas such as employing noise protocol channels and other cryptographic-related aspects. By leveraging cutting-edge cryptographic technologies, ACZ enhances the security, privacy, and trustworthiness of Logos projects, contributing to the overall integrity and resilience of the decentralised web ecosystem. ACZ develops zerokit and stealth-address-kit.","s":"Applied Cryptography & ZK (ACZ)","u":"/vsus","h":"#applied-cryptography--zk-acz","p":68},{"i":85,"t":"The Vac RFC unit serves as a vital cornerstone in the IFT, taking on the responsibility of shepherding and editing specifications for IFT projects. By meticulously crafting and overseeing these specifications, the Vac RFC unit acts as a linchpin for ensuring standardised and interoperable protocols within the IFT ecosystem The RFC unit's expertise and attention to detail contribute to a cohesive and collaborative environment, facilitating seamless integration and advancement of decentralised technologies throughout the IFT and beyond.","s":"RFC","u":"/vsus","h":"#rfc","p":68},{"i":87,"t":"The Vac RFC unit serves as a vital cornerstone in the Logos collective, taking on the responsibility of shepherding and editing specifications for Logos projects and Vac incubator projects. By meticulously crafting and overseeing these specifications, the Vac RFC unit acts as a linchpin for ensuring standardised and interoperable protocols within the Logos ecosystem. Their expertise and attention to detail contribute to a cohesive and collaborative environment, facilitating seamless integration and advancement of decentralised technologies throughout the Logos collective and beyond.","s":"Vac RFC Process","u":"/rfcprocess","h":"","p":86},{"i":90,"t":"Waku: A Family of Modular P2P Protocols For Secure & Censorship-Resistant Communication (demo) WAKU-RLN-RELAY: Privacy-Preserving Peer-to-Peer Economic Spam Protection (full) Privacy-Preserving Spam-Protected Gossip-Based Routing (poster)","s":"Papers","u":"/publications","h":"#papers","p":88},{"i":92,"t":"See write-ups.","s":"Write-ups","u":"/publications","h":"#write-ups","p":88},{"i":94,"t":"On this page Last updated: 14 February 2024 These website terms of use ('Website Terms of Use') are entered into by you and us, and they govern your access and use of this Website, including any content and functionality contained in the Website. It is your responsibility to read the Website Terms of Use carefully before your use of the Website and your use of the Website means you have agreed to be bound and comply with these Website Terms of Use. If you do not agree with these Website Terms of Use, you must not access or use the Website.","s":"Terms of Use","u":"/terms","h":"","p":93},{"i":96,"t":"For the purposes of these Website Terms of Use, the relevant entity is the Logos Collective Association, which has its registered office in Zug and its legal domicile address at: Logos Collective Association c/o PST Consulting GmbH Baarerstrasse 10 6300 Zug Switzerland Whenever we refer to “Logos”, “we”, “us” or any other similar references, we are referring to the Logos Collective Association.","s":"1) Who we are","u":"/terms","h":"#1-who-we-are","p":93},{"i":98,"t":"The Website is provided by us on an ‘as is’ basis and you use the Website at your own sole discretion and risk. We disclaim all warranties of any kind, express or implied, including without limitation the warranties of merchantability, fitness for a particular purpose, and non-infringement of intellectual property or other violation of rights. We do not warrant or make any representations concerning the completeness, accuracy, legality, utility, reliability, suitability or availability of the use of the Website, the content on this Website or otherwise relating to the Website, such content or on any sites linked to this site.These disclaimers will apply to the maximum extent permitted by applicable law. We make no claims that the Website or any of its content is accessible, legally compliant or appropriate in your jurisdiction. Your access or use of the Website is at your own sole discretion and you are solely responsible for complying with any applicable local laws. The content herein or as accessible through this website is intended to be made available for informational purposes only and should not be considered as creating any expectations or forming the basis of any contract, commitment or binding obligation with us. No information herein shall be considered to contain or be relied upon as a promise, representation, warranty or guarantee, whether express or implied and whether as to the past, present or the future in relation to the projects and matters described herein. The information contained herein does not constitute financial, legal, tax, or other advice and should not be treated as such. Nothing in this Website should be construed by you as an offer to buy or sell, or soliciting any offer to buy or sell any tokens or any security.","s":"2) Disclaimers","u":"/terms","h":"#2-disclaimers","p":93},{"i":100,"t":"The Website may also contain forward-looking statements that are based on current expectations, estimates, forecasts, assumptions and projections about the technology, industry and markets in general. The forward looking statements, which may include statements about the roadmap, project descriptions, technical details, functionalities, features, the development and use of tokens by projects, and any other statements related to such matters or as accessible through this website are subject to a high degree of risk and uncertainty. The forward looking statements are subject to change based on, among other things, market conditions, technical developments, and regulatory environment. The actual development and results, including the order and the timeline, might vary from what’s presented. The information contained herein is a summary and does not purport to be accurate, reliable or complete and we bear no responsibility for the accuracy, reliability or completeness of information contained herein. Because of the high degree of risk and uncertainty described above, you should not place undue reliance on any matters described in this website or as accessible through this website. While we aim to update our website regularly, all information, including the timeline and the specifics of each stage, is subject to change and may be amended or supplemented at any time, without notice and at our sole discretion.","s":"3) Forward looking statements","u":"/terms","h":"#3-forward-looking-statements","p":93},{"i":102,"t":"The Website and its contents are made available under Creative Commons Attribution 4.0 International license (CC-BY 4.0). In essence this licence allows users to copy, modify and distribute the content in any format for any purpose, including commercial use, subject to certain requirements such as attributing us. For the full terms of this licence, please refer to the following website: https://creativecommons.org/licenses/by/4.0/.","s":"4) Intellectual property rights","u":"/terms","h":"#4-intellectual-property-rights","p":93},{"i":104,"t":"To the extent the Website provides any links to a third party website, then their terms and conditions, including privacy policies, govern your use of those third party websites. By linking such third party websites, Status does not represent or imply that it endorses or supports such third party websites or content therein, or that it believes such third party websites and content therein to be accurate, useful or non-harmful. We have no control over such third party websites and will not be liable for your use of or activities on any third party websites accessed through the Website. If you access such third party websites through the Website, it is at your own risk and you are solely responsible for your activities on such third party websites.","s":"5) Third-party website links","u":"/terms","h":"#5-third-party-website-links","p":93},{"i":106,"t":"We will not be held liable to you under any contract, negligence, strict liability, or other legal or equitable theory for any lost profits, cost of procurement for substitute services, or any special, incidental, or consequential damages related to, arising from, or in any way connected with these Website Terms of Use, the Website, the content on the Website, or your use of the Website, even if we have been advised of the possibility of such damages. In any event, our aggregate liability for such claims is limited to EUR 100 (one hundred Euros). This limitation of liability will apply to the maximum extent permitted by applicable law.","s":"6) Limitation of liability","u":"/terms","h":"#6-limitation-of-liability","p":93},{"i":108,"t":"You shall indemnify us and hold us harmless from and against any and all claims, damages and expenses, including attorneys’ fees, arising from or related to your use of the Website, the content on the Website, including without limitation your violation of these Website Terms of Use.","s":"7) Indemnity","u":"/terms","h":"#7-indemnity","p":93},{"i":110,"t":"We may modify or replace any part of this Website Terms of Use at any time and without notice. You are responsible for checking the Website periodically for any changes. The new Website Terms of Use will be effective immediately upon its posting on the Website.","s":"8) Modifications","u":"/terms","h":"#8-modifications","p":93},{"i":112,"t":"Swiss law governs these Website Terms of Use and any disputes between you and us, whether in court or arbitration, without regard to conflict of laws provisions.","s":"9) Governing law","u":"/terms","h":"#9-governing-law","p":93},{"i":114,"t":"In these terms, “dispute” has the broadest meaning enforceable by law and includes any claim you make against or controversy you may have in relation to these Website Terms of Use, the Website, the content on the Website, or your use of the Website. We prefer arbitration over litigation as we believe it meets our principle of resolving disputes in the most effective and cost effective manner. You are bound by the following arbitration clause, which waives your right to litigation and to be heard by a judge. Please note that court review of an arbitration award is limited. You also waive all your rights to a jury trial (if any) in any and all jurisdictions. If a (potential) dispute arises, you must first use your reasonable efforts to resolve it amicably with us. If these efforts do not result in a resolution of such dispute, you shall then send us a written notice of dispute setting out (i) the nature of the dispute, and the claim you are making; and (ii) the remedy you are seeking. If we and you are unable to further resolve this dispute within sixty (60) calendar days of us receiving this notice of dispute, then any such dispute will be referred to and finally resolved by you and us through an arbitration administered by the Swiss Chambers’ Arbitration Institution in accordance with the Swiss Rules of International Arbitration for the time being in force, which rules are deemed to be incorporated herein by reference. The arbitral decision may be enforced in any court. The arbitration will be held in Zug, Switzerland, and may be conducted via video conference virtual/online methods if possible. The tribunal will consist of one arbitrator, and all proceedings as well as communications between the parties will be kept confidential. The language of the arbitration will be in English. Payment of all relevant fees in respect of the arbitration, including filing, administration and arbitrator fees will be in accordance with the Swiss Rules of International Arbitration. Regardless of any applicable statute of limitations, you must bring any claims within one year after the claim arose or the time when you should have reasonably known about the claim. You also waive the right to participate in a class action lawsuit or a classwide arbitration against us.","s":"10) Disputes","u":"/terms","h":"#10-disputes","p":93},{"i":116,"t":"These Website Terms of Use cover the entire agreement between you and us regarding the Website and supersede all prior and contemporaneous understandings, agreements, representations and warranties, both written and oral, with respect to the Website. The captions and headings identifying sections and subsections of these Website Terms of Use are for reference only and do not define, modify, expand, limit, or affect the interpretation of any provisions of these Website Terms of Use. If any part of these Website Terms of Use is held invalid or unenforceable, that part will be severable from these Website Terms of Use, and the remaining portions will remain in full force and effect. If we fail to enforce any of these Website Terms of Use, that does not mean that we have waived our right to enforce them. If you have any specific questions about these Website Terms of Use, please contact us at legal@free.technology. This document is licensed under CC-BY-SA.","s":"11) About these Website Terms of Use","u":"/terms","h":"#11-about-these-website-terms-of-use","p":93},{"i":118,"t":"Vac incubator projects are emerging initiatives that stem from Vac's deep research efforts. These projects are envisioned to eventually become separate IFT projects, benefiting from the support and resources of both the Deep Research and R&D Service Units within Vac. The incubator projects operate within Vac, leveraging the expertise and collaboration available to them.","s":"Vac Incubator Projects","u":"/vips","h":"","p":117},{"i":120,"t":"Nescience focuses on developing a privacy-preserving general-purpose zero-knowledge virtual machine. It enables privacy-preserving computing, which holds significant importance for IFT programs, especially Logos.","s":"Nescience","u":"/vips","h":"#nescience","p":117}],"index":{"version":"2.3.9","fields":["t"],"fieldVectors":[["t/2",[0,1.719,1,2.959,2,2.358,3,2.744,4,2.113,5,2.364,6,2.364,7,2.744,8,1.836,9,1.891,10,2.113,11,2.364,12,1.926,13,2.744,14,2.113,15,1.926,16,2.744,17,2.744,18,1.777,19,2.364,20,4.101,21,1.777,22,1.653,23,2.364,24,1.926,25,1.007,26,1.547,27,1.109,28,2.656,29,1.566,30,2.113,31,4.101,32,2.744,33,1.653,34,1.926,35,1.836,36,1.547,37,2.744,38,2.744,39,1.653,40,2.364,41,2.744,42,1.453,43,2.744,44,2.364,45,2.744,46,2.113,47,1.777,48,1.653,49,2.113,50,1.296,51,1.435,52,1.926,53,2.364,54,1.296,55,1.453,56,2.364,57,1.547,58,1.926,59,1.926]],["t/4",[0,1.815,1,3.125,2,2.098,4,2.936,8,1.707,21,2.469,28,2.469,29,1.216,42,2.019,47,2.469,48,2.297,49,2.936,50,1.801,51,1.334,52,2.677,55,2.019,60,3.812,61,3.284,62,2.469,63,2.149,64,3.812,65,3.812,66,2.936,67,3.812,68,3.812,69,3.284,70,3.812,71,3.812,72,2.019,73,2.677,74,3.812,75,3.812,76,3.812,77,1.904,78,3.284,79,3.284]],["t/6",[0,1.767,1,3.043,2,2.336,4,2.824,8,1.642,9,1.411,21,2.374,29,1.169,46,2.824,50,1.732,55,1.942,57,2.847,58,3.546,59,3.546,63,2.066,80,3.158,81,3.665,82,2.574,83,2.374,84,2.824,85,2.824,86,1.942,87,1.942,88,2.574,89,3.665,90,3.665,91,2.208,92,3.665,93,1.942,94,2.824,95,1.942,96,2.574,97,2.824,98,3.158,99,2.824,100,2.824]],["t/8",[0,1.778,2,2.054,29,1.62,55,2.691,57,2.864,58,3.567,100,3.913,101,6.248,102,5.08,103,3.913,104,5.08,105,2.275,106,5.08]],["t/10",[0,1.598,39,1.914,50,1.501,61,2.737,86,1.683,95,1.683,107,5.553,108,5.346,109,3.177,110,3.177,111,2.958,112,3.177,113,3.177,114,4.567,115,5.845,116,3.177,117,2.737,118,2.058,119,4.347,120,3.177,121,2.737,122,3.177,123,3.177,124,3.177,125,0.968,126,5.346,127,5.346,128,4.567,129,3.177,130,4.567,131,3.177,132,1.791,133,3.177,134,2.058,135,3.177,136,3.177]],["t/12",[0,1.516,2,2.284,47,3.658,48,3.403,55,2.294,57,2.441,66,3.336,137,5.648,138,6.66,139,6.66,140,2.164,141,1.939,142,3.336,143,4.331,144,3.731,145,3.731,146,3.731]],["t/14",[62,3.576,147,4.257,148,5.521,149,5.521,150,5.521,151,5.521,152,3.576]],["t/16",[0,1.754,50,2.369,103,3.862,147,3.247,153,4.319,154,6.198,155,4.319,156,5.013,157,5.013,158,5.013,159,5.013,160,5.013,161,5.013,162,5.013]],["t/18",[2,1.926,35,2.133,91,2.87,163,2.87,164,4.763,165,4.103,166,3.344,167,4.763,168,4.763,169,2.685,170,4.763,171,4.103,172,4.103,173,4.763,174,3.344,175,4.763,176,4.103,177,4.763,178,3.669]],["t/20",[93,3.18,111,3.085,147,3.085,178,3.669,179,3.669,180,4.763,181,2.25,182,2.87,183,4.763,184,4.763,185,4.103,186,4.624,187,4.103,188,4.103,189,4.763,190,4.763,191,4.763]],["t/22",[2,1.95,39,2.906,72,3.205,77,3.303,125,1.47,192,4.823,193,4.823,194,3.715,195,3.715,196,4.823,197,4.823,198,4.155,199,3.124,200,4.823,201,4.155]],["t/24",[51,2.052,54,2.169,95,2.432,118,2.974,202,4.591,203,4.591,204,4.591,205,4.591,206,3.955,207,4.591,208,3.955,209,2.974,210,4.591,211,3.955,212,4.591,213,5.865,214,4.591,215,3.955,216,2.974,217,4.591]],["t/26",[8,2.032,18,2.939,93,2.403,95,2.403,103,3.495,166,3.186,199,2.939,215,3.908,218,3.495,219,3.495,220,4.537,221,4.537,222,3.495,223,4.537,224,4.537,225,4.537,226,3.908,227,4.537,228,2.475,229,4.537,230,2.032,231,4.537]],["t/28",[14,3.715,62,3.124,94,3.715,140,2.41,163,2.906,179,3.715,219,3.715,232,3.715,233,4.155,234,3.387,235,3.715,236,4.823,237,4.155,238,4.823,239,3.124,240,4.155,241,4.155,242,3.715]],["t/30",[55,2.492,134,3.047,140,2.35,165,4.053,166,3.303,171,5.131,194,3.624,209,3.047,243,4.704,244,4.704,245,4.704,246,4.704,247,5.956,248,4.704,249,4.053,250,4.704,251,3.303,252,4.704]],["t/32",[11,4.208,34,3.43,125,1.488,140,2.441,153,4.208,163,2.943,172,4.208,241,4.208,242,3.763,253,4.885,254,2.943,255,4.885,256,4.885,257,4.885,258,3.43,259,4.885,260,4.885]],["t/34",[21,3.335,24,3.615,59,3.615,140,2.572,232,3.966,261,5.148,262,5.148,263,5.148,264,2.902,265,5.148,266,5.148,267,3.966,268,5.148]],["t/36",[8,1.939,82,3.041,166,3.041,174,3.041,228,1.842,254,2.609,269,4.331,270,4.35,271,4.331,272,4.331,273,5.648,274,3.336,275,3.041,276,4.331,277,4.331,278,4.331,279,4.331,280,2.805,281,4.331,282,4.331,283,2.805,284,3.041,285,4.331,286,3.336,287,2.609]],["t/38",[0,1.803,1,2.274,2,2.372,9,1.453,14,2.907,26,2.128,27,1.526,28,2.445,29,1.204,54,1.783,87,2.73,91,2.274,105,1.69,141,1.69,147,3.338,194,2.907,222,2.907,230,1.69,288,3.774,289,3.774,290,2.65,291,2.274,292,3.252,293,3.774,294,3.774,295,2.274,296,2.274,297,3.252,298,3.774,299,3.774,300,3.252,301,1.783,302,2.907,303,3.774,304,2.907]],["t/40",[0,2.037,2,2.598,94,3.495,95,3.404,305,5.014,306,4.537,307,3.186,308,3.495,309,5.82,310,3.908,311,3.908,312,3.186,313,4.537,314,3.908,315,4.537,316,3.908]],["t/42",[51,2.261,93,2.432,295,2.766,317,3.955,318,3.955,319,3.224,320,4.591,321,3.955,322,3.955,323,3.107,324,3.537,325,3.537,326,3.537,327,2.974,328,2.061,329,2.974,330,4.591]],["t/44",[24,2.65,51,1.321,132,2.128,169,2.128,251,2.65,323,1.999,331,2.274,332,3.798,333,2.128,334,2.65,335,4.083,336,5.054,337,3.252,338,3.252,339,3.969,340,2.445,341,3.252,342,2.128,343,3.252,344,3.252,345,3.252,346,3.252,347,3.252,348,3.252,349,3.252,350,2.65,351,3.252,352,3.8,353,3.252]],["t/46",[25,1.529,33,1.689,36,1.581,42,1.485,51,0.981,77,1.401,82,1.969,83,1.816,91,1.689,105,1.256,125,1.27,132,3.318,134,1.816,169,3.318,182,1.689,287,2.511,290,1.969,301,1.325,312,1.969,325,2.16,328,1.757,329,1.816,331,2.511,332,3.546,333,3.477,340,1.816,342,3.105,354,1.485,355,1.969,356,2.16,357,2.16,358,2.804,359,2.927,360,4.975,361,2.804,362,2.804,363,5.507,364,2.804,365,2.804,366,2.416,367,1.816,368,2.416]],["t/48",[25,1.52,51,1.45,54,1.957,79,3.569,125,1.262,132,3.092,169,3.092,181,2.592,195,4.225,199,2.684,295,2.496,323,2.195,327,2.684,328,1.321,332,3.305,333,2.335,354,2.195,355,3.852,369,3.569,370,4.225,371,3.553,372,3.191,373,2.684]],["t/50",[25,1.77,77,3.023,93,2.555,132,3.411,169,2.719,326,3.715,328,1.538,368,4.155,374,3.387,375,3.387,376,4.155,377,3.715,378,4.823,379,4.155,380,4.823,381,4.155]],["t/52",[25,1.636,42,1.629,51,1.561,54,2.107,105,1.377,118,3.729,125,0.937,132,3.445,144,2.649,169,3.445,274,2.369,280,1.992,301,1.453,333,1.733,350,4.042,357,2.369,371,1.992,381,2.649,382,3.075,383,3.842,384,3.075,385,2.649,386,4.46,387,5.248,388,4.46,389,3.075,390,3.075,391,2.649,392,3.075,393,2.649,394,3.842,395,3.075,396,2.649,397,3.075,398,2.159,399,3.075,400,3.075,401,3.075,402,2.649,403,3.075]],["t/54",[15,3.32,25,0.945,51,1.369,56,2.22,80,2.22,93,1.365,118,1.669,132,3.765,163,1.553,169,3.606,216,2.534,251,1.809,284,2.747,296,1.553,304,1.985,319,1.809,323,1.365,327,1.669,332,2.357,333,3.606,334,1.809,354,1.365,355,1.809,357,1.985,404,2.577,405,2.577,406,2.577,407,2.577,408,2.577,409,2.577,410,2.22,411,5.279,412,2.577,413,2.22,414,2.577,415,1.809,416,2.22,417,2.577,418,2.577,419,2.577,420,5.279,421,3.37,422,2.577,423,2.22,424,2.577,425,2.22,426,2.577,427,2.577,428,2.577,429,2.577,430,2.577]],["t/56",[15,3.263,51,1.626,181,2.196,323,2.462,328,2.073,370,5.006,371,4.21,431,4.647,432,3.58,433,4.004,434,4.004,435,4.647,436,4.647,437,2.196,438,4.004]],["t/58",[33,2.8,39,2.8,51,2.068,152,3.01,239,3.01,264,2.62,283,3.01,287,2.8,323,3.131,328,1.885,439,4.004,440,3.263,441,2.8,442,4.004,443,4.004,444,4.004,445,3.58,446,4.004]],["t/60",[51,1.826,182,3.144,323,2.765,373,3.381,441,3.144,447,4.496,448,4.496,449,4.496,450,4.496,451,4.02,452,4.02,453,4.496]],["t/63",[119,3.52,219,5.182,267,3.862,305,4.319,314,4.319,316,4.319,454,5.013,455,5.013,456,3.52,457,5.013,458,5.013,459,3.862,460,5.013]],["t/65",[0,1.588,2,1.834,23,3.908,57,2.557,63,3.281,209,2.939,233,3.908,296,2.733,342,2.557,366,3.908,456,3.186,459,3.495,461,6.426,462,3.908,463,4.537,464,2.403,465,3.186,466,3.495,467,3.908,468,3.908]],["t/67",[0,1.516,72,2.294,77,3.14,87,2.294,140,2.164,179,3.336,235,3.336,301,2.046,375,3.041,376,3.731,441,3.403,469,3.731,470,4.331,471,4.866,472,4.331,473,4.331,474,4.331,475,3.731,476,4.331,477,4.331,478,4.331,479,3.731,480,3.731]],["t/69",[9,1.747,25,1.665,26,2.557,27,1.834,29,1.447,54,2.144,57,2.557,140,2.267,141,2.032,230,2.032,270,3.495,290,3.186,291,2.733,369,3.908,465,3.186,466,3.495,481,3.495,482,3.908,483,3.908,484,3.908,485,2.733,486,4.537,487,4.537]],["t/71",[0,1.579,1,1.883,2,1.825,8,1.4,9,1.203,10,2.407,12,2.195,22,1.883,26,1.762,27,2.345,29,1.439,33,1.883,50,2.132,55,2.391,57,2.986,58,3.169,59,3.169,63,1.762,72,2.391,73,2.195,83,2.025,85,2.407,87,1.656,88,2.195,91,1.883,95,1.656,96,2.195,99,5.09,100,2.407,111,2.025,141,1.4,230,1.4,465,2.195,488,2.407,489,2.407,490,3.888,491,2.195,492,2.025,493,3.125,494,2.195,495,2.195]],["t/73",[0,1.181,2,1.364,9,1.835,21,3.088,22,2.033,27,1.364,29,1.52,30,2.599,39,2.033,48,2.033,174,2.369,185,2.907,186,2.599,275,3.347,296,2.033,356,2.599,359,2.369,374,2.369,402,2.907,415,2.369,491,2.369,496,2.907,497,3.374,498,3.374,499,2.907,500,4.766,501,3.374,502,4.106,503,3.374,504,3.374,505,2.907,506,3.374,507,3.374,508,2.907,509,2.907,510,3.374,511,3.374,512,3.374,513,3.374,514,3.374,515,3.374,516,3.374,517,4.766,518,3.374,519,3.374]],["t/75",[8,1.4,9,1.737,26,1.762,27,1.825,29,1.689,36,1.762,42,1.656,50,1.477,53,2.693,55,1.656,84,2.407,86,1.656,88,2.195,98,2.693,111,2.025,140,1.562,141,1.4,142,4.468,206,2.693,230,1.4,301,1.477,304,2.407,415,3.719,437,1.477,456,2.195,479,2.693,485,1.883,491,2.195,520,4.563,521,5.297,522,3.125,523,2.693,524,2.693,525,3.125,526,3.125,527,3.125,528,2.693,529,3.125,530,2.407,531,3.125,532,3.125,533,2.407,534,2.693,535,2.693,536,2.407,537,3.125,538,2.693,539,3.125]],["t/77",[9,1.562,27,2.188,29,1.725,35,1.211,36,1.525,83,1.752,84,2.083,86,1.433,96,1.899,97,2.083,105,1.211,140,2.027,141,1.211,142,4.465,230,1.817,258,1.899,291,1.63,301,2.556,302,2.083,326,2.083,333,1.525,342,1.525,367,2.628,377,3.75,398,1.899,415,1.899,437,1.278,456,1.899,471,2.33,482,2.33,483,2.33,484,2.33,492,1.752,495,1.899,496,2.33,505,2.33,523,2.33,534,2.33,536,2.083,540,5.41,541,2.628,542,2.705,543,2.705,544,2.33,545,2.705,546,2.705,547,2.083,548,2.33,549,2.705,550,2.705,551,2.705,552,2.705,553,4.057,554,1.899,555,2.705,556,2.33]],["t/79",[9,1.758,27,1.847,29,1.864,36,1.791,77,2.282,86,1.683,97,2.448,105,1.423,141,2.045,152,2.058,186,2.448,230,1.423,301,2.526,302,2.448,307,2.231,308,2.448,324,2.448,333,1.791,359,2.231,367,2.058,398,3.207,475,2.737,481,2.448,489,2.448,528,2.737,530,2.448,533,2.448,554,2.231,557,6.191,558,4.769,559,2.737,560,4.567,561,4.567,562,3.177,563,3.177,564,2.737,565,3.177,566,3.177,567,3.177]],["t/81",[9,1.966,10,2.26,25,1.076,27,2.276,29,1.629,35,1.93,36,1.653,54,1.386,85,2.26,86,1.554,105,1.314,125,1.313,141,1.93,208,2.527,222,3.319,230,1.314,291,1.767,297,3.712,301,1.386,307,2.06,308,2.26,329,1.9,342,1.653,359,2.06,379,2.527,464,1.554,465,4.91,494,2.06,509,2.527,538,2.527,544,2.527,559,2.527,568,2.933,569,2.933,570,3.586,571,4.309,572,2.933,573,2.933,574,2.933,575,2.933,576,2.933,577,2.527,578,2.933,579,2.933]],["t/83",[5,2.607,6,2.607,9,1.165,25,1.11,26,1.706,27,1.783,29,1.406,46,2.331,47,1.96,48,1.823,49,4.006,50,1.43,51,1.059,54,1.43,63,1.706,69,3.798,72,1.603,77,1.512,83,1.96,87,1.603,96,2.125,119,2.125,141,1.355,146,4.922,155,2.607,230,1.355,295,1.823,311,2.607,335,1.96,342,1.706,377,2.331,464,1.603,466,2.331,467,2.607,468,2.607,485,1.823,489,2.331,491,2.125,492,1.96,494,2.125,535,2.607,536,2.331,570,2.125,580,3.026,581,5.713,582,3.026,583,2.607,584,4.409,585,3.026,586,3.026,587,3.026,588,2.607,589,3.026]],["t/85",[0,1.711,8,1.566,9,2.349,12,2.456,22,2.107,27,1.977,29,1.116,50,1.653,63,1.972,72,1.853,73,2.456,87,1.853,105,2.189,258,2.456,301,1.653,375,2.456,437,1.653,485,2.107,488,2.694,492,2.266,495,2.456,533,2.694,554,2.456,570,2.456,590,4.855,591,3.013,592,3.013,593,3.013,594,3.013,595,3.013,596,3.013,597,3.013,598,3.013,599,3.013,600,3.013,601,2.694,602,3.013,603,2.694,604,3.013,605,3.013]],["t/87",[0,1.943,8,1.524,12,2.39,22,2.051,27,1.939,28,2.205,29,1.53,50,1.608,63,1.919,72,1.803,73,2.39,87,1.803,105,2.148,258,2.39,301,1.608,332,2.89,335,3.906,375,2.39,437,1.608,485,2.051,488,2.622,492,2.205,495,2.39,554,2.39,570,2.39,590,4.132,591,2.933,592,2.933,593,2.933,594,2.933,595,2.933,596,2.933,597,2.933,598,2.933,599,2.933,600,2.933,601,2.622,602,2.933,603,2.622,604,2.933,605,2.933]],["t/90",[51,1.934,52,3.88,77,2.093,87,2.219,95,2.219,99,3.226,107,4.76,117,4.76,118,3.579,119,2.941,174,2.941,178,3.226,187,3.608,296,2.523,490,4.76,606,4.188,607,4.188,608,4.188,609,4.188,610,4.188,611,3.226,612,4.188,613,4.188,614,4.188]],["t/92",[307,4.179,459,4.584,615,5.951]],["t/94",[35,1.581,125,2.161,181,1.668,228,2.739,254,2.964,280,2.287,317,3.041,318,3.041,319,2.479,321,3.041,322,3.041,328,2.291,367,2.287,423,3.041,437,1.668,616,3.53,617,3.53,618,2.719,619,2.719,620,3.53,621,3.53,622,4.92,623,3.041,624,3.041]],["t/96",[24,2.759,125,1.197,228,1.671,328,1.253,331,2.368,332,3.608,334,2.759,335,4.152,336,5.16,337,3.385,338,3.385,339,4.079,340,2.546,341,3.385,342,2.215,343,3.385,344,3.385,345,3.385,346,3.385,347,3.385,348,3.385,349,3.385,350,2.759,351,3.385,352,3.88,353,3.385]],["t/98",[25,1.124,29,0.602,35,0.846,42,1.623,54,0.892,62,1.223,77,0.944,86,1.001,93,2.048,125,1.178,181,2.102,199,1.985,201,1.627,216,1.223,218,1.455,232,1.455,234,2.152,254,2.329,264,1.065,274,1.455,275,1.326,295,1.138,324,1.455,328,1.894,331,1.846,340,2.504,354,1.001,356,2.36,373,1.223,393,1.627,394,1.627,432,1.455,433,1.627,437,0.892,445,1.455,464,1.623,541,1.223,558,1.455,583,2.64,619,2.36,624,1.627,625,2.978,626,2.64,627,1.455,628,3.064,629,3.331,630,1.889,631,3.064,632,2.64,633,1.889,634,1.889,635,1.889,636,1.627,637,1.889,638,1.889,639,1.889,640,1.627,641,1.889,642,2.64,643,1.889,644,1.627,645,1.889,646,1.889,647,1.889,648,1.627,649,1.627,650,2.152,651,1.326,652,1.889,653,1.889,654,1.627,655,1.889,656,3.427,657,3.064,658,1.627,659,1.889,660,1.889,661,1.455,662,1.889,663,1.889,664,2.64,665,1.889,666,1.627,667,1.889,668,1.627,669,1.627,670,1.889,671,1.889,672,1.889,673,1.889,674,1.889,675,1.889,676,1.889,677,3.064,678,3.064,679,1.889]],["t/100",[25,0.791,29,1.347,35,1.891,72,1.142,86,1.804,91,1.298,93,2.237,105,0.965,125,0.657,141,1.891,152,2.206,195,1.66,218,2.623,254,2.052,264,1.215,267,1.66,275,1.513,287,1.298,290,2.391,292,1.857,296,2.052,319,1.513,328,1.667,367,1.396,372,1.66,374,1.513,385,1.857,437,1.018,440,1.513,464,1.142,499,2.934,508,3.638,541,2.206,556,2.934,601,1.66,603,1.66,619,3.253,625,1.66,626,1.857,627,2.623,644,1.857,656,2.623,658,1.857,666,1.857,668,2.934,669,2.934,680,4.223,681,5.225,682,2.155,683,2.155,684,2.155,685,2.155,686,2.155,687,2.155,688,3.638,689,3.406,690,3.406,691,2.155,692,1.857,693,2.155,694,2.155,695,2.155,696,3.406,697,2.155,698,2.155,699,2.155,700,2.155,701,1.857,702,2.155,703,2.155,704,2.155,705,2.155,706,2.155,707,2.155,708,2.155,709,2.155]],["t/102",[25,1.399,35,1.707,40,3.284,62,2.469,125,1.161,181,2.451,182,2.297,228,1.621,234,2.677,237,4.469,239,2.469,312,2.677,325,2.936,328,1.654,331,2.297,352,2.469,355,2.677,398,2.677,416,3.284,441,2.297,451,2.936,452,2.936,520,3.284,611,2.936,688,3.284,710,3.812,711,3.812,712,5.187,713,5.187,714,3.284,715,3.812,716,3.812,717,3.812,718,3.812]],["t/104",[15,2.927,25,2.263,35,1.256,51,0.981,54,1.325,121,2.416,125,1.516,134,1.816,163,1.689,181,1.969,228,1.192,251,1.969,254,2.511,291,1.689,323,1.485,328,2.236,370,5.164,371,4.343,373,1.816,432,3.211,437,1.325,541,2.7,618,2.16,625,2.16,627,2.16,632,2.416,636,2.416,692,2.416,701,2.416,719,2.804,720,2.804,721,2.804,722,4.168,723,2.804,724,2.416]],["t/106",[19,2.807,25,1.706,42,1.726,82,2.288,125,1.417,181,1.54,182,1.963,188,2.807,228,1.386,230,1.459,284,2.288,286,2.51,295,1.963,310,2.807,328,1.886,340,2.111,354,2.464,373,2.111,383,2.807,438,4.671,464,1.726,558,2.51,648,2.807,649,2.807,650,2.288,651,2.288,724,2.807,725,2.51,726,3.259,727,3.259,728,3.259,729,3.259,730,3.259,731,3.259,732,3.259,733,3.259,734,3.259,735,3.259,736,4.006,737,2.51,738,3.259,739,3.259,740,3.259,741,3.259,742,2.807,743,3.259,744,3.259]],["t/108",[35,2.587,125,1.76,181,2.118,228,1.906,264,2.527,328,2.038,354,2.375,464,2.375,547,3.454,640,3.862,651,3.148,661,3.454,736,3.862,737,3.454,745,4.483,746,3.862,747,4.483,748,4.483,749,4.483,750,3.862]],["t/110",[33,2.733,39,2.733,125,1.773,152,2.939,228,2.475,239,2.939,264,2.557,283,2.939,287,2.733,328,2.162,437,2.144,439,3.908,440,3.186,442,3.908,443,3.908,444,3.908,445,3.495,446,3.908]],["t/112",[18,3.205,125,1.508,228,2.104,264,2.789,328,1.578,329,3.205,618,3.812,650,4.317,664,4.263,751,4.263,752,4.263,753,4.263,754,4.263,755,4.948,756,4.263]],["t/114",[8,1.158,18,0.997,25,0.949,30,1.185,34,1.816,35,1.158,42,0.815,78,1.325,88,1.08,95,0.815,125,1.02,134,0.997,147,0.997,163,0.927,176,1.325,181,0.727,198,1.325,199,1.676,211,1.325,216,2.168,228,1.1,235,1.185,242,1.185,280,0.997,283,1.676,284,1.08,286,1.185,287,1.558,300,1.325,312,1.08,327,0.997,328,1.251,334,1.08,339,1.185,350,1.08,352,1.676,354,1.37,371,0.997,372,1.185,391,1.325,396,1.325,410,1.325,413,2.228,425,1.325,440,1.816,441,0.927,462,1.325,464,0.815,469,1.325,502,1.325,530,1.185,541,0.997,547,1.992,564,1.325,577,1.325,623,1.325,650,1.08,651,3.072,654,1.325,656,1.185,661,1.185,714,2.228,725,1.185,737,1.185,742,2.228,750,2.228,751,2.883,752,4.74,753,2.228,754,5.356,757,1.538,758,2.228,759,1.538,760,1.538,761,2.587,762,1.538,763,3.923,764,1.538,765,2.883,766,1.538,767,1.538,768,1.538,769,1.538,770,1.538,771,1.538,772,1.538,773,1.538,774,1.538,775,1.325,776,1.538,777,1.538,778,1.538,779,1.538,780,1.538,781,1.538,782,1.538,783,1.538,784,1.538,785,1.538,786,1.538,787,1.538,788,2.587,789,3.347,790,1.325,791,1.538,792,1.538,793,1.538,794,1.538,795,1.538,796,1.538,797,1.538,798,1.538,799,1.538,800,1.538,801,1.538,802,1.538,803,1.538,804,1.538,805,1.538,806,1.538,807,1.538,808,1.538,809,1.538,810,1.538,811,1.538,812,1.538]],["t/116",[18,1.752,33,2.444,36,1.525,44,2.33,105,1.211,125,1.923,182,1.63,209,1.752,216,1.752,228,2.684,239,1.752,280,1.752,283,1.752,327,1.752,328,2.118,329,1.752,352,1.752,354,1.433,421,2.33,441,1.63,447,2.33,448,2.33,449,2.33,450,2.33,451,2.083,452,2.083,453,2.33,480,3.495,524,2.33,548,2.33,611,2.083,629,2.33,642,2.33,725,2.083,756,2.33,758,3.495,765,2.33,775,2.33,790,2.33,813,2.705,814,2.705,815,4.057,816,2.705,817,2.705,818,2.705,819,2.705,820,2.705,821,2.705,822,2.705,823,2.705,824,2.705,825,2.705,826,2.705,827,2.705,828,2.705,829,2.705]],["t/118",[0,2.085,1,3.168,2,2.126,8,2.355,9,1.497,22,2.343,26,2.193,27,1.573,28,3.407,29,2.036,34,2.731,209,2.52,230,1.742,234,2.731,240,3.351,270,2.996,291,2.343,434,3.351,481,2.996,485,2.343,588,3.351,830,3.89,831,3.89,832,3.89,833,3.89,834,3.89,835,3.89,836,3.89]],["t/120",[9,1.768,47,2.974,48,2.766,51,2.052,52,4.118,66,3.537,111,2.974,141,2.056,145,3.955,226,3.955,249,3.955,331,2.766,335,2.974,374,3.224,494,3.224,746,3.955,837,4.591,838,4.591,839,4.591,840,4.591]]],"invertedIndex":[["",{"_index":119,"t":{"10":{"position":[[138,1],[189,1],[266,1],[318,1],[431,1]]},"63":{"position":[[94,1]]},"83":{"position":[[25,1]]},"90":{"position":[[51,1]]}}}],["10",{"_index":348,"t":{"44":{"position":[[305,2]]},"96":{"position":[[246,2]]}}}],["100",{"_index":741,"t":{"106":{"position":[[528,3]]}}}],["14",{"_index":616,"t":{"94":{"position":[[27,2]]}}}],["2024",{"_index":322,"t":{"42":{"position":[[38,4]]},"94":{"position":[[39,4]]}}}],["4.0",{"_index":713,"t":{"102":{"position":[[83,3],[116,5]]}}}],["60",{"_index":782,"t":{"114":{"position":[[1068,4]]}}}],["6300",{"_index":349,"t":{"44":{"position":[[308,4]]},"96":{"position":[[249,4]]}}}],["9",{"_index":320,"t":{"42":{"position":[[27,1]]}}}],["abid",{"_index":184,"t":{"20":{"position":[[77,5]]}}}],["abov",{"_index":703,"t":{"100":{"position":[[1073,6]]}}}],["access",{"_index":254,"t":{"32":{"position":[[34,6]]},"36":{"position":[[59,6]]},"94":{"position":[[149,6],[519,6]]},"98":{"position":[[773,11],[845,6],[1007,10]]},"100":{"position":[[451,10],[1163,10]]},"104":{"position":[[563,8],[600,6]]}}}],["accord",{"_index":788,"t":{"114":{"position":[[1290,10],[1937,10]]}}}],["accur",{"_index":701,"t":{"100":{"position":[[872,9]]},"104":{"position":[[399,9]]}}}],["accuraci",{"_index":644,"t":{"98":{"position":[[421,9]]},"100":{"position":[[941,9]]}}}],["achiev",{"_index":157,"t":{"16":{"position":[[82,9]]}}}],["act",{"_index":597,"t":{"85":{"position":[[227,4]]},"87":{"position":[[269,4]]}}}],["action",{"_index":810,"t":{"114":{"position":[[2234,6]]}}}],["activ",{"_index":15,"t":{"2":{"position":[[148,8]]},"54":{"position":[[646,10],[687,10],[780,10]]},"56":{"position":[[209,10]]},"104":{"position":[[524,10],[717,10]]}}}],["actual",{"_index":694,"t":{"100":{"position":[[695,6]]}}}],["acz",{"_index":146,"t":{"12":{"position":[[153,5]]},"83":{"position":[[114,3],[255,3],[423,3],[587,3]]}}}],["addit",{"_index":369,"t":{"48":{"position":[[3,8]]},"69":{"position":[[75,8]]}}}],["addition",{"_index":214,"t":{"24":{"position":[[177,13]]}}}],["address",{"_index":342,"t":{"44":{"position":[[227,7]]},"46":{"position":[[552,8],[623,7],[730,9],[836,7]]},"65":{"position":[[179,7]]},"77":{"position":[[596,9]]},"81":{"position":[[569,10]]},"83":{"position":[[620,7]]},"96":{"position":[[167,7]]}}}],["adequ",{"_index":390,"t":{"52":{"position":[[288,8]]}}}],["adher",{"_index":299,"t":{"38":{"position":[[333,6]]}}}],["administ",{"_index":786,"t":{"114":{"position":[[1227,12]]}}}],["administr",{"_index":803,"t":{"114":{"position":[[1891,14]]}}}],["adopt",{"_index":154,"t":{"16":{"position":[[30,8],[97,8]]}}}],["advanc",{"_index":73,"t":{"4":{"position":[[277,9]]},"71":{"position":[[376,9]]},"85":{"position":[[468,11]]},"87":{"position":[[504,11]]}}}],["advic",{"_index":673,"t":{"98":{"position":[[1586,6]]}}}],["advis",{"_index":738,"t":{"106":{"position":[[412,7]]}}}],["affect",{"_index":421,"t":{"54":{"position":[[668,7],[741,6]]},"116":{"position":[[412,6]]}}}],["affili",{"_index":470,"t":{"67":{"position":[[86,11]]}}}],["against",{"_index":547,"t":{"77":{"position":[[403,7]]},"108":{"position":[[53,7]]},"114":{"position":[[102,7],[2276,7]]}}}],["aggreg",{"_index":739,"t":{"106":{"position":[[474,9]]}}}],["agnost",{"_index":190,"t":{"20":{"position":[[173,8]]}}}],["agre",{"_index":622,"t":{"94":{"position":[[390,6],[467,5]]}}}],["agreement",{"_index":815,"t":{"116":{"position":[[44,9],[155,11]]}}}],["aim",{"_index":91,"t":{"6":{"position":[[271,4]]},"18":{"position":[[123,3]]},"38":{"position":[[323,3]]},"46":{"position":[[3,3]]},"71":{"position":[[324,5]]},"100":{"position":[[1205,3]]}}}],["align",{"_index":302,"t":{"38":{"position":[[381,9]]},"77":{"position":[[471,5]]},"79":{"position":[[199,7]]}}}],["allow",{"_index":40,"t":{"2":{"position":[[451,8]]},"102":{"position":[[146,6]]}}}],["alway",{"_index":401,"t":{"52":{"position":[[662,6]]}}}],["amend",{"_index":708,"t":{"100":{"position":[[1347,7]]}}}],["amic",{"_index":772,"t":{"114":{"position":[[755,8]]}}}],["amount",{"_index":361,"t":{"46":{"position":[[403,6]]}}}],["anonym",{"_index":213,"t":{"24":{"position":[[166,10],[231,10]]}}}],["anonymis",{"_index":101,"t":{"8":{"position":[[20,13],[85,13]]}}}],["anoth",{"_index":80,"t":{"6":{"position":[[0,7]]},"54":{"position":[[509,7]]}}}],["anyon",{"_index":238,"t":{"28":{"position":[[102,6]]}}}],["appli",{"_index":295,"t":{"38":{"position":[[188,7]]},"42":{"position":[[227,7]]},"48":{"position":[[309,6]]},"83":{"position":[[4,7]]},"98":{"position":[[656,5]]},"106":{"position":[[587,5]]}}}],["applic",{"_index":42,"t":{"2":{"position":[[530,12]]},"4":{"position":[[198,12]]},"46":{"position":[[226,10]]},"52":{"position":[[694,10]]},"75":{"position":[[604,13]]},"98":{"position":[[697,10],[959,10]]},"106":{"position":[[628,10]]},"114":{"position":[[2017,10]]}}}],["approach",{"_index":326,"t":{"42":{"position":[[98,8]]},"50":{"position":[[13,9]]},"77":{"position":[[525,8]]}}}],["appropri",{"_index":653,"t":{"98":{"position":[[806,11]]}}}],["arbitr",{"_index":754,"t":{"112":{"position":[[102,12]]},"114":{"position":[[260,11],[427,11],[549,11],[1215,11],[1263,11],[1339,11],[1447,8],[1499,11],[1656,11],[1781,11],[1860,12],[1910,10],[1986,12],[2264,11]]}}}],["area",{"_index":46,"t":{"2":{"position":[[597,6]]},"6":{"position":[[8,4]]},"83":{"position":[[279,5]]}}}],["aris",{"_index":737,"t":{"106":{"position":[[251,7]]},"108":{"position":[[130,7]]},"114":{"position":[[690,7]]}}}],["aros",{"_index":807,"t":{"114":{"position":[[2110,5]]}}}],["art",{"_index":197,"t":{"22":{"position":[[76,3]]}}}],["artefact",{"_index":487,"t":{"69":{"position":[[170,10]]}}}],["ask",{"_index":411,"t":{"54":{"position":[[305,3],[381,3],[435,3],[623,5]]}}}],["aspect",{"_index":587,"t":{"83":{"position":[[359,8]]}}}],["assist",{"_index":491,"t":{"71":{"position":[[186,7]]},"73":{"position":[[45,9]]},"75":{"position":[[153,6]]},"83":{"position":[[136,10]]}}}],["associ",{"_index":336,"t":{"44":{"position":[[152,12],[255,11],[434,12]]},"96":{"position":[[92,12],[196,11],[385,12]]}}}],["assumpt",{"_index":684,"t":{"100":{"position":[[118,11]]}}}],["assur",{"_index":555,"t":{"77":{"position":[[718,9]]}}}],["attent",{"_index":600,"t":{"85":{"position":[[354,9]]},"87":{"position":[[390,9]]}}}],["attorney",{"_index":749,"t":{"108":{"position":[[113,10]]}}}],["attribut",{"_index":712,"t":{"102":{"position":[[71,11],[299,11]]}}}],["audit",{"_index":560,"t":{"79":{"position":[[84,8],[438,8]]}}}],["avail",{"_index":234,"t":{"28":{"position":[[52,9]]},"98":{"position":[[478,12],[1062,9]]},"102":{"position":[[38,9]]},"118":{"position":[[354,9]]}}}],["award",{"_index":769,"t":{"114":{"position":[[561,5]]}}}],["baarerstrass",{"_index":347,"t":{"44":{"position":[[291,13]]},"96":{"position":[[232,13]]}}}],["base",{"_index":296,"t":{"38":{"position":[[205,5]]},"54":{"position":[[707,5]]},"65":{"position":[[145,6]]},"73":{"position":[[354,5]]},"90":{"position":[[216,5]]},"100":{"position":[[65,5],[590,5]]}}}],["basi",{"_index":356,"t":{"46":{"position":[[205,5]]},"73":{"position":[[212,6]]},"98":{"position":[[44,5],[1177,5]]}}}],["be",{"_index":176,"t":{"18":{"position":[[195,5]]},"114":{"position":[[1364,5]]}}}],["bear",{"_index":702,"t":{"100":{"position":[[910,4]]}}}],["becom",{"_index":835,"t":{"118":{"position":[[136,6]]}}}],["befor",{"_index":423,"t":{"54":{"position":[[791,6]]},"94":{"position":[[316,6]]}}}],["behaviour",{"_index":526,"t":{"75":{"position":[[202,9]]}}}],["believ",{"_index":163,"t":{"18":{"position":[[3,7]]},"28":{"position":[[148,7]]},"32":{"position":[[3,7]]},"54":{"position":[[978,7]]},"104":{"position":[[338,8]]},"114":{"position":[[294,7]]}}}],["below",{"_index":162,"t":{"16":{"position":[[152,6]]}}}],["benefit",{"_index":240,"t":{"28":{"position":[[131,7]]},"118":{"position":[[166,10]]}}}],["between",{"_index":18,"t":{"2":{"position":[[174,7]]},"26":{"position":[[104,7]]},"112":{"position":[[62,7]]},"114":{"position":[[1714,7]]},"116":{"position":[[54,7]]}}}],["beyond",{"_index":12,"t":{"2":{"position":[[116,6]]},"71":{"position":[[568,7]]},"85":{"position":[[533,7]]},"87":{"position":[[582,7]]}}}],["bind",{"_index":660,"t":{"98":{"position":[[1214,7]]}}}],["border",{"_index":221,"t":{"26":{"position":[[97,6]]}}}],["both",{"_index":209,"t":{"24":{"position":[[110,4]]},"30":{"position":[[34,4]]},"65":{"position":[[21,4]]},"116":{"position":[[199,4]]},"118":{"position":[[211,4]]}}}],["bottleneck",{"_index":531,"t":{"75":{"position":[[332,11]]}}}],["bound",{"_index":623,"t":{"94":{"position":[[403,5]]},"114":{"position":[[404,5]]}}}],["boundari",{"_index":71,"t":{"4":{"position":[[227,10]]}}}],["bounti",{"_index":476,"t":{"67":{"position":[[217,6]]}}}],["bridg",{"_index":16,"t":{"2":{"position":[[157,8]]}}}],["briefli",{"_index":364,"t":{"46":{"position":[[599,7]]}}}],["bring",{"_index":30,"t":{"2":{"position":[[312,5]]},"73":{"position":[[388,6]]},"114":{"position":[[2061,5]]}}}],["broad",{"_index":513,"t":{"73":{"position":[[406,5]]}}}],["broadest",{"_index":757,"t":{"114":{"position":[[34,8]]}}}],["bug",{"_index":551,"t":{"77":{"position":[[563,4]]}}}],["build",{"_index":194,"t":{"22":{"position":[[37,8]]},"30":{"position":[[247,9]]},"38":{"position":[[223,5]]}}}],["bureaucraci",{"_index":278,"t":{"36":{"position":[[125,11]]}}}],["buy",{"_index":677,"t":{"98":{"position":[[1694,3],[1734,3]]}}}],["c/o",{"_index":343,"t":{"44":{"position":[[267,3]]},"96":{"position":[[208,3]]}}}],["calendar",{"_index":783,"t":{"114":{"position":[[1073,8]]}}}],["capit",{"_index":273,"t":{"36":{"position":[[69,8],[281,8]]}}}],["caption",{"_index":820,"t":{"116":{"position":[[255,8]]}}}],["carefulli",{"_index":621,"t":{"94":{"position":[[306,9]]}}}],["caus",{"_index":168,"t":{"18":{"position":[[93,5]]}}}],["cc",{"_index":452,"t":{"60":{"position":[[144,2]]},"102":{"position":[[109,3]]},"116":{"position":[[957,2]]}}}],["censorship",{"_index":187,"t":{"20":{"position":[[125,10]]},"90":{"position":[[53,10]]}}}],["centralis",{"_index":244,"t":{"30":{"position":[[12,14]]}}}],["certain",{"_index":355,"t":{"46":{"position":[[133,7]]},"48":{"position":[[152,7],[183,7]]},"54":{"position":[[145,7]]},"102":{"position":[[270,7]]}}}],["challeng",{"_index":156,"t":{"16":{"position":[[69,9]]}}}],["chamber",{"_index":787,"t":{"114":{"position":[[1253,9]]}}}],["chang",{"_index":152,"t":{"14":{"position":[[102,7]]},"58":{"position":[[135,8]]},"79":{"position":[[393,7]]},"100":{"position":[[583,6],[1329,6]]},"110":{"position":[[161,8]]}}}],["channel",{"_index":311,"t":{"40":{"position":[[106,9]]},"83":{"position":[[318,8]]}}}],["check",{"_index":442,"t":{"58":{"position":[[96,5]]},"110":{"position":[[119,8]]}}}],["choic",{"_index":408,"t":{"54":{"position":[[153,7]]}}}],["chrono",{"_index":578,"t":{"81":{"position":[[442,8]]}}}],["claim",{"_index":651,"t":{"98":{"position":[[724,6]]},"106":{"position":[[503,6]]},"108":{"position":[[73,7]]},"114":{"position":[[87,5],[939,5],[2071,6],[2104,5],[2176,6]]}}}],["class",{"_index":809,"t":{"114":{"position":[[2228,5]]}}}],["classwid",{"_index":812,"t":{"114":{"position":[[2254,9]]}}}],["claus",{"_index":396,"t":{"52":{"position":[[459,7]]},"114":{"position":[[439,7]]}}}],["close",{"_index":493,"t":{"71":{"position":[[273,7]]}}}],["code",{"_index":461,"t":{"65":{"position":[[39,4],[63,4],[140,4]]}}}],["coercion",{"_index":177,"t":{"18":{"position":[[201,8]]}}}],["cohes",{"_index":602,"t":{"85":{"position":[[390,8]]},"87":{"position":[[426,8]]}}}],["collabor",{"_index":22,"t":{"2":{"position":[[212,12]]},"71":{"position":[[260,12]]},"73":{"position":[[135,13]]},"85":{"position":[[403,13]]},"87":{"position":[[439,13]]},"118":{"position":[[340,13]]}}}],["collect",{"_index":332,"t":{"44":{"position":[[48,10],[141,10],[244,10],[423,10]]},"46":{"position":[[20,10],[35,10],[113,7],[270,7],[471,7]]},"48":{"position":[[31,10],[78,7]]},"54":{"position":[[50,10],[216,7]]},"87":{"position":[[60,11],[567,10]]},"96":{"position":[[81,10],[185,10],[374,10]]}}}],["come",{"_index":431,"t":{"56":{"position":[[25,4]]}}}],["commerci",{"_index":717,"t":{"102":{"position":[[243,10]]}}}],["commiss",{"_index":392,"t":{"52":{"position":[[358,11]]}}}],["commission",{"_index":428,"t":{"54":{"position":[[949,12]]}}}],["commit",{"_index":659,"t":{"98":{"position":[[1200,10]]}}}],["common",{"_index":711,"t":{"102":{"position":[[63,7]]}}}],["commun",{"_index":95,"t":{"6":{"position":[[312,13]]},"10":{"position":[[227,14]]},"24":{"position":[[115,14]]},"26":{"position":[[142,10]]},"40":{"position":[[13,10],[94,11],[140,9]]},"71":{"position":[[530,13]]},"90":{"position":[[74,13]]},"114":{"position":[[1699,14]]}}}],["compil",{"_index":573,"t":{"81":{"position":[[254,9]]}}}],["complaint",{"_index":426,"t":{"54":{"position":[[890,9]]}}}],["complet",{"_index":218,"t":{"26":{"position":[[14,8]]},"98":{"position":[[407,13]]},"100":{"position":[[894,8],[966,12]]}}}],["compli",{"_index":624,"t":{"94":{"position":[[413,6]]},"98":{"position":[[940,9]]}}}],["compliant",{"_index":652,"t":{"98":{"position":[[793,9]]}}}],["compon",{"_index":106,"t":{"8":{"position":[[137,11]]}}}],["compos",{"_index":250,"t":{"30":{"position":[[142,9]]}}}],["comprehens",{"_index":543,"t":{"77":{"position":[[101,13]]}}}],["compris",{"_index":294,"t":{"38":{"position":[[114,9]]}}}],["compromis",{"_index":193,"t":{"22":{"position":[[9,10]]}}}],["comput",{"_index":249,"t":{"30":{"position":[[132,9]]},"120":{"position":[[131,10]]}}}],["concern",{"_index":643,"t":{"98":{"position":[[392,10]]}}}],["condit",{"_index":692,"t":{"100":{"position":[[627,11]]},"104":{"position":[[92,11]]}}}],["conduct",{"_index":88,"t":{"6":{"position":[[196,10]]},"71":{"position":[[307,7]]},"75":{"position":[[254,10]]},"114":{"position":[[1556,9]]}}}],["confer",{"_index":794,"t":{"114":{"position":[[1576,10]]}}}],["confidenti",{"_index":78,"t":{"4":{"position":[[364,12]]},"114":{"position":[[1747,13]]}}}],["conflict",{"_index":755,"t":{"112":{"position":[[133,8]]}}}],["conform",{"_index":403,"t":{"52":{"position":[[678,10]]}}}],["connect",{"_index":310,"t":{"40":{"position":[[68,10]]},"106":{"position":[[279,9]]}}}],["consent",{"_index":420,"t":{"54":{"position":[[564,7],[611,7],[721,7],[822,8]]}}}],["consequenti",{"_index":735,"t":{"106":{"position":[[217,13]]}}}],["consid",{"_index":657,"t":{"98":{"position":[[1122,10],[1273,10]]}}}],["consist",{"_index":797,"t":{"114":{"position":[[1641,7]]}}}],["constitut",{"_index":670,"t":{"98":{"position":[[1543,10]]}}}],["constru",{"_index":676,"t":{"98":{"position":[[1662,9]]}}}],["consult",{"_index":345,"t":{"44":{"position":[[275,10]]},"96":{"position":[[216,10]]}}}],["contact",{"_index":448,"t":{"60":{"position":[[75,7]]},"116":{"position":[[888,7]]}}}],["contain",{"_index":619,"t":{"94":{"position":[[221,9]]},"98":{"position":[[1287,7],[1517,9]]},"100":{"position":[[21,7],[815,9],[994,9]]}}}],["contemporan",{"_index":818,"t":{"116":{"position":[[123,15]]}}}],["content",{"_index":181,"t":{"20":{"position":[[43,7]]},"48":{"position":[[191,8],[249,7]]},"56":{"position":[[197,7]]},"94":{"position":[[195,7]]},"98":{"position":[[522,7],[589,7],[762,7],[986,7]]},"102":{"position":[[20,8],[194,7]]},"104":{"position":[[310,7],[377,7]]},"106":{"position":[[339,7]]},"108":{"position":[[186,7]]},"114":{"position":[[198,7]]}}}],["continu",{"_index":262,"t":{"34":{"position":[[35,8]]}}}],["contract",{"_index":558,"t":{"79":{"position":[[12,9],[102,9],[165,9],[264,9],[493,9]]},"98":{"position":[[1190,9]]},"106":{"position":[[44,9]]}}}],["contractu",{"_index":395,"t":{"52":{"position":[[447,11]]}}}],["contribut",{"_index":63,"t":{"4":{"position":[[48,13]]},"6":{"position":[[357,12]]},"65":{"position":[[44,14],[68,14]]},"71":{"position":[[417,11]]},"83":{"position":[[498,12]]},"85":{"position":[[374,10]]},"87":{"position":[[410,10]]}}}],["contributor",{"_index":223,"t":{"26":{"position":[[121,12]]}}}],["control",{"_index":251,"t":{"30":{"position":[[213,7]]},"44":{"position":[[96,11]]},"54":{"position":[[522,10]]},"104":{"position":[[443,7]]}}}],["controversi",{"_index":759,"t":{"114":{"position":[[113,11]]}}}],["convers",{"_index":507,"t":{"73":{"position":[[294,12]]}}}],["copi",{"_index":416,"t":{"54":{"position":[[448,4]]},"102":{"position":[[162,5]]}}}],["core",{"_index":222,"t":{"26":{"position":[[116,4]]},"38":{"position":[[400,4]]},"81":{"position":[[134,4],[401,4]]}}}],["cornerston",{"_index":592,"t":{"85":{"position":[[35,11]]},"87":{"position":[[35,11]]}}}],["correct",{"_index":412,"t":{"54":{"position":[[315,7]]}}}],["cost",{"_index":286,"t":{"36":{"position":[[262,5]]},"106":{"position":[[141,4]]},"114":{"position":[[373,4]]}}}],["countri",{"_index":389,"t":{"52":{"position":[[248,9]]}}}],["court",{"_index":753,"t":{"112":{"position":[[93,5]]},"114":{"position":[[530,5],[1488,6]]}}}],["cover",{"_index":813,"t":{"116":{"position":[[27,5]]}}}],["craft",{"_index":595,"t":{"85":{"position":[[164,8]]},"87":{"position":[[206,8]]}}}],["creat",{"_index":232,"t":{"28":{"position":[[16,6]]},"34":{"position":[[3,6]]},"98":{"position":[[1136,8]]}}}],["creativ",{"_index":710,"t":{"102":{"position":[[54,8]]}}}],["critic",{"_index":572,"t":{"81":{"position":[[199,8]]}}}],["crucial",{"_index":483,"t":{"69":{"position":[[31,7]]},"77":{"position":[[296,7]]}}}],["cryptoeconom",{"_index":185,"t":{"20":{"position":[[90,14]]},"73":{"position":[[529,16]]}}}],["cryptograph",{"_index":581,"t":{"83":{"position":[[58,13],[225,13],[337,13],[395,13]]}}}],["cryptographi",{"_index":580,"t":{"83":{"position":[[12,12]]}}}],["current",{"_index":267,"t":{"34":{"position":[[122,7]]},"63":{"position":[[125,7]]},"100":{"position":[[74,7]]}}}],["custodian",{"_index":298,"t":{"38":{"position":[[288,10]]}}}],["cut",{"_index":5,"t":{"2":{"position":[[57,7]]},"83":{"position":[[382,7]]}}}],["damag",{"_index":736,"t":{"106":{"position":[[231,7],[447,8]]},"108":{"position":[[81,7]]}}}],["dapp",{"_index":113,"t":{"10":{"position":[[60,5]]}}}],["dappconnect",{"_index":124,"t":{"10":{"position":[[191,12]]}}}],["data",{"_index":132,"t":{"10":{"position":[[376,4]]},"44":{"position":[[86,4]]},"46":{"position":[[73,4],[150,4],[302,4],[361,5],[514,4]]},"48":{"position":[[54,5],[106,4]]},"50":{"position":[[31,4],[165,4]]},"52":{"position":[[50,4],[134,4],[217,4],[491,4],[609,4]]},"54":{"position":[[93,4],[199,4],[347,4],[412,4],[470,5],[517,4],[597,4],[873,5],[917,4],[1005,4]]}}}],["date",{"_index":308,"t":{"40":{"position":[[35,4]]},"79":{"position":[[371,4]]},"81":{"position":[[356,5]]}}}],["day",{"_index":502,"t":{"73":{"position":[[201,3],[208,3]]},"114":{"position":[[1082,4]]}}}],["dean",{"_index":128,"t":{"10":{"position":[[304,4],[416,4]]}}}],["decentr",{"_index":120,"t":{"10":{"position":[[140,13]]}}}],["decentralis",{"_index":50,"t":{"2":{"position":[[635,13]]},"4":{"position":[[397,13]]},"6":{"position":[[333,13]]},"10":{"position":[[213,13]]},"16":{"position":[[46,13]]},"71":{"position":[[474,13],[516,13]]},"75":{"position":[[590,13]]},"83":{"position":[[558,13]]},"85":{"position":[[483,13]]},"87":{"position":[[519,13]]}}}],["decis",{"_index":792,"t":{"114":{"position":[[1456,8]]}}}],["dedic",{"_index":496,"t":{"73":{"position":[[32,9]]},"77":{"position":[[23,9]]}}}],["deem",{"_index":391,"t":{"52":{"position":[[320,6]]},"114":{"position":[[1396,6]]}}}],["deep",{"_index":1,"t":{"2":{"position":[[4,4],[464,4],[559,4]]},"4":{"position":[[25,4],[308,4]]},"6":{"position":[[30,4],[257,4]]},"38":{"position":[[143,4]]},"71":{"position":[[290,4]]},"118":{"position":[[69,4],[220,4]]}}}],["defin",{"_index":548,"t":{"77":{"position":[[411,7]]},"116":{"position":[[378,7]]}}}],["degre",{"_index":689,"t":{"100":{"position":[[505,6],[1032,6]]}}}],["deliv",{"_index":534,"t":{"75":{"position":[[504,7]]},"77":{"position":[[785,7]]}}}],["delv",{"_index":67,"t":{"4":{"position":[[128,6]]}}}],["demand",{"_index":538,"t":{"75":{"position":[[568,7]]},"81":{"position":[[607,7]]}}}],["demo",{"_index":608,"t":{"90":{"position":[[88,6]]}}}],["depth",{"_index":89,"t":{"6":{"position":[[210,5]]}}}],["describ",{"_index":669,"t":{"98":{"position":[[1483,9]]},"100":{"position":[[1063,9],[1131,9]]}}}],["descript",{"_index":687,"t":{"100":{"position":[[289,13]]}}}],["design",{"_index":186,"t":{"20":{"position":[[105,6],[166,6]]},"73":{"position":[[71,9]]},"79":{"position":[[237,7]]}}}],["detail",{"_index":601,"t":{"85":{"position":[[367,6]]},"87":{"position":[[403,6]]},"100":{"position":[[313,8]]}}}],["devcon5",{"_index":136,"t":{"10":{"position":[[446,9]]}}}],["develop",{"_index":141,"t":{"12":{"position":[[59,9]]},"38":{"position":[[39,11]]},"69":{"position":[[153,7]]},"71":{"position":[[111,8]]},"75":{"position":[[74,10]]},"77":{"position":[[72,11]]},"79":{"position":[[54,12],[249,8]]},"81":{"position":[[87,11],[416,9]]},"83":{"position":[[591,8]]},"100":{"position":[[353,11],[649,13],[702,11]]},"120":{"position":[[21,10]]}}}],["dimens",{"_index":112,"t":{"10":{"position":[[46,9]]}}}],["disclaim",{"_index":628,"t":{"98":{"position":[[115,8],[639,11]]}}}],["discord",{"_index":314,"t":{"40":{"position":[[153,7]]},"63":{"position":[[36,8]]}}}],["discov",{"_index":474,"t":{"67":{"position":[[183,10]]}}}],["discret",{"_index":626,"t":{"98":{"position":[[91,10],[894,10]]},"100":{"position":[[1415,11]]}}}],["disput",{"_index":752,"t":{"112":{"position":[[53,8]]},"114":{"position":[[16,9],[338,8],[682,7],[828,8],[880,7],[922,8],[1047,7],[1118,8],[1141,7]]}}}],["distribut",{"_index":520,"t":{"75":{"position":[[4,11],[85,11],[452,11]]},"102":{"position":[[179,10]]}}}],["document",{"_index":450,"t":{"60":{"position":[[117,8]]},"116":{"position":[[930,8]]}}}],["doesn’t",{"_index":422,"t":{"54":{"position":[[733,7]]}}}],["domicil",{"_index":341,"t":{"44":{"position":[[218,8]]},"96":{"position":[[158,8]]}}}],["don't",{"_index":192,"t":{"22":{"position":[[3,5]]}}}],["don’t",{"_index":358,"t":{"46":{"position":[[315,5]]}}}],["drive",{"_index":506,"t":{"73":{"position":[[283,6]]}}}],["driven",{"_index":288,"t":{"38":{"position":[[19,6]]}}}],["dst",{"_index":521,"t":{"75":{"position":[[32,5],[298,3],[428,3]]}}}],["dst'",{"_index":522,"t":{"75":{"position":[[123,5]]}}}],["dynam",{"_index":518,"t":{"73":{"position":[[476,7]]}}}],["each",{"_index":292,"t":{"38":{"position":[[92,4]]},"100":{"position":[[1303,4]]}}}],["eas",{"_index":256,"t":{"32":{"position":[[78,4]]}}}],["econom",{"_index":174,"t":{"18":{"position":[[162,8]]},"36":{"position":[[253,8]]},"73":{"position":[[14,9]]},"90":{"position":[[143,8]]}}}],["economi",{"_index":497,"t":{"73":{"position":[[93,10]]}}}],["ecosystem",{"_index":570,"t":{"81":{"position":[[40,10],[225,10],[634,10]]},"83":{"position":[[576,10]]},"85":{"position":[[315,9]]},"87":{"position":[[359,10]]}}}],["edg",{"_index":6,"t":{"2":{"position":[[65,4]]},"83":{"position":[[390,4]]}}}],["edit",{"_index":594,"t":{"85":{"position":[[107,7]]},"87":{"position":[[120,7]]}}}],["educ",{"_index":260,"t":{"32":{"position":[[197,11]]}}}],["effect",{"_index":283,"t":{"36":{"position":[[221,9]]},"58":{"position":[[175,9]]},"110":{"position":[[207,9]]},"114":{"position":[[359,9],[378,9]]},"116":{"position":[[681,7]]}}}],["effici",{"_index":85,"t":{"6":{"position":[[131,11]]},"71":{"position":[[460,10]]},"81":{"position":[[325,10]]}}}],["effort",{"_index":34,"t":{"2":{"position":[[368,6]]},"32":{"position":[[209,8]]},"114":{"position":[[733,7],[782,7]]},"118":{"position":[[83,8]]}}}],["eigenman",{"_index":129,"t":{"10":{"position":[[309,8]]}}}],["eigenmann",{"_index":135,"t":{"10":{"position":[[421,9]]}}}],["emerg",{"_index":830,"t":{"118":{"position":[[27,8]]}}}],["emphasi",{"_index":255,"t":{"32":{"position":[[66,8]]}}}],["employ",{"_index":584,"t":{"83":{"position":[[188,9],[293,9]]}}}],["enabl",{"_index":111,"t":{"10":{"position":[[31,8],[204,8]]},"20":{"position":[[3,6]]},"71":{"position":[[498,8]]},"75":{"position":[[480,7]]},"120":{"position":[[104,7]]}}}],["encompass",{"_index":43,"t":{"2":{"position":[[573,11]]}}}],["endors",{"_index":721,"t":{"104":{"position":[[260,8]]}}}],["enforc",{"_index":758,"t":{"114":{"position":[[51,11],[1472,8]]},"116":{"position":[[703,7],[798,7]]}}}],["engin",{"_index":137,"t":{"12":{"position":[[22,8],[144,8]]}}}],["english",{"_index":801,"t":{"114":{"position":[[1804,8]]}}}],["enhanc",{"_index":83,"t":{"6":{"position":[[106,7]]},"46":{"position":[[782,7]]},"71":{"position":[[333,9]]},"77":{"position":[[616,9]]},"83":{"position":[[427,8]]}}}],["ensur",{"_index":301,"t":{"38":{"position":[[368,6]]},"46":{"position":[[743,6]]},"52":{"position":[[470,6]]},"67":{"position":[[257,6]]},"75":{"position":[[368,8]]},"77":{"position":[[214,6],[438,7],[568,7],[759,7]]},"79":{"position":[[142,7],[322,8],[554,8]]},"81":{"position":[[307,8]]},"85":{"position":[[250,8]]},"87":{"position":[[292,8]]}}}],["enter",{"_index":617,"t":{"94":{"position":[[100,7]]}}}],["entir",{"_index":814,"t":{"116":{"position":[[37,6]]}}}],["entiti",{"_index":24,"t":{"2":{"position":[[238,9]]},"34":{"position":[[101,6]]},"44":{"position":[[121,6]]},"96":{"position":[[61,6]]}}}],["environ",{"_index":603,"t":{"85":{"position":[[417,12]]},"87":{"position":[[453,12]]},"100":{"position":[[678,12]]}}}],["envis",{"_index":833,"t":{"118":{"position":[[111,10]]}}}],["equit",{"_index":728,"t":{"106":{"position":[[102,9]]}}}],["especi",{"_index":226,"t":{"26":{"position":[[190,10]]},"120":{"position":[[195,10]]}}}],["essenc",{"_index":715,"t":{"102":{"position":[[125,7]]}}}],["essenti",{"_index":208,"t":{"24":{"position":[[78,9]]},"81":{"position":[[149,9]]}}}],["estim",{"_index":682,"t":{"100":{"position":[[96,10]]}}}],["ethereum",{"_index":114,"t":{"10":{"position":[[83,8],[285,8]]}}}],["eur",{"_index":740,"t":{"106":{"position":[[524,3]]}}}],["euro",{"_index":744,"t":{"106":{"position":[[545,7]]}}}],["europ",{"_index":399,"t":{"52":{"position":[[558,7]]}}}],["european",{"_index":387,"t":{"52":{"position":[[161,8],[349,8],[626,8]]}}}],["even",{"_index":188,"t":{"20":{"position":[[148,4]]},"106":{"position":[[391,4]]}}}],["event",{"_index":383,"t":{"52":{"position":[[99,5],[573,6]]},"106":{"position":[[463,6]]}}}],["eventu",{"_index":834,"t":{"118":{"position":[[125,10]]}}}],["execut",{"_index":542,"t":{"77":{"position":[[88,9]]}}}],["exist",{"_index":263,"t":{"34":{"position":[[47,5]]}}}],["expand",{"_index":824,"t":{"116":{"position":[[394,7]]}}}],["expect",{"_index":658,"t":{"98":{"position":[[1149,12]]},"100":{"position":[[82,13]]}}}],["expens",{"_index":748,"t":{"108":{"position":[[93,9]]}}}],["expertis",{"_index":485,"t":{"69":{"position":[[97,10]]},"75":{"position":[[439,9]]},"83":{"position":[[175,9]]},"85":{"position":[[340,9]]},"87":{"position":[[376,9]]},"118":{"position":[[326,9]]}}}],["explain",{"_index":404,"t":{"54":{"position":[[3,9]]}}}],["explor",{"_index":4,"t":{"2":{"position":[[41,11]]},"4":{"position":[[182,9]]},"6":{"position":[[89,8]]}}}],["export",{"_index":384,"t":{"52":{"position":[[113,6]]}}}],["express",{"_index":631,"t":{"98":{"position":[[152,7],[1374,7]]}}}],["extend",{"_index":11,"t":{"2":{"position":[[108,7]]},"32":{"position":[[101,7]]}}}],["extens",{"_index":569,"t":{"81":{"position":[[15,9]]}}}],["extent",{"_index":373,"t":{"48":{"position":[[207,6]]},"60":{"position":[[7,6]]},"98":{"position":[[677,6]]},"104":{"position":[[7,6]]},"106":{"position":[[608,6]]}}}],["facilit",{"_index":604,"t":{"85":{"position":[[430,12]]},"87":{"position":[[466,12]]}}}],["fail",{"_index":829,"t":{"116":{"position":[[695,4]]}}}],["fair",{"_index":253,"t":{"32":{"position":[[14,4]]}}}],["famili",{"_index":606,"t":{"90":{"position":[[8,6]]}}}],["fdpic",{"_index":429,"t":{"54":{"position":[[962,8]]}}}],["featur",{"_index":195,"t":{"22":{"position":[[46,9]]},"48":{"position":[[160,8],[260,9]]},"100":{"position":[[339,9]]}}}],["februari",{"_index":321,"t":{"42":{"position":[[29,8]]},"94":{"position":[[30,8]]}}}],["feder",{"_index":427,"t":{"54":{"position":[[909,7]]}}}],["fee",{"_index":750,"t":{"108":{"position":[[124,5]]},"114":{"position":[[1837,4],[1921,4]]}}}],["field",{"_index":74,"t":{"4":{"position":[[291,5]]}}}],["fight",{"_index":277,"t":{"36":{"position":[[119,5]]}}}],["file",{"_index":425,"t":{"54":{"position":[[883,4]]},"114":{"position":[[1883,7]]}}}],["final",{"_index":785,"t":{"114":{"position":[[1173,7]]}}}],["financi",{"_index":671,"t":{"98":{"position":[[1554,10]]}}}],["find",{"_index":31,"t":{"2":{"position":[[333,8],[506,8]]}}}],["first",{"_index":462,"t":{"65":{"position":[[97,5]]},"114":{"position":[[707,5]]}}}],["fit",{"_index":634,"t":{"98":{"position":[[236,7]]}}}],["flow",{"_index":180,"t":{"20":{"position":[[19,4]]}}}],["focu",{"_index":81,"t":{"6":{"position":[[16,5]]}}}],["focus",{"_index":494,"t":{"71":{"position":[[364,8]]},"81":{"position":[[72,7]]},"83":{"position":[[47,7]]},"120":{"position":[[10,7]]}}}],["follow",{"_index":312,"t":{"40":{"position":[[116,6]]},"46":{"position":[[495,9]]},"102":{"position":[[371,9]]},"114":{"position":[[417,9]]}}}],["forc",{"_index":790,"t":{"114":{"position":[[1373,6]]},"116":{"position":[[671,5]]}}}],["forecast",{"_index":683,"t":{"100":{"position":[[107,10]]}}}],["forefront",{"_index":3,"t":{"2":{"position":[[28,9]]}}}],["form",{"_index":394,"t":{"52":{"position":[[399,5],[438,5]]},"98":{"position":[[1165,7]]}}}],["format",{"_index":716,"t":{"102":{"position":[[209,6]]}}}],["forum",{"_index":316,"t":{"40":{"position":[[224,5]]},"63":{"position":[[69,6]]}}}],["forward",{"_index":508,"t":{"73":{"position":[[307,7]]},"100":{"position":[[29,7],[205,7],[541,7]]}}}],["foundat",{"_index":76,"t":{"4":{"position":[[338,10]]}}}],["franck",{"_index":122,"t":{"10":{"position":[[176,6]]}}}],["frank",{"_index":224,"t":{"26":{"position":[[160,5]]}}}],["free",{"_index":179,"t":{"20":{"position":[[14,4]]},"28":{"position":[[68,4]]},"67":{"position":[[62,4]]}}}],["freedom",{"_index":175,"t":{"18":{"position":[[171,9]]}}}],["fruition",{"_index":32,"t":{"2":{"position":[[345,9]]}}}],["full",{"_index":611,"t":{"90":{"position":[[168,6]]},"102":{"position":[[323,4]]},"116":{"position":[[666,4]]}}}],["function",{"_index":367,"t":{"46":{"position":[[764,13]]},"77":{"position":[[246,13],[455,15]]},"79":{"position":[[336,8]]},"94":{"position":[[207,13]]},"100":{"position":[[322,16]]}}}],["further",{"_index":577,"t":{"81":{"position":[[375,7]]},"114":{"position":[[1026,7]]}}}],["futur",{"_index":667,"t":{"98":{"position":[[1436,6]]}}}],["gap",{"_index":17,"t":{"2":{"position":[[170,3]]}}}],["gener",{"_index":374,"t":{"50":{"position":[[5,7]]},"73":{"position":[[521,7]]},"100":{"position":[[192,8]]},"120":{"position":[[53,7]]}}}],["github",{"_index":458,"t":{"63":{"position":[[103,7]]}}}],["given",{"_index":64,"t":{"4":{"position":[[72,5]]}}}],["gmbh",{"_index":346,"t":{"44":{"position":[[286,4]]},"96":{"position":[[227,4]]}}}],["goal",{"_index":103,"t":{"8":{"position":[[58,4]]},"16":{"position":[[4,4]]},"26":{"position":[[262,6]]}}}],["good",{"_index":233,"t":{"28":{"position":[[35,5]]},"65":{"position":[[91,5]]}}}],["gossip",{"_index":612,"t":{"90":{"position":[[209,6]]}}}],["gossipsub",{"_index":58,"t":{"2":{"position":[[722,9]]},"6":{"position":[[55,9],[173,9]]},"8":{"position":[[75,9]]},"71":{"position":[[162,9],[350,10]]}}}],["govern",{"_index":618,"t":{"94":{"position":[[137,6]]},"104":{"position":[[132,6]]},"112":{"position":[[10,7]]}}}],["group",{"_index":289,"t":{"38":{"position":[[51,5]]}}}],["grow",{"_index":271,"t":{"36":{"position":[[39,4]]}}}],["guarante",{"_index":201,"t":{"22":{"position":[[169,11]]},"98":{"position":[[1355,10]]}}}],["guidanc",{"_index":486,"t":{"69":{"position":[[133,9]]}}}],["hackenproof",{"_index":478,"t":{"67":{"position":[[237,11]]}}}],["harm",{"_index":723,"t":{"104":{"position":[[423,8]]}}}],["harmless",{"_index":747,"t":{"108":{"position":[[35,8]]}}}],["head",{"_index":821,"t":{"116":{"position":[[268,8]]}}}],["heard",{"_index":766,"t":{"114":{"position":[[495,5]]}}}],["held",{"_index":725,"t":{"106":{"position":[[15,4]]},"114":{"position":[[1519,4]]},"116":{"position":[[532,4]]}}}],["help",{"_index":479,"t":{"67":{"position":[[252,4]]},"75":{"position":[[307,5]]}}}],["herein",{"_index":656,"t":{"98":{"position":[[994,6],[1257,6],[1493,7],[1527,6]]},"100":{"position":[[825,6],[1004,7]]},"114":{"position":[[1422,6]]}}}],["high",{"_index":556,"t":{"77":{"position":[[804,4]]},"100":{"position":[[500,4],[1027,4]]}}}],["highest",{"_index":566,"t":{"79":{"position":[[567,7]]}}}],["hold",{"_index":746,"t":{"108":{"position":[[27,4]]},"120":{"position":[[148,5]]}}}],["holder",{"_index":276,"t":{"36":{"position":[[108,7]]}}}],["https://creativecommons.org/licenses/by/4.0",{"_index":718,"t":{"102":{"position":[[390,45]]}}}],["https://our.status.im/our",{"_index":149,"t":{"14":{"position":[[42,25]]}}}],["hundr",{"_index":743,"t":{"106":{"position":[[537,7]]}}}],["idea",{"_index":510,"t":{"73":{"position":[[333,5]]}}}],["identifi",{"_index":36,"t":{"2":{"position":[[384,11]]},"46":{"position":[[653,11]]},"75":{"position":[[313,8]]},"77":{"position":[[537,11]]},"79":{"position":[[506,8]]},"81":{"position":[[553,11]]},"116":{"position":[[277,11]]}}}],["ift",{"_index":9,"t":{"2":{"position":[[92,4],[295,3],[554,4]]},"6":{"position":[[433,3]]},"38":{"position":[[97,3]]},"69":{"position":[[58,3]]},"71":{"position":[[551,3]]},"73":{"position":[[55,3],[154,3]]},"75":{"position":[[160,3],[488,3]]},"77":{"position":[[47,3],[772,3]]},"79":{"position":[[116,3],[308,3]]},"81":{"position":[[163,3],[429,4],[514,3]]},"83":{"position":[[150,3]]},"85":{"position":[[54,4],[134,3],[311,3],[525,3]]},"118":{"position":[[152,3]]},"120":{"position":[[181,3]]}}}],["ift'",{"_index":568,"t":{"81":{"position":[[9,5]]}}}],["ii",{"_index":777,"t":{"114":{"position":[[965,4]]}}}],["immedi",{"_index":444,"t":{"58":{"position":[[185,11]]},"110":{"position":[[217,11]]}}}],["implement",{"_index":377,"t":{"50":{"position":[[67,11]]},"77":{"position":[[160,12],[340,16],[387,15]]},"83":{"position":[[212,12]]}}}],["impli",{"_index":632,"t":{"98":{"position":[[163,8],[1385,7]]},"104":{"position":[[246,5]]}}}],["import",{"_index":840,"t":{"120":{"position":[[166,10]]}}}],["improv",{"_index":59,"t":{"2":{"position":[[732,13]]},"6":{"position":[[65,14],[239,13]]},"34":{"position":[[57,7]]},"71":{"position":[[141,9],[444,11]]}}}],["incent",{"_index":498,"t":{"73":{"position":[[104,11]]}}}],["incentivis",{"_index":261,"t":{"34":{"position":[[19,12]]}}}],["incid",{"_index":472,"t":{"67":{"position":[[125,9]]}}}],["incident",{"_index":734,"t":{"106":{"position":[[202,11]]}}}],["includ",{"_index":35,"t":{"2":{"position":[[375,8],[604,9]]},"18":{"position":[[186,8]]},"77":{"position":[[152,7]]},"81":{"position":[[236,9],[484,8]]},"94":{"position":[[181,9]]},"98":{"position":[[172,9]]},"100":{"position":[[243,7],[727,9],[1259,9]]},"102":{"position":[[233,9]]},"104":{"position":[[104,9]]},"108":{"position":[[103,9],[210,9]]},"114":{"position":[[74,8],[1873,9]]}}}],["inclus",{"_index":257,"t":{"32":{"position":[[119,12]]}}}],["incorpor",{"_index":791,"t":{"114":{"position":[[1409,12]]}}}],["incub",{"_index":28,"t":{"2":{"position":[[271,9],[431,9]]},"4":{"position":[[90,9]]},"38":{"position":[[162,9]]},"87":{"position":[[170,9]]},"118":{"position":[[4,9],[272,9]]}}}],["indemnifi",{"_index":745,"t":{"108":{"position":[[10,9]]}}}],["independ",{"_index":435,"t":{"56":{"position":[[110,11]]}}}],["indic",{"_index":362,"t":{"46":{"position":[[433,9]]}}}],["individu",{"_index":165,"t":{"18":{"position":[[33,12]]},"30":{"position":[[192,11]]}}}],["industri",{"_index":685,"t":{"100":{"position":[[168,8]]}}}],["ineffici",{"_index":279,"t":{"36":{"position":[[141,14]]}}}],["inform",{"_index":93,"t":{"6":{"position":[[288,11]]},"20":{"position":[[27,12],[202,12]]},"26":{"position":[[48,11]]},"42":{"position":[[78,6]]},"50":{"position":[[191,11]]},"54":{"position":[[937,11]]},"98":{"position":[[1076,13],[1245,11],[1505,11]]},"100":{"position":[[803,11],[982,11],[1246,12]]}}}],["infrastructur",{"_index":191,"t":{"20":{"position":[[182,15]]}}}],["infring",{"_index":637,"t":{"98":{"position":[[278,12]]}}}],["inherit",{"_index":148,"t":{"14":{"position":[[27,9]]}}}],["initi",{"_index":831,"t":{"118":{"position":[[36,11]]}}}],["innov",{"_index":7,"t":{"2":{"position":[[70,10]]}}}],["institut",{"_index":469,"t":{"67":{"position":[[49,9]]},"114":{"position":[[1275,11]]}}}],["integr",{"_index":492,"t":{"71":{"position":[[212,11]]},"77":{"position":[[230,11]]},"83":{"position":[[526,9]]},"85":{"position":[[452,11]]},"87":{"position":[[488,11]]}}}],["intellectu",{"_index":638,"t":{"98":{"position":[[294,12]]}}}],["intend",{"_index":324,"t":{"42":{"position":[[66,8]]},"79":{"position":[[348,8]]},"98":{"position":[[1042,8]]}}}],["intens",{"_index":501,"t":{"73":{"position":[[175,9]]}}}],["interact",{"_index":79,"t":{"4":{"position":[[377,12]]},"48":{"position":[[218,8]]}}}],["interest",{"_index":366,"t":{"46":{"position":[[699,8]]},"65":{"position":[[7,10]]}}}],["intern",{"_index":714,"t":{"102":{"position":[[87,13]]},"114":{"position":[[1325,13],[1972,13]]}}}],["interoper",{"_index":258,"t":{"32":{"position":[[162,17]]},"77":{"position":[[188,16]]},"85":{"position":[[276,13]]},"87":{"position":[[318,13]]}}}],["interpret",{"_index":825,"t":{"116":{"position":[[423,14]]}}}],["intricaci",{"_index":68,"t":{"4":{"position":[[144,11]]}}}],["invalid",{"_index":826,"t":{"116":{"position":[[537,7]]}}}],["invest",{"_index":259,"t":{"32":{"position":[[184,9]]}}}],["involv",{"_index":563,"t":{"79":{"position":[[455,8]]}}}],["ip",{"_index":363,"t":{"46":{"position":[[549,2],[620,2],[727,2],[833,2]]}}}],["issu",{"_index":456,"t":{"63":{"position":[[87,6]]},"65":{"position":[[103,6]]},"75":{"position":[[360,7]]},"77":{"position":[[585,6]]}}}],["it'",{"_index":207,"t":{"24":{"position":[[73,4]]}}}],["itself",{"_index":245,"t":{"30":{"position":[[73,7]]}}}],["job",{"_index":460,"t":{"63":{"position":[[133,3]]}}}],["join",{"_index":305,"t":{"40":{"position":[[0,4],[131,4]]},"63":{"position":[[24,7]]}}}],["judg",{"_index":767,"t":{"114":{"position":[[506,6]]}}}],["juri",{"_index":770,"t":{"114":{"position":[[615,4]]}}}],["jurisdict",{"_index":654,"t":{"98":{"position":[[826,13]]},"114":{"position":[[650,14]]}}}],["keep",{"_index":306,"t":{"40":{"position":[[24,4]]}}}],["kept",{"_index":799,"t":{"114":{"position":[[1742,4]]}}}],["key",{"_index":45,"t":{"2":{"position":[[593,3]]}}}],["kind",{"_index":630,"t":{"98":{"position":[[146,5]]}}}],["kit",{"_index":468,"t":{"65":{"position":[[187,3]]},"83":{"position":[[628,4]]}}}],["knowledg",{"_index":48,"t":{"2":{"position":[[619,9]]},"4":{"position":[[164,9]]},"12":{"position":[[125,9],[183,9]]},"73":{"position":[[435,10]]},"83":{"position":[[91,9]]},"120":{"position":[[74,9]]}}}],["known",{"_index":808,"t":{"114":{"position":[[2160,5]]}}}],["laid",{"_index":409,"t":{"54":{"position":[[240,4]]}}}],["languag",{"_index":800,"t":{"114":{"position":[[1765,8]]}}}],["larger",{"_index":527,"t":{"75":{"position":[[234,6]]}}}],["last",{"_index":318,"t":{"42":{"position":[[13,4]]},"94":{"position":[[13,4]]}}}],["latest",{"_index":309,"t":{"40":{"position":[[49,6],[188,6]]}}}],["law",{"_index":650,"t":{"98":{"position":[[708,4],[976,5]]},"106":{"position":[[639,4]]},"112":{"position":[[6,3],[145,4]]},"114":{"position":[[66,3]]}}}],["lawsuit",{"_index":811,"t":{"114":{"position":[[2241,7]]}}}],["layer",{"_index":100,"t":{"6":{"position":[[423,6]]},"8":{"position":[[99,5]]},"71":{"position":[[239,7]]}}}],["legal",{"_index":340,"t":{"44":{"position":[[212,5]]},"46":{"position":[[199,5]]},"96":{"position":[[152,5]]},"98":{"position":[[431,9],[785,7],[1565,6]]},"106":{"position":[[93,5]]}}}],["legal@free.technolog",{"_index":449,"t":{"60":{"position":[[89,22]]},"116":{"position":[[902,22]]}}}],["legisl",{"_index":357,"t":{"46":{"position":[[245,12]]},"52":{"position":[[713,12]]},"54":{"position":[[269,12]]}}}],["legitim",{"_index":365,"t":{"46":{"position":[[688,10]]}}}],["level",{"_index":144,"t":{"12":{"position":[[82,5]]},"52":{"position":[[297,5]]}}}],["leverag",{"_index":588,"t":{"83":{"position":[[371,10]]},"118":{"position":[[311,10]]}}}],["liabil",{"_index":438,"t":{"56":{"position":[[179,9]]},"106":{"position":[[73,10],[484,9],[572,9]]}}}],["liabl",{"_index":724,"t":{"104":{"position":[[498,6]]},"106":{"position":[[20,6]]}}}],["liberti",{"_index":170,"t":{"18":{"position":[[111,8]]}}}],["libp2p",{"_index":57,"t":{"2":{"position":[[715,6]]},"6":{"position":[[47,7],[166,6]]},"8":{"position":[[68,6]]},"12":{"position":[[4,6]]},"65":{"position":[[156,6]]},"69":{"position":[[193,6]]},"71":{"position":[[124,7],[155,6],[343,6]]}}}],["librari",{"_index":297,"t":{"38":{"position":[[240,10]]},"81":{"position":[[139,9],[406,9]]}}}],["licenc",{"_index":237,"t":{"28":{"position":[[89,8]]},"102":{"position":[[138,7],[342,8]]}}}],["licens",{"_index":451,"t":{"60":{"position":[[129,8]]},"102":{"position":[[101,7]]},"116":{"position":[[942,8]]}}}],["limit",{"_index":354,"t":{"46":{"position":[[10,5]]},"48":{"position":[[19,7]]},"54":{"position":[[40,5]]},"98":{"position":[[190,10]]},"106":{"position":[[513,7],[558,10]]},"108":{"position":[[228,10]]},"114":{"position":[[570,8],[2039,12]]},"116":{"position":[[402,6]]}}}],["linchpin",{"_index":598,"t":{"85":{"position":[[237,8]]},"87":{"position":[[279,8]]}}}],["link",{"_index":432,"t":{"56":{"position":[[37,5]]},"98":{"position":[[613,6]]},"104":{"position":[[39,5],[182,7]]}}}],["list",{"_index":463,"t":{"65":{"position":[[110,5]]}}}],["litig",{"_index":761,"t":{"114":{"position":[[277,10],[474,10]]}}}],["local",{"_index":655,"t":{"98":{"position":[[970,5]]}}}],["logo",{"_index":335,"t":{"44":{"position":[[135,5],[238,5],[350,8],[417,5]]},"83":{"position":[[482,5]]},"87":{"position":[[54,5],[147,5],[353,5],[561,5]]},"96":{"position":[[75,5],[179,5],[291,8],[368,5]]},"120":{"position":[[206,6]]}}}],["long",{"_index":231,"t":{"26":{"position":[[252,4]]}}}],["look",{"_index":680,"t":{"100":{"position":[[37,7],[213,7],[549,7]]}}}],["lost",{"_index":729,"t":{"106":{"position":[[127,4]]}}}],["low",{"_index":143,"t":{"12":{"position":[[77,4]]}}}],["lower",{"_index":285,"t":{"36":{"position":[[247,5]]}}}],["machin",{"_index":838,"t":{"120":{"position":[[92,8]]}}}],["made",{"_index":62,"t":{"4":{"position":[[43,4]]},"14":{"position":[[120,4]]},"28":{"position":[[47,4]]},"98":{"position":[[1057,4]]},"102":{"position":[[33,4]]}}}],["main",{"_index":102,"t":{"8":{"position":[[53,4]]}}}],["maintain",{"_index":379,"t":{"50":{"position":[[128,8]]},"81":{"position":[[392,8]]}}}],["mainten",{"_index":559,"t":{"79":{"position":[[67,12]]},"81":{"position":[[103,11]]}}}],["make",{"_index":199,"t":{"22":{"position":[[148,4]]},"26":{"position":[[206,6]]},"48":{"position":[[138,6]]},"98":{"position":[[367,4],[716,4]]},"114":{"position":[[97,4],[953,7]]}}}],["manag",{"_index":576,"t":{"81":{"position":[[280,9]]}}}],["mandat",{"_index":579,"t":{"81":{"position":[[455,7]]}}}],["manner",{"_index":764,"t":{"114":{"position":[[388,7]]}}}],["market",{"_index":499,"t":{"73":{"position":[[120,8]]},"100":{"position":[[181,7],[620,6]]}}}],["mass",{"_index":158,"t":{"16":{"position":[[92,4]]}}}],["matter",{"_index":668,"t":{"98":{"position":[[1475,7]]},"100":{"position":[[437,7],[1123,7]]}}}],["maximis",{"_index":171,"t":{"18":{"position":[[130,8]]},"30":{"position":[[100,8],[169,8]]}}}],["maximum",{"_index":648,"t":{"98":{"position":[[669,7]]},"106":{"position":[[600,7]]}}}],["mean",{"_index":280,"t":{"36":{"position":[[186,5]]},"52":{"position":[[197,5]]},"94":{"position":[[375,5]]},"114":{"position":[[43,7]]},"116":{"position":[[760,4]]}}}],["measur",{"_index":368,"t":{"46":{"position":[[803,8]]},"50":{"position":[[101,8]]}}}],["meet",{"_index":762,"t":{"114":{"position":[[305,5]]}}}],["member",{"_index":268,"t":{"34":{"position":[[135,8]]}}}],["merchant",{"_index":633,"t":{"98":{"position":[[219,16]]}}}],["messag",{"_index":115,"t":{"10":{"position":[[92,9],[154,9],[294,9],[390,9]]}}}],["method",{"_index":198,"t":{"22":{"position":[[120,7]]},"114":{"position":[[1602,7]]}}}],["meticul",{"_index":554,"t":{"77":{"position":[[687,10]]},"79":{"position":[[464,12]]},"85":{"position":[[151,12]]},"87":{"position":[[193,12]]}}}],["minimis",{"_index":243,"t":{"30":{"position":[[3,8]]}}}],["minor",{"_index":150,"t":{"14":{"position":[[86,5]]}}}],["model",{"_index":517,"t":{"73":{"position":[[463,9],[507,9]]}}}],["modifi",{"_index":239,"t":{"28":{"position":[[119,7]]},"58":{"position":[[7,6]]},"102":{"position":[[168,6]]},"110":{"position":[[7,6]]},"116":{"position":[[386,7]]}}}],["modular",{"_index":607,"t":{"90":{"position":[[18,7]]}}}],["natur",{"_index":776,"t":{"114":{"position":[[908,6]]}}}],["need",{"_index":359,"t":{"46":{"position":[[321,4],[418,6]]},"73":{"position":[[256,5]]},"79":{"position":[[299,5]]},"81":{"position":[[597,5]]}}}],["neglig",{"_index":726,"t":{"106":{"position":[[54,11]]}}}],["nescienc",{"_index":66,"t":{"4":{"position":[[108,10]]},"12":{"position":[[204,11]]},"120":{"position":[[0,9]]}}}],["network",{"_index":55,"t":{"2":{"position":[[682,9]]},"4":{"position":[[411,9]]},"6":{"position":[[347,9]]},"8":{"position":[[34,9]]},"12":{"position":[[11,10]]},"30":{"position":[[156,8]]},"71":{"position":[[231,7],[488,9]]},"75":{"position":[[241,9]]}}}],["new",{"_index":39,"t":{"2":{"position":[[427,3]]},"10":{"position":[[42,3]]},"22":{"position":[[107,3]]},"58":{"position":[[148,3]]},"73":{"position":[[329,3]]},"110":{"position":[[174,3]]}}}],["nim",{"_index":465,"t":{"65":{"position":[[152,3]]},"69":{"position":[[189,3]]},"71":{"position":[[120,3]]},"81":{"position":[[36,3],[55,3],[118,3],[181,3],[221,3],[250,3],[294,3],[366,3],[470,3],[548,4],[630,3]]}}}],["nimbl",{"_index":574,"t":{"81":{"position":[[264,6]]}}}],["node",{"_index":53,"t":{"2":{"position":[[668,4]]},"75":{"position":[[221,5]]}}}],["nois",{"_index":586,"t":{"83":{"position":[[303,5]]}}}],["non",{"_index":636,"t":{"98":{"position":[[274,3]]},"104":{"position":[[419,3]]}}}],["nonetheless",{"_index":406,"t":{"54":{"position":[[117,12]]}}}],["note",{"_index":768,"t":{"114":{"position":[[520,4]]}}}],["noth",{"_index":675,"t":{"98":{"position":[[1628,7]]}}}],["notic",{"_index":440,"t":{"58":{"position":[[81,7]]},"100":{"position":[[1392,6]]},"110":{"position":[[87,7]]},"114":{"position":[[870,6],[1108,6]]}}}],["number",{"_index":247,"t":{"30":{"position":[[113,6],[182,6]]}}}],["object",{"_index":304,"t":{"38":{"position":[[416,11]]},"54":{"position":[[831,6]]},"75":{"position":[[137,9]]}}}],["oblig",{"_index":274,"t":{"36":{"position":[[88,10]]},"52":{"position":[[7,7]]},"98":{"position":[[1222,10]]}}}],["occur",{"_index":402,"t":{"52":{"position":[[669,5]]},"73":{"position":[[189,6]]}}}],["offer",{"_index":583,"t":{"83":{"position":[[166,8]]},"98":{"position":[[1685,5],[1725,5]]}}}],["offic",{"_index":338,"t":{"44":{"position":[[190,6]]},"96":{"position":[[130,6]]}}}],["on",{"_index":742,"t":{"106":{"position":[[532,4]]},"114":{"position":[[1652,3],[2085,3]]}}}],["oneself",{"_index":205,"t":{"24":{"position":[[43,7]]}}}],["open",{"_index":219,"t":{"26":{"position":[[23,8]]},"28":{"position":[[77,4]]},"63":{"position":[[45,7],[79,7],[137,9]]}}}],["oper",{"_index":836,"t":{"118":{"position":[[291,7]]}}}],["opportun",{"_index":37,"t":{"2":{"position":[[396,13]]}}}],["optimis",{"_index":92,"t":{"6":{"position":[[279,8]]}}}],["oral",{"_index":819,"t":{"116":{"position":[[216,5]]}}}],["order",{"_index":695,"t":{"100":{"position":[[741,5]]}}}],["organis",{"_index":166,"t":{"18":{"position":[[60,12]]},"26":{"position":[[71,13]]},"30":{"position":[[60,12]]},"36":{"position":[[167,13]]}}}],["oskar",{"_index":126,"t":{"10":{"position":[[253,5],[320,5],[433,5]]}}}],["otherwis",{"_index":393,"t":{"52":{"position":[[370,10]]},"98":{"position":[[549,9]]}}}],["out",{"_index":410,"t":{"54":{"position":[[245,3]]},"114":{"position":[[896,3]]}}}],["outlin",{"_index":161,"t":{"16":{"position":[[143,8]]}}}],["outsid",{"_index":386,"t":{"52":{"position":[[149,7],[614,7]]}}}],["over",{"_index":134,"t":{"10":{"position":[[400,4]]},"30":{"position":[[221,4]]},"46":{"position":[[864,4]]},"104":{"position":[[451,4]]},"114":{"position":[[272,4]]}}}],["overal",{"_index":96,"t":{"6":{"position":[[377,7]]},"71":{"position":[[436,7]]},"77":{"position":[[630,7]]},"83":{"position":[[518,7]]}}}],["overse",{"_index":596,"t":{"85":{"position":[[177,10]]},"87":{"position":[[219,10]]}}}],["p2p",{"_index":99,"t":{"6":{"position":[[419,3]]},"71":{"position":[[4,3],[78,5],[102,3],[227,3],[251,3],[386,3],[408,3]]},"90":{"position":[[26,3]]}}}],["packag",{"_index":575,"t":{"81":{"position":[[271,8]]}}}],["page",{"_index":317,"t":{"42":{"position":[[8,4]]},"94":{"position":[[8,4]]}}}],["part",{"_index":33,"t":{"2":{"position":[[355,4]]},"46":{"position":[[564,4]]},"58":{"position":[[29,4]]},"71":{"position":[[36,4]]},"110":{"position":[[29,4]]},"116":{"position":[[494,4],[568,4]]}}}],["parti",{"_index":371,"t":{"48":{"position":[[66,7],[243,5]]},"52":{"position":[[264,7]]},"56":{"position":[[52,5],[80,5],[235,5]]},"104":{"position":[[56,5],[163,5],[201,5],[292,5],[358,5],[467,5],[548,5],[618,5],[742,5]]},"114":{"position":[[1726,7]]}}}],["particip",{"_index":242,"t":{"28":{"position":[[174,14]]},"32":{"position":[[147,14]]},"114":{"position":[[2211,11]]}}}],["particular",{"_index":635,"t":{"98":{"position":[[250,10]]}}}],["past",{"_index":665,"t":{"98":{"position":[[1415,5]]}}}],["payment",{"_index":802,"t":{"114":{"position":[[1813,7]]}}}],["peer",{"_index":490,"t":{"71":{"position":[[65,4],[73,4]]},"90":{"position":[[130,4],[138,4]]}}}],["perform",{"_index":84,"t":{"6":{"position":[[118,12]]},"75":{"position":[[348,11]]},"77":{"position":[[809,10]]}}}],["period",{"_index":443,"t":{"58":{"position":[[114,12]]},"110":{"position":[[140,12]]}}}],["permissionless",{"_index":241,"t":{"28":{"position":[[159,14]]},"32":{"position":[[132,14]]}}}],["permit",{"_index":649,"t":{"98":{"position":[[684,9]]},"106":{"position":[[615,9]]}}}],["person",{"_index":169,"t":{"18":{"position":[[102,8]]},"44":{"position":[[77,8]]},"46":{"position":[[64,8],[141,8],[293,8],[352,8],[505,8]]},"48":{"position":[[45,8],[97,8]]},"50":{"position":[[156,8]]},"52":{"position":[[41,8],[125,8],[208,8],[482,8],[600,8]]},"54":{"position":[[84,8],[190,8],[338,8],[403,8],[461,8],[588,8],[864,8],[996,8]]}}}],["physic",{"_index":248,"t":{"30":{"position":[[123,8]]}}}],["place",{"_index":385,"t":{"52":{"position":[[142,6]]},"100":{"position":[[1095,5]]}}}],["plan",{"_index":544,"t":{"77":{"position":[[120,6]]},"81":{"position":[[383,5]]}}}],["play",{"_index":482,"t":{"69":{"position":[[24,4]]},"77":{"position":[[288,5]]}}}],["pleas",{"_index":441,"t":{"58":{"position":[[89,6]]},"60":{"position":[[68,6]]},"67":{"position":[[98,6],[165,6]]},"102":{"position":[[351,6]]},"114":{"position":[[513,6]]},"116":{"position":[[881,6]]}}}],["pluggabl",{"_index":104,"t":{"8":{"position":[[110,9]]}}}],["polici",{"_index":323,"t":{"42":{"position":[[56,6],[220,6]]},"44":{"position":[[33,6]]},"48":{"position":[[295,8]]},"54":{"position":[[29,7]]},"56":{"position":[[130,9]]},"58":{"position":[[50,6],[160,6]]},"60":{"position":[[60,7]]},"104":{"position":[[122,9]]}}}],["polit",{"_index":173,"t":{"18":{"position":[[147,10]]}}}],["portion",{"_index":828,"t":{"116":{"position":[[642,8]]}}}],["possibl",{"_index":284,"t":{"36":{"position":[[235,8]]},"54":{"position":[[107,9],[370,10]]},"106":{"position":[[427,11]]},"114":{"position":[[1613,9]]}}}],["post",{"_index":446,"t":{"58":{"position":[[206,7]]},"110":{"position":[[238,7]]}}}],["poster",{"_index":614,"t":{"90":{"position":[[230,8]]}}}],["potenti",{"_index":530,"t":{"75":{"position":[[322,9]]},"79":{"position":[[527,9]]},"114":{"position":[[670,11]]}}}],["power",{"_index":202,"t":{"24":{"position":[[15,5]]}}}],["pr",{"_index":457,"t":{"63":{"position":[[96,3]]}}}],["practic",{"_index":20,"t":{"2":{"position":[[193,9],[520,9]]}}}],["prefer",{"_index":760,"t":{"114":{"position":[[253,6]]}}}],["present",{"_index":666,"t":{"98":{"position":[[1421,7]]},"100":{"position":[[788,10]]}}}],["preserv",{"_index":52,"t":{"2":{"position":[[657,10]]},"4":{"position":[[249,10]]},"90":{"position":[[119,10],[183,10]]},"120":{"position":[[42,10],[120,10]]}}}],["primari",{"_index":523,"t":{"75":{"position":[[129,7]]},"77":{"position":[[127,7]]}}}],["principl",{"_index":147,"t":{"14":{"position":[[6,10],[68,12]]},"16":{"position":[[132,10]]},"20":{"position":[[112,9]]},"38":{"position":[[9,9],[352,10]]},"114":{"position":[[315,9]]}}}],["prior",{"_index":817,"t":{"116":{"position":[[113,5]]}}}],["privaci",{"_index":51,"t":{"2":{"position":[[649,7],[702,8]]},"4":{"position":[[241,7]]},"24":{"position":[[0,7],[99,7]]},"42":{"position":[[48,7],[110,7],[212,7]]},"44":{"position":[[25,7]]},"46":{"position":[[237,7]]},"48":{"position":[[287,7]]},"52":{"position":[[30,7],[705,7]]},"54":{"position":[[21,7],[261,7]]},"56":{"position":[[122,7]]},"58":{"position":[[42,7],[152,7]]},"60":{"position":[[52,7]]},"83":{"position":[[450,8]]},"90":{"position":[[111,7],[175,7]]},"104":{"position":[[114,7]]},"120":{"position":[[34,7],[112,7]]}}}],["privat",{"_index":131,"t":{"10":{"position":[[355,7]]}}}],["proactiv",{"_index":505,"t":{"73":{"position":[[271,11]]},"77":{"position":[[515,9]]}}}],["problem",{"_index":282,"t":{"36":{"position":[[200,8]]}}}],["proceed",{"_index":798,"t":{"114":{"position":[[1676,11]]}}}],["process",{"_index":333,"t":{"44":{"position":[[63,10]]},"46":{"position":[[50,10],[125,7],[281,7],[483,7],[607,7],[711,10]]},"48":{"position":[[89,7]]},"52":{"position":[[235,9]]},"54":{"position":[[65,10],[228,8],[575,7],[635,10],[676,10],[769,10],[845,10],[1019,9]]},"77":{"position":[[728,10]]},"79":{"position":[[447,7]]}}}],["procur",{"_index":731,"t":{"106":{"position":[[149,11]]}}}],["profit",{"_index":730,"t":{"106":{"position":[[132,8]]}}}],["program",{"_index":145,"t":{"12":{"position":[[88,12]]},"120":{"position":[[185,9]]}}}],["programm",{"_index":477,"t":{"67":{"position":[[224,9]]}}}],["project",{"_index":29,"t":{"2":{"position":[[281,9],[299,9],[441,9]]},"4":{"position":[[100,7]]},"6":{"position":[[437,9]]},"8":{"position":[[120,7]]},"38":{"position":[[172,9]]},"69":{"position":[[62,9]]},"71":{"position":[[194,8],[555,8]]},"73":{"position":[[59,8],[158,7]]},"75":{"position":[[164,8],[414,9],[492,8]]},"77":{"position":[[51,8],[332,7],[379,7],[776,8]]},"79":{"position":[[120,9],[212,7],[312,9],[385,7]]},"81":{"position":[[167,9],[518,8],[589,7]]},"83":{"position":[[154,8],[488,9]]},"85":{"position":[[138,9]]},"87":{"position":[[153,8],[180,9]]},"98":{"position":[[1462,8]]},"100":{"position":[[134,11],[281,7],[386,9]]},"118":{"position":[[14,8],[98,8],[156,9],[282,8]]}}}],["project'",{"_index":549,"t":{"77":{"position":[[486,9]]}}}],["promis",{"_index":663,"t":{"98":{"position":[[1318,8]]}}}],["promptli",{"_index":552,"t":{"77":{"position":[[606,9]]}}}],["proof",{"_index":69,"t":{"4":{"position":[[174,7]]},"83":{"position":[[106,7],[201,6]]}}}],["properti",{"_index":639,"t":{"98":{"position":[[307,8]]}}}],["propos",{"_index":90,"t":{"6":{"position":[[229,9]]}}}],["protect",{"_index":118,"t":{"10":{"position":[[127,10]]},"24":{"position":[[91,7]]},"52":{"position":[[18,7],[306,10],[408,12],[517,10]]},"54":{"position":[[922,10]]},"90":{"position":[[157,10],[199,9]]}}}],["protocol",{"_index":87,"t":{"6":{"position":[[183,9]]},"38":{"position":[[229,10],[308,10]]},"67":{"position":[[268,9]]},"71":{"position":[[172,9]]},"83":{"position":[[309,8]]},"85":{"position":[[290,9]]},"87":{"position":[[332,9]]},"90":{"position":[[30,9]]}}}],["provid",{"_index":54,"t":{"2":{"position":[[673,8]]},"24":{"position":[[204,7]]},"38":{"position":[[62,8]]},"48":{"position":[[175,7]]},"52":{"position":[[277,7],[499,8]]},"69":{"position":[[87,9]]},"81":{"position":[[493,9]]},"83":{"position":[[118,8]]},"98":{"position":[[15,8]]},"104":{"position":[[26,8]]}}}],["provis",{"_index":756,"t":{"112":{"position":[[150,11]]},"116":{"position":[[445,10]]}}}],["pseudo",{"_index":212,"t":{"24":{"position":[[159,6]]}}}],["pst",{"_index":344,"t":{"44":{"position":[[271,3]]},"96":{"position":[[212,3]]}}}],["public",{"_index":14,"t":{"2":{"position":[[134,13]]},"28":{"position":[[28,6]]},"38":{"position":[[271,13]]}}}],["purport",{"_index":700,"t":{"100":{"position":[[858,7]]}}}],["purpos",{"_index":331,"t":{"44":{"position":[[8,8]]},"46":{"position":[[168,8],[443,8]]},"96":{"position":[[8,8]]},"98":{"position":[[261,8],[1090,8]]},"102":{"position":[[224,8]]},"120":{"position":[[61,7]]}}}],["push",{"_index":70,"t":{"4":{"position":[[215,7]]}}}],["qa",{"_index":540,"t":{"77":{"position":[[4,2],[280,2],[435,2],[743,2]]}}}],["qa'",{"_index":550,"t":{"77":{"position":[[510,4]]}}}],["qualiti",{"_index":553,"t":{"77":{"position":[[638,7],[710,7]]}}}],["question",{"_index":447,"t":{"60":{"position":[[32,9]]},"116":{"position":[[837,9]]}}}],["r&d",{"_index":26,"t":{"2":{"position":[[260,3]]},"38":{"position":[[124,3]]},"69":{"position":[[6,3]]},"71":{"position":[[8,3]]},"75":{"position":[[38,3]]},"83":{"position":[[30,3]]},"118":{"position":[[238,3]]}}}],["rang",{"_index":516,"t":{"73":{"position":[[446,7]]}}}],["read",{"_index":620,"t":{"94":{"position":[[276,4]]}}}],["readi",{"_index":272,"t":{"36":{"position":[[53,5]]}}}],["real",{"_index":539,"t":{"75":{"position":[[579,4]]}}}],["realm",{"_index":60,"t":{"4":{"position":[[7,5]]}}}],["reason",{"_index":413,"t":{"54":{"position":[[359,10]]},"114":{"position":[[722,10],[2149,10]]}}}],["receiv",{"_index":784,"t":{"114":{"position":[[1093,9]]}}}],["rectifi",{"_index":565,"t":{"79":{"position":[[519,7]]}}}],["refer",{"_index":352,"t":{"44":{"position":[[341,5],[381,11],[400,9]]},"96":{"position":[[282,5],[332,11],[351,9]]},"102":{"position":[[358,5]]},"114":{"position":[[1157,8],[1432,10]]},"116":{"position":[[352,9]]}}}],["regard",{"_index":329,"t":{"42":{"position":[[166,7]]},"46":{"position":[[460,7]]},"81":{"position":[[527,9]]},"112":{"position":[[123,6]]},"116":{"position":[[73,9]]}}}],["regardless",{"_index":804,"t":{"114":{"position":[[1999,10]]}}}],["regist",{"_index":337,"t":{"44":{"position":[[179,10]]},"96":{"position":[[119,10]]}}}],["regress",{"_index":529,"t":{"75":{"position":[[274,10]]}}}],["regularli",{"_index":706,"t":{"100":{"position":[[1231,10]]}}}],["regulatori",{"_index":693,"t":{"100":{"position":[[667,10]]}}}],["relat",{"_index":464,"t":{"65":{"position":[[132,7]]},"81":{"position":[[615,7]]},"83":{"position":[[351,7]]},"98":{"position":[[559,8],[1446,8]]},"100":{"position":[[421,7]]},"106":{"position":[[239,7]]},"108":{"position":[[146,7]]},"114":{"position":[[141,8]]}}}],["relay",{"_index":610,"t":{"90":{"position":[[104,6]]}}}],["relentlessli",{"_index":269,"t":{"36":{"position":[[7,12]]}}}],["relev",{"_index":334,"t":{"44":{"position":[[112,8]]},"54":{"position":[[252,8]]},"96":{"position":[[52,8]]},"114":{"position":[[1828,8]]}}}],["reli",{"_index":662,"t":{"98":{"position":[[1301,6]]}}}],["reliabl",{"_index":86,"t":{"6":{"position":[[147,11]]},"10":{"position":[[367,8]]},"75":{"position":[[381,11]]},"77":{"position":[[650,11]]},"79":{"position":[[601,12]]},"81":{"position":[[336,9]]},"98":{"position":[[450,12]]},"100":{"position":[[882,8],[951,11]]}}}],["relianc",{"_index":705,"t":{"100":{"position":[[1107,8]]}}}],["remain",{"_index":480,"t":{"67":{"position":[[291,6]]},"116":{"position":[[632,9],[656,6]]}}}],["remedi",{"_index":778,"t":{"114":{"position":[[974,6]]}}}],["remot",{"_index":138,"t":{"12":{"position":[[31,6],[101,6],[159,6],[216,6]]}}}],["remov",{"_index":414,"t":{"54":{"position":[[391,6]]}}}],["replac",{"_index":439,"t":{"58":{"position":[[17,7]]},"110":{"position":[[17,7]]}}}],["report",{"_index":471,"t":{"67":{"position":[[105,6],[172,6]]},"77":{"position":[[553,9]]}}}],["repres",{"_index":720,"t":{"104":{"position":[[233,9]]}}}],["represent",{"_index":642,"t":{"98":{"position":[[376,15],[1327,15]]},"116":{"position":[[167,15]]}}}],["request",{"_index":418,"t":{"54":{"position":[[541,8]]}}}],["requir",{"_index":398,"t":{"52":{"position":[[531,8]]},"77":{"position":[[496,13]]},"79":{"position":[[220,13],[404,13]]},"102":{"position":[[278,12]]}}}],["research",{"_index":2,"t":{"2":{"position":[[9,8],[324,8],[469,8],[497,8],[564,8]]},"4":{"position":[[30,8],[313,8]]},"6":{"position":[[35,8],[216,8],[262,8]]},"8":{"position":[[9,10]]},"12":{"position":[[135,8],[193,10]]},"18":{"position":[[51,8]]},"22":{"position":[[98,8]]},"38":{"position":[[26,8],[148,9],[196,8]]},"40":{"position":[[56,8],[195,8],[215,8]]},"65":{"position":[[26,8]]},"71":{"position":[[295,8],[315,8]]},"73":{"position":[[369,9]]},"118":{"position":[[74,8],[225,8]]}}}],["resili",{"_index":535,"t":{"75":{"position":[[525,9]]},"83":{"position":[[540,10]]}}}],["resist",{"_index":178,"t":{"18":{"position":[[210,10]]},"20":{"position":[[136,11]]},"90":{"position":[[64,9]]}}}],["resolut",{"_index":773,"t":{"114":{"position":[[809,10]]}}}],["resolv",{"_index":763,"t":{"114":{"position":[[328,9],[744,7],[1034,7],[1181,8]]}}}],["resourc",{"_index":270,"t":{"36":{"position":[[20,12],[300,11]]},"69":{"position":[[108,10]]},"118":{"position":[[198,9]]}}}],["respect",{"_index":327,"t":{"42":{"position":[[121,7]]},"48":{"position":[[276,10]]},"54":{"position":[[175,7]]},"114":{"position":[[1845,7]]},"116":{"position":[[227,7]]}}}],["respond",{"_index":504,"t":{"73":{"position":[[238,8]]}}}],["respons",{"_index":437,"t":{"56":{"position":[[161,14]]},"75":{"position":[[58,11]]},"77":{"position":[[135,16]]},"85":{"position":[[73,14]]},"87":{"position":[[86,14]]},"94":{"position":[[258,14]]},"98":{"position":[[924,11]]},"100":{"position":[[918,14]]},"104":{"position":[[696,11]]},"110":{"position":[[103,11]]}}}],["result",{"_index":372,"t":{"48":{"position":[[116,6]]},"100":{"position":[[718,8]]},"114":{"position":[[797,6]]}}}],["reveal",{"_index":204,"t":{"24":{"position":[[36,6]]}}}],["review",{"_index":564,"t":{"79":{"position":[[477,9]]},"114":{"position":[[536,6]]}}}],["rfc",{"_index":590,"t":{"85":{"position":[[8,3],[218,3],[329,3]]},"87":{"position":[[8,3],[260,3]]}}}],["right",{"_index":216,"t":{"24":{"position":[[216,5]]},"54":{"position":[[165,6],[295,5]]},"98":{"position":[[338,7]]},"114":{"position":[[465,5],[603,6],[2202,5]]},"116":{"position":[[789,5]]}}}],["rigor",{"_index":546,"t":{"77":{"position":[[360,10]]}}}],["rise",{"_index":65,"t":{"4":{"position":[[78,4]]}}}],["risk",{"_index":627,"t":{"98":{"position":[[106,5]]},"100":{"position":[[515,4],[1042,4]]},"104":{"position":[[672,4]]}}}],["rln",{"_index":609,"t":{"90":{"position":[[100,3]]}}}],["roadmap",{"_index":686,"t":{"100":{"position":[[272,8]]}}}],["robust",{"_index":97,"t":{"6":{"position":[[385,10]]},"77":{"position":[[793,6]]},"79":{"position":[[179,7]]}}}],["role",{"_index":484,"t":{"69":{"position":[[39,4]]},"77":{"position":[[304,4]]}}}],["rout",{"_index":613,"t":{"90":{"position":[[222,7]]}}}],["royer",{"_index":123,"t":{"10":{"position":[[183,5]]}}}],["rule",{"_index":789,"t":{"114":{"position":[[1316,5],[1386,5],[1963,5]]}}}],["sa",{"_index":453,"t":{"60":{"position":[[150,3]]},"116":{"position":[[963,3]]}}}],["safeti",{"_index":380,"t":{"50":{"position":[[141,6]]}}}],["same",{"_index":397,"t":{"52":{"position":[[512,4]]}}}],["sc",{"_index":561,"t":{"79":{"position":[[134,2],[234,2]]}}}],["scalabl",{"_index":98,"t":{"6":{"position":[[400,11]]},"75":{"position":[[512,8]]}}}],["scale",{"_index":525,"t":{"75":{"position":[[194,7]]}}}],["scientif",{"_index":13,"t":{"2":{"position":[[123,10]]}}}],["seamless",{"_index":495,"t":{"71":{"position":[[507,8]]},"77":{"position":[[221,8]]},"85":{"position":[[443,8]]},"87":{"position":[[479,8]]}}}],["section",{"_index":822,"t":{"116":{"position":[[289,8]]}}}],["secur",{"_index":77,"t":{"4":{"position":[[353,6]]},"22":{"position":[[23,8],[111,8],[160,8]]},"46":{"position":[[794,8]]},"50":{"position":[[36,8],[92,8]]},"67":{"position":[[8,8],[116,8],[298,7]]},"79":{"position":[[187,7],[588,8]]},"83":{"position":[[440,9]]},"90":{"position":[[44,6]]},"98":{"position":[[1764,9]]}}}],["security@free.technolog",{"_index":473,"t":{"67":{"position":[[139,25]]}}}],["see",{"_index":459,"t":{"63":{"position":[[117,3]]},"65":{"position":[[83,3]]},"92":{"position":[[0,3]]}}}],["seek",{"_index":779,"t":{"114":{"position":[[989,8]]}}}],["select",{"_index":203,"t":{"24":{"position":[[24,11]]}}}],["sell",{"_index":678,"t":{"98":{"position":[[1701,5],[1741,4]]}}}],["send",{"_index":774,"t":{"114":{"position":[[852,4]]}}}],["separ",{"_index":434,"t":{"56":{"position":[[97,8]]},"118":{"position":[[143,8]]}}}],["serious",{"_index":376,"t":{"50":{"position":[[45,9]]},"67":{"position":[[17,9]]}}}],["serv",{"_index":591,"t":{"85":{"position":[[17,6]]},"87":{"position":[[17,6]]}}}],["servic",{"_index":230,"t":{"26":{"position":[[237,7]]},"38":{"position":[[128,7]]},"69":{"position":[[10,7]]},"71":{"position":[[12,7]]},"75":{"position":[[42,7]]},"77":{"position":[[7,7],[746,7]]},"79":{"position":[[22,7]]},"81":{"position":[[59,7]]},"83":{"position":[[34,7]]},"106":{"position":[[176,9]]},"118":{"position":[[242,7]]}}}],["session",{"_index":110,"t":{"10":{"position":[[17,7]]}}}],["set",{"_index":300,"t":{"38":{"position":[[345,3]]},"114":{"position":[[888,7]]}}}],["sever",{"_index":44,"t":{"2":{"position":[[585,7]]},"116":{"position":[[581,9]]}}}],["shall",{"_index":661,"t":{"98":{"position":[[1264,5]]},"108":{"position":[[4,5]]},"114":{"position":[[841,5]]}}}],["share",{"_index":94,"t":{"6":{"position":[[300,7]]},"28":{"position":[[112,6]]},"40":{"position":[[161,5]]}}}],["shepherd",{"_index":593,"t":{"85":{"position":[[91,11]]},"87":{"position":[[104,11]]}}}],["short",{"_index":227,"t":{"26":{"position":[[213,5]]}}}],["shortcom",{"_index":225,"t":{"26":{"position":[[176,13]]}}}],["signific",{"_index":839,"t":{"120":{"position":[[154,11]]}}}],["similar",{"_index":353,"t":{"44":{"position":[[373,7]]},"96":{"position":[[324,7]]}}}],["singl",{"_index":266,"t":{"34":{"position":[[94,6]]}}}],["site",{"_index":433,"t":{"56":{"position":[[86,5]]},"98":{"position":[[607,5]]}}}],["site.thes",{"_index":647,"t":{"98":{"position":[[628,10]]}}}],["sixti",{"_index":781,"t":{"114":{"position":[[1062,5]]}}}],["skill",{"_index":515,"t":{"73":{"position":[[424,6]]}}}],["smart",{"_index":557,"t":{"79":{"position":[[6,5],[96,5],[159,5],[258,5],[487,5]]}}}],["social",{"_index":172,"t":{"18":{"position":[[139,7]]},"32":{"position":[[112,6]]}}}],["softwar",{"_index":140,"t":{"12":{"position":[[50,8]]},"28":{"position":[[4,8]]},"30":{"position":[[43,8]]},"32":{"position":[[48,9]]},"34":{"position":[[10,8]]},"67":{"position":[[282,8]]},"69":{"position":[[161,8]]},"75":{"position":[[113,9]]},"77":{"position":[[669,9],[820,8]]}}}],["sole",{"_index":625,"t":{"98":{"position":[[86,4],[889,4],[917,6]]},"100":{"position":[[1410,4]]},"104":{"position":[[689,6]]}}}],["solicit",{"_index":679,"t":{"98":{"position":[[1710,10]]}}}],["solut",{"_index":536,"t":{"75":{"position":[[535,9]]},"77":{"position":[[829,10]]},"83":{"position":[[72,9]]}}}],["solv",{"_index":281,"t":{"36":{"position":[[192,7]]}}}],["sourc",{"_index":236,"t":{"28":{"position":[[82,6]]}}}],["sovereignti",{"_index":164,"t":{"18":{"position":[[18,11]]}}}],["spam",{"_index":117,"t":{"10":{"position":[[122,4]]},"90":{"position":[[152,4],[194,4]]}}}],["spawn",{"_index":38,"t":{"2":{"position":[[418,8]]}}}],["special",{"_index":733,"t":{"106":{"position":[[193,8]]}}}],["specialis",{"_index":489,"t":{"71":{"position":[[49,12]]},"79":{"position":[[35,11]]},"83":{"position":[[264,11]]}}}],["specif",{"_index":105,"t":{"8":{"position":[[128,8]]},"38":{"position":[[251,15]]},"46":{"position":[[159,8]]},"52":{"position":[[429,8]]},"77":{"position":[[419,15]]},"79":{"position":[[290,8]]},"81":{"position":[[580,8]]},"85":{"position":[[115,14],[194,15]]},"87":{"position":[[128,14],[236,15]]},"100":{"position":[[1290,9]]},"116":{"position":[[828,8]]}}}],["spectrum",{"_index":514,"t":{"73":{"position":[[412,8]]}}}],["stabil",{"_index":532,"t":{"75":{"position":[[397,9]]}}}],["stage",{"_index":707,"t":{"100":{"position":[[1308,6]]}}}],["stand",{"_index":167,"t":{"18":{"position":[[78,6]]}}}],["standard",{"_index":567,"t":{"79":{"position":[[575,9]]}}}],["standardis",{"_index":599,"t":{"85":{"position":[[259,12]]},"87":{"position":[[301,12]]}}}],["startup",{"_index":293,"t":{"38":{"position":[[101,8]]}}}],["state",{"_index":196,"t":{"22":{"position":[[63,5]]}}}],["statement",{"_index":681,"t":{"100":{"position":[[45,10],[221,11],[251,10],[410,10],[557,10]]}}}],["statu",{"_index":121,"t":{"10":{"position":[[169,6]]},"104":{"position":[[217,6]]}}}],["statut",{"_index":805,"t":{"114":{"position":[[2028,7]]}}}],["stay",{"_index":159,"t":{"16":{"position":[[112,7]]}}}],["stealth",{"_index":467,"t":{"65":{"position":[[171,7]]},"83":{"position":[[612,7]]}}}],["stem",{"_index":832,"t":{"118":{"position":[[53,4]]}}}],["stewardship",{"_index":265,"t":{"34":{"position":[[77,11]]}}}],["still",{"_index":407,"t":{"54":{"position":[[134,5]]}}}],["store",{"_index":360,"t":{"46":{"position":[[342,5],[380,5],[851,6]]}}}],["strategi",{"_index":511,"t":{"73":{"position":[[343,10]]}}}],["strengthen",{"_index":75,"t":{"4":{"position":[[322,11]]}}}],["strict",{"_index":727,"t":{"106":{"position":[[66,6]]}}}],["strive",{"_index":215,"t":{"24":{"position":[[194,6]]},"26":{"position":[[3,6]]}}}],["strong",{"_index":200,"t":{"22":{"position":[[153,6]]}}}],["stronger",{"_index":189,"t":{"20":{"position":[[153,9]]}}}],["stylist",{"_index":151,"t":{"14":{"position":[[92,9]]}}}],["subject",{"_index":688,"t":{"100":{"position":[[487,7],[572,7],[1318,7]]},"102":{"position":[[259,7]]}}}],["submit",{"_index":381,"t":{"50":{"position":[[179,6]]},"52":{"position":[[73,9]]}}}],["subsect",{"_index":823,"t":{"116":{"position":[[302,11]]}}}],["substitut",{"_index":732,"t":{"106":{"position":[[165,10]]}}}],["such",{"_index":25,"t":{"2":{"position":[[248,4]]},"46":{"position":[[572,4],[722,4]]},"48":{"position":[[232,4]]},"50":{"position":[[186,4]]},"52":{"position":[[421,4],[477,4]]},"54":{"position":[[764,4]]},"69":{"position":[[181,4]]},"81":{"position":[[434,4]]},"83":{"position":[[285,4]]},"98":{"position":[[584,4],[1622,5]]},"100":{"position":[[432,4]]},"102":{"position":[[291,4]]},"104":{"position":[[190,4],[281,4],[347,4],[456,4],[607,4],[731,4]]},"106":{"position":[[442,4],[498,4]]},"114":{"position":[[823,4],[1136,4]]}}}],["suggest",{"_index":509,"t":{"73":{"position":[[318,10]]},"81":{"position":[[298,8]]}}}],["suitabl",{"_index":646,"t":{"98":{"position":[[463,11]]}}}],["summari",{"_index":699,"t":{"100":{"position":[[837,7]]}}}],["supersed",{"_index":816,"t":{"116":{"position":[[99,9]]}}}],["supplement",{"_index":709,"t":{"100":{"position":[[1358,12]]}}}],["support",{"_index":291,"t":{"38":{"position":[[81,7]]},"69":{"position":[[47,10]]},"77":{"position":[[36,10]]},"81":{"position":[[503,7]]},"104":{"position":[[272,8]]},"118":{"position":[[186,7]]}}}],["surveil",{"_index":183,"t":{"20":{"position":[[60,13]]}}}],["swiss",{"_index":751,"t":{"112":{"position":[[0,5]]},"114":{"position":[[1247,5],[1310,5],[1957,5]]}}}],["switzerland",{"_index":350,"t":{"44":{"position":[[317,11]]},"52":{"position":[[179,12],[330,11],[543,11],[645,11]]},"96":{"position":[[258,11]]},"114":{"position":[[1532,12]]}}}],["symmetri",{"_index":220,"t":{"26":{"position":[[36,8]]}}}],["sync",{"_index":133,"t":{"10":{"position":[[381,4]]}}}],["system",{"_index":415,"t":{"54":{"position":[[426,8]]},"73":{"position":[[484,7]]},"75":{"position":[[16,7],[97,7],[464,7]]},"77":{"position":[[267,8]]}}}],["system(",{"_index":252,"t":{"30":{"position":[[230,9]]}}}],["tailor",{"_index":562,"t":{"79":{"position":[[274,8]]}}}],["take",{"_index":375,"t":{"50":{"position":[[26,4]]},"67":{"position":[[3,4]]},"85":{"position":[[59,6]]},"87":{"position":[[72,6]]}}}],["tax",{"_index":672,"t":{"98":{"position":[[1572,4]]}}}],["team",{"_index":21,"t":{"2":{"position":[[207,4]]},"4":{"position":[[123,4]]},"6":{"position":[[84,4]]},"34":{"position":[[130,4]]},"73":{"position":[[166,5],[383,4]]}}}],["technic",{"_index":290,"t":{"38":{"position":[[71,9]]},"46":{"position":[[754,9]]},"69":{"position":[[123,9]]},"100":{"position":[[303,9],[639,9]]}}}],["techniqu",{"_index":585,"t":{"83":{"position":[[239,11]]}}}],["technolog",{"_index":72,"t":{"4":{"position":[[260,13]]},"22":{"position":[[80,13],[132,12]]},"67":{"position":[[67,10]]},"71":{"position":[[84,13],[390,13]]},"83":{"position":[[409,13]]},"85":{"position":[[497,12]]},"87":{"position":[[533,12]]},"100":{"position":[[156,11]]}}}],["term",{"_index":228,"t":{"26":{"position":[[219,4],[257,4]]},"36":{"position":[[272,5]]},"94":{"position":[[58,5],[81,5],[293,5],[439,5],[492,5]]},"96":{"position":[[34,5]]},"102":{"position":[[328,5]]},"104":{"position":[[82,5]]},"106":{"position":[[308,5]]},"108":{"position":[[271,5]]},"110":{"position":[[50,5],[186,5]]},"112":{"position":[[32,5]]},"114":{"position":[[9,6],[167,5]]},"116":{"position":[[14,5],[331,5],[473,5],[516,5],[610,5],[732,5],[867,5]]}}}],["test",{"_index":142,"t":{"12":{"position":[[72,4]]},"75":{"position":[[24,7],[105,7],[285,8],[472,7]]},"77":{"position":[[115,4],[178,5],[205,5],[371,7],[698,7]]}}}],["theoret",{"_index":519,"t":{"73":{"position":[[495,11]]}}}],["theori",{"_index":19,"t":{"2":{"position":[[182,6]]},"106":{"position":[[112,6]]}}}],["therefor",{"_index":436,"t":{"56":{"position":[[143,9]]}}}],["therein",{"_index":722,"t":{"104":{"position":[[318,8],[385,7]]}}}],["thing",{"_index":691,"t":{"100":{"position":[[612,7]]}}}],["third",{"_index":370,"t":{"48":{"position":[[60,5],[237,5]]},"56":{"position":[[46,5],[74,5],[229,5]]},"104":{"position":[[50,5],[157,5],[195,5],[286,5],[352,5],[461,5],[542,5],[612,5],[736,5]]}}}],["thoren",{"_index":127,"t":{"10":{"position":[[259,6],[326,7],[439,6]]}}}],["thorough",{"_index":528,"t":{"75":{"position":[[265,8]]},"79":{"position":[[429,8]]}}}],["those",{"_index":719,"t":{"104":{"position":[[151,5]]}}}],["thought",{"_index":315,"t":{"40":{"position":[[172,8]]}}}],["thread",{"_index":455,"t":{"63":{"position":[[55,6]]}}}],["through",{"_index":541,"t":{"77":{"position":[[60,7],[679,7]]},"98":{"position":[[1018,7]]},"100":{"position":[[462,7],[1174,7]]},"104":{"position":[[572,7],[633,7]]},"114":{"position":[[1204,7]]}}}],["throughout",{"_index":605,"t":{"85":{"position":[[510,10]]},"87":{"position":[[546,10]]}}}],["time",{"_index":287,"t":{"36":{"position":[[290,5]]},"46":{"position":[[413,4],[869,5]]},"58":{"position":[[64,4]]},"100":{"position":[[1378,5]]},"110":{"position":[[70,4]]},"114":{"position":[[1359,4],[2123,4]]}}}],["timelin",{"_index":696,"t":{"100":{"position":[[755,9],[1273,8]]}}}],["tke",{"_index":503,"t":{"73":{"position":[[225,3]]}}}],["tke'",{"_index":500,"t":{"73":{"position":[[129,5],[363,5]]}}}],["togeth",{"_index":512,"t":{"73":{"position":[[395,8]]}}}],["token",{"_index":275,"t":{"36":{"position":[[102,5]]},"73":{"position":[[8,5],[87,5]]},"98":{"position":[[1750,6]]},"100":{"position":[[376,6]]}}}],["tool",{"_index":571,"t":{"81":{"position":[[122,7],[208,5]]}}}],["total",{"_index":217,"t":{"24":{"position":[[225,5]]}}}],["touch",{"_index":454,"t":{"63":{"position":[[7,5]]}}}],["tradeoff",{"_index":229,"t":{"26":{"position":[[224,9]]}}}],["train",{"_index":109,"t":{"10":{"position":[[8,8]]}}}],["transact",{"_index":210,"t":{"24":{"position":[[134,13]]}}}],["transfer",{"_index":417,"t":{"54":{"position":[[494,11]]}}}],["translat",{"_index":41,"t":{"2":{"position":[[481,9]]}}}],["transmiss",{"_index":400,"t":{"52":{"position":[[584,12]]}}}],["treat",{"_index":674,"t":{"98":{"position":[[1611,7]]}}}],["trial",{"_index":771,"t":{"114":{"position":[[620,5]]}}}],["tribun",{"_index":796,"t":{"114":{"position":[[1627,8]]}}}],["true",{"_index":160,"t":{"16":{"position":[[120,4]]}}}],["trustworthi",{"_index":589,"t":{"83":{"position":[[463,15]]}}}],["unabl",{"_index":780,"t":{"114":{"position":[[1016,6]]}}}],["uncertainti",{"_index":690,"t":{"100":{"position":[[524,12],[1051,11]]}}}],["under",{"_index":182,"t":{"20":{"position":[[54,5]]},"46":{"position":[[220,5]]},"60":{"position":[[138,5]]},"102":{"position":[[48,5]]},"106":{"position":[[34,5]]},"116":{"position":[[951,5]]}}}],["understand",{"_index":524,"t":{"75":{"position":[[176,13]]},"116":{"position":[[139,15]]}}}],["undu",{"_index":704,"t":{"100":{"position":[[1101,5]]}}}],["unenforc",{"_index":827,"t":{"116":{"position":[[548,14]]}}}],["union",{"_index":388,"t":{"52":{"position":[[170,5],[635,5]]}}}],["unit",{"_index":27,"t":{"2":{"position":[[264,6]]},"38":{"position":[[136,6]]},"69":{"position":[[18,5]]},"71":{"position":[[20,4],[106,4],[255,4],[412,4]]},"73":{"position":[[24,4]]},"75":{"position":[[50,4],[302,4]]},"77":{"position":[[15,4],[173,4],[283,4],[754,4]]},"79":{"position":[[30,4],[137,4]]},"81":{"position":[[67,4],[185,4],[370,4],[474,4]]},"83":{"position":[[42,4],[259,4]]},"85":{"position":[[12,4],[222,4]]},"87":{"position":[[12,4],[264,4]]},"118":{"position":[[250,5]]}}}],["unit'",{"_index":533,"t":{"75":{"position":[[432,6]]},"79":{"position":[[422,6]]},"85":{"position":[[333,6]]}}}],["unlawfulli",{"_index":430,"t":{"54":{"position":[[1029,11]]}}}],["unlik",{"_index":382,"t":{"52":{"position":[[90,8]]}}}],["up",{"_index":307,"t":{"40":{"position":[[29,2]]},"79":{"position":[[365,2]]},"81":{"position":[[350,2]]},"92":{"position":[[10,4]]}}}],["updat",{"_index":319,"t":{"42":{"position":[[18,8]]},"54":{"position":[[326,6]]},"94":{"position":[[18,8]]},"100":{"position":[[1212,6]]}}}],["upon",{"_index":445,"t":{"58":{"position":[[197,4]]},"98":{"position":[[1308,4]]},"110":{"position":[[229,4]]}}}],["us",{"_index":125,"t":{"10":{"position":[[242,5]]},"22":{"position":[[59,3]]},"32":{"position":[[86,4]]},"46":{"position":[[529,3],[577,3]]},"48":{"position":[[145,3]]},"52":{"position":[[389,3]]},"81":{"position":[[25,3],[541,3]]},"94":{"position":[[67,3],[90,5],[160,3],[302,3],[328,3],[356,3],[448,4],[501,4],[529,3]]},"96":{"position":[[43,4]]},"98":{"position":[[58,3],[498,3],[855,3]]},"100":{"position":[[369,3]]},"102":{"position":[[254,4]]},"104":{"position":[[144,3],[409,6],[514,3]]},"106":{"position":[[317,4],[371,3]]},"108":{"position":[[162,3],[280,4]]},"110":{"position":[[59,3],[195,3]]},"112":{"position":[[41,3]]},"114":{"position":[[176,4],[230,3],[713,3]]},"116":{"position":[[23,3],[340,3],[482,4],[525,3],[619,4],[741,4],[876,4]]}}}],["user",{"_index":325,"t":{"42":{"position":[[85,5]]},"46":{"position":[[83,5]]},"102":{"position":[[153,5]]}}}],["util",{"_index":645,"t":{"98":{"position":[[441,8]]}}}],["v2",{"_index":108,"t":{"10":{"position":[[5,2],[76,2],[278,2]]}}}],["vac",{"_index":0,"t":{"2":{"position":[[0,3],[256,3],[460,3]]},"4":{"position":[[21,3],[304,3]]},"6":{"position":[[26,3],[253,3]]},"8":{"position":[[0,3]]},"10":{"position":[[66,4],[268,4]]},"12":{"position":[[0,3]]},"16":{"position":[[12,3]]},"38":{"position":[[0,3],[110,3]]},"40":{"position":[[9,3],[211,3]]},"65":{"position":[[128,3]]},"67":{"position":[[30,3]]},"71":{"position":[[44,4],[286,3]]},"73":{"position":[[4,3]]},"85":{"position":[[4,3],[214,3]]},"87":{"position":[[4,3],[166,3],[256,3]]},"118":{"position":[[0,3],[263,4],[306,4]]}}}],["vac'",{"_index":481,"t":{"69":{"position":[[0,5]]},"79":{"position":[[0,5]]},"118":{"position":[[63,5]]}}}],["valid",{"_index":56,"t":{"2":{"position":[[692,9]]},"54":{"position":[[752,8]]}}}],["valu",{"_index":303,"t":{"38":{"position":[[405,6]]}}}],["valuabl",{"_index":582,"t":{"83":{"position":[[127,8]]}}}],["vari",{"_index":697,"t":{"100":{"position":[[771,4]]}}}],["varieti",{"_index":378,"t":{"50":{"position":[[81,7]]}}}],["variou",{"_index":23,"t":{"2":{"position":[[230,7]]},"65":{"position":[[120,7]]}}}],["verif",{"_index":545,"t":{"77":{"position":[[316,12]]}}}],["via",{"_index":235,"t":{"28":{"position":[[62,3]]},"67":{"position":[[135,3]]},"114":{"position":[[1566,3]]}}}],["video",{"_index":793,"t":{"114":{"position":[[1570,5]]}}}],["violat",{"_index":640,"t":{"98":{"position":[[325,9]]},"108":{"position":[[244,9]]}}}],["virtual",{"_index":837,"t":{"120":{"position":[[84,7]]}}}],["virtual/onlin",{"_index":795,"t":{"114":{"position":[[1587,14]]}}}],["visit",{"_index":330,"t":{"42":{"position":[[185,8]]}}}],["vital",{"_index":488,"t":{"71":{"position":[[30,5]]},"85":{"position":[[29,5]]},"87":{"position":[[29,5]]}}}],["vulner",{"_index":475,"t":{"67":{"position":[[194,15]]},"79":{"position":[[537,16]]}}}],["waiv",{"_index":765,"t":{"114":{"position":[[453,6],[588,5],[2192,5]]},"116":{"position":[[778,6]]}}}],["waku",{"_index":107,"t":{"10":{"position":[[0,4],[25,5],[71,4],[248,4],[273,4],[350,4]]},"90":{"position":[[0,5],[95,4]]}}}],["warrant",{"_index":641,"t":{"98":{"position":[[356,7]]}}}],["warranti",{"_index":629,"t":{"98":{"position":[[128,10],[205,10],[1343,8]]},"116":{"position":[[187,11]]}}}],["way",{"_index":82,"t":{"6":{"position":[[98,4]]},"36":{"position":[[231,3]]},"46":{"position":[[646,3]]},"106":{"position":[[275,3]]}}}],["web",{"_index":155,"t":{"16":{"position":[[60,4]]},"83":{"position":[[572,3]]}}}],["websit",{"_index":328,"t":{"42":{"position":[[137,7],[145,12],[198,8]]},"46":{"position":[[96,8],[540,8],[588,7],[819,8]]},"48":{"position":[[130,7]]},"50":{"position":[[117,7]]},"56":{"position":[[8,8],[58,9],[241,9]]},"58":{"position":[[106,7],[221,8]]},"94":{"position":[[50,7],[71,9],[172,8],[238,8],[285,7],[339,7],[367,7],[431,7],[484,7],[537,8]]},"96":{"position":[[26,7]]},"98":{"position":[[4,7],[66,7],[509,8],[538,7],[575,8],[740,7],[866,7],[1031,7],[1644,7]]},"100":{"position":[[4,7],[475,7],[1149,7],[1187,8],[1223,7]]},"102":{"position":[[4,7],[381,8]]},"104":{"position":[[18,7],[62,8],[169,9],[207,9],[298,8],[364,8],[473,8],[554,8],[584,8],[624,8],[645,8],[748,9]]},"106":{"position":[[300,7],[326,8],[354,8],[382,8]]},"108":{"position":[[173,8],[201,8],[263,7]]},"110":{"position":[[42,7],[132,7],[178,7],[253,8]]},"112":{"position":[[24,7]]},"114":{"position":[[159,7],[185,8],[213,8],[241,8]]},"116":{"position":[[6,7],[87,7],[242,8],[323,7],[465,7],[508,7],[602,7],[724,7],[859,7]]}}}],["well",{"_index":211,"t":{"24":{"position":[[151,4]]},"114":{"position":[[1691,4]]}}}],["what’",{"_index":698,"t":{"100":{"position":[[781,6]]}}}],["whenev",{"_index":351,"t":{"44":{"position":[[329,8]]},"96":{"position":[[270,8]]}}}],["wherev",{"_index":405,"t":{"54":{"position":[[98,8]]}}}],["whether",{"_index":664,"t":{"98":{"position":[[1366,7],[1397,7]]},"112":{"position":[[82,7]]}}}],["whisper",{"_index":130,"t":{"10":{"position":[[339,7],[405,7]]}}}],["widespread",{"_index":153,"t":{"16":{"position":[[19,10]]},"32":{"position":[[23,10]]}}}],["withdraw",{"_index":419,"t":{"54":{"position":[[550,8]]}}}],["withdrawn",{"_index":424,"t":{"54":{"position":[[807,9]]}}}],["within",{"_index":8,"t":{"2":{"position":[[81,6],[543,6]]},"4":{"position":[[390,6]]},"6":{"position":[[326,6]]},"26":{"position":[[60,6]]},"36":{"position":[[156,6]]},"71":{"position":[[544,6]]},"75":{"position":[[227,6]]},"85":{"position":[[300,6]]},"87":{"position":[[342,6]]},"114":{"position":[[1055,6],[2078,6]]},"118":{"position":[[256,6],[299,6]]}}}],["without",{"_index":264,"t":{"34":{"position":[[65,7]]},"58":{"position":[[73,7]]},"98":{"position":[[182,7]]},"100":{"position":[[1384,7]]},"108":{"position":[[220,7]]},"110":{"position":[[79,7]]},"112":{"position":[[115,7]]}}}],["withstand",{"_index":537,"t":{"75":{"position":[[554,9]]}}}],["word",{"_index":246,"t":{"30":{"position":[[90,6]]}}}],["work",{"_index":10,"t":{"2":{"position":[[103,4]]},"71":{"position":[[132,5]]},"81":{"position":[[190,5]]}}}],["world",{"_index":206,"t":{"24":{"position":[[58,6]]},"75":{"position":[[584,5]]}}}],["worldwid",{"_index":139,"t":{"12":{"position":[[38,11],[108,11],[166,11],[223,11]]}}}],["write",{"_index":615,"t":{"92":{"position":[[4,5]]}}}],["written",{"_index":775,"t":{"114":{"position":[[862,7]]},"116":{"position":[[204,7]]}}}],["x",{"_index":313,"t":{"40":{"position":[[129,1]]}}}],["year",{"_index":806,"t":{"114":{"position":[[2089,4]]}}}],["zero",{"_index":47,"t":{"2":{"position":[[614,4]]},"4":{"position":[[159,4]]},"12":{"position":[[120,4],[178,4]]},"83":{"position":[[86,4]]},"120":{"position":[[69,4]]}}}],["zerokit",{"_index":466,"t":{"65":{"position":[[163,7]]},"69":{"position":[[204,8]]},"83":{"position":[[600,7]]}}}],["zk",{"_index":49,"t":{"2":{"position":[[629,5]]},"4":{"position":[[300,3]]},"83":{"position":[[27,2],[101,4],[198,2]]}}}],["zkp",{"_index":61,"t":{"4":{"position":[[16,4]]},"10":{"position":[[113,4]]}}}],["zkpodcast",{"_index":116,"t":{"10":{"position":[[102,10]]}}}],["zug",{"_index":339,"t":{"44":{"position":[[200,3],[313,3]]},"96":{"position":[[140,3],[254,3]]},"114":{"position":[[1527,4]]}}}]],"pipeline":["stemmer"]}}] \ No newline at end of file +[{"documents":[{"i":1,"t":"About Vac","u":"/","b":["About Vac"]},{"i":3,"t":"Contribute","u":"/contribute","b":[]},{"i":8,"t":"Current job openings","u":"/join-us","b":["Join Us"]},{"i":10,"t":"Vac Deep Research","u":"/deepresearch","b":[]},{"i":18,"t":"","u":"/media","b":[]},{"i":20,"t":"","u":"/principles","b":[]},{"i":44,"t":"Privacy Policy","u":"/privacy-policy","b":[]},{"i":64,"t":"Security","u":"/security","b":[]},{"i":66,"t":"Join the community","u":"/community","b":["Community"]},{"i":68,"t":"Publications","u":"/publications","b":[]},{"i":73,"t":"Vac RFC Process","u":"/rfcprocess","b":[]},{"i":75,"t":"Terms of Use","u":"/terms","b":[]},{"i":99,"t":"Vac Incubator Projects","u":"/vips","b":[]},{"i":103,"t":"Vac R&D Service Units","u":"/vsus","b":[]}],"index":{"version":"2.3.9","fields":["t"],"fieldVectors":[["t/1",[0,1.237]],["t/3",[1,2.839]],["t/8",[2,1.839,3,1.839,4,1.839]],["t/10",[0,0.802,5,1.839,6,1.839]],["t/18",[]],["t/20",[]],["t/44",[7,2.232,8,2.232]],["t/64",[9,2.839]],["t/66",[10,2.232,11,2.232]],["t/68",[12,2.839]],["t/73",[0,0.802,13,1.839,14,1.839]],["t/75",[15,2.232,16,2.232]],["t/99",[0,0.802,17,1.839,18,1.839]],["t/103",[0,0.682,19,1.564,20,1.564,21,1.564]]],"invertedIndex":[["commun",{"_index":11,"t":{"66":{"position":[[9,9]]}}}],["contribut",{"_index":1,"t":{"3":{"position":[[0,10]]}}}],["current",{"_index":2,"t":{"8":{"position":[[0,7]]}}}],["deep",{"_index":5,"t":{"10":{"position":[[4,4]]}}}],["incub",{"_index":17,"t":{"99":{"position":[[4,9]]}}}],["job",{"_index":3,"t":{"8":{"position":[[8,3]]}}}],["join",{"_index":10,"t":{"66":{"position":[[0,4]]}}}],["open",{"_index":4,"t":{"8":{"position":[[12,8]]}}}],["polici",{"_index":8,"t":{"44":{"position":[[8,6]]}}}],["privaci",{"_index":7,"t":{"44":{"position":[[0,7]]}}}],["process",{"_index":14,"t":{"73":{"position":[[8,7]]}}}],["project",{"_index":18,"t":{"99":{"position":[[14,8]]}}}],["public",{"_index":12,"t":{"68":{"position":[[0,12]]}}}],["r&d",{"_index":19,"t":{"103":{"position":[[4,3]]}}}],["research",{"_index":6,"t":{"10":{"position":[[9,8]]}}}],["rfc",{"_index":13,"t":{"73":{"position":[[4,3]]}}}],["secur",{"_index":9,"t":{"64":{"position":[[0,8]]}}}],["servic",{"_index":20,"t":{"103":{"position":[[8,7]]}}}],["term",{"_index":15,"t":{"75":{"position":[[0,5]]}}}],["unit",{"_index":21,"t":{"103":{"position":[[16,5]]}}}],["us",{"_index":16,"t":{"75":{"position":[[9,3]]}}}],["vac",{"_index":0,"t":{"1":{"position":[[6,3]]},"10":{"position":[[0,3]]},"73":{"position":[[0,3]]},"99":{"position":[[0,3]]},"103":{"position":[[0,3]]}}}]],"pipeline":["stemmer"]}},{"documents":[{"i":4,"t":"How to Contribute","u":"/contribute","h":"#how-to-contribute","p":3},{"i":6,"t":"What to Contribute","u":"/contribute","h":"#what-to-contribute","p":3},{"i":12,"t":"Zero-Knowledge Proofs","u":"/deepresearch","h":"#zero-knowledge-proofs","p":10},{"i":14,"t":"Libp2p Gossipsub Improvements","u":"/deepresearch","h":"#libp2p-gossipsub-improvements","p":10},{"i":16,"t":"Anonymisation Networks","u":"/deepresearch","h":"#anonymisation-networks","p":10},{"i":22,"t":"Principles","u":"/principles","h":"","p":20},{"i":24,"t":"I. Liberty","u":"/principles","h":"#i-liberty","p":20},{"i":26,"t":"II. Censorship resistance","u":"/principles","h":"#ii-censorship-resistance","p":20},{"i":28,"t":"III. Security","u":"/principles","h":"#iii-security","p":20},{"i":30,"t":"IV. Privacy","u":"/principles","h":"#iv-privacy","p":20},{"i":32,"t":"V. Transparency","u":"/principles","h":"#v-transparency","p":20},{"i":34,"t":"VI. Openness","u":"/principles","h":"#vi-openness","p":20},{"i":36,"t":"VII. Decentralisation","u":"/principles","h":"#vii-decentralisation","p":20},{"i":38,"t":"VIII. Inclusivity","u":"/principles","h":"#viii-inclusivity","p":20},{"i":40,"t":"IX. Continuance","u":"/principles","h":"#ix-continuance","p":20},{"i":42,"t":"X. Resourcefulness","u":"/principles","h":"#x-resourcefulness","p":20},{"i":46,"t":"1) Who we are","u":"/privacy-policy","h":"#1-who-we-are","p":44},{"i":48,"t":"2) We limit the collection and processing of personal data from your use of the Website","u":"/privacy-policy","h":"#2-we-limit-the-collection-and-processing-of-personal-data-from-your-use-of-the-website","p":44},{"i":50,"t":"3) Third party processing of personal data","u":"/privacy-policy","h":"#3-third-party-processing-of-personal-data","p":44},{"i":52,"t":"4) Security measures we take in respect of the Website","u":"/privacy-policy","h":"#4-security-measures-we-take-in-respect-of-the-website","p":44},{"i":54,"t":"5) Exporting data outside the European Union and Switzerland","u":"/privacy-policy","h":"#5-exporting-data-outside-the-european-union-and-switzerland","p":44},{"i":56,"t":"6) Your choices and rights","u":"/privacy-policy","h":"#6-your-choices-and-rights","p":44},{"i":58,"t":"7) Third party links","u":"/privacy-policy","h":"#7-third-party-links","p":44},{"i":60,"t":"8) This Privacy Policy might change","u":"/privacy-policy","h":"#8-this-privacy-policy-might-change","p":44},{"i":62,"t":"9) Contact information","u":"/privacy-policy","h":"#9-contact-information","p":44},{"i":69,"t":"Papers","u":"/publications","h":"#papers","p":68},{"i":71,"t":"Write-ups","u":"/publications","h":"#write-ups","p":68},{"i":77,"t":"1) Who we are","u":"/terms","h":"#1-who-we-are","p":75},{"i":79,"t":"2) Disclaimers","u":"/terms","h":"#2-disclaimers","p":75},{"i":81,"t":"3) Forward looking statements","u":"/terms","h":"#3-forward-looking-statements","p":75},{"i":83,"t":"4) Intellectual property rights","u":"/terms","h":"#4-intellectual-property-rights","p":75},{"i":85,"t":"5) Third-party website links","u":"/terms","h":"#5-third-party-website-links","p":75},{"i":87,"t":"6) Limitation of liability","u":"/terms","h":"#6-limitation-of-liability","p":75},{"i":89,"t":"7) Indemnity","u":"/terms","h":"#7-indemnity","p":75},{"i":91,"t":"8) Modifications","u":"/terms","h":"#8-modifications","p":75},{"i":93,"t":"9) Governing law","u":"/terms","h":"#9-governing-law","p":75},{"i":95,"t":"10) Disputes","u":"/terms","h":"#10-disputes","p":75},{"i":97,"t":"11) About these Website Terms of Use","u":"/terms","h":"#11-about-these-website-terms-of-use","p":75},{"i":101,"t":"Nescience","u":"/vips","h":"#nescience","p":99},{"i":105,"t":"P2P","u":"/vsus","h":"#p2p","p":103},{"i":107,"t":"Token Economics (TKE)","u":"/vsus","h":"#token-economics-tke","p":103},{"i":109,"t":"Distributed Systems Testing (DST)","u":"/vsus","h":"#distributed-systems-testing-dst","p":103},{"i":111,"t":"Quality Assurance (QA)","u":"/vsus","h":"#quality-assurance-qa","p":103},{"i":113,"t":"Smart Contracts (SC)","u":"/vsus","h":"#smart-contracts-sc","p":103},{"i":115,"t":"Nim","u":"/vsus","h":"#nim","p":103},{"i":117,"t":"Applied Cryptography & ZK (ACZ)","u":"/vsus","h":"#applied-cryptography--zk-acz","p":103},{"i":119,"t":"RFC","u":"/vsus","h":"#rfc","p":103}],"index":{"version":"2.3.9","fields":["t"],"fieldVectors":[["t/4",[0,4]],["t/6",[0,4]],["t/12",[1,3.35,2,3.35,3,3.35]],["t/14",[4,3.35,5,3.35,6,3.35]],["t/16",[7,3.909,8,3.909]],["t/22",[9,4.691]],["t/24",[10,4.691]],["t/26",[11,3.35,12,3.35,13,3.35]],["t/28",[14,3.909,15,3.332]],["t/30",[16,3.909,17,3.332]],["t/32",[18,3.909,19,3.909]],["t/34",[20,3.909,21,3.909]],["t/36",[22,3.909,23,3.909]],["t/38",[24,3.909,25,3.909]],["t/40",[26,3.909,27,3.909]],["t/42",[28,3.909,29,3.909]],["t/46",[30,4]],["t/48",[31,1.666,32,1.666,33,1.953,34,1.666,35,1.666,36,1.476,37,1.666,38,1.334]],["t/50",[34,1.999,35,1.999,36,1.771,39,1.999,40,1.771,41,1.771]],["t/52",[15,1.999,38,1.601,42,1.999,43,2.344,44,2.344,45,2.344]],["t/54",[36,1.61,46,1.817,47,2.131,48,2.131,49,2.131,50,2.131,51,2.131]],["t/56",[52,2.856,53,3.35,54,2.856]],["t/58",[40,2.214,41,2.214,55,2.499,56,2.499]],["t/60",[17,2.499,57,2.499,58,2.931,59,2.931]],["t/62",[60,2.856,61,3.35,62,3.35]],["t/69",[63,4.691]],["t/71",[64,3.909,65,3.909]],["t/77",[30,4]],["t/79",[31,3.332,66,3.909]],["t/81",[39,2.499,67,2.931,68,2.931,69,2.931]],["t/83",[42,2.499,54,2.499,70,2.931,71,2.931]],["t/85",[38,1.779,40,1.968,41,1.968,46,2.221,56,2.221]],["t/87",[32,2.856,52,2.856,72,3.35]],["t/89",[55,3.332,73,3.909]],["t/91",[57,3.332,74,3.909]],["t/93",[60,2.856,75,3.35,76,3.35]],["t/95",[77,3.909,78,3.909]],["t/97",[37,2.499,38,2.002,79,2.931,80,2.931]],["t/101",[81,4.691]],["t/105",[82,4.691]],["t/107",[83,3.35,84,3.35,85,3.35]],["t/109",[86,2.931,87,2.931,88,2.931,89,2.931]],["t/111",[90,3.35,91,3.35,92,3.35]],["t/113",[93,3.35,94,3.35,95,3.35]],["t/115",[96,4.691]],["t/117",[97,2.605,98,2.605,99,2.605,100,2.605,101,2.605]],["t/119",[102,4.691]]],"invertedIndex":[["",{"_index":99,"t":{"117":{"position":[[21,1]]}}}],["1",{"_index":30,"t":{"46":{"position":[[0,2]]},"77":{"position":[[0,2]]}}}],["10",{"_index":77,"t":{"95":{"position":[[0,3]]}}}],["11",{"_index":79,"t":{"97":{"position":[[0,3]]}}}],["2",{"_index":31,"t":{"48":{"position":[[0,2]]},"79":{"position":[[0,2]]}}}],["3",{"_index":39,"t":{"50":{"position":[[0,2]]},"81":{"position":[[0,2]]}}}],["4",{"_index":42,"t":{"52":{"position":[[0,2]]},"83":{"position":[[0,2]]}}}],["5",{"_index":46,"t":{"54":{"position":[[0,2]]},"85":{"position":[[0,2]]}}}],["6",{"_index":52,"t":{"56":{"position":[[0,2]]},"87":{"position":[[0,2]]}}}],["7",{"_index":55,"t":{"58":{"position":[[0,2]]},"89":{"position":[[0,2]]}}}],["8",{"_index":57,"t":{"60":{"position":[[0,2]]},"91":{"position":[[0,2]]}}}],["9",{"_index":60,"t":{"62":{"position":[[0,2]]},"93":{"position":[[0,2]]}}}],["acz",{"_index":101,"t":{"117":{"position":[[26,5]]}}}],["anonymis",{"_index":7,"t":{"16":{"position":[[0,13]]}}}],["appli",{"_index":97,"t":{"117":{"position":[[0,7]]}}}],["assur",{"_index":91,"t":{"111":{"position":[[8,9]]}}}],["censorship",{"_index":12,"t":{"26":{"position":[[4,10]]}}}],["chang",{"_index":59,"t":{"60":{"position":[[29,6]]}}}],["choic",{"_index":53,"t":{"56":{"position":[[8,7]]}}}],["collect",{"_index":33,"t":{"48":{"position":[[16,10]]}}}],["contact",{"_index":61,"t":{"62":{"position":[[3,7]]}}}],["continu",{"_index":27,"t":{"40":{"position":[[4,11]]}}}],["contract",{"_index":94,"t":{"113":{"position":[[6,9]]}}}],["contribut",{"_index":0,"t":{"4":{"position":[[7,10]]},"6":{"position":[[8,10]]}}}],["cryptographi",{"_index":98,"t":{"117":{"position":[[8,12]]}}}],["data",{"_index":36,"t":{"48":{"position":[[54,4]]},"50":{"position":[[38,4]]},"54":{"position":[[13,4]]}}}],["decentralis",{"_index":23,"t":{"36":{"position":[[5,16]]}}}],["disclaim",{"_index":66,"t":{"79":{"position":[[3,11]]}}}],["disput",{"_index":78,"t":{"95":{"position":[[4,8]]}}}],["distribut",{"_index":86,"t":{"109":{"position":[[0,11]]}}}],["dst",{"_index":89,"t":{"109":{"position":[[28,5]]}}}],["econom",{"_index":84,"t":{"107":{"position":[[6,9]]}}}],["european",{"_index":49,"t":{"54":{"position":[[30,8]]}}}],["export",{"_index":47,"t":{"54":{"position":[[3,9]]}}}],["forward",{"_index":67,"t":{"81":{"position":[[3,7]]}}}],["gossipsub",{"_index":5,"t":{"14":{"position":[[7,9]]}}}],["govern",{"_index":75,"t":{"93":{"position":[[3,9]]}}}],["ii",{"_index":11,"t":{"26":{"position":[[0,3]]}}}],["iii",{"_index":14,"t":{"28":{"position":[[0,4]]}}}],["improv",{"_index":6,"t":{"14":{"position":[[17,12]]}}}],["inclus",{"_index":25,"t":{"38":{"position":[[6,11]]}}}],["indemn",{"_index":73,"t":{"89":{"position":[[3,9]]}}}],["inform",{"_index":62,"t":{"62":{"position":[[11,11]]}}}],["intellectu",{"_index":70,"t":{"83":{"position":[[3,12]]}}}],["iv",{"_index":16,"t":{"30":{"position":[[0,3]]}}}],["ix",{"_index":26,"t":{"40":{"position":[[0,3]]}}}],["knowledg",{"_index":2,"t":{"12":{"position":[[5,9]]}}}],["law",{"_index":76,"t":{"93":{"position":[[13,3]]}}}],["liabil",{"_index":72,"t":{"87":{"position":[[17,9]]}}}],["liberti",{"_index":10,"t":{"24":{"position":[[3,7]]}}}],["libp2p",{"_index":4,"t":{"14":{"position":[[0,6]]}}}],["limit",{"_index":32,"t":{"48":{"position":[[6,5]]},"87":{"position":[[3,10]]}}}],["link",{"_index":56,"t":{"58":{"position":[[15,5]]},"85":{"position":[[23,5]]}}}],["look",{"_index":68,"t":{"81":{"position":[[11,7]]}}}],["measur",{"_index":43,"t":{"52":{"position":[[12,8]]}}}],["modif",{"_index":74,"t":{"91":{"position":[[3,13]]}}}],["nescienc",{"_index":81,"t":{"101":{"position":[[0,9]]}}}],["network",{"_index":8,"t":{"16":{"position":[[14,8]]}}}],["nim",{"_index":96,"t":{"115":{"position":[[0,3]]}}}],["open",{"_index":21,"t":{"34":{"position":[[4,8]]}}}],["outsid",{"_index":48,"t":{"54":{"position":[[18,7]]}}}],["p2p",{"_index":82,"t":{"105":{"position":[[0,3]]}}}],["paper",{"_index":63,"t":{"69":{"position":[[0,6]]}}}],["parti",{"_index":41,"t":{"50":{"position":[[9,5]]},"58":{"position":[[9,5]]},"85":{"position":[[9,5]]}}}],["person",{"_index":35,"t":{"48":{"position":[[45,8]]},"50":{"position":[[29,8]]}}}],["polici",{"_index":58,"t":{"60":{"position":[[16,6]]}}}],["principl",{"_index":9,"t":{"22":{"position":[[0,10]]}}}],["privaci",{"_index":17,"t":{"30":{"position":[[4,7]]},"60":{"position":[[8,7]]}}}],["process",{"_index":34,"t":{"48":{"position":[[31,10]]},"50":{"position":[[15,10]]}}}],["proof",{"_index":3,"t":{"12":{"position":[[15,6]]}}}],["properti",{"_index":71,"t":{"83":{"position":[[16,8]]}}}],["qa",{"_index":92,"t":{"111":{"position":[[18,4]]}}}],["qualiti",{"_index":90,"t":{"111":{"position":[[0,7]]}}}],["resist",{"_index":13,"t":{"26":{"position":[[15,10]]}}}],["resourc",{"_index":29,"t":{"42":{"position":[[3,15]]}}}],["respect",{"_index":45,"t":{"52":{"position":[[32,7]]}}}],["rfc",{"_index":102,"t":{"119":{"position":[[0,3]]}}}],["right",{"_index":54,"t":{"56":{"position":[[20,6]]},"83":{"position":[[25,6]]}}}],["sc",{"_index":95,"t":{"113":{"position":[[16,4]]}}}],["secur",{"_index":15,"t":{"28":{"position":[[5,8]]},"52":{"position":[[3,8]]}}}],["smart",{"_index":93,"t":{"113":{"position":[[0,5]]}}}],["statement",{"_index":69,"t":{"81":{"position":[[19,10]]}}}],["switzerland",{"_index":51,"t":{"54":{"position":[[49,11]]}}}],["system",{"_index":87,"t":{"109":{"position":[[12,7]]}}}],["take",{"_index":44,"t":{"52":{"position":[[24,4]]}}}],["term",{"_index":80,"t":{"97":{"position":[[24,5]]}}}],["test",{"_index":88,"t":{"109":{"position":[[20,7]]}}}],["third",{"_index":40,"t":{"50":{"position":[[3,5]]},"58":{"position":[[3,5]]},"85":{"position":[[3,5]]}}}],["tke",{"_index":85,"t":{"107":{"position":[[16,5]]}}}],["token",{"_index":83,"t":{"107":{"position":[[0,5]]}}}],["transpar",{"_index":19,"t":{"32":{"position":[[3,12]]}}}],["union",{"_index":50,"t":{"54":{"position":[[39,5]]}}}],["up",{"_index":65,"t":{"71":{"position":[[6,3]]}}}],["us",{"_index":37,"t":{"48":{"position":[[69,3]]},"97":{"position":[[33,3]]}}}],["v",{"_index":18,"t":{"32":{"position":[[0,2]]}}}],["vi",{"_index":20,"t":{"34":{"position":[[0,3]]}}}],["vii",{"_index":22,"t":{"36":{"position":[[0,4]]}}}],["viii",{"_index":24,"t":{"38":{"position":[[0,5]]}}}],["websit",{"_index":38,"t":{"48":{"position":[[80,7]]},"52":{"position":[[47,7]]},"85":{"position":[[15,7]]},"97":{"position":[[16,7]]}}}],["write",{"_index":64,"t":{"71":{"position":[[0,5]]}}}],["x",{"_index":28,"t":{"42":{"position":[[0,2]]}}}],["zero",{"_index":1,"t":{"12":{"position":[[0,4]]}}}],["zk",{"_index":100,"t":{"117":{"position":[[23,2]]}}}]],"pipeline":["stemmer"]}},{"documents":[{"i":2,"t":"Vac is a principle-driven research and development group that provides technical support to each IFT startup. Vac comprises R&D Service Units, Deep Research, and Incubator Projects. We do applied research based on which we build protocols, libraries, specifications, and publications. As custodians of these protocols, our aim is to adhere to a set of principles that ensure their alignment with our core values and objectives.","s":"About Vac","u":"/","h":"","p":1},{"i":5,"t":"Get in touch with us by joining our Discord, opening a thread in our forum, or opening issues / PRs on GitHub. Also, see our current job openings.","s":"How to Contribute","u":"/contribute","h":"#how-to-contribute","p":3},{"i":7,"t":"We are interested in both research and code contributions. For code contributions, see our \"good first issue\" lists for various Vac-related code bases: nim-libp2p zerokit stealth-address-kit","s":"What to Contribute","u":"/contribute","h":"#what-to-contribute","p":3},{"i":9,"t":"Vac Networking Engineer P2P Remote (Worldwide) Zero Knowledge Research Engineer (ACZ) Remote (Worldwide) Zero Knowledge Researcher (Nescience) Remote (Worldwide)","s":"Current job openings","u":"/join-us","h":"","p":8},{"i":11,"t":"Vac Deep Research is at the forefront of exploration and cutting-edge innovation within the IFT. Their work extends beyond scientific publications, actively bridging the gap between theory and practice. The team collaborates with various entities, such as Vac R&D units, incubator projects, and IFT projects, to bring their research findings to fruition. Part of this effort includes identifying opportunities for and spawning new incubator projects, allowing Vac Deep Research to translate their research findings into practical applications within the IFT. Deep Research encompasses several key areas, including zero knowledge (ZK), decentralised privacy-preserving node provider networks, validator privacy, and libp2p gossipsub improvements.","s":"Vac Deep Research","u":"/deepresearch","h":"","p":10},{"i":13,"t":"In the realm of ZKP, Vac Deep Research has made contributions that have given rise to the incubator project Nescience. The team delved into the intricacies of zero-knowledge proofs, exploring their applications and pushing the boundaries of privacy-preserving technologies. By advancing the field of ZK, Vac Deep Research strengthens the foundation for secure and confidential interactions within decentralised networks.","s":"Zero-Knowledge Proofs","u":"/deepresearch","h":"#zero-knowledge-proofs","p":10},{"i":15,"t":"Another area of focus for Vac Deep Research is \"libp2p gossipsub improvements\". The team explores ways to enhance the performance, efficiency, and reliability of the libp2p gossipsub protocol. By conducting in-depth research and proposing improvements, Vac Deep Research aims to optimise information sharing and communication within decentralised networks, contributing to the overall robustness and scalability of the P2P layers of IFT projects.","s":"Libp2p Gossipsub Improvements","u":"/deepresearch","h":"#libp2p-gossipsub-improvements","p":10},{"i":17,"t":"Vac also researches anonymisation networks, with the main goal of a libp2p gossipsub anonymisation layer with pluggable project-specific components.","s":"Anonymisation Networks","u":"/deepresearch","h":"#anonymisation-networks","p":10},{"i":19,"t":"Waku v2 training session Waku: Enabling a New Dimension for dApps Vac, Waku v2 and Ethereum Messaging ZKPodcast: ZKPs for Spam Protection & Decentralized Messaging with Status Franck Royer : DappConnect: Enabling decentralised communications using Waku Oskar Thoren | Vac, Waku v2 and Ethereum Messaging Dean Eigenman & Oskar Thoren: From Whisper to Waku Private and Reliable Data Sync for Messaging Over Whisper by Dean Eigenmann & Oskar Thoren (Devcon5)","s":"","u":"/media","h":"","p":18},{"i":21,"t":"These principles have been inherited from https://our.status.im/our-principles/. Only minor stylistic changes have been made to them.","s":"","u":"/principles","h":"","p":20},{"i":23,"t":"The goal of Vac is widespread adoption of the decentralised web. Our challenge is achieving mass adoption while staying true to the principles outlined below.","s":"Principles","u":"/principles","h":"","p":20},{"i":25,"t":"We believe in the sovereignty of individuals. As a research organisation that stands for the cause of personal liberty, we aim to maximise social, political, and economic freedoms. This includes being coercion resistant.","s":"I. Liberty","u":"/principles","h":"#i-liberty","p":20},{"i":27,"t":"We enable the free flow of information. No content is under surveillance. We abide by the cryptoeconomic design principle of censorship resistance. Even stronger, we design agnostic infrastructures for information.","s":"II. Censorship resistance","u":"/principles","h":"#ii-censorship-resistance","p":20},{"i":29,"t":"We don't compromise on security when building features. We use state-of-the-art technologies, and research new security methods and technologies to make strong security guarantees.","s":"III. Security","u":"/principles","h":"#iii-security","p":20},{"i":31,"t":"Privacy is the power to selectively reveal oneself to the world. For us, it's essential to protect privacy in both communications and transactions, as well as pseudo-anonymity. Additionally, we strive to provide the right of total anonymity.","s":"IV. Privacy","u":"/principles","h":"#iv-privacy","p":20},{"i":33,"t":"We strive for complete openness and symmetry of information within the organisation, and have no border between our core contributors and our community. We are frank about our shortcomings, especially when making short-term tradeoffs in service of our long-term goals.","s":"V. Transparency","u":"/principles","h":"#v-transparency","p":20},{"i":35,"t":"The software we create is a public good. It is made available via a free and open-source licence, for anyone to share, modify, and benefit from. We believe in permissionless participation.","s":"VI. Openness","u":"/principles","h":"#vi-openness","p":20},{"i":37,"t":"We minimise centralisation across both the software and the organisation itself. In other words, we maximise the number of physical computers composing the network, and maximise the number of individuals who have control over the system(s) we are building.","s":"VII. Decentralisation","u":"/principles","h":"#vii-decentralisation","p":20},{"i":39,"t":"We believe in fair and widespread access to our software, with an emphasis on ease of use. This also extends to social inclusivity, permissionless participation, interoperability, and investing in educational efforts.","s":"VIII. Inclusivity","u":"/principles","h":"#viii-inclusivity","p":20},{"i":41,"t":"We create software incentivised to continue to exist and improve without the stewardship of a single entity or any of the current team members.","s":"IX. Continuance","u":"/principles","h":"#ix-continuance","p":20},{"i":43,"t":"We are relentlessly resourceful. As we grow and have ready access to capital, it is our obligation to token holders to fight bureaucracy and inefficiencies within the organisation. This means solving problems in the most effective way possible at lower economic costs (in terms of capital, time, and resources).","s":"X. Resourcefulness","u":"/principles","h":"#x-resourcefulness","p":20},{"i":45,"t":"On this page Last updated: 9 February 2024 This Privacy Policy is intended to inform users of our approach to privacy in respect of this website (\"Website\"). In this regard, if you are visiting our Website, this Privacy Policy applies to you.","s":"Privacy Policy","u":"/privacy-policy","h":"","p":44},{"i":47,"t":"For the purposes of this Privacy Policy and the collection and processing of personal data as a controller, the relevant entity is the Logos Collective Association, which has its registered office in Zug and its legal domicile address at Logos Collective Association c/o PST Consulting GmbH Baarerstrasse 10 6300 Zug Switzerland Whenever we refer to “Logos”, “we” or other similar references, we are referring to the Logos Collective Association.","s":"1) Who we are","u":"/privacy-policy","h":"#1-who-we-are","p":44},{"i":49,"t":"We aim to limit the collection and collection and processing of personal data from users of the Website. We only collect and process certain personal data for specific purposes and where we have the legal basis to do so under applicable privacy legislation. We will not collect or process any personal data that we don’t need and where we do store any personal data, we will only store it for the least amount of time needed for the indicated purpose. In this regard, we collect and process the following personal data from your use of the Website: IP address: As part of such use of the Website we briefly process your IP address but we have no way of identifying you. We however have a legitimate interest in processing such IP addresses to ensure the technical functionality and enhance the security measures of the Website. This IP address is not stored by us over time.","s":"2) We limit the collection and processing of personal data from your use of the Website","u":"/privacy-policy","h":"#2-we-limit-the-collection-and-processing-of-personal-data-from-your-use-of-the-website","p":44},{"i":51,"t":"In addition to our limited and collection of personal data, third parties may collect or process personal data as a result of the Website making use of certain features or to provide certain content. To the extent you interact with such third party content or features, their respective privacy policies will apply.","s":"3) Third party processing of personal data","u":"/privacy-policy","h":"#3-third-party-processing-of-personal-data","p":44},{"i":53,"t":"As a general approach, we take data security seriously and we have implemented a variety of security measures on the Website to maintain the safety of your personal data when you submit such information to us.","s":"4) Security measures we take in respect of the Website","u":"/privacy-policy","h":"#4-security-measures-we-take-in-respect-of-the-website","p":44},{"i":55,"t":"We are obliged to protect the privacy of personal data that you may have submitted in the unlikely event that we export your personal data to places outside the European Union or Switzerland. This means that personal data will only be processed in countries or by parties that provide an adequate level of protection as deemed by Switzerland or the European Commission. Otherwise, we will use other forms of protections, such as specific forms of contractual clauses to ensure such personal data is provided the same protection as required in Switzerland or Europe. In any event, the transmission of personal data outside the European Union and Switzerland will always occur in conformity with applicable privacy legislation.","s":"5) Exporting data outside the European Union and Switzerland","u":"/privacy-policy","h":"#5-exporting-data-outside-the-european-union-and-switzerland","p":44},{"i":57,"t":"As explained in this Privacy Policy, we limit our collection and processing of your personal data wherever possible. Nonetheless, you still have certain choices and rights in respect of the personal data which we do collect and process. As laid out in relevant privacy legislation, you have the right to: Ask us to correct or update your personal data (where reasonably possible); Ask us to remove your personal data from our systems; Ask us for a copy of your personal data, which may also be transferred to another data controller at your request; Withdraw your consent to process your personal data (only if consent was asked for a processing activity), which only affects processing activities that are based on your consent and doesn’t affect the validity of such processing activities before you have withdrawn your consent; Object to the processing of your personal data; and File a complaint with the Federal Data Protection and Information Commissioner (FDPIC), if you believe that your personal data has been processed unlawfully.","s":"6) Your choices and rights","u":"/privacy-policy","h":"#6-your-choices-and-rights","p":44},{"i":59,"t":"On this Website, you may come across links to third party websites. These third party sites have separate and independent privacy policies. We therefore have no responsibility or liability for the content and activities of these third party websites.","s":"7) Third party links","u":"/privacy-policy","h":"#7-third-party-links","p":44},{"i":61,"t":"We may modify or replace any part of this Privacy Policy at any time and without notice. Please check the Website periodically for any changes. The new Privacy Policy will be effective immediately upon its posting on our Website.","s":"8) This Privacy Policy might change","u":"/privacy-policy","h":"#8-this-privacy-policy-might-change","p":44},{"i":63,"t":"To the extent that you have any questions about the Privacy Policy, please contact us at legal@free.technology. This document is licensed under CC-BY-SA.","s":"9) Contact information","u":"/privacy-policy","h":"#9-contact-information","p":44},{"i":65,"t":"We take security seriously at Vac and across the Institute of Free Technology and its affiliates. Please report any security incidents via security@free.technology. Please report any discovered vulnerabilities in our bounty programme at HackenProof to help ensure our protocols and software remain secure.","s":"Security","u":"/security","h":"","p":64},{"i":67,"t":"Join the Vac Community! Keep up to date with our latest research by connecting with us on our communities channels. Follow us on X Join the community on Discord Share your thoughts on the latest research on the Vac research forum","s":"Join the community","u":"/community","h":"","p":66},{"i":70,"t":"Waku: A Family of Modular P2P Protocols For Secure & Censorship-Resistant Communication (demo) WAKU-RLN-RELAY: Privacy-Preserving Peer-to-Peer Economic Spam Protection (full) Privacy-Preserving Spam-Protected Gossip-Based Routing (poster)","s":"Papers","u":"/publications","h":"#papers","p":68},{"i":72,"t":"See write-ups.","s":"Write-ups","u":"/publications","h":"#write-ups","p":68},{"i":74,"t":"The Vac RFC unit serves as a vital cornerstone in the Logos collective, taking on the responsibility of shepherding and editing specifications for Logos projects and Vac incubator projects. By meticulously crafting and overseeing these specifications, the Vac RFC unit acts as a linchpin for ensuring standardised and interoperable protocols within the Logos ecosystem. Their expertise and attention to detail contribute to a cohesive and collaborative environment, facilitating seamless integration and advancement of decentralised technologies throughout the Logos collective and beyond.","s":"Vac RFC Process","u":"/rfcprocess","h":"","p":73},{"i":76,"t":"On this page Last updated: 14 February 2024 These website terms of use ('Website Terms of Use') are entered into by you and us, and they govern your access and use of this Website, including any content and functionality contained in the Website. It is your responsibility to read the Website Terms of Use carefully before your use of the Website and your use of the Website means you have agreed to be bound and comply with these Website Terms of Use. If you do not agree with these Website Terms of Use, you must not access or use the Website.","s":"Terms of Use","u":"/terms","h":"","p":75},{"i":78,"t":"For the purposes of these Website Terms of Use, the relevant entity is the Logos Collective Association, which has its registered office in Zug and its legal domicile address at: Logos Collective Association c/o PST Consulting GmbH Baarerstrasse 10 6300 Zug Switzerland Whenever we refer to “Logos”, “we”, “us” or any other similar references, we are referring to the Logos Collective Association.","s":"1) Who we are","u":"/terms","h":"#1-who-we-are","p":75},{"i":80,"t":"The Website is provided by us on an ‘as is’ basis and you use the Website at your own sole discretion and risk. We disclaim all warranties of any kind, express or implied, including without limitation the warranties of merchantability, fitness for a particular purpose, and non-infringement of intellectual property or other violation of rights. We do not warrant or make any representations concerning the completeness, accuracy, legality, utility, reliability, suitability or availability of the use of the Website, the content on this Website or otherwise relating to the Website, such content or on any sites linked to this site.These disclaimers will apply to the maximum extent permitted by applicable law. We make no claims that the Website or any of its content is accessible, legally compliant or appropriate in your jurisdiction. Your access or use of the Website is at your own sole discretion and you are solely responsible for complying with any applicable local laws. The content herein or as accessible through this website is intended to be made available for informational purposes only and should not be considered as creating any expectations or forming the basis of any contract, commitment or binding obligation with us. No information herein shall be considered to contain or be relied upon as a promise, representation, warranty or guarantee, whether express or implied and whether as to the past, present or the future in relation to the projects and matters described herein. The information contained herein does not constitute financial, legal, tax, or other advice and should not be treated as such. Nothing in this Website should be construed by you as an offer to buy or sell, or soliciting any offer to buy or sell any tokens or any security.","s":"2) Disclaimers","u":"/terms","h":"#2-disclaimers","p":75},{"i":82,"t":"The Website may also contain forward-looking statements that are based on current expectations, estimates, forecasts, assumptions and projections about the technology, industry and markets in general. The forward looking statements, which may include statements about the roadmap, project descriptions, technical details, functionalities, features, the development and use of tokens by projects, and any other statements related to such matters or as accessible through this website are subject to a high degree of risk and uncertainty. The forward looking statements are subject to change based on, among other things, market conditions, technical developments, and regulatory environment. The actual development and results, including the order and the timeline, might vary from what’s presented. The information contained herein is a summary and does not purport to be accurate, reliable or complete and we bear no responsibility for the accuracy, reliability or completeness of information contained herein. Because of the high degree of risk and uncertainty described above, you should not place undue reliance on any matters described in this website or as accessible through this website. While we aim to update our website regularly, all information, including the timeline and the specifics of each stage, is subject to change and may be amended or supplemented at any time, without notice and at our sole discretion.","s":"3) Forward looking statements","u":"/terms","h":"#3-forward-looking-statements","p":75},{"i":84,"t":"The Website and its contents are made available under Creative Commons Attribution 4.0 International license (CC-BY 4.0). In essence this licence allows users to copy, modify and distribute the content in any format for any purpose, including commercial use, subject to certain requirements such as attributing us. For the full terms of this licence, please refer to the following website: https://creativecommons.org/licenses/by/4.0/.","s":"4) Intellectual property rights","u":"/terms","h":"#4-intellectual-property-rights","p":75},{"i":86,"t":"To the extent the Website provides any links to a third party website, then their terms and conditions, including privacy policies, govern your use of those third party websites. By linking such third party websites, Status does not represent or imply that it endorses or supports such third party websites or content therein, or that it believes such third party websites and content therein to be accurate, useful or non-harmful. We have no control over such third party websites and will not be liable for your use of or activities on any third party websites accessed through the Website. If you access such third party websites through the Website, it is at your own risk and you are solely responsible for your activities on such third party websites.","s":"5) Third-party website links","u":"/terms","h":"#5-third-party-website-links","p":75},{"i":88,"t":"We will not be held liable to you under any contract, negligence, strict liability, or other legal or equitable theory for any lost profits, cost of procurement for substitute services, or any special, incidental, or consequential damages related to, arising from, or in any way connected with these Website Terms of Use, the Website, the content on the Website, or your use of the Website, even if we have been advised of the possibility of such damages. In any event, our aggregate liability for such claims is limited to EUR 100 (one hundred Euros). This limitation of liability will apply to the maximum extent permitted by applicable law.","s":"6) Limitation of liability","u":"/terms","h":"#6-limitation-of-liability","p":75},{"i":90,"t":"You shall indemnify us and hold us harmless from and against any and all claims, damages and expenses, including attorneys’ fees, arising from or related to your use of the Website, the content on the Website, including without limitation your violation of these Website Terms of Use.","s":"7) Indemnity","u":"/terms","h":"#7-indemnity","p":75},{"i":92,"t":"We may modify or replace any part of this Website Terms of Use at any time and without notice. You are responsible for checking the Website periodically for any changes. The new Website Terms of Use will be effective immediately upon its posting on the Website.","s":"8) Modifications","u":"/terms","h":"#8-modifications","p":75},{"i":94,"t":"Swiss law governs these Website Terms of Use and any disputes between you and us, whether in court or arbitration, without regard to conflict of laws provisions.","s":"9) Governing law","u":"/terms","h":"#9-governing-law","p":75},{"i":96,"t":"In these terms, “dispute” has the broadest meaning enforceable by law and includes any claim you make against or controversy you may have in relation to these Website Terms of Use, the Website, the content on the Website, or your use of the Website. We prefer arbitration over litigation as we believe it meets our principle of resolving disputes in the most effective and cost effective manner. You are bound by the following arbitration clause, which waives your right to litigation and to be heard by a judge. Please note that court review of an arbitration award is limited. You also waive all your rights to a jury trial (if any) in any and all jurisdictions. If a (potential) dispute arises, you must first use your reasonable efforts to resolve it amicably with us. If these efforts do not result in a resolution of such dispute, you shall then send us a written notice of dispute setting out (i) the nature of the dispute, and the claim you are making; and (ii) the remedy you are seeking. If we and you are unable to further resolve this dispute within sixty (60) calendar days of us receiving this notice of dispute, then any such dispute will be referred to and finally resolved by you and us through an arbitration administered by the Swiss Chambers’ Arbitration Institution in accordance with the Swiss Rules of International Arbitration for the time being in force, which rules are deemed to be incorporated herein by reference. The arbitral decision may be enforced in any court. The arbitration will be held in Zug, Switzerland, and may be conducted via video conference virtual/online methods if possible. The tribunal will consist of one arbitrator, and all proceedings as well as communications between the parties will be kept confidential. The language of the arbitration will be in English. Payment of all relevant fees in respect of the arbitration, including filing, administration and arbitrator fees will be in accordance with the Swiss Rules of International Arbitration. Regardless of any applicable statute of limitations, you must bring any claims within one year after the claim arose or the time when you should have reasonably known about the claim. You also waive the right to participate in a class action lawsuit or a classwide arbitration against us.","s":"10) Disputes","u":"/terms","h":"#10-disputes","p":75},{"i":98,"t":"These Website Terms of Use cover the entire agreement between you and us regarding the Website and supersede all prior and contemporaneous understandings, agreements, representations and warranties, both written and oral, with respect to the Website. The captions and headings identifying sections and subsections of these Website Terms of Use are for reference only and do not define, modify, expand, limit, or affect the interpretation of any provisions of these Website Terms of Use. If any part of these Website Terms of Use is held invalid or unenforceable, that part will be severable from these Website Terms of Use, and the remaining portions will remain in full force and effect. If we fail to enforce any of these Website Terms of Use, that does not mean that we have waived our right to enforce them. If you have any specific questions about these Website Terms of Use, please contact us at legal@free.technology. This document is licensed under CC-BY-SA.","s":"11) About these Website Terms of Use","u":"/terms","h":"#11-about-these-website-terms-of-use","p":75},{"i":100,"t":"Vac incubator projects are emerging initiatives that stem from Vac's deep research efforts. These projects are envisioned to eventually become separate IFT projects, benefiting from the support and resources of both the Deep Research and R&D Service Units within Vac. The incubator projects operate within Vac, leveraging the expertise and collaboration available to them.","s":"Vac Incubator Projects","u":"/vips","h":"","p":99},{"i":102,"t":"Nescience focuses on developing a privacy-preserving general-purpose zero-knowledge virtual machine. It enables privacy-preserving computing, which holds significant importance for IFT programs, especially Logos.","s":"Nescience","u":"/vips","h":"#nescience","p":99},{"i":104,"t":"Vac's R&D Service Units play a crucial role in supporting IFT projects. In addition to providing expertise, resources, and technical guidance, they also develop software artefacts, such as nim-libp2p and zerokit.","s":"Vac R&D Service Units","u":"/vsus","h":"","p":103},{"i":106,"t":"The P2P R&D Service Unit is a vital part of Vac, specialising in peer-to-peer (P2P) technologies. The P2P unit develops nim-libp2p, works on improving the libp2p gossipsub protocol, and assists projects with the integration of P2P network layers. The P2P unit collaborates closely with Vac Deep Research to conduct research aimed at enhancing libp2p gossipsub. By focusing on advancing P2P technologies, the P2P unit contributes to the overall improvement and efficiency of decentralised networks, enabling seamless decentralised communication within IFT projects and beyond.","s":"P2P","u":"/vsus","h":"#p2p","p":103},{"i":108,"t":"The Vac Token Economics Unit is dedicated to assisting IFT projects in designing their token economies, incentives, and markets. TKE's collaboration with IFT project teams is intensive and occurs on a day-to-day basis, where TKE not only responds to their needs but also proactively drives the conversation forward by suggesting new ideas and strategies based on TKE's research. The team brings together a broad spectrum of skills and knowledge, ranging from the modelling of dynamic systems to theoretical modelling and general cryptoeconomics.","s":"Token Economics (TKE)","u":"/vsus","h":"#token-economics-tke","p":103},{"i":110,"t":"The Distributed Systems Testing (DST) R&D Service Unit is responsible for developing distributed systems testing software. DST's primary objective is to assist IFT projects in understanding the scaling behaviour of their nodes within larger networks. By conducting thorough regression testing, the DST unit helps identify potential bottlenecks and performance issues, ensuring the reliability and stability of the projects. The DST unit's expertise in distributed systems testing enables IFT projects to deliver scalable and resilient solutions that can withstand the demands of real-world decentralised applications.","s":"Distributed Systems Testing (DST)","u":"/vsus","h":"#distributed-systems-testing-dst","p":103},{"i":112,"t":"The QA Service Unit is dedicated to supporting IFT projects through the development and execution of comprehensive test plans. Primary responsibilities include implementing unit tests and interoperability tests to ensure seamless integration and functionality across systems. The QA unit plays a crucial role in the verification of project implementations. By rigorously testing project implementations against defined specifications, QA ensures that all functionalities align with the project's requirements. QA's proactive approach to identifying and reporting bugs ensures that any issues are addressed promptly, enhancing the overall quality and reliability of the software. Through meticulous testing and quality assurance processes, the QA Service Unit ensures that IFT projects deliver robust and high-performing software solutions.","s":"Quality Assurance (QA)","u":"/vsus","h":"#quality-assurance-qa","p":103},{"i":114,"t":"Vac's Smart Contracts Service Unit specialises in the development, maintenance, and auditing of smart contracts for IFT projects. The SC unit ensures that all smart contracts are robust, secure, and aligned with project requirements. SC designs and develops smart contracts tailored to the specific needs of IFT projects, ensuring they function as intended and are up-to-date with any project changes or requirements. The unit's thorough auditing process involves meticulously reviewing smart contracts to identify and rectify potential vulnerabilities, ensuring the highest standards of security and reliability.","s":"Smart Contracts (SC)","u":"/vsus","h":"#smart-contracts-sc","p":103},{"i":116,"t":"With the IFT's extensive use of the Nim ecosystem, the Nim Service Unit focuses on the development and maintenance of Nim tooling and core libraries essential for IFT projects. The Nim unit works on critical tools in the Nim ecosystem, including the Nim compiler, Nimble (package manager), and nim-suggest, ensuring they are efficient, reliable, and up-to-date. The Nim unit further plans to maintain core libraries developed by IFT, such as Chronos. The mandate of the Nim unit also includes providing support to IFT projects regarding the use of Nim, identifying and addressing specific project needs and demands related to the Nim ecosystem.","s":"Nim","u":"/vsus","h":"#nim","p":103},{"i":118,"t":"The Applied Cryptography & ZK R&D Service Unit focuses on cryptographic solutions and zero-knowledge (ZK) proofs. ACZ provides valuable assistance to IFT projects by offering expertise in employing ZK proofs and implementing cryptographic techniques. The ACZ unit specialises in areas such as employing noise protocol channels and other cryptographic-related aspects. By leveraging cutting-edge cryptographic technologies, ACZ enhances the security, privacy, and trustworthiness of Logos projects, contributing to the overall integrity and resilience of the decentralised web ecosystem. ACZ develops zerokit and stealth-address-kit.","s":"Applied Cryptography & ZK (ACZ)","u":"/vsus","h":"#applied-cryptography--zk-acz","p":103},{"i":120,"t":"The Vac RFC unit serves as a vital cornerstone in the IFT, taking on the responsibility of shepherding and editing specifications for IFT projects. By meticulously crafting and overseeing these specifications, the Vac RFC unit acts as a linchpin for ensuring standardised and interoperable protocols within the IFT ecosystem The RFC unit's expertise and attention to detail contribute to a cohesive and collaborative environment, facilitating seamless integration and advancement of decentralised technologies throughout the IFT and beyond.","s":"RFC","u":"/vsus","h":"#rfc","p":103}],"index":{"version":"2.3.9","fields":["t"],"fieldVectors":[["t/2",[0,1.802,1,3.335,2,3.769,3,2.371,4,1.781,5,3.769,6,1.781,7,2.647,8,2.271,9,3.247,10,1.451,11,3.769,12,3.769,13,2.125,14,1.688,15,1.524,16,2.271,17,2.442,18,1.202,19,2.271,20,2.271,21,2.904,22,2.727,23,3.247,24,1.688,25,2.904,26,3.769,27,2.271,28,3.769,29,3.247,30,1.781,31,2.904,32,2.904,33,3.769,34,2.904]],["t/5",[35,5.01,36,4.316,37,4.316,38,5.181,39,5.01,40,4.316,41,3.518,42,3.518,43,5.01,44,5.01,45,3.859,46,3.859,47,5.01]],["t/7",[0,1.586,3,1.833,20,2.731,41,3.183,45,3.492,48,3.905,49,2.936,50,6.423,51,3.279,52,3.905,53,3.905,54,4.533,55,3.905,56,2.401,57,3.183,58,2.731,59,3.492,60,3.905,61,2.555,62,3.905]],["t/9",[0,1.666,3,2.426,63,2.521,64,6,65,3.342,66,6.571,67,6.571,68,3.887,69,3.615,70,4.1,71,3.666]],["t/11",[0,1.717,3,2.356,6,1.294,10,1.888,13,1.544,15,1.107,16,2.955,17,2.653,18,1.565,25,2.11,55,2.359,58,1.65,63,1.451,68,1.774,69,1.65,72,2.739,73,2.11,74,2.359,75,2.359,76,2.739,77,1.834,78,2.11,79,2.359,80,1.923,81,2.739,82,1.923,83,2.739,84,2.739,85,1.774,86,2.359,87,4.095,88,1.774,89,1.65,90,1.923,91,1.005,92,2.11,93,4.095,94,2.739,95,1.65,96,1.923,97,1.834,98,1.544,99,2.739,100,2.739,101,1.65,102,2.359,103,2.739,104,1.451,105,2.739,106,2.359,107,2.739,108,2.11,109,2.11,110,1.294,111,1.433,112,1.923,113,2.359,114,2.359,115,1.923,116,1.923]],["t/13",[0,1.814,3,2.096,16,3.123,17,2.466,18,1.214,51,2.146,63,2.017,68,2.466,69,2.294,71,2.933,73,2.933,77,1.705,88,2.466,104,2.017,109,2.933,110,1.799,111,1.332,112,2.673,117,3.807,118,3.28,119,2.466,120,3.807,121,3.807,122,3.807,123,3.807,124,3.28,125,3.807,126,3.807,127,2.017,128,2.673,129,3.807,130,3.807,131,3.807,132,1.902,133,3.28,134,3.28]],["t/15",[0,1.766,3,2.335,10,1.409,16,3.04,18,1.168,22,1.939,27,2.206,51,2.064,58,3.04,63,1.939,65,2.57,73,2.82,77,1.639,88,2.371,108,2.82,110,1.73,115,3.543,116,3.543,135,3.154,136,3.661,137,2.57,138,2.371,139,2.82,140,2.82,141,1.939,142,2.57,143,3.661,144,3.661,145,3.661,146,1.939,147,2.82,148,1.939,149,2.57,150,2.82,151,3.154,152,2.82]],["t/17",[0,1.777,3,2.053,18,1.619,24,2.274,58,3.059,63,2.69,115,3.565,152,3.911,153,6.246,154,5.077,155,3.911,156,5.077,157,5.077]],["t/19",[0,1.596,42,4.345,101,1.911,110,1.499,118,2.733,141,1.681,148,1.681,158,5.55,159,5.341,160,3.172,161,3.172,162,2.955,163,3.172,164,3.172,165,4.562,166,5.84,167,3.172,168,2.733,169,2.055,170,3.172,171,2.733,172,3.172,173,3.172,174,3.172,175,0.967,176,5.341,177,5.341,178,4.562,179,3.172,180,4.562,181,3.172,182,1.788,183,3.172,184,2.055,185,3.172,186,3.172]],["t/21",[1,4.256,119,3.575,187,5.519,188,5.519,189,5.519,190,5.519,191,3.575]],["t/23",[0,1.753,1,3.245,110,2.367,155,3.859,192,4.316,193,6.195,194,4.316,195,5.01,196,5.01,197,5.01,198,5.01,199,5.01,200,5.01,201,5.01]],["t/25",[3,1.925,27,2.867,97,2.131,202,2.867,203,4.759,204,4.1,205,3.342,206,4.759,207,4.759,208,2.683,209,4.759,210,4.1,211,4.1,212,4.759,213,3.342,214,4.759,215,4.1,216,4.759,217,3.666]],["t/27",[1,3.083,146,3.179,162,3.083,217,3.666,218,3.666,219,4.759,220,2.249,221,2.867,222,4.759,223,4.759,224,4.1,225,4.622,226,4.1,227,4.1,228,4.759,229,4.759,230,4.759]],["t/29",[3,1.949,21,3.713,101,2.904,127,3.204,132,3.302,175,1.468,231,4.82,232,4.82,233,3.713,234,4.82,235,4.82,236,4.152,237,3.122,238,4.82,239,4.152]],["t/31",[6,2.167,49,2.972,111,2.051,148,2.43,169,2.972,240,4.587,241,4.587,242,4.587,243,4.587,244,3.952,245,4.587,246,3.952,247,4.587,248,3.952,249,4.587,250,5.861,251,4.587,252,3.952,253,2.972,254,4.587]],["t/33",[14,2.03,32,3.492,38,3.492,77,2.03,85,2.936,146,2.401,148,2.401,155,3.492,205,3.183,237,2.936,252,3.905,255,3.492,256,4.533,257,4.533,258,4.533,259,4.533,260,4.533,261,3.905,262,4.533,263,2.473,264,4.533,265,4.533]],["t/35",[25,3.713,38,3.713,52,4.152,119,3.122,147,3.713,202,2.904,218,3.713,266,2.553,267,3.713,268,3.384,269,3.713,270,4.82,271,4.152,272,4.82,273,3.122,274,4.152,275,4.152,276,3.713]],["t/37",[21,3.621,49,3.045,63,2.49,184,3.045,204,4.05,205,3.301,210,5.129,266,2.49,277,4.701,278,4.701,279,4.701,280,4.701,281,5.953,282,4.701,283,4.05,284,4.701,285,3.301,286,4.701]],["t/39",[79,4.205,96,3.428,175,1.487,192,4.205,202,2.941,211,4.205,266,2.586,275,4.205,276,3.76,287,4.881,288,2.941,289,4.881,290,4.881,291,4.881,292,3.428,293,4.881,294,4.881]],["t/41",[46,3.964,88,3.333,90,3.613,116,3.613,266,2.726,267,3.964,295,5.145,296,5.145,297,5.145,298,2.901,299,5.145,300,5.145,301,5.145]],["t/43",[77,1.938,137,3.038,205,3.038,213,3.038,263,1.84,288,2.607,302,4.326,303,4.348,304,4.326,305,4.326,306,5.644,307,3.333,308,3.038,309,4.326,310,4.326,311,4.326,312,4.326,313,2.803,314,4.326,315,4.326,316,2.803,317,3.038,318,4.326,319,3.333,320,2.607]],["t/45",[19,2.764,111,2.261,146,2.43,321,3.952,322,3.952,323,3.221,324,4.587,325,3.952,326,3.952,327,3.105,328,3.534,329,3.534,330,3.534,331,2.972,332,2.06,333,2.972,334,4.587]],["t/47",[61,2.125,90,2.647,111,1.319,182,2.125,208,2.125,285,2.647,327,1.997,335,2.271,336,3.796,337,2.125,338,2.647,339,4.081,340,5.051,341,3.247,342,3.247,343,3.965,344,2.442,345,3.247,346,3.247,347,3.247,348,3.247,349,3.247,350,3.247,351,3.247,352,3.247,353,2.647,354,3.247,355,3.798,356,3.247]],["t/49",[7,1.965,24,1.253,27,1.686,30,1.323,48,2.411,61,3.102,91,1.527,95,1.686,98,1.578,104,1.483,111,0.98,132,1.398,137,1.965,138,1.813,175,1.268,182,3.315,184,1.813,208,3.315,221,1.686,320,2.508,329,2.156,332,1.755,333,1.813,335,2.508,336,3.543,337,3.475,344,1.813,357,1.483,358,1.965,359,2.156,360,2.156,361,2.799,362,2.923,363,4.969,364,2.799,365,2.799,366,1.965,367,5.503,368,2.799,369,2.799,370,1.813,371,2.411]],["t/51",[6,1.955,19,2.493,91,1.518,111,1.448,134,3.565,175,1.261,182,3.09,208,3.09,220,2.59,233,4.222,237,2.681,327,2.192,331,2.681,332,1.32,336,3.303,337,2.333,357,2.192,358,3.849,372,3.565,373,4.222,374,3.551,375,3.188,376,2.681]],["t/53",[91,1.768,132,3.022,146,2.553,182,3.409,208,2.717,330,3.713,332,1.537,371,4.152,377,3.384,378,3.384,379,4.152,380,3.713,381,4.82,382,4.152,383,4.82,384,4.152]],["t/55",[6,2.105,24,1.375,30,1.451,91,1.635,104,1.626,111,1.559,169,3.726,175,0.935,182,3.443,208,3.443,307,2.365,313,1.989,337,1.731,353,4.039,360,2.365,374,1.989,384,2.645,385,3.07,386,3.838,387,3.07,388,2.645,389,4.455,390,5.243,391,4.455,392,3.07,393,3.07,394,3.07,395,2.645,396,3.07,397,2.645,398,3.838,399,3.07,400,2.645,401,3.07,402,2.156,403,3.07,404,3.07,405,3.07,406,2.645,407,3.07]],["t/57",[20,1.55,34,1.981,82,3.316,91,0.944,111,1.367,114,2.216,135,2.216,146,1.363,169,1.666,182,3.764,202,1.55,208,3.604,253,2.53,285,1.806,317,2.743,323,1.806,327,1.363,331,1.666,336,2.353,337,3.604,338,1.806,357,1.363,358,1.806,360,1.981,408,2.572,409,2.572,410,2.572,411,2.572,412,2.572,413,2.572,414,2.216,415,5.274,416,2.572,417,2.216,418,2.572,419,1.806,420,2.216,421,2.572,422,2.572,423,2.572,424,5.274,425,3.365,426,2.572,427,2.216,428,2.572,429,2.216,430,2.572,431,2.572,432,2.572,433,2.572,434,2.572]],["t/59",[82,3.26,111,1.625,220,2.194,327,2.46,332,2.072,373,5.004,374,4.208,435,4.643,436,3.577,437,4,438,4,439,4.643,440,4.643,441,2.194,442,4]],["t/61",[95,2.798,101,2.798,111,2.067,191,3.008,273,3.008,298,2.617,316,3.008,320,2.798,327,3.129,332,1.884,443,4,444,3.26,445,2.798,446,4,447,4,448,4,449,3.577,450,4]],["t/63",[111,1.825,221,3.143,327,2.763,376,3.379,445,3.143,451,4.494,452,4.494,453,4.494,454,4.494,455,4.018,456,4.018,457,4.494]],["t/65",[0,1.514,22,2.292,30,2.044,127,2.292,132,3.139,218,3.333,266,2.292,269,3.333,378,3.038,379,3.727,445,3.401,458,3.727,459,4.326,460,4.862,461,4.326,462,4.326,463,4.326,464,3.727,465,4.326,466,4.326,467,4.326,468,3.727,469,3.727]],["t/67",[0,2.036,3,2.597,36,5.011,37,3.905,40,3.905,147,3.492,148,3.403,366,3.183,470,4.533,471,3.183,472,3.492,473,5.817,474,3.905,475,3.905,476,4.533,477,4.533]],["t/70",[20,2.521,22,2.216,42,2.938,65,2.938,111,1.932,112,3.877,132,2.09,148,2.216,158,4.757,168,4.757,169,3.577,213,2.938,217,3.223,226,3.604,478,4.184,479,4.184,480,4.184,481,4.184,482,4.184,483,4.757,484,3.223,485,4.184,486,4.184,487,4.184]],["t/72",[45,4.583,471,4.178,488,5.95]],["t/74",[0,1.942,15,1.937,17,2.202,18,1.528,22,1.801,24,2.146,30,1.606,51,1.916,77,1.522,80,2.387,89,2.048,110,1.606,127,1.801,128,2.387,292,2.387,336,2.887,339,3.903,378,2.387,441,1.606,489,4.128,490,2.928,491,2.618,492,2.928,493,2.928,494,2.928,495,2.387,496,2.928,497,2.928,498,2.928,499,2.928,500,2.928,501,2.387,502,2.048,503,2.928,504,2.618,505,2.928,506,2.618,507,2.928,508,2.387,509,2.202,510,2.928]],["t/76",[97,1.579,175,2.16,220,1.666,263,2.738,288,2.961,313,2.283,321,3.037,322,3.037,323,2.475,325,3.037,326,3.037,332,2.29,370,2.283,427,3.037,441,1.666,511,3.525,512,3.525,513,2.715,514,2.715,515,3.525,516,3.525,517,4.915,518,3.037,519,3.037]],["t/78",[61,2.212,90,2.756,175,1.196,263,1.669,332,1.252,335,2.365,336,3.606,338,2.756,339,4.149,340,5.157,341,3.381,342,3.381,343,4.076,344,2.542,345,3.381,346,3.381,347,3.381,348,3.381,349,3.381,350,3.381,351,3.381,352,3.381,353,2.756,354,3.381,355,3.877,356,3.381]],["t/80",[6,0.89,18,0.601,19,1.135,56,1.62,91,1.122,97,0.844,104,1.62,119,1.221,132,0.941,141,0.998,146,2.045,175,1.176,220,2.099,237,1.981,239,1.623,253,1.221,255,1.452,267,1.452,268,2.148,288,2.326,298,1.062,307,1.452,308,1.323,328,1.452,332,1.893,335,1.843,344,2.501,357,0.998,359,2.356,376,1.221,397,1.623,398,1.623,436,1.452,437,1.623,441,0.89,449,1.452,514,2.356,519,1.623,520,2.974,521,2.635,522,1.452,523,3.059,524,3.326,525,1.884,526,3.059,527,2.635,528,1.884,529,1.884,530,1.884,531,1.623,532,1.884,533,1.884,534,1.884,535,1.623,536,1.884,537,2.635,538,1.884,539,1.623,540,1.884,541,1.884,542,1.884,543,1.623,544,1.623,545,2.148,546,1.323,547,1.884,548,1.884,549,1.623,550,1.884,551,3.422,552,1.221,553,3.059,554,1.623,555,1.452,556,1.884,557,1.884,558,1.452,559,1.884,560,1.884,561,2.635,562,1.884,563,1.623,564,1.884,565,1.623,566,1.623,567,1.884,568,1.884,569,1.884,570,1.884,571,1.884,572,1.884,573,1.884,574,2.635,575,3.059,576,3.059,577,1.884]],["t/82",[4,1.992,7,2.387,9,1.853,18,1.345,20,2.049,24,0.963,27,1.296,46,1.657,56,1.139,91,0.789,97,1.888,127,1.139,141,1.801,146,2.234,175,0.655,191,2.203,233,1.657,255,2.619,288,2.049,298,1.212,308,1.51,320,1.296,323,1.51,332,1.665,370,1.393,375,1.657,377,1.51,388,1.853,441,1.016,444,1.51,504,1.657,506,1.657,514,3.248,520,1.657,521,1.853,522,2.619,539,1.853,551,2.619,552,2.203,554,1.853,563,1.853,565,2.929,566,2.929,578,3.633,579,4.217,580,5.22,581,2.151,582,2.151,583,2.151,584,2.151,585,2.929,586,2.151,587,2.151,588,3.633,589,2.929,590,3.4,591,3.4,592,2.151,593,1.853,594,2.151,595,2.151,596,2.151,597,3.4,598,2.151,599,2.151,600,2.151,601,2.151,602,1.853,603,2.151,604,2.151,605,2.151,606,2.151,607,2.151,608,2.151,609,2.151,610,2.151]],["t/84",[91,1.397,97,1.705,102,3.28,119,2.466,175,1.16,220,2.449,221,2.294,263,1.619,268,2.673,271,4.465,273,2.466,329,2.933,332,1.653,335,2.294,355,2.466,358,2.673,366,2.673,402,2.673,420,3.28,445,2.294,455,2.933,456,2.933,484,2.933,588,3.28,611,3.807,612,3.807,613,5.183,614,5.183,615,3.28,616,3.807,617,3.28,618,3.807,619,3.807,620,3.807]],["t/86",[6,1.323,8,1.686,82,2.923,91,2.262,97,1.253,111,0.98,171,2.411,175,1.514,184,1.813,202,1.686,220,1.967,263,1.19,285,1.965,288,2.508,327,1.483,332,2.235,373,5.162,374,4.341,376,1.813,436,3.206,441,1.323,513,2.156,520,2.156,522,2.156,527,2.411,531,2.411,552,2.696,593,2.411,602,2.411,621,2.799,622,2.799,623,2.799,624,4.162,625,2.799,626,2.411]],["t/88",[14,1.457,19,1.96,56,1.724,86,2.803,91,1.704,104,1.724,137,2.285,175,1.415,220,1.537,221,1.96,227,2.803,263,1.384,317,2.285,319,2.506,332,1.884,344,2.108,357,2.461,376,2.108,386,2.803,442,4.667,474,2.803,543,2.803,544,2.803,545,2.285,546,2.285,555,2.506,626,2.803,627,2.506,628,3.254,629,3.254,630,3.254,631,3.254,632,3.254,633,3.254,634,3.254,635,3.254,636,3.254,637,3.254,638,4.002,639,2.506,640,3.254,641,3.254,642,3.254,643,3.254,644,2.803,645,3.254,646,3.254]],["t/90",[56,2.373,97,2.585,175,1.759,220,2.116,263,1.905,298,2.525,332,2.037,357,2.373,535,3.859,546,3.145,558,3.45,638,3.859,639,3.45,647,4.479,648,3.859,649,4.479,650,3.45,651,4.479,652,4.479,653,3.859]],["t/92",[95,2.731,101,2.731,175,1.772,191,2.936,263,2.473,273,2.936,298,2.555,316,2.936,320,2.731,332,2.161,441,2.142,443,3.905,444,3.183,446,3.905,447,3.905,448,3.905,449,3.492,450,3.905]],["t/94",[85,3.203,175,1.507,263,2.103,298,2.787,332,1.577,333,3.203,513,3.809,545,4.315,561,4.26,654,4.26,655,4.26,656,4.26,657,4.26,658,4.945,659,4.26]],["t/96",[1,0.994,29,1.322,53,1.322,56,0.813,77,1.156,85,0.994,91,0.947,92,1.182,96,1.813,97,1.156,104,0.813,133,1.322,142,1.078,148,0.813,175,1.018,184,0.994,202,0.925,215,1.322,220,0.725,236,1.322,237,1.672,248,1.322,253,2.164,263,1.098,269,1.182,276,1.182,313,0.994,316,1.672,317,1.078,319,1.182,320,1.555,331,0.994,332,1.249,338,1.078,343,1.182,353,1.078,355,1.672,357,1.368,366,1.078,374,0.994,375,1.182,395,1.322,400,1.322,414,1.322,417,2.224,429,1.322,444,1.813,445,0.925,458,1.322,518,1.322,545,1.078,546,3.068,549,1.322,551,1.182,552,0.994,558,1.182,615,2.224,627,1.182,639,1.182,644,2.224,650,1.988,653,2.224,654,2.878,655,4.736,656,2.224,657,5.352,660,1.535,661,2.224,662,1.535,663,1.535,664,2.581,665,1.535,666,3.917,667,1.535,668,2.878,669,1.535,670,1.535,671,1.535,672,1.322,673,1.535,674,1.535,675,1.535,676,1.182,677,1.535,678,1.535,679,1.535,680,1.322,681,1.535,682,1.535,683,1.535,684,1.535,685,1.535,686,1.322,687,1.535,688,1.535,689,1.535,690,1.322,691,1.535,692,1.535,693,1.535,694,1.535,695,2.581,696,3.341,697,1.322,698,1.535,699,1.535,700,1.535,701,1.535,702,1.535,703,1.535,704,1.535,705,1.535,706,1.535,707,1.535,708,1.535,709,1.535,710,1.535,711,1.535,712,1.535,713,1.535,714,1.535,715,1.535,716,1.535,717,1.535,718,1.535,719,1.535]],["t/98",[24,1.209,49,1.749,85,1.749,95,2.441,98,1.522,106,2.326,175,1.922,221,1.627,253,1.749,263,2.682,273,1.749,313,1.749,316,1.749,331,1.749,332,2.117,333,1.749,355,1.749,357,1.43,425,2.326,445,1.627,451,2.326,452,2.326,453,2.326,454,2.326,455,2.08,456,2.08,457,2.326,469,3.491,484,2.08,524,2.326,537,2.326,627,2.08,659,2.326,661,3.491,668,2.326,680,2.326,697,2.326,720,2.7,721,2.7,722,4.052,723,2.7,724,2.7,725,2.7,726,2.326,727,2.7,728,2.7,729,2.7,730,2.7,731,2.7,732,2.326,733,2.7,734,2.7,735,2.7,736,2.7,737,2.7,738,2.7]],["t/100",[0,2.084,3,2.125,8,2.341,10,1.496,13,2.19,14,1.74,15,1.571,16,3.166,17,3.404,18,2.035,49,2.517,77,2.353,89,2.341,96,2.728,268,2.728,274,3.347,303,2.993,438,3.347,502,2.341,739,3.885,740,3.885,741,3.885,742,2.993,743,3.885,744,3.885,745,3.885,746,3.885,747,3.347]],["t/102",[4,2.167,10,1.766,68,2.972,69,2.764,71,3.534,111,2.051,112,4.116,162,2.972,261,3.952,283,3.952,335,2.764,339,2.972,377,3.221,648,3.952,748,3.221,749,4.587,750,4.587,751,4.587,752,4.587,753,4.587]],["t/104",[4,2.142,6,2.142,7,3.183,8,2.731,10,1.745,13,2.555,14,2.03,15,1.833,18,1.446,57,3.183,58,2.731,59,3.492,91,1.663,266,2.401,303,3.492,372,3.905,502,2.731,742,3.492,754,3.905,755,3.905,756,3.905,757,4.533,758,4.533]],["t/106",[0,1.577,3,1.823,4,1.474,10,1.201,13,1.759,14,1.397,15,2.344,16,1.88,18,1.438,22,1.653,27,1.88,51,1.759,57,2.191,58,3.188,63,2.388,65,4.638,77,1.397,78,2.404,80,2.191,89,1.88,95,1.88,110,2.13,115,3.165,116,3.165,127,2.388,128,2.191,138,2.021,140,2.404,142,2.191,148,1.653,149,2.191,152,2.404,162,2.021,483,3.883,491,2.404,508,2.191,509,2.021,748,2.191,759,2.404,760,2.191,761,3.12]],["t/108",[0,1.179,3,1.362,10,1.833,15,1.362,18,1.519,20,2.03,69,2.03,88,3.084,89,2.03,92,2.595,101,2.03,213,2.366,224,2.902,225,2.595,308,3.343,359,2.595,362,2.366,377,2.366,406,2.902,419,2.366,578,2.902,585,2.902,690,4.102,760,2.366,762,2.902,763,3.369,764,3.369,765,4.761,766,3.369,767,3.369,768,3.369,769,2.902,770,3.369,771,3.369,772,2.902,773,3.369,774,3.369,775,3.369,776,3.369,777,3.369,778,3.369,779,3.369,780,4.761,781,3.369,782,3.369]],["t/110",[4,1.474,10,1.735,13,1.759,14,1.397,15,1.823,18,1.688,30,1.474,34,2.404,41,2.191,63,1.653,77,1.397,98,1.759,104,1.653,110,1.474,113,2.688,139,2.404,141,1.653,142,2.191,151,2.688,162,2.021,244,2.688,266,1.653,419,3.716,441,1.474,468,2.688,502,1.88,617,4.559,676,2.404,726,2.688,760,2.191,783,4.993,784,5.292,785,3.12,786,2.688,787,3.12,788,3.12,789,3.12,790,2.688,791,3.12,792,3.12,793,3.12,794,2.404,795,2.688,796,2.688,797,2.404,798,3.12,799,2.688,800,3.12]],["t/112",[4,1.276,8,1.627,10,1.56,14,1.814,15,2.186,18,1.724,24,1.209,30,2.554,31,2.08,41,1.896,61,1.522,97,1.209,98,1.522,138,1.749,139,2.08,141,1.43,149,1.896,150,2.08,266,2.146,292,1.896,330,2.08,337,1.522,370,2.625,380,3.746,402,1.896,419,1.896,441,1.276,460,2.326,495,1.896,508,1.896,509,1.749,552,2.625,589,2.326,650,2.08,732,2.326,754,2.326,755,2.326,756,2.326,762,2.326,769,2.326,783,4.99,786,2.326,795,2.326,797,2.08,801,5.405,802,2.7,803,2.7,804,2.326,805,2.7,806,2.7,807,2.7,808,2.7,809,2.7,810,2.7,811,4.052,812,2.7]],["t/114",[4,2.155,10,1.756,14,1.421,15,1.845,18,1.863,24,1.421,30,2.524,31,2.444,98,1.788,132,2.279,141,1.681,150,2.444,191,2.055,225,2.444,328,2.444,337,1.788,362,2.228,370,2.055,402,3.203,464,2.733,471,2.228,472,2.444,495,2.228,555,4.766,672,2.733,676,2.444,742,2.444,759,2.444,790,2.733,794,2.444,813,6.187,814,2.733,815,4.562,816,4.562,817,3.172,818,3.172,819,3.172,820,3.172,821,3.172]],["t/116",[4,2.033,6,1.384,8,1.764,10,1.964,14,1.311,15,2.274,18,1.627,23,3.708,24,1.311,30,1.384,32,3.315,56,1.551,57,4.908,61,1.651,78,2.256,91,1.074,97,1.927,98,1.651,140,2.256,141,1.551,175,1.311,246,2.523,333,1.897,362,2.056,382,2.523,471,2.056,472,2.256,501,3.583,686,2.523,748,2.056,772,2.523,799,2.523,804,2.523,814,2.523,822,2.928,823,2.928,824,4.304,825,2.928,826,2.928,827,2.928,828,2.928,829,2.928,830,2.928,831,2.928]],["t/118",[4,1.428,6,1.428,10,1.163,13,1.703,14,1.353,15,1.781,18,1.404,19,1.82,22,1.601,42,2.121,51,1.703,56,1.601,59,2.327,60,2.603,61,1.703,62,2.603,68,1.957,69,1.82,70,4.918,74,2.603,75,2.603,91,1.109,108,2.327,109,4.002,110,1.428,111,1.057,124,3.794,127,1.601,132,1.509,138,1.957,149,2.121,194,2.603,339,1.957,380,2.327,475,2.603,501,2.121,502,1.82,509,1.957,574,2.603,747,2.603,748,2.121,759,2.327,760,2.121,796,2.603,797,2.327,832,3.021,833,5.709,834,3.021,835,4.403,836,3.021,837,3.021,838,3.021,839,3.021]],["t/120",[0,1.709,10,2.348,15,1.975,18,1.114,22,1.85,24,2.187,30,1.65,51,1.969,77,1.564,80,2.452,89,2.104,110,1.65,127,1.85,128,2.452,292,2.452,378,2.452,441,1.65,489,4.851,490,3.009,491,2.69,492,3.009,493,3.009,494,3.009,495,2.452,496,3.009,497,3.009,498,3.009,499,3.009,500,3.009,501,2.452,502,2.104,503,3.009,504,2.69,505,3.009,506,2.69,507,3.009,508,2.452,509,2.262,510,3.009,794,2.69]]],"invertedIndex":[["",{"_index":42,"t":{"5":{"position":[[94,1]]},"19":{"position":[[138,1],[189,1],[266,1],[318,1],[431,1]]},"70":{"position":[[51,1]]},"118":{"position":[[25,1]]}}}],["10",{"_index":351,"t":{"47":{"position":[[305,2]]},"78":{"position":[[246,2]]}}}],["100",{"_index":643,"t":{"88":{"position":[[528,3]]}}}],["14",{"_index":511,"t":{"76":{"position":[[27,2]]}}}],["2024",{"_index":326,"t":{"45":{"position":[[38,4]]},"76":{"position":[[39,4]]}}}],["4.0",{"_index":614,"t":{"84":{"position":[[83,3],[116,5]]}}}],["60",{"_index":688,"t":{"96":{"position":[[1068,4]]}}}],["6300",{"_index":352,"t":{"47":{"position":[[308,4]]},"78":{"position":[[249,4]]}}}],["9",{"_index":324,"t":{"45":{"position":[[27,1]]}}}],["abid",{"_index":223,"t":{"27":{"position":[[77,5]]}}}],["abov",{"_index":604,"t":{"82":{"position":[[1073,6]]}}}],["access",{"_index":288,"t":{"39":{"position":[[34,6]]},"43":{"position":[[59,6]]},"76":{"position":[[149,6],[519,6]]},"80":{"position":[[773,11],[845,6],[1007,10]]},"82":{"position":[[451,10],[1163,10]]},"86":{"position":[[563,8],[600,6]]}}}],["accord",{"_index":695,"t":{"96":{"position":[[1290,10],[1937,10]]}}}],["accur",{"_index":602,"t":{"82":{"position":[[872,9]]},"86":{"position":[[399,9]]}}}],["accuraci",{"_index":539,"t":{"80":{"position":[[421,9]]},"82":{"position":[[941,9]]}}}],["achiev",{"_index":196,"t":{"23":{"position":[[82,9]]}}}],["act",{"_index":498,"t":{"74":{"position":[[269,4]]},"120":{"position":[[227,4]]}}}],["action",{"_index":717,"t":{"96":{"position":[[2234,6]]}}}],["activ",{"_index":82,"t":{"11":{"position":[[148,8]]},"57":{"position":[[646,10],[687,10],[780,10]]},"59":{"position":[[209,10]]},"86":{"position":[[524,10],[717,10]]}}}],["actual",{"_index":595,"t":{"82":{"position":[[695,6]]}}}],["acz",{"_index":70,"t":{"9":{"position":[[80,5]]},"118":{"position":[[114,3],[255,3],[423,3],[587,3]]}}}],["addit",{"_index":372,"t":{"51":{"position":[[3,8]]},"104":{"position":[[75,8]]}}}],["addition",{"_index":251,"t":{"31":{"position":[[177,13]]}}}],["address",{"_index":61,"t":{"7":{"position":[[179,7]]},"47":{"position":[[227,7]]},"49":{"position":[[552,8],[623,7],[730,9],[836,7]]},"78":{"position":[[167,7]]},"112":{"position":[[596,9]]},"116":{"position":[[569,10]]},"118":{"position":[[620,7]]}}}],["adequ",{"_index":393,"t":{"55":{"position":[[288,8]]}}}],["adher",{"_index":28,"t":{"2":{"position":[[333,6]]}}}],["administ",{"_index":693,"t":{"96":{"position":[[1227,12]]}}}],["administr",{"_index":710,"t":{"96":{"position":[[1891,14]]}}}],["adopt",{"_index":193,"t":{"23":{"position":[[30,8],[97,8]]}}}],["advanc",{"_index":128,"t":{"13":{"position":[[277,9]]},"74":{"position":[[504,11]]},"106":{"position":[[376,9]]},"120":{"position":[[468,11]]}}}],["advic",{"_index":570,"t":{"80":{"position":[[1586,6]]}}}],["advis",{"_index":640,"t":{"88":{"position":[[412,7]]}}}],["affect",{"_index":425,"t":{"57":{"position":[[668,7],[741,6]]},"98":{"position":[[412,6]]}}}],["affili",{"_index":459,"t":{"65":{"position":[[86,11]]}}}],["against",{"_index":650,"t":{"90":{"position":[[53,7]]},"96":{"position":[[102,7],[2276,7]]},"112":{"position":[[403,7]]}}}],["aggreg",{"_index":641,"t":{"88":{"position":[[474,9]]}}}],["agnost",{"_index":229,"t":{"27":{"position":[[173,8]]}}}],["agre",{"_index":517,"t":{"76":{"position":[[390,6],[467,5]]}}}],["agreement",{"_index":722,"t":{"98":{"position":[[44,9],[155,11]]}}}],["aim",{"_index":27,"t":{"2":{"position":[[323,3]]},"15":{"position":[[271,4]]},"25":{"position":[[123,3]]},"49":{"position":[[3,3]]},"82":{"position":[[1205,3]]},"106":{"position":[[324,5]]}}}],["align",{"_index":31,"t":{"2":{"position":[[381,9]]},"112":{"position":[[471,5]]},"114":{"position":[[199,7]]}}}],["allow",{"_index":102,"t":{"11":{"position":[[451,8]]},"84":{"position":[[146,6]]}}}],["alway",{"_index":405,"t":{"55":{"position":[[662,6]]}}}],["amend",{"_index":609,"t":{"82":{"position":[[1347,7]]}}}],["amic",{"_index":677,"t":{"96":{"position":[[755,8]]}}}],["amount",{"_index":364,"t":{"49":{"position":[[403,6]]}}}],["anonym",{"_index":250,"t":{"31":{"position":[[166,10],[231,10]]}}}],["anonymis",{"_index":153,"t":{"17":{"position":[[20,13],[85,13]]}}}],["anoth",{"_index":135,"t":{"15":{"position":[[0,7]]},"57":{"position":[[509,7]]}}}],["anyon",{"_index":272,"t":{"35":{"position":[[102,6]]}}}],["appli",{"_index":19,"t":{"2":{"position":[[188,7]]},"45":{"position":[[227,7]]},"51":{"position":[[309,6]]},"80":{"position":[[656,5]]},"88":{"position":[[587,5]]},"118":{"position":[[4,7]]}}}],["applic",{"_index":104,"t":{"11":{"position":[[530,12]]},"13":{"position":[[198,12]]},"49":{"position":[[226,10]]},"55":{"position":[[694,10]]},"80":{"position":[[697,10],[959,10]]},"88":{"position":[[628,10]]},"96":{"position":[[2017,10]]},"110":{"position":[[604,13]]}}}],["approach",{"_index":330,"t":{"45":{"position":[[98,8]]},"53":{"position":[[13,9]]},"112":{"position":[[525,8]]}}}],["appropri",{"_index":548,"t":{"80":{"position":[[806,11]]}}}],["arbitr",{"_index":657,"t":{"94":{"position":[[102,12]]},"96":{"position":[[260,11],[427,11],[549,11],[1215,11],[1263,11],[1339,11],[1447,8],[1499,11],[1656,11],[1781,11],[1860,12],[1910,10],[1986,12],[2264,11]]}}}],["area",{"_index":108,"t":{"11":{"position":[[597,6]]},"15":{"position":[[8,4]]},"118":{"position":[[279,5]]}}}],["aris",{"_index":639,"t":{"88":{"position":[[251,7]]},"90":{"position":[[130,7]]},"96":{"position":[[690,7]]}}}],["aros",{"_index":714,"t":{"96":{"position":[[2110,5]]}}}],["art",{"_index":235,"t":{"29":{"position":[[76,3]]}}}],["artefact",{"_index":758,"t":{"104":{"position":[[170,10]]}}}],["ask",{"_index":415,"t":{"57":{"position":[[305,3],[381,3],[435,3],[623,5]]}}}],["aspect",{"_index":838,"t":{"118":{"position":[[359,8]]}}}],["assist",{"_index":760,"t":{"106":{"position":[[186,7]]},"108":{"position":[[45,9]]},"110":{"position":[[153,6]]},"118":{"position":[[136,10]]}}}],["associ",{"_index":340,"t":{"47":{"position":[[152,12],[255,11],[434,12]]},"78":{"position":[[92,12],[196,11],[385,12]]}}}],["assumpt",{"_index":583,"t":{"82":{"position":[[118,11]]}}}],["assur",{"_index":812,"t":{"112":{"position":[[718,9]]}}}],["attent",{"_index":503,"t":{"74":{"position":[[390,9]]},"120":{"position":[[354,9]]}}}],["attorney",{"_index":652,"t":{"90":{"position":[[113,10]]}}}],["attribut",{"_index":613,"t":{"84":{"position":[[71,11],[299,11]]}}}],["audit",{"_index":815,"t":{"114":{"position":[[84,8],[438,8]]}}}],["avail",{"_index":268,"t":{"35":{"position":[[52,9]]},"80":{"position":[[478,12],[1062,9]]},"84":{"position":[[38,9]]},"100":{"position":[[354,9]]}}}],["award",{"_index":673,"t":{"96":{"position":[[561,5]]}}}],["baarerstrass",{"_index":350,"t":{"47":{"position":[[291,13]]},"78":{"position":[[232,13]]}}}],["base",{"_index":20,"t":{"2":{"position":[[205,5]]},"7":{"position":[[145,6]]},"57":{"position":[[707,5]]},"70":{"position":[[216,5]]},"82":{"position":[[65,5],[590,5]]},"108":{"position":[[354,5]]}}}],["basi",{"_index":359,"t":{"49":{"position":[[205,5]]},"80":{"position":[[44,5],[1177,5]]},"108":{"position":[[212,6]]}}}],["be",{"_index":215,"t":{"25":{"position":[[195,5]]},"96":{"position":[[1364,5]]}}}],["bear",{"_index":603,"t":{"82":{"position":[[910,4]]}}}],["becom",{"_index":745,"t":{"100":{"position":[[136,6]]}}}],["befor",{"_index":427,"t":{"57":{"position":[[791,6]]},"76":{"position":[[316,6]]}}}],["behaviour",{"_index":788,"t":{"110":{"position":[[202,9]]}}}],["believ",{"_index":202,"t":{"25":{"position":[[3,7]]},"35":{"position":[[148,7]]},"39":{"position":[[3,7]]},"57":{"position":[[978,7]]},"86":{"position":[[338,8]]},"96":{"position":[[294,7]]}}}],["below",{"_index":201,"t":{"23":{"position":[[152,6]]}}}],["benefit",{"_index":274,"t":{"35":{"position":[[131,7]]},"100":{"position":[[166,10]]}}}],["between",{"_index":85,"t":{"11":{"position":[[174,7]]},"33":{"position":[[104,7]]},"94":{"position":[[62,7]]},"96":{"position":[[1714,7]]},"98":{"position":[[54,7]]}}}],["beyond",{"_index":80,"t":{"11":{"position":[[116,6]]},"74":{"position":[[582,7]]},"106":{"position":[[568,7]]},"120":{"position":[[533,7]]}}}],["bind",{"_index":557,"t":{"80":{"position":[[1214,7]]}}}],["border",{"_index":257,"t":{"33":{"position":[[97,6]]}}}],["both",{"_index":49,"t":{"7":{"position":[[21,4]]},"31":{"position":[[110,4]]},"37":{"position":[[34,4]]},"98":{"position":[[199,4]]},"100":{"position":[[211,4]]}}}],["bottleneck",{"_index":792,"t":{"110":{"position":[[332,11]]}}}],["bound",{"_index":518,"t":{"76":{"position":[[403,5]]},"96":{"position":[[404,5]]}}}],["boundari",{"_index":126,"t":{"13":{"position":[[227,10]]}}}],["bounti",{"_index":465,"t":{"65":{"position":[[217,6]]}}}],["bridg",{"_index":83,"t":{"11":{"position":[[157,8]]}}}],["briefli",{"_index":368,"t":{"49":{"position":[[599,7]]}}}],["bring",{"_index":92,"t":{"11":{"position":[[312,5]]},"96":{"position":[[2061,5]]},"108":{"position":[[388,6]]}}}],["broad",{"_index":776,"t":{"108":{"position":[[406,5]]}}}],["broadest",{"_index":660,"t":{"96":{"position":[[34,8]]}}}],["bug",{"_index":809,"t":{"112":{"position":[[563,4]]}}}],["build",{"_index":21,"t":{"2":{"position":[[223,5]]},"29":{"position":[[37,8]]},"37":{"position":[[247,9]]}}}],["bureaucraci",{"_index":311,"t":{"43":{"position":[[125,11]]}}}],["buy",{"_index":575,"t":{"80":{"position":[[1694,3],[1734,3]]}}}],["c/o",{"_index":346,"t":{"47":{"position":[[267,3]]},"78":{"position":[[208,3]]}}}],["calendar",{"_index":689,"t":{"96":{"position":[[1073,8]]}}}],["capit",{"_index":306,"t":{"43":{"position":[[69,8],[281,8]]}}}],["caption",{"_index":728,"t":{"98":{"position":[[255,8]]}}}],["carefulli",{"_index":516,"t":{"76":{"position":[[306,9]]}}}],["caus",{"_index":207,"t":{"25":{"position":[[93,5]]}}}],["cc",{"_index":456,"t":{"63":{"position":[[144,2]]},"84":{"position":[[109,3]]},"98":{"position":[[957,2]]}}}],["censorship",{"_index":226,"t":{"27":{"position":[[125,10]]},"70":{"position":[[53,10]]}}}],["centralis",{"_index":278,"t":{"37":{"position":[[12,14]]}}}],["certain",{"_index":358,"t":{"49":{"position":[[133,7]]},"51":{"position":[[152,7],[183,7]]},"57":{"position":[[145,7]]},"84":{"position":[[270,7]]}}}],["challeng",{"_index":195,"t":{"23":{"position":[[69,9]]}}}],["chamber",{"_index":694,"t":{"96":{"position":[[1253,9]]}}}],["chang",{"_index":191,"t":{"21":{"position":[[102,7]]},"61":{"position":[[135,8]]},"82":{"position":[[583,6],[1329,6]]},"92":{"position":[[161,8]]},"114":{"position":[[393,7]]}}}],["channel",{"_index":475,"t":{"67":{"position":[[106,9]]},"118":{"position":[[318,8]]}}}],["check",{"_index":446,"t":{"61":{"position":[[96,5]]},"92":{"position":[[119,8]]}}}],["choic",{"_index":412,"t":{"57":{"position":[[153,7]]}}}],["chrono",{"_index":830,"t":{"116":{"position":[[442,8]]}}}],["claim",{"_index":546,"t":{"80":{"position":[[724,6]]},"88":{"position":[[503,6]]},"90":{"position":[[73,7]]},"96":{"position":[[87,5],[939,5],[2071,6],[2104,5],[2176,6]]}}}],["class",{"_index":716,"t":{"96":{"position":[[2228,5]]}}}],["classwid",{"_index":719,"t":{"96":{"position":[[2254,9]]}}}],["claus",{"_index":400,"t":{"55":{"position":[[459,7]]},"96":{"position":[[439,7]]}}}],["close",{"_index":761,"t":{"106":{"position":[[273,7]]}}}],["code",{"_index":50,"t":{"7":{"position":[[39,4],[63,4],[140,4]]}}}],["coercion",{"_index":216,"t":{"25":{"position":[[201,8]]}}}],["cohes",{"_index":505,"t":{"74":{"position":[[426,8]]},"120":{"position":[[390,8]]}}}],["collabor",{"_index":89,"t":{"11":{"position":[[212,12]]},"74":{"position":[[439,13]]},"100":{"position":[[340,13]]},"106":{"position":[[260,12]]},"108":{"position":[[135,13]]},"120":{"position":[[403,13]]}}}],["collect",{"_index":336,"t":{"47":{"position":[[48,10],[141,10],[244,10],[423,10]]},"49":{"position":[[20,10],[35,10],[113,7],[270,7],[471,7]]},"51":{"position":[[31,10],[78,7]]},"57":{"position":[[50,10],[216,7]]},"74":{"position":[[60,11],[567,10]]},"78":{"position":[[81,10],[185,10],[374,10]]}}}],["come",{"_index":435,"t":{"59":{"position":[[25,4]]}}}],["commerci",{"_index":619,"t":{"84":{"position":[[243,10]]}}}],["commiss",{"_index":396,"t":{"55":{"position":[[358,11]]}}}],["commission",{"_index":432,"t":{"57":{"position":[[949,12]]}}}],["commit",{"_index":556,"t":{"80":{"position":[[1200,10]]}}}],["common",{"_index":612,"t":{"84":{"position":[[63,7]]}}}],["commun",{"_index":148,"t":{"15":{"position":[[312,13]]},"19":{"position":[[227,14]]},"31":{"position":[[115,14]]},"33":{"position":[[142,10]]},"67":{"position":[[13,10],[94,11],[140,9]]},"70":{"position":[[74,13]]},"96":{"position":[[1699,14]]},"106":{"position":[[530,13]]}}}],["compil",{"_index":826,"t":{"116":{"position":[[254,9]]}}}],["complaint",{"_index":430,"t":{"57":{"position":[[890,9]]}}}],["complet",{"_index":255,"t":{"33":{"position":[[14,8]]},"80":{"position":[[407,13]]},"82":{"position":[[894,8],[966,12]]}}}],["compli",{"_index":519,"t":{"76":{"position":[[413,6]]},"80":{"position":[[940,9]]}}}],["compliant",{"_index":547,"t":{"80":{"position":[[793,9]]}}}],["compon",{"_index":157,"t":{"17":{"position":[[137,11]]}}}],["compos",{"_index":284,"t":{"37":{"position":[[142,9]]}}}],["comprehens",{"_index":803,"t":{"112":{"position":[[101,13]]}}}],["compris",{"_index":12,"t":{"2":{"position":[[114,9]]}}}],["compromis",{"_index":232,"t":{"29":{"position":[[9,10]]}}}],["comput",{"_index":283,"t":{"37":{"position":[[132,9]]},"102":{"position":[[131,10]]}}}],["concern",{"_index":538,"t":{"80":{"position":[[392,10]]}}}],["condit",{"_index":593,"t":{"82":{"position":[[627,11]]},"86":{"position":[[92,11]]}}}],["conduct",{"_index":142,"t":{"15":{"position":[[196,10]]},"96":{"position":[[1556,9]]},"106":{"position":[[307,7]]},"110":{"position":[[254,10]]}}}],["confer",{"_index":701,"t":{"96":{"position":[[1576,10]]}}}],["confidenti",{"_index":133,"t":{"13":{"position":[[364,12]]},"96":{"position":[[1747,13]]}}}],["conflict",{"_index":658,"t":{"94":{"position":[[133,8]]}}}],["conform",{"_index":407,"t":{"55":{"position":[[678,10]]}}}],["connect",{"_index":474,"t":{"67":{"position":[[68,10]]},"88":{"position":[[279,9]]}}}],["consent",{"_index":424,"t":{"57":{"position":[[564,7],[611,7],[721,7],[822,8]]}}}],["consequenti",{"_index":637,"t":{"88":{"position":[[217,13]]}}}],["consid",{"_index":553,"t":{"80":{"position":[[1122,10],[1273,10]]}}}],["consist",{"_index":704,"t":{"96":{"position":[[1641,7]]}}}],["constitut",{"_index":567,"t":{"80":{"position":[[1543,10]]}}}],["constru",{"_index":573,"t":{"80":{"position":[[1662,9]]}}}],["consult",{"_index":348,"t":{"47":{"position":[[275,10]]},"78":{"position":[[216,10]]}}}],["contact",{"_index":452,"t":{"63":{"position":[[75,7]]},"98":{"position":[[888,7]]}}}],["contain",{"_index":514,"t":{"76":{"position":[[221,9]]},"80":{"position":[[1287,7],[1517,9]]},"82":{"position":[[21,7],[815,9],[994,9]]}}}],["contemporan",{"_index":725,"t":{"98":{"position":[[123,15]]}}}],["content",{"_index":220,"t":{"27":{"position":[[43,7]]},"51":{"position":[[191,8],[249,7]]},"59":{"position":[[197,7]]},"76":{"position":[[195,7]]},"80":{"position":[[522,7],[589,7],[762,7],[986,7]]},"84":{"position":[[20,8],[194,7]]},"86":{"position":[[310,7],[377,7]]},"88":{"position":[[339,7]]},"90":{"position":[[186,7]]},"96":{"position":[[198,7]]}}}],["continu",{"_index":296,"t":{"41":{"position":[[35,8]]}}}],["contract",{"_index":555,"t":{"80":{"position":[[1190,9]]},"88":{"position":[[44,9]]},"114":{"position":[[12,9],[102,9],[165,9],[264,9],[493,9]]}}}],["contractu",{"_index":399,"t":{"55":{"position":[[447,11]]}}}],["contribut",{"_index":51,"t":{"7":{"position":[[44,14],[68,14]]},"13":{"position":[[48,13]]},"15":{"position":[[357,12]]},"74":{"position":[[410,10]]},"106":{"position":[[417,11]]},"118":{"position":[[498,12]]},"120":{"position":[[374,10]]}}}],["contributor",{"_index":258,"t":{"33":{"position":[[121,12]]}}}],["control",{"_index":285,"t":{"37":{"position":[[213,7]]},"47":{"position":[[96,11]]},"57":{"position":[[522,10]]},"86":{"position":[[443,7]]}}}],["controversi",{"_index":662,"t":{"96":{"position":[[113,11]]}}}],["convers",{"_index":771,"t":{"108":{"position":[[294,12]]}}}],["copi",{"_index":420,"t":{"57":{"position":[[448,4]]},"84":{"position":[[162,5]]}}}],["core",{"_index":32,"t":{"2":{"position":[[400,4]]},"33":{"position":[[116,4]]},"116":{"position":[[134,4],[401,4]]}}}],["cornerston",{"_index":492,"t":{"74":{"position":[[35,11]]},"120":{"position":[[35,11]]}}}],["correct",{"_index":416,"t":{"57":{"position":[[315,7]]}}}],["cost",{"_index":319,"t":{"43":{"position":[[262,5]]},"88":{"position":[[141,4]]},"96":{"position":[[373,4]]}}}],["countri",{"_index":392,"t":{"55":{"position":[[248,9]]}}}],["court",{"_index":656,"t":{"94":{"position":[[93,5]]},"96":{"position":[[530,5],[1488,6]]}}}],["cover",{"_index":720,"t":{"98":{"position":[[27,5]]}}}],["craft",{"_index":496,"t":{"74":{"position":[[206,8]]},"120":{"position":[[164,8]]}}}],["creat",{"_index":267,"t":{"35":{"position":[[16,6]]},"41":{"position":[[3,6]]},"80":{"position":[[1136,8]]}}}],["creativ",{"_index":611,"t":{"84":{"position":[[54,8]]}}}],["critic",{"_index":825,"t":{"116":{"position":[[199,8]]}}}],["crucial",{"_index":755,"t":{"104":{"position":[[31,7]]},"112":{"position":[[296,7]]}}}],["cryptoeconom",{"_index":224,"t":{"27":{"position":[[90,14]]},"108":{"position":[[529,16]]}}}],["cryptograph",{"_index":833,"t":{"118":{"position":[[58,13],[225,13],[337,13],[395,13]]}}}],["cryptographi",{"_index":832,"t":{"118":{"position":[[12,12]]}}}],["current",{"_index":46,"t":{"5":{"position":[[125,7]]},"41":{"position":[[122,7]]},"82":{"position":[[74,7]]}}}],["custodian",{"_index":26,"t":{"2":{"position":[[288,10]]}}}],["cut",{"_index":74,"t":{"11":{"position":[[57,7]]},"118":{"position":[[382,7]]}}}],["damag",{"_index":638,"t":{"88":{"position":[[231,7],[447,8]]},"90":{"position":[[81,7]]}}}],["dapp",{"_index":164,"t":{"19":{"position":[[60,5]]}}}],["dappconnect",{"_index":174,"t":{"19":{"position":[[191,12]]}}}],["data",{"_index":182,"t":{"19":{"position":[[376,4]]},"47":{"position":[[86,4]]},"49":{"position":[[73,4],[150,4],[302,4],[361,5],[514,4]]},"51":{"position":[[54,5],[106,4]]},"53":{"position":[[31,4],[165,4]]},"55":{"position":[[50,4],[134,4],[217,4],[491,4],[609,4]]},"57":{"position":[[93,4],[199,4],[347,4],[412,4],[470,5],[517,4],[597,4],[873,5],[917,4],[1005,4]]}}}],["date",{"_index":472,"t":{"67":{"position":[[35,4]]},"114":{"position":[[371,4]]},"116":{"position":[[356,5]]}}}],["day",{"_index":690,"t":{"96":{"position":[[1082,4]]},"108":{"position":[[201,3],[208,3]]}}}],["dean",{"_index":178,"t":{"19":{"position":[[304,4],[416,4]]}}}],["decentr",{"_index":170,"t":{"19":{"position":[[140,13]]}}}],["decentralis",{"_index":110,"t":{"11":{"position":[[635,13]]},"13":{"position":[[397,13]]},"15":{"position":[[333,13]]},"19":{"position":[[213,13]]},"23":{"position":[[46,13]]},"74":{"position":[[519,13]]},"106":{"position":[[474,13],[516,13]]},"110":{"position":[[590,13]]},"118":{"position":[[558,13]]},"120":{"position":[[483,13]]}}}],["decis",{"_index":699,"t":{"96":{"position":[[1456,8]]}}}],["dedic",{"_index":762,"t":{"108":{"position":[[32,9]]},"112":{"position":[[23,9]]}}}],["deem",{"_index":395,"t":{"55":{"position":[[320,6]]},"96":{"position":[[1396,6]]}}}],["deep",{"_index":16,"t":{"2":{"position":[[143,4]]},"11":{"position":[[4,4],[464,4],[559,4]]},"13":{"position":[[25,4],[308,4]]},"15":{"position":[[30,4],[257,4]]},"100":{"position":[[69,4],[220,4]]},"106":{"position":[[290,4]]}}}],["defin",{"_index":732,"t":{"98":{"position":[[378,7]]},"112":{"position":[[411,7]]}}}],["degre",{"_index":590,"t":{"82":{"position":[[505,6],[1032,6]]}}}],["deliv",{"_index":795,"t":{"110":{"position":[[504,7]]},"112":{"position":[[785,7]]}}}],["delv",{"_index":122,"t":{"13":{"position":[[128,6]]}}}],["demand",{"_index":799,"t":{"110":{"position":[[568,7]]},"116":{"position":[[607,7]]}}}],["demo",{"_index":480,"t":{"70":{"position":[[88,6]]}}}],["depth",{"_index":143,"t":{"15":{"position":[[210,5]]}}}],["describ",{"_index":566,"t":{"80":{"position":[[1483,9]]},"82":{"position":[[1063,9],[1131,9]]}}}],["descript",{"_index":587,"t":{"82":{"position":[[289,13]]}}}],["design",{"_index":225,"t":{"27":{"position":[[105,6],[166,6]]},"108":{"position":[[71,9]]},"114":{"position":[[237,7]]}}}],["detail",{"_index":504,"t":{"74":{"position":[[403,6]]},"82":{"position":[[313,8]]},"120":{"position":[[367,6]]}}}],["devcon5",{"_index":186,"t":{"19":{"position":[[446,9]]}}}],["develop",{"_index":4,"t":{"2":{"position":[[39,11]]},"82":{"position":[[353,11],[649,13],[702,11]]},"102":{"position":[[21,10]]},"104":{"position":[[153,7]]},"106":{"position":[[111,8]]},"110":{"position":[[74,10]]},"112":{"position":[[72,11]]},"114":{"position":[[54,12],[249,8]]},"116":{"position":[[87,11],[416,9]]},"118":{"position":[[591,8]]}}}],["dimens",{"_index":163,"t":{"19":{"position":[[46,9]]}}}],["disclaim",{"_index":523,"t":{"80":{"position":[[115,8],[639,11]]}}}],["discord",{"_index":37,"t":{"5":{"position":[[36,8]]},"67":{"position":[[153,7]]}}}],["discov",{"_index":463,"t":{"65":{"position":[[183,10]]}}}],["discret",{"_index":521,"t":{"80":{"position":[[91,10],[894,10]]},"82":{"position":[[1415,11]]}}}],["disput",{"_index":655,"t":{"94":{"position":[[53,8]]},"96":{"position":[[16,9],[338,8],[682,7],[828,8],[880,7],[922,8],[1047,7],[1118,8],[1141,7]]}}}],["distribut",{"_index":617,"t":{"84":{"position":[[179,10]]},"110":{"position":[[4,11],[85,11],[452,11]]}}}],["document",{"_index":454,"t":{"63":{"position":[[117,8]]},"98":{"position":[[930,8]]}}}],["doesn’t",{"_index":426,"t":{"57":{"position":[[733,7]]}}}],["domicil",{"_index":345,"t":{"47":{"position":[[218,8]]},"78":{"position":[[158,8]]}}}],["don't",{"_index":231,"t":{"29":{"position":[[3,5]]}}}],["don’t",{"_index":361,"t":{"49":{"position":[[315,5]]}}}],["drive",{"_index":770,"t":{"108":{"position":[[283,6]]}}}],["driven",{"_index":2,"t":{"2":{"position":[[19,6]]}}}],["dst",{"_index":784,"t":{"110":{"position":[[32,5],[298,3],[428,3]]}}}],["dst'",{"_index":785,"t":{"110":{"position":[[123,5]]}}}],["dynam",{"_index":781,"t":{"108":{"position":[[476,7]]}}}],["each",{"_index":9,"t":{"2":{"position":[[92,4]]},"82":{"position":[[1303,4]]}}}],["eas",{"_index":290,"t":{"39":{"position":[[78,4]]}}}],["econom",{"_index":213,"t":{"25":{"position":[[162,8]]},"43":{"position":[[253,8]]},"70":{"position":[[143,8]]},"108":{"position":[[14,9]]}}}],["economi",{"_index":763,"t":{"108":{"position":[[93,10]]}}}],["ecosystem",{"_index":501,"t":{"74":{"position":[[359,10]]},"116":{"position":[[40,10],[225,10],[634,10]]},"118":{"position":[[576,10]]},"120":{"position":[[315,9]]}}}],["edg",{"_index":75,"t":{"11":{"position":[[65,4]]},"118":{"position":[[390,4]]}}}],["edit",{"_index":494,"t":{"74":{"position":[[120,7]]},"120":{"position":[[107,7]]}}}],["educ",{"_index":294,"t":{"39":{"position":[[197,11]]}}}],["effect",{"_index":316,"t":{"43":{"position":[[221,9]]},"61":{"position":[[175,9]]},"92":{"position":[[207,9]]},"96":{"position":[[359,9],[378,9]]},"98":{"position":[[681,7]]}}}],["effici",{"_index":140,"t":{"15":{"position":[[131,11]]},"106":{"position":[[460,10]]},"116":{"position":[[325,10]]}}}],["effort",{"_index":96,"t":{"11":{"position":[[368,6]]},"39":{"position":[[209,8]]},"96":{"position":[[733,7],[782,7]]},"100":{"position":[[83,8]]}}}],["eigenman",{"_index":179,"t":{"19":{"position":[[309,8]]}}}],["eigenmann",{"_index":185,"t":{"19":{"position":[[421,9]]}}}],["emerg",{"_index":739,"t":{"100":{"position":[[27,8]]}}}],["emphasi",{"_index":289,"t":{"39":{"position":[[66,8]]}}}],["employ",{"_index":835,"t":{"118":{"position":[[188,9],[293,9]]}}}],["enabl",{"_index":162,"t":{"19":{"position":[[31,8],[204,8]]},"27":{"position":[[3,6]]},"102":{"position":[[104,7]]},"106":{"position":[[498,8]]},"110":{"position":[[480,7]]}}}],["encompass",{"_index":105,"t":{"11":{"position":[[573,11]]}}}],["endors",{"_index":623,"t":{"86":{"position":[[260,8]]}}}],["enforc",{"_index":661,"t":{"96":{"position":[[51,11],[1472,8]]},"98":{"position":[[703,7],[798,7]]}}}],["engin",{"_index":64,"t":{"9":{"position":[[15,8],[71,8]]}}}],["english",{"_index":708,"t":{"96":{"position":[[1804,8]]}}}],["enhanc",{"_index":138,"t":{"15":{"position":[[106,7]]},"49":{"position":[[782,7]]},"106":{"position":[[333,9]]},"112":{"position":[[616,9]]},"118":{"position":[[427,8]]}}}],["ensur",{"_index":30,"t":{"2":{"position":[[368,6]]},"49":{"position":[[743,6]]},"55":{"position":[[470,6]]},"65":{"position":[[257,6]]},"74":{"position":[[292,8]]},"110":{"position":[[368,8]]},"112":{"position":[[214,6],[438,7],[568,7],[759,7]]},"114":{"position":[[142,7],[322,8],[554,8]]},"116":{"position":[[307,8]]},"120":{"position":[[250,8]]}}}],["enter",{"_index":512,"t":{"76":{"position":[[100,7]]}}}],["entir",{"_index":721,"t":{"98":{"position":[[37,6]]}}}],["entiti",{"_index":90,"t":{"11":{"position":[[238,9]]},"41":{"position":[[101,6]]},"47":{"position":[[121,6]]},"78":{"position":[[61,6]]}}}],["environ",{"_index":506,"t":{"74":{"position":[[453,12]]},"82":{"position":[[678,12]]},"120":{"position":[[417,12]]}}}],["envis",{"_index":743,"t":{"100":{"position":[[111,10]]}}}],["equit",{"_index":630,"t":{"88":{"position":[[102,9]]}}}],["especi",{"_index":261,"t":{"33":{"position":[[190,10]]},"102":{"position":[[195,10]]}}}],["essenc",{"_index":616,"t":{"84":{"position":[[125,7]]}}}],["essenti",{"_index":246,"t":{"31":{"position":[[78,9]]},"116":{"position":[[149,9]]}}}],["estim",{"_index":581,"t":{"82":{"position":[[96,10]]}}}],["ethereum",{"_index":165,"t":{"19":{"position":[[83,8],[285,8]]}}}],["eur",{"_index":642,"t":{"88":{"position":[[524,3]]}}}],["euro",{"_index":646,"t":{"88":{"position":[[545,7]]}}}],["europ",{"_index":403,"t":{"55":{"position":[[558,7]]}}}],["european",{"_index":390,"t":{"55":{"position":[[161,8],[349,8],[626,8]]}}}],["even",{"_index":227,"t":{"27":{"position":[[148,4]]},"88":{"position":[[391,4]]}}}],["event",{"_index":386,"t":{"55":{"position":[[99,5],[573,6]]},"88":{"position":[[463,6]]}}}],["eventu",{"_index":744,"t":{"100":{"position":[[125,10]]}}}],["execut",{"_index":802,"t":{"112":{"position":[[88,9]]}}}],["exist",{"_index":297,"t":{"41":{"position":[[47,5]]}}}],["expand",{"_index":733,"t":{"98":{"position":[[394,7]]}}}],["expect",{"_index":554,"t":{"80":{"position":[[1149,12]]},"82":{"position":[[82,13]]}}}],["expens",{"_index":651,"t":{"90":{"position":[[93,9]]}}}],["expertis",{"_index":502,"t":{"74":{"position":[[376,9]]},"100":{"position":[[326,9]]},"104":{"position":[[97,10]]},"110":{"position":[[439,9]]},"118":{"position":[[175,9]]},"120":{"position":[[340,9]]}}}],["explain",{"_index":408,"t":{"57":{"position":[[3,9]]}}}],["explor",{"_index":73,"t":{"11":{"position":[[41,11]]},"13":{"position":[[182,9]]},"15":{"position":[[89,8]]}}}],["export",{"_index":387,"t":{"55":{"position":[[113,6]]}}}],["express",{"_index":526,"t":{"80":{"position":[[152,7],[1374,7]]}}}],["extend",{"_index":79,"t":{"11":{"position":[[108,7]]},"39":{"position":[[101,7]]}}}],["extens",{"_index":823,"t":{"116":{"position":[[15,9]]}}}],["extent",{"_index":376,"t":{"51":{"position":[[207,6]]},"63":{"position":[[7,6]]},"80":{"position":[[677,6]]},"86":{"position":[[7,6]]},"88":{"position":[[608,6]]}}}],["facilit",{"_index":507,"t":{"74":{"position":[[466,12]]},"120":{"position":[[430,12]]}}}],["fail",{"_index":738,"t":{"98":{"position":[[695,4]]}}}],["fair",{"_index":287,"t":{"39":{"position":[[14,4]]}}}],["famili",{"_index":478,"t":{"70":{"position":[[8,6]]}}}],["fdpic",{"_index":433,"t":{"57":{"position":[[962,8]]}}}],["featur",{"_index":233,"t":{"29":{"position":[[46,9]]},"51":{"position":[[160,8],[260,9]]},"82":{"position":[[339,9]]}}}],["februari",{"_index":325,"t":{"45":{"position":[[29,8]]},"76":{"position":[[30,8]]}}}],["feder",{"_index":431,"t":{"57":{"position":[[909,7]]}}}],["fee",{"_index":653,"t":{"90":{"position":[[124,5]]},"96":{"position":[[1837,4],[1921,4]]}}}],["field",{"_index":129,"t":{"13":{"position":[[291,5]]}}}],["fight",{"_index":310,"t":{"43":{"position":[[119,5]]}}}],["file",{"_index":429,"t":{"57":{"position":[[883,4]]},"96":{"position":[[1883,7]]}}}],["final",{"_index":692,"t":{"96":{"position":[[1173,7]]}}}],["financi",{"_index":568,"t":{"80":{"position":[[1554,10]]}}}],["find",{"_index":93,"t":{"11":{"position":[[333,8],[506,8]]}}}],["first",{"_index":53,"t":{"7":{"position":[[97,5]]},"96":{"position":[[707,5]]}}}],["fit",{"_index":529,"t":{"80":{"position":[[236,7]]}}}],["flow",{"_index":219,"t":{"27":{"position":[[19,4]]}}}],["focu",{"_index":136,"t":{"15":{"position":[[16,5]]}}}],["focus",{"_index":748,"t":{"102":{"position":[[10,7]]},"106":{"position":[[364,8]]},"116":{"position":[[72,7]]},"118":{"position":[[47,7]]}}}],["follow",{"_index":366,"t":{"49":{"position":[[495,9]]},"67":{"position":[[116,6]]},"84":{"position":[[371,9]]},"96":{"position":[[417,9]]}}}],["forc",{"_index":697,"t":{"96":{"position":[[1373,6]]},"98":{"position":[[671,5]]}}}],["forecast",{"_index":582,"t":{"82":{"position":[[107,10]]}}}],["forefront",{"_index":72,"t":{"11":{"position":[[28,9]]}}}],["form",{"_index":398,"t":{"55":{"position":[[399,5],[438,5]]},"80":{"position":[[1165,7]]}}}],["format",{"_index":618,"t":{"84":{"position":[[209,6]]}}}],["forum",{"_index":40,"t":{"5":{"position":[[69,6]]},"67":{"position":[[224,5]]}}}],["forward",{"_index":578,"t":{"82":{"position":[[29,7],[205,7],[541,7]]},"108":{"position":[[307,7]]}}}],["foundat",{"_index":131,"t":{"13":{"position":[[338,10]]}}}],["franck",{"_index":172,"t":{"19":{"position":[[176,6]]}}}],["frank",{"_index":259,"t":{"33":{"position":[[160,5]]}}}],["free",{"_index":218,"t":{"27":{"position":[[14,4]]},"35":{"position":[[68,4]]},"65":{"position":[[62,4]]}}}],["freedom",{"_index":214,"t":{"25":{"position":[[171,9]]}}}],["fruition",{"_index":94,"t":{"11":{"position":[[345,9]]}}}],["full",{"_index":484,"t":{"70":{"position":[[168,6]]},"84":{"position":[[323,4]]},"98":{"position":[[666,4]]}}}],["function",{"_index":370,"t":{"49":{"position":[[764,13]]},"76":{"position":[[207,13]]},"82":{"position":[[322,16]]},"112":{"position":[[246,13],[455,15]]},"114":{"position":[[336,8]]}}}],["further",{"_index":686,"t":{"96":{"position":[[1026,7]]},"116":{"position":[[375,7]]}}}],["futur",{"_index":564,"t":{"80":{"position":[[1436,6]]}}}],["gap",{"_index":84,"t":{"11":{"position":[[170,3]]}}}],["gener",{"_index":377,"t":{"53":{"position":[[5,7]]},"82":{"position":[[192,8]]},"102":{"position":[[53,7]]},"108":{"position":[[521,7]]}}}],["github",{"_index":44,"t":{"5":{"position":[[103,7]]}}}],["given",{"_index":120,"t":{"13":{"position":[[72,5]]}}}],["gmbh",{"_index":349,"t":{"47":{"position":[[286,4]]},"78":{"position":[[227,4]]}}}],["goal",{"_index":155,"t":{"17":{"position":[[58,4]]},"23":{"position":[[4,4]]},"33":{"position":[[262,6]]}}}],["good",{"_index":52,"t":{"7":{"position":[[91,5]]},"35":{"position":[[35,5]]}}}],["gossip",{"_index":485,"t":{"70":{"position":[[209,6]]}}}],["gossipsub",{"_index":115,"t":{"11":{"position":[[722,9]]},"15":{"position":[[55,9],[173,9]]},"17":{"position":[[75,9]]},"106":{"position":[[162,9],[350,10]]}}}],["govern",{"_index":513,"t":{"76":{"position":[[137,6]]},"86":{"position":[[132,6]]},"94":{"position":[[10,7]]}}}],["group",{"_index":5,"t":{"2":{"position":[[51,5]]}}}],["grow",{"_index":304,"t":{"43":{"position":[[39,4]]}}}],["guarante",{"_index":239,"t":{"29":{"position":[[169,11]]},"80":{"position":[[1355,10]]}}}],["guidanc",{"_index":757,"t":{"104":{"position":[[133,9]]}}}],["hackenproof",{"_index":467,"t":{"65":{"position":[[237,11]]}}}],["harm",{"_index":625,"t":{"86":{"position":[[423,8]]}}}],["harmless",{"_index":649,"t":{"90":{"position":[[35,8]]}}}],["head",{"_index":729,"t":{"98":{"position":[[268,8]]}}}],["heard",{"_index":669,"t":{"96":{"position":[[495,5]]}}}],["held",{"_index":627,"t":{"88":{"position":[[15,4]]},"96":{"position":[[1519,4]]},"98":{"position":[[532,4]]}}}],["help",{"_index":468,"t":{"65":{"position":[[252,4]]},"110":{"position":[[307,5]]}}}],["herein",{"_index":551,"t":{"80":{"position":[[994,6],[1257,6],[1493,7],[1527,6]]},"82":{"position":[[825,6],[1004,7]]},"96":{"position":[[1422,6]]}}}],["high",{"_index":589,"t":{"82":{"position":[[500,4],[1027,4]]},"112":{"position":[[804,4]]}}}],["highest",{"_index":820,"t":{"114":{"position":[[567,7]]}}}],["hold",{"_index":648,"t":{"90":{"position":[[27,4]]},"102":{"position":[[148,5]]}}}],["holder",{"_index":309,"t":{"43":{"position":[[108,7]]}}}],["https://creativecommons.org/licenses/by/4.0",{"_index":620,"t":{"84":{"position":[[390,45]]}}}],["https://our.status.im/our",{"_index":188,"t":{"21":{"position":[[42,25]]}}}],["hundr",{"_index":645,"t":{"88":{"position":[[537,7]]}}}],["idea",{"_index":773,"t":{"108":{"position":[[333,5]]}}}],["identifi",{"_index":98,"t":{"11":{"position":[[384,11]]},"49":{"position":[[653,11]]},"98":{"position":[[277,11]]},"110":{"position":[[313,8]]},"112":{"position":[[537,11]]},"114":{"position":[[506,8]]},"116":{"position":[[553,11]]}}}],["ift",{"_index":10,"t":{"2":{"position":[[97,3]]},"11":{"position":[[92,4],[295,3],[554,4]]},"15":{"position":[[433,3]]},"100":{"position":[[152,3]]},"102":{"position":[[181,3]]},"104":{"position":[[58,3]]},"106":{"position":[[551,3]]},"108":{"position":[[55,3],[154,3]]},"110":{"position":[[160,3],[488,3]]},"112":{"position":[[47,3],[772,3]]},"114":{"position":[[116,3],[308,3]]},"116":{"position":[[163,3],[429,4],[514,3]]},"118":{"position":[[150,3]]},"120":{"position":[[54,4],[134,3],[311,3],[525,3]]}}}],["ift'",{"_index":822,"t":{"116":{"position":[[9,5]]}}}],["ii",{"_index":682,"t":{"96":{"position":[[965,4]]}}}],["immedi",{"_index":448,"t":{"61":{"position":[[185,11]]},"92":{"position":[[217,11]]}}}],["implement",{"_index":380,"t":{"53":{"position":[[67,11]]},"112":{"position":[[160,12],[340,16],[387,15]]},"118":{"position":[[212,12]]}}}],["impli",{"_index":527,"t":{"80":{"position":[[163,8],[1385,7]]},"86":{"position":[[246,5]]}}}],["import",{"_index":752,"t":{"102":{"position":[[166,10]]}}}],["improv",{"_index":116,"t":{"11":{"position":[[732,13]]},"15":{"position":[[65,14],[239,13]]},"41":{"position":[[57,7]]},"106":{"position":[[141,9],[444,11]]}}}],["incent",{"_index":764,"t":{"108":{"position":[[104,11]]}}}],["incentivis",{"_index":295,"t":{"41":{"position":[[19,12]]}}}],["incid",{"_index":461,"t":{"65":{"position":[[125,9]]}}}],["incident",{"_index":636,"t":{"88":{"position":[[202,11]]}}}],["includ",{"_index":97,"t":{"11":{"position":[[375,8],[604,9]]},"25":{"position":[[186,8]]},"76":{"position":[[181,9]]},"80":{"position":[[172,9]]},"82":{"position":[[243,7],[727,9],[1259,9]]},"84":{"position":[[233,9]]},"86":{"position":[[104,9]]},"90":{"position":[[103,9],[210,9]]},"96":{"position":[[74,8],[1873,9]]},"112":{"position":[[152,7]]},"116":{"position":[[236,9],[484,8]]}}}],["inclus",{"_index":291,"t":{"39":{"position":[[119,12]]}}}],["incorpor",{"_index":698,"t":{"96":{"position":[[1409,12]]}}}],["incub",{"_index":17,"t":{"2":{"position":[[162,9]]},"11":{"position":[[271,9],[431,9]]},"13":{"position":[[90,9]]},"74":{"position":[[170,9]]},"100":{"position":[[4,9],[272,9]]}}}],["indemnifi",{"_index":647,"t":{"90":{"position":[[10,9]]}}}],["independ",{"_index":439,"t":{"59":{"position":[[110,11]]}}}],["indic",{"_index":365,"t":{"49":{"position":[[433,9]]}}}],["individu",{"_index":204,"t":{"25":{"position":[[33,12]]},"37":{"position":[[192,11]]}}}],["industri",{"_index":584,"t":{"82":{"position":[[168,8]]}}}],["ineffici",{"_index":312,"t":{"43":{"position":[[141,14]]}}}],["inform",{"_index":146,"t":{"15":{"position":[[288,11]]},"27":{"position":[[27,12],[202,12]]},"33":{"position":[[48,11]]},"45":{"position":[[78,6]]},"53":{"position":[[191,11]]},"57":{"position":[[937,11]]},"80":{"position":[[1076,13],[1245,11],[1505,11]]},"82":{"position":[[803,11],[982,11],[1246,12]]}}}],["infrastructur",{"_index":230,"t":{"27":{"position":[[182,15]]}}}],["infring",{"_index":532,"t":{"80":{"position":[[278,12]]}}}],["inherit",{"_index":187,"t":{"21":{"position":[[27,9]]}}}],["initi",{"_index":740,"t":{"100":{"position":[[36,11]]}}}],["innov",{"_index":76,"t":{"11":{"position":[[70,10]]}}}],["institut",{"_index":458,"t":{"65":{"position":[[49,9]]},"96":{"position":[[1275,11]]}}}],["integr",{"_index":509,"t":{"74":{"position":[[488,11]]},"106":{"position":[[212,11]]},"112":{"position":[[230,11]]},"118":{"position":[[526,9]]},"120":{"position":[[452,11]]}}}],["intellectu",{"_index":533,"t":{"80":{"position":[[294,12]]}}}],["intend",{"_index":328,"t":{"45":{"position":[[66,8]]},"80":{"position":[[1042,8]]},"114":{"position":[[348,8]]}}}],["intens",{"_index":766,"t":{"108":{"position":[[175,9]]}}}],["interact",{"_index":134,"t":{"13":{"position":[[377,12]]},"51":{"position":[[218,8]]}}}],["interest",{"_index":48,"t":{"7":{"position":[[7,10]]},"49":{"position":[[699,8]]}}}],["intern",{"_index":615,"t":{"84":{"position":[[87,13]]},"96":{"position":[[1325,13],[1972,13]]}}}],["interoper",{"_index":292,"t":{"39":{"position":[[162,17]]},"74":{"position":[[318,13]]},"112":{"position":[[188,16]]},"120":{"position":[[276,13]]}}}],["interpret",{"_index":734,"t":{"98":{"position":[[423,14]]}}}],["intricaci",{"_index":123,"t":{"13":{"position":[[144,11]]}}}],["invalid",{"_index":735,"t":{"98":{"position":[[537,7]]}}}],["invest",{"_index":293,"t":{"39":{"position":[[184,9]]}}}],["involv",{"_index":818,"t":{"114":{"position":[[455,8]]}}}],["ip",{"_index":367,"t":{"49":{"position":[[549,2],[620,2],[727,2],[833,2]]}}}],["issu",{"_index":41,"t":{"5":{"position":[[87,6]]},"7":{"position":[[103,6]]},"110":{"position":[[360,7]]},"112":{"position":[[585,6]]}}}],["it'",{"_index":245,"t":{"31":{"position":[[73,4]]}}}],["itself",{"_index":279,"t":{"37":{"position":[[73,7]]}}}],["job",{"_index":47,"t":{"5":{"position":[[133,3]]}}}],["join",{"_index":36,"t":{"5":{"position":[[24,7]]},"67":{"position":[[0,4],[131,4]]}}}],["judg",{"_index":670,"t":{"96":{"position":[[506,6]]}}}],["juri",{"_index":674,"t":{"96":{"position":[[615,4]]}}}],["jurisdict",{"_index":549,"t":{"80":{"position":[[826,13]]},"96":{"position":[[650,14]]}}}],["keep",{"_index":470,"t":{"67":{"position":[[24,4]]}}}],["kept",{"_index":706,"t":{"96":{"position":[[1742,4]]}}}],["key",{"_index":107,"t":{"11":{"position":[[593,3]]}}}],["kind",{"_index":525,"t":{"80":{"position":[[146,5]]}}}],["kit",{"_index":62,"t":{"7":{"position":[[187,3]]},"118":{"position":[[628,4]]}}}],["knowledg",{"_index":69,"t":{"9":{"position":[[52,9],[110,9]]},"11":{"position":[[619,9]]},"13":{"position":[[164,9]]},"102":{"position":[[74,9]]},"108":{"position":[[435,10]]},"118":{"position":[[91,9]]}}}],["known",{"_index":715,"t":{"96":{"position":[[2160,5]]}}}],["laid",{"_index":413,"t":{"57":{"position":[[240,4]]}}}],["languag",{"_index":707,"t":{"96":{"position":[[1765,8]]}}}],["larger",{"_index":789,"t":{"110":{"position":[[234,6]]}}}],["last",{"_index":322,"t":{"45":{"position":[[13,4]]},"76":{"position":[[13,4]]}}}],["latest",{"_index":473,"t":{"67":{"position":[[49,6],[188,6]]}}}],["law",{"_index":545,"t":{"80":{"position":[[708,4],[976,5]]},"88":{"position":[[639,4]]},"94":{"position":[[6,3],[145,4]]},"96":{"position":[[66,3]]}}}],["lawsuit",{"_index":718,"t":{"96":{"position":[[2241,7]]}}}],["layer",{"_index":152,"t":{"15":{"position":[[423,6]]},"17":{"position":[[99,5]]},"106":{"position":[[239,7]]}}}],["legal",{"_index":344,"t":{"47":{"position":[[212,5]]},"49":{"position":[[199,5]]},"78":{"position":[[152,5]]},"80":{"position":[[431,9],[785,7],[1565,6]]},"88":{"position":[[93,5]]}}}],["legal@free.technolog",{"_index":453,"t":{"63":{"position":[[89,22]]},"98":{"position":[[902,22]]}}}],["legisl",{"_index":360,"t":{"49":{"position":[[245,12]]},"55":{"position":[[713,12]]},"57":{"position":[[269,12]]}}}],["legitim",{"_index":369,"t":{"49":{"position":[[688,10]]}}}],["level",{"_index":394,"t":{"55":{"position":[[297,5]]}}}],["leverag",{"_index":747,"t":{"100":{"position":[[311,10]]},"118":{"position":[[371,10]]}}}],["liabil",{"_index":442,"t":{"59":{"position":[[179,9]]},"88":{"position":[[73,10],[484,9],[572,9]]}}}],["liabl",{"_index":626,"t":{"86":{"position":[[498,6]]},"88":{"position":[[20,6]]}}}],["liberti",{"_index":209,"t":{"25":{"position":[[111,8]]}}}],["libp2p",{"_index":58,"t":{"7":{"position":[[156,6]]},"11":{"position":[[715,6]]},"15":{"position":[[47,7],[166,6]]},"17":{"position":[[68,6]]},"104":{"position":[[193,6]]},"106":{"position":[[124,7],[155,6],[343,6]]}}}],["librari",{"_index":23,"t":{"2":{"position":[[240,10]]},"116":{"position":[[139,9],[406,9]]}}}],["licenc",{"_index":271,"t":{"35":{"position":[[89,8]]},"84":{"position":[[138,7],[342,8]]}}}],["licens",{"_index":455,"t":{"63":{"position":[[129,8]]},"84":{"position":[[101,7]]},"98":{"position":[[942,8]]}}}],["limit",{"_index":357,"t":{"49":{"position":[[10,5]]},"51":{"position":[[19,7]]},"57":{"position":[[40,5]]},"80":{"position":[[190,10]]},"88":{"position":[[513,7],[558,10]]},"90":{"position":[[228,10]]},"96":{"position":[[570,8],[2039,12]]},"98":{"position":[[402,6]]}}}],["linchpin",{"_index":499,"t":{"74":{"position":[[279,8]]},"120":{"position":[[237,8]]}}}],["link",{"_index":436,"t":{"59":{"position":[[37,5]]},"80":{"position":[[613,6]]},"86":{"position":[[39,5],[182,7]]}}}],["list",{"_index":54,"t":{"7":{"position":[[110,5]]}}}],["litig",{"_index":664,"t":{"96":{"position":[[277,10],[474,10]]}}}],["local",{"_index":550,"t":{"80":{"position":[[970,5]]}}}],["logo",{"_index":339,"t":{"47":{"position":[[135,5],[238,5],[350,8],[417,5]]},"74":{"position":[[54,5],[147,5],[353,5],[561,5]]},"78":{"position":[[75,5],[179,5],[291,8],[368,5]]},"102":{"position":[[206,6]]},"118":{"position":[[482,5]]}}}],["long",{"_index":265,"t":{"33":{"position":[[252,4]]}}}],["look",{"_index":579,"t":{"82":{"position":[[37,7],[213,7],[549,7]]}}}],["lost",{"_index":631,"t":{"88":{"position":[[127,4]]}}}],["lower",{"_index":318,"t":{"43":{"position":[[247,5]]}}}],["machin",{"_index":750,"t":{"102":{"position":[[92,8]]}}}],["made",{"_index":119,"t":{"13":{"position":[[43,4]]},"21":{"position":[[120,4]]},"35":{"position":[[47,4]]},"80":{"position":[[1057,4]]},"84":{"position":[[33,4]]}}}],["main",{"_index":154,"t":{"17":{"position":[[53,4]]}}}],["maintain",{"_index":382,"t":{"53":{"position":[[128,8]]},"116":{"position":[[392,8]]}}}],["mainten",{"_index":814,"t":{"114":{"position":[[67,12]]},"116":{"position":[[103,11]]}}}],["make",{"_index":237,"t":{"29":{"position":[[148,4]]},"33":{"position":[[206,6]]},"51":{"position":[[138,6]]},"80":{"position":[[367,4],[716,4]]},"96":{"position":[[97,4],[953,7]]}}}],["manag",{"_index":829,"t":{"116":{"position":[[280,9]]}}}],["mandat",{"_index":831,"t":{"116":{"position":[[455,7]]}}}],["manner",{"_index":667,"t":{"96":{"position":[[388,7]]}}}],["market",{"_index":585,"t":{"82":{"position":[[181,7],[620,6]]},"108":{"position":[[120,8]]}}}],["mass",{"_index":197,"t":{"23":{"position":[[92,4]]}}}],["matter",{"_index":565,"t":{"80":{"position":[[1475,7]]},"82":{"position":[[437,7],[1123,7]]}}}],["maximis",{"_index":210,"t":{"25":{"position":[[130,8]]},"37":{"position":[[100,8],[169,8]]}}}],["maximum",{"_index":543,"t":{"80":{"position":[[669,7]]},"88":{"position":[[600,7]]}}}],["mean",{"_index":313,"t":{"43":{"position":[[186,5]]},"55":{"position":[[197,5]]},"76":{"position":[[375,5]]},"96":{"position":[[43,7]]},"98":{"position":[[760,4]]}}}],["measur",{"_index":371,"t":{"49":{"position":[[803,8]]},"53":{"position":[[101,8]]}}}],["meet",{"_index":665,"t":{"96":{"position":[[305,5]]}}}],["member",{"_index":301,"t":{"41":{"position":[[135,8]]}}}],["merchant",{"_index":528,"t":{"80":{"position":[[219,16]]}}}],["messag",{"_index":166,"t":{"19":{"position":[[92,9],[154,9],[294,9],[390,9]]}}}],["method",{"_index":236,"t":{"29":{"position":[[120,7]]},"96":{"position":[[1602,7]]}}}],["meticul",{"_index":495,"t":{"74":{"position":[[193,12]]},"112":{"position":[[687,10]]},"114":{"position":[[464,12]]},"120":{"position":[[151,12]]}}}],["minimis",{"_index":277,"t":{"37":{"position":[[3,8]]}}}],["minor",{"_index":189,"t":{"21":{"position":[[86,5]]}}}],["model",{"_index":780,"t":{"108":{"position":[[463,9],[507,9]]}}}],["modifi",{"_index":273,"t":{"35":{"position":[[119,7]]},"61":{"position":[[7,6]]},"84":{"position":[[168,6]]},"92":{"position":[[7,6]]},"98":{"position":[[386,7]]}}}],["modular",{"_index":479,"t":{"70":{"position":[[18,7]]}}}],["natur",{"_index":681,"t":{"96":{"position":[[908,6]]}}}],["need",{"_index":362,"t":{"49":{"position":[[321,4],[418,6]]},"108":{"position":[[256,5]]},"114":{"position":[[299,5]]},"116":{"position":[[597,5]]}}}],["neglig",{"_index":628,"t":{"88":{"position":[[54,11]]}}}],["nescienc",{"_index":71,"t":{"9":{"position":[[131,11]]},"13":{"position":[[108,10]]},"102":{"position":[[0,9]]}}}],["network",{"_index":63,"t":{"9":{"position":[[4,10]]},"11":{"position":[[682,9]]},"13":{"position":[[411,9]]},"15":{"position":[[347,9]]},"17":{"position":[[34,9]]},"37":{"position":[[156,8]]},"106":{"position":[[231,7],[488,9]]},"110":{"position":[[241,9]]}}}],["new",{"_index":101,"t":{"11":{"position":[[427,3]]},"19":{"position":[[42,3]]},"29":{"position":[[107,3]]},"61":{"position":[[148,3]]},"92":{"position":[[174,3]]},"108":{"position":[[329,3]]}}}],["nim",{"_index":57,"t":{"7":{"position":[[152,3]]},"104":{"position":[[189,3]]},"106":{"position":[[120,3]]},"116":{"position":[[36,3],[55,3],[118,3],[181,3],[221,3],[250,3],[294,3],[366,3],[470,3],[548,4],[630,3]]}}}],["nimbl",{"_index":827,"t":{"116":{"position":[[264,6]]}}}],["node",{"_index":113,"t":{"11":{"position":[[668,4]]},"110":{"position":[[221,5]]}}}],["nois",{"_index":837,"t":{"118":{"position":[[303,5]]}}}],["non",{"_index":531,"t":{"80":{"position":[[274,3]]},"86":{"position":[[419,3]]}}}],["nonetheless",{"_index":410,"t":{"57":{"position":[[117,12]]}}}],["note",{"_index":671,"t":{"96":{"position":[[520,4]]}}}],["noth",{"_index":572,"t":{"80":{"position":[[1628,7]]}}}],["notic",{"_index":444,"t":{"61":{"position":[[81,7]]},"82":{"position":[[1392,6]]},"92":{"position":[[87,7]]},"96":{"position":[[870,6],[1108,6]]}}}],["number",{"_index":281,"t":{"37":{"position":[[113,6],[182,6]]}}}],["object",{"_index":34,"t":{"2":{"position":[[416,11]]},"57":{"position":[[831,6]]},"110":{"position":[[137,9]]}}}],["oblig",{"_index":307,"t":{"43":{"position":[[88,10]]},"55":{"position":[[7,7]]},"80":{"position":[[1222,10]]}}}],["occur",{"_index":406,"t":{"55":{"position":[[669,5]]},"108":{"position":[[189,6]]}}}],["offer",{"_index":574,"t":{"80":{"position":[[1685,5],[1725,5]]},"118":{"position":[[166,8]]}}}],["offic",{"_index":342,"t":{"47":{"position":[[190,6]]},"78":{"position":[[130,6]]}}}],["on",{"_index":644,"t":{"88":{"position":[[532,4]]},"96":{"position":[[1652,3],[2085,3]]}}}],["oneself",{"_index":243,"t":{"31":{"position":[[43,7]]}}}],["open",{"_index":38,"t":{"5":{"position":[[45,7],[79,7],[137,9]]},"33":{"position":[[23,8]]},"35":{"position":[[77,4]]}}}],["oper",{"_index":746,"t":{"100":{"position":[[291,7]]}}}],["opportun",{"_index":99,"t":{"11":{"position":[[396,13]]}}}],["optimis",{"_index":145,"t":{"15":{"position":[[279,8]]}}}],["oral",{"_index":727,"t":{"98":{"position":[[216,5]]}}}],["order",{"_index":596,"t":{"82":{"position":[[741,5]]}}}],["organis",{"_index":205,"t":{"25":{"position":[[60,12]]},"33":{"position":[[71,13]]},"37":{"position":[[60,12]]},"43":{"position":[[167,13]]}}}],["oskar",{"_index":176,"t":{"19":{"position":[[253,5],[320,5],[433,5]]}}}],["otherwis",{"_index":397,"t":{"55":{"position":[[370,10]]},"80":{"position":[[549,9]]}}}],["out",{"_index":414,"t":{"57":{"position":[[245,3]]},"96":{"position":[[896,3]]}}}],["outlin",{"_index":200,"t":{"23":{"position":[[143,8]]}}}],["outsid",{"_index":389,"t":{"55":{"position":[[149,7],[614,7]]}}}],["over",{"_index":184,"t":{"19":{"position":[[400,4]]},"37":{"position":[[221,4]]},"49":{"position":[[864,4]]},"86":{"position":[[451,4]]},"96":{"position":[[272,4]]}}}],["overal",{"_index":149,"t":{"15":{"position":[[377,7]]},"106":{"position":[[436,7]]},"112":{"position":[[630,7]]},"118":{"position":[[518,7]]}}}],["overse",{"_index":497,"t":{"74":{"position":[[219,10]]},"120":{"position":[[177,10]]}}}],["p2p",{"_index":65,"t":{"9":{"position":[[24,3]]},"15":{"position":[[419,3]]},"70":{"position":[[26,3]]},"106":{"position":[[4,3],[78,5],[102,3],[227,3],[251,3],[386,3],[408,3]]}}}],["packag",{"_index":828,"t":{"116":{"position":[[271,8]]}}}],["page",{"_index":321,"t":{"45":{"position":[[8,4]]},"76":{"position":[[8,4]]}}}],["part",{"_index":95,"t":{"11":{"position":[[355,4]]},"49":{"position":[[564,4]]},"61":{"position":[[29,4]]},"92":{"position":[[29,4]]},"98":{"position":[[494,4],[568,4]]},"106":{"position":[[36,4]]}}}],["parti",{"_index":374,"t":{"51":{"position":[[66,7],[243,5]]},"55":{"position":[[264,7]]},"59":{"position":[[52,5],[80,5],[235,5]]},"86":{"position":[[56,5],[163,5],[201,5],[292,5],[358,5],[467,5],[548,5],[618,5],[742,5]]},"96":{"position":[[1726,7]]}}}],["particip",{"_index":276,"t":{"35":{"position":[[174,14]]},"39":{"position":[[147,14]]},"96":{"position":[[2211,11]]}}}],["particular",{"_index":530,"t":{"80":{"position":[[250,10]]}}}],["past",{"_index":562,"t":{"80":{"position":[[1415,5]]}}}],["payment",{"_index":709,"t":{"96":{"position":[[1813,7]]}}}],["peer",{"_index":483,"t":{"70":{"position":[[130,4],[138,4]]},"106":{"position":[[65,4],[73,4]]}}}],["perform",{"_index":139,"t":{"15":{"position":[[118,12]]},"110":{"position":[[348,11]]},"112":{"position":[[809,10]]}}}],["period",{"_index":447,"t":{"61":{"position":[[114,12]]},"92":{"position":[[140,12]]}}}],["permissionless",{"_index":275,"t":{"35":{"position":[[159,14]]},"39":{"position":[[132,14]]}}}],["permit",{"_index":544,"t":{"80":{"position":[[684,9]]},"88":{"position":[[615,9]]}}}],["person",{"_index":208,"t":{"25":{"position":[[102,8]]},"47":{"position":[[77,8]]},"49":{"position":[[64,8],[141,8],[293,8],[352,8],[505,8]]},"51":{"position":[[45,8],[97,8]]},"53":{"position":[[156,8]]},"55":{"position":[[41,8],[125,8],[208,8],[482,8],[600,8]]},"57":{"position":[[84,8],[190,8],[338,8],[403,8],[461,8],[588,8],[864,8],[996,8]]}}}],["physic",{"_index":282,"t":{"37":{"position":[[123,8]]}}}],["place",{"_index":388,"t":{"55":{"position":[[142,6]]},"82":{"position":[[1095,5]]}}}],["plan",{"_index":804,"t":{"112":{"position":[[120,6]]},"116":{"position":[[383,5]]}}}],["play",{"_index":754,"t":{"104":{"position":[[24,4]]},"112":{"position":[[288,5]]}}}],["pleas",{"_index":445,"t":{"61":{"position":[[89,6]]},"63":{"position":[[68,6]]},"65":{"position":[[98,6],[165,6]]},"84":{"position":[[351,6]]},"96":{"position":[[513,6]]},"98":{"position":[[881,6]]}}}],["pluggabl",{"_index":156,"t":{"17":{"position":[[110,9]]}}}],["polici",{"_index":327,"t":{"45":{"position":[[56,6],[220,6]]},"47":{"position":[[33,6]]},"51":{"position":[[295,8]]},"57":{"position":[[29,7]]},"59":{"position":[[130,9]]},"61":{"position":[[50,6],[160,6]]},"63":{"position":[[60,7]]},"86":{"position":[[122,9]]}}}],["polit",{"_index":212,"t":{"25":{"position":[[147,10]]}}}],["portion",{"_index":737,"t":{"98":{"position":[[642,8]]}}}],["possibl",{"_index":317,"t":{"43":{"position":[[235,8]]},"57":{"position":[[107,9],[370,10]]},"88":{"position":[[427,11]]},"96":{"position":[[1613,9]]}}}],["post",{"_index":450,"t":{"61":{"position":[[206,7]]},"92":{"position":[[238,7]]}}}],["poster",{"_index":487,"t":{"70":{"position":[[230,8]]}}}],["potenti",{"_index":676,"t":{"96":{"position":[[670,11]]},"110":{"position":[[322,9]]},"114":{"position":[[527,9]]}}}],["power",{"_index":240,"t":{"31":{"position":[[15,5]]}}}],["pr",{"_index":43,"t":{"5":{"position":[[96,3]]}}}],["practic",{"_index":87,"t":{"11":{"position":[[193,9],[520,9]]}}}],["prefer",{"_index":663,"t":{"96":{"position":[[253,6]]}}}],["present",{"_index":563,"t":{"80":{"position":[[1421,7]]},"82":{"position":[[788,10]]}}}],["preserv",{"_index":112,"t":{"11":{"position":[[657,10]]},"13":{"position":[[249,10]]},"70":{"position":[[119,10],[183,10]]},"102":{"position":[[42,10],[120,10]]}}}],["primari",{"_index":786,"t":{"110":{"position":[[129,7]]},"112":{"position":[[127,7]]}}}],["principl",{"_index":1,"t":{"2":{"position":[[9,9],[352,10]]},"21":{"position":[[6,10],[68,12]]},"23":{"position":[[132,10]]},"27":{"position":[[112,9]]},"96":{"position":[[315,9]]}}}],["prior",{"_index":724,"t":{"98":{"position":[[113,5]]}}}],["privaci",{"_index":111,"t":{"11":{"position":[[649,7],[702,8]]},"13":{"position":[[241,7]]},"31":{"position":[[0,7],[99,7]]},"45":{"position":[[48,7],[110,7],[212,7]]},"47":{"position":[[25,7]]},"49":{"position":[[237,7]]},"51":{"position":[[287,7]]},"55":{"position":[[30,7],[705,7]]},"57":{"position":[[21,7],[261,7]]},"59":{"position":[[122,7]]},"61":{"position":[[42,7],[152,7]]},"63":{"position":[[52,7]]},"70":{"position":[[111,7],[175,7]]},"86":{"position":[[114,7]]},"102":{"position":[[34,7],[112,7]]},"118":{"position":[[450,8]]}}}],["privat",{"_index":181,"t":{"19":{"position":[[355,7]]}}}],["proactiv",{"_index":769,"t":{"108":{"position":[[271,11]]},"112":{"position":[[515,9]]}}}],["problem",{"_index":315,"t":{"43":{"position":[[200,8]]}}}],["proceed",{"_index":705,"t":{"96":{"position":[[1676,11]]}}}],["process",{"_index":337,"t":{"47":{"position":[[63,10]]},"49":{"position":[[50,10],[125,7],[281,7],[483,7],[607,7],[711,10]]},"51":{"position":[[89,7]]},"55":{"position":[[235,9]]},"57":{"position":[[65,10],[228,8],[575,7],[635,10],[676,10],[769,10],[845,10],[1019,9]]},"112":{"position":[[728,10]]},"114":{"position":[[447,7]]}}}],["procur",{"_index":633,"t":{"88":{"position":[[149,11]]}}}],["profit",{"_index":632,"t":{"88":{"position":[[132,8]]}}}],["program",{"_index":753,"t":{"102":{"position":[[185,9]]}}}],["programm",{"_index":466,"t":{"65":{"position":[[224,9]]}}}],["project",{"_index":18,"t":{"2":{"position":[[172,9]]},"11":{"position":[[281,9],[299,9],[441,9]]},"13":{"position":[[100,7]]},"15":{"position":[[437,9]]},"17":{"position":[[120,7]]},"74":{"position":[[153,8],[180,9]]},"80":{"position":[[1462,8]]},"82":{"position":[[134,11],[281,7],[386,9]]},"100":{"position":[[14,8],[98,8],[156,9],[282,8]]},"104":{"position":[[62,9]]},"106":{"position":[[194,8],[555,8]]},"108":{"position":[[59,8],[158,7]]},"110":{"position":[[164,8],[414,9],[492,8]]},"112":{"position":[[51,8],[332,7],[379,7],[776,8]]},"114":{"position":[[120,9],[212,7],[312,9],[385,7]]},"116":{"position":[[167,9],[518,8],[589,7]]},"118":{"position":[[154,8],[488,9]]},"120":{"position":[[138,9]]}}}],["project'",{"_index":807,"t":{"112":{"position":[[486,9]]}}}],["promis",{"_index":560,"t":{"80":{"position":[[1318,8]]}}}],["promptli",{"_index":810,"t":{"112":{"position":[[606,9]]}}}],["proof",{"_index":124,"t":{"13":{"position":[[174,7]]},"118":{"position":[[106,7],[201,6]]}}}],["properti",{"_index":534,"t":{"80":{"position":[[307,8]]}}}],["propos",{"_index":144,"t":{"15":{"position":[[229,9]]}}}],["protect",{"_index":169,"t":{"19":{"position":[[127,10]]},"31":{"position":[[91,7]]},"55":{"position":[[18,7],[306,10],[408,12],[517,10]]},"57":{"position":[[922,10]]},"70":{"position":[[157,10],[199,9]]}}}],["protocol",{"_index":22,"t":{"2":{"position":[[229,10],[308,10]]},"15":{"position":[[183,9]]},"65":{"position":[[268,9]]},"70":{"position":[[30,9]]},"74":{"position":[[332,9]]},"106":{"position":[[172,9]]},"118":{"position":[[309,8]]},"120":{"position":[[290,9]]}}}],["provid",{"_index":6,"t":{"2":{"position":[[62,8]]},"11":{"position":[[673,8]]},"31":{"position":[[204,7]]},"51":{"position":[[175,7]]},"55":{"position":[[277,7],[499,8]]},"80":{"position":[[15,8]]},"86":{"position":[[26,8]]},"104":{"position":[[87,9]]},"116":{"position":[[493,9]]},"118":{"position":[[118,8]]}}}],["provis",{"_index":659,"t":{"94":{"position":[[150,11]]},"98":{"position":[[445,10]]}}}],["pseudo",{"_index":249,"t":{"31":{"position":[[159,6]]}}}],["pst",{"_index":347,"t":{"47":{"position":[[271,3]]},"78":{"position":[[212,3]]}}}],["public",{"_index":25,"t":{"2":{"position":[[271,13]]},"11":{"position":[[134,13]]},"35":{"position":[[28,6]]}}}],["purport",{"_index":601,"t":{"82":{"position":[[858,7]]}}}],["purpos",{"_index":335,"t":{"47":{"position":[[8,8]]},"49":{"position":[[168,8],[443,8]]},"78":{"position":[[8,8]]},"80":{"position":[[261,8],[1090,8]]},"84":{"position":[[224,8]]},"102":{"position":[[61,7]]}}}],["push",{"_index":125,"t":{"13":{"position":[[215,7]]}}}],["qa",{"_index":801,"t":{"112":{"position":[[4,2],[280,2],[435,2],[743,2]]}}}],["qa'",{"_index":808,"t":{"112":{"position":[[510,4]]}}}],["qualiti",{"_index":811,"t":{"112":{"position":[[638,7],[710,7]]}}}],["question",{"_index":451,"t":{"63":{"position":[[32,9]]},"98":{"position":[[837,9]]}}}],["r&d",{"_index":13,"t":{"2":{"position":[[124,3]]},"11":{"position":[[260,3]]},"100":{"position":[[238,3]]},"104":{"position":[[6,3]]},"106":{"position":[[8,3]]},"110":{"position":[[38,3]]},"118":{"position":[[30,3]]}}}],["rang",{"_index":779,"t":{"108":{"position":[[446,7]]}}}],["read",{"_index":515,"t":{"76":{"position":[[276,4]]}}}],["readi",{"_index":305,"t":{"43":{"position":[[53,5]]}}}],["real",{"_index":800,"t":{"110":{"position":[[579,4]]}}}],["realm",{"_index":117,"t":{"13":{"position":[[7,5]]}}}],["reason",{"_index":417,"t":{"57":{"position":[[359,10]]},"96":{"position":[[722,10],[2149,10]]}}}],["receiv",{"_index":691,"t":{"96":{"position":[[1093,9]]}}}],["rectifi",{"_index":819,"t":{"114":{"position":[[519,7]]}}}],["refer",{"_index":355,"t":{"47":{"position":[[341,5],[381,11],[400,9]]},"78":{"position":[[282,5],[332,11],[351,9]]},"84":{"position":[[358,5]]},"96":{"position":[[1157,8],[1432,10]]},"98":{"position":[[352,9]]}}}],["regard",{"_index":333,"t":{"45":{"position":[[166,7]]},"49":{"position":[[460,7]]},"94":{"position":[[123,6]]},"98":{"position":[[73,9]]},"116":{"position":[[527,9]]}}}],["regardless",{"_index":711,"t":{"96":{"position":[[1999,10]]}}}],["regist",{"_index":341,"t":{"47":{"position":[[179,10]]},"78":{"position":[[119,10]]}}}],["regress",{"_index":791,"t":{"110":{"position":[[274,10]]}}}],["regularli",{"_index":607,"t":{"82":{"position":[[1231,10]]}}}],["regulatori",{"_index":594,"t":{"82":{"position":[[667,10]]}}}],["relat",{"_index":56,"t":{"7":{"position":[[132,7]]},"80":{"position":[[559,8],[1446,8]]},"82":{"position":[[421,7]]},"88":{"position":[[239,7]]},"90":{"position":[[146,7]]},"96":{"position":[[141,8]]},"116":{"position":[[615,7]]},"118":{"position":[[351,7]]}}}],["relay",{"_index":482,"t":{"70":{"position":[[104,6]]}}}],["relentlessli",{"_index":302,"t":{"43":{"position":[[7,12]]}}}],["relev",{"_index":338,"t":{"47":{"position":[[112,8]]},"57":{"position":[[252,8]]},"78":{"position":[[52,8]]},"96":{"position":[[1828,8]]}}}],["reli",{"_index":559,"t":{"80":{"position":[[1301,6]]}}}],["reliabl",{"_index":141,"t":{"15":{"position":[[147,11]]},"19":{"position":[[367,8]]},"80":{"position":[[450,12]]},"82":{"position":[[882,8],[951,11]]},"110":{"position":[[381,11]]},"112":{"position":[[650,11]]},"114":{"position":[[601,12]]},"116":{"position":[[336,9]]}}}],["relianc",{"_index":606,"t":{"82":{"position":[[1107,8]]}}}],["remain",{"_index":469,"t":{"65":{"position":[[291,6]]},"98":{"position":[[632,9],[656,6]]}}}],["remedi",{"_index":683,"t":{"96":{"position":[[974,6]]}}}],["remot",{"_index":66,"t":{"9":{"position":[[28,6],[86,6],[143,6]]}}}],["remov",{"_index":418,"t":{"57":{"position":[[391,6]]}}}],["replac",{"_index":443,"t":{"61":{"position":[[17,7]]},"92":{"position":[[17,7]]}}}],["report",{"_index":460,"t":{"65":{"position":[[105,6],[172,6]]},"112":{"position":[[553,9]]}}}],["repres",{"_index":622,"t":{"86":{"position":[[233,9]]}}}],["represent",{"_index":537,"t":{"80":{"position":[[376,15],[1327,15]]},"98":{"position":[[167,15]]}}}],["request",{"_index":422,"t":{"57":{"position":[[541,8]]}}}],["requir",{"_index":402,"t":{"55":{"position":[[531,8]]},"84":{"position":[[278,12]]},"112":{"position":[[496,13]]},"114":{"position":[[220,13],[404,13]]}}}],["research",{"_index":3,"t":{"2":{"position":[[26,8],[148,9],[196,8]]},"7":{"position":[[26,8]]},"9":{"position":[[62,8],[120,10]]},"11":{"position":[[9,8],[324,8],[469,8],[497,8],[564,8]]},"13":{"position":[[30,8],[313,8]]},"15":{"position":[[35,8],[216,8],[262,8]]},"17":{"position":[[9,10]]},"25":{"position":[[51,8]]},"29":{"position":[[98,8]]},"67":{"position":[[56,8],[195,8],[215,8]]},"100":{"position":[[74,8],[225,8]]},"106":{"position":[[295,8],[315,8]]},"108":{"position":[[369,9]]}}}],["resili",{"_index":796,"t":{"110":{"position":[[525,9]]},"118":{"position":[[540,10]]}}}],["resist",{"_index":217,"t":{"25":{"position":[[210,10]]},"27":{"position":[[136,11]]},"70":{"position":[[64,9]]}}}],["resolut",{"_index":678,"t":{"96":{"position":[[809,10]]}}}],["resolv",{"_index":666,"t":{"96":{"position":[[328,9],[744,7],[1034,7],[1181,8]]}}}],["resourc",{"_index":303,"t":{"43":{"position":[[20,12],[300,11]]},"100":{"position":[[198,9]]},"104":{"position":[[108,10]]}}}],["respect",{"_index":331,"t":{"45":{"position":[[121,7]]},"51":{"position":[[276,10]]},"57":{"position":[[175,7]]},"96":{"position":[[1845,7]]},"98":{"position":[[227,7]]}}}],["respond",{"_index":768,"t":{"108":{"position":[[238,8]]}}}],["respons",{"_index":441,"t":{"59":{"position":[[161,14]]},"74":{"position":[[86,14]]},"76":{"position":[[258,14]]},"80":{"position":[[924,11]]},"82":{"position":[[918,14]]},"86":{"position":[[696,11]]},"92":{"position":[[103,11]]},"110":{"position":[[58,11]]},"112":{"position":[[135,16]]},"120":{"position":[[73,14]]}}}],["result",{"_index":375,"t":{"51":{"position":[[116,6]]},"82":{"position":[[718,8]]},"96":{"position":[[797,6]]}}}],["reveal",{"_index":242,"t":{"31":{"position":[[36,6]]}}}],["review",{"_index":672,"t":{"96":{"position":[[536,6]]},"114":{"position":[[477,9]]}}}],["rfc",{"_index":489,"t":{"74":{"position":[[8,3],[260,3]]},"120":{"position":[[8,3],[218,3],[329,3]]}}}],["right",{"_index":253,"t":{"31":{"position":[[216,5]]},"57":{"position":[[165,6],[295,5]]},"80":{"position":[[338,7]]},"96":{"position":[[465,5],[603,6],[2202,5]]},"98":{"position":[[789,5]]}}}],["rigor",{"_index":806,"t":{"112":{"position":[[360,10]]}}}],["rise",{"_index":121,"t":{"13":{"position":[[78,4]]}}}],["risk",{"_index":522,"t":{"80":{"position":[[106,5]]},"82":{"position":[[515,4],[1042,4]]},"86":{"position":[[672,4]]}}}],["rln",{"_index":481,"t":{"70":{"position":[[100,3]]}}}],["roadmap",{"_index":586,"t":{"82":{"position":[[272,8]]}}}],["robust",{"_index":150,"t":{"15":{"position":[[385,10]]},"112":{"position":[[793,6]]},"114":{"position":[[179,7]]}}}],["role",{"_index":756,"t":{"104":{"position":[[39,4]]},"112":{"position":[[304,4]]}}}],["rout",{"_index":486,"t":{"70":{"position":[[222,7]]}}}],["royer",{"_index":173,"t":{"19":{"position":[[183,5]]}}}],["rule",{"_index":696,"t":{"96":{"position":[[1316,5],[1386,5],[1963,5]]}}}],["sa",{"_index":457,"t":{"63":{"position":[[150,3]]},"98":{"position":[[963,3]]}}}],["safeti",{"_index":383,"t":{"53":{"position":[[141,6]]}}}],["same",{"_index":401,"t":{"55":{"position":[[512,4]]}}}],["sc",{"_index":816,"t":{"114":{"position":[[134,2],[234,2]]}}}],["scalabl",{"_index":151,"t":{"15":{"position":[[400,11]]},"110":{"position":[[512,8]]}}}],["scale",{"_index":787,"t":{"110":{"position":[[194,7]]}}}],["scientif",{"_index":81,"t":{"11":{"position":[[123,10]]}}}],["seamless",{"_index":508,"t":{"74":{"position":[[479,8]]},"106":{"position":[[507,8]]},"112":{"position":[[221,8]]},"120":{"position":[[443,8]]}}}],["section",{"_index":730,"t":{"98":{"position":[[289,8]]}}}],["secur",{"_index":132,"t":{"13":{"position":[[353,6]]},"29":{"position":[[23,8],[111,8],[160,8]]},"49":{"position":[[794,8]]},"53":{"position":[[36,8],[92,8]]},"65":{"position":[[8,8],[116,8],[298,7]]},"70":{"position":[[44,6]]},"80":{"position":[[1764,9]]},"114":{"position":[[187,7],[588,8]]},"118":{"position":[[440,9]]}}}],["security@free.technolog",{"_index":462,"t":{"65":{"position":[[139,25]]}}}],["see",{"_index":45,"t":{"5":{"position":[[117,3]]},"7":{"position":[[83,3]]},"72":{"position":[[0,3]]}}}],["seek",{"_index":684,"t":{"96":{"position":[[989,8]]}}}],["select",{"_index":241,"t":{"31":{"position":[[24,11]]}}}],["sell",{"_index":576,"t":{"80":{"position":[[1701,5],[1741,4]]}}}],["send",{"_index":679,"t":{"96":{"position":[[852,4]]}}}],["separ",{"_index":438,"t":{"59":{"position":[[97,8]]},"100":{"position":[[143,8]]}}}],["serious",{"_index":379,"t":{"53":{"position":[[45,9]]},"65":{"position":[[17,9]]}}}],["serv",{"_index":490,"t":{"74":{"position":[[17,6]]},"120":{"position":[[17,6]]}}}],["servic",{"_index":14,"t":{"2":{"position":[[128,7]]},"33":{"position":[[237,7]]},"88":{"position":[[176,9]]},"100":{"position":[[242,7]]},"104":{"position":[[10,7]]},"106":{"position":[[12,7]]},"110":{"position":[[42,7]]},"112":{"position":[[7,7],[746,7]]},"114":{"position":[[22,7]]},"116":{"position":[[59,7]]},"118":{"position":[[34,7]]}}}],["session",{"_index":161,"t":{"19":{"position":[[17,7]]}}}],["set",{"_index":29,"t":{"2":{"position":[[345,3]]},"96":{"position":[[888,7]]}}}],["sever",{"_index":106,"t":{"11":{"position":[[585,7]]},"98":{"position":[[581,9]]}}}],["shall",{"_index":558,"t":{"80":{"position":[[1264,5]]},"90":{"position":[[4,5]]},"96":{"position":[[841,5]]}}}],["share",{"_index":147,"t":{"15":{"position":[[300,7]]},"35":{"position":[[112,6]]},"67":{"position":[[161,5]]}}}],["shepherd",{"_index":493,"t":{"74":{"position":[[104,11]]},"120":{"position":[[91,11]]}}}],["short",{"_index":262,"t":{"33":{"position":[[213,5]]}}}],["shortcom",{"_index":260,"t":{"33":{"position":[[176,13]]}}}],["signific",{"_index":751,"t":{"102":{"position":[[154,11]]}}}],["similar",{"_index":356,"t":{"47":{"position":[[373,7]]},"78":{"position":[[324,7]]}}}],["singl",{"_index":300,"t":{"41":{"position":[[94,6]]}}}],["site",{"_index":437,"t":{"59":{"position":[[86,5]]},"80":{"position":[[607,5]]}}}],["site.thes",{"_index":542,"t":{"80":{"position":[[628,10]]}}}],["sixti",{"_index":687,"t":{"96":{"position":[[1062,5]]}}}],["skill",{"_index":778,"t":{"108":{"position":[[424,6]]}}}],["smart",{"_index":813,"t":{"114":{"position":[[6,5],[96,5],[159,5],[258,5],[487,5]]}}}],["social",{"_index":211,"t":{"25":{"position":[[139,7]]},"39":{"position":[[112,6]]}}}],["softwar",{"_index":266,"t":{"35":{"position":[[4,8]]},"37":{"position":[[43,8]]},"39":{"position":[[48,9]]},"41":{"position":[[10,8]]},"65":{"position":[[282,8]]},"104":{"position":[[161,8]]},"110":{"position":[[113,9]]},"112":{"position":[[669,9],[820,8]]}}}],["sole",{"_index":520,"t":{"80":{"position":[[86,4],[889,4],[917,6]]},"82":{"position":[[1410,4]]},"86":{"position":[[689,6]]}}}],["solicit",{"_index":577,"t":{"80":{"position":[[1710,10]]}}}],["solut",{"_index":797,"t":{"110":{"position":[[535,9]]},"112":{"position":[[829,10]]},"118":{"position":[[72,9]]}}}],["solv",{"_index":314,"t":{"43":{"position":[[192,7]]}}}],["sourc",{"_index":270,"t":{"35":{"position":[[82,6]]}}}],["sovereignti",{"_index":203,"t":{"25":{"position":[[18,11]]}}}],["spam",{"_index":168,"t":{"19":{"position":[[122,4]]},"70":{"position":[[152,4],[194,4]]}}}],["spawn",{"_index":100,"t":{"11":{"position":[[418,8]]}}}],["special",{"_index":635,"t":{"88":{"position":[[193,8]]}}}],["specialis",{"_index":759,"t":{"106":{"position":[[49,12]]},"114":{"position":[[35,11]]},"118":{"position":[[264,11]]}}}],["specif",{"_index":24,"t":{"2":{"position":[[251,15]]},"17":{"position":[[128,8]]},"49":{"position":[[159,8]]},"55":{"position":[[429,8]]},"74":{"position":[[128,14],[236,15]]},"82":{"position":[[1290,9]]},"98":{"position":[[828,8]]},"112":{"position":[[419,15]]},"114":{"position":[[290,8]]},"116":{"position":[[580,8]]},"120":{"position":[[115,14],[194,15]]}}}],["spectrum",{"_index":777,"t":{"108":{"position":[[412,8]]}}}],["stabil",{"_index":793,"t":{"110":{"position":[[397,9]]}}}],["stage",{"_index":608,"t":{"82":{"position":[[1308,6]]}}}],["stand",{"_index":206,"t":{"25":{"position":[[78,6]]}}}],["standard",{"_index":821,"t":{"114":{"position":[[575,9]]}}}],["standardis",{"_index":500,"t":{"74":{"position":[[301,12]]},"120":{"position":[[259,12]]}}}],["startup",{"_index":11,"t":{"2":{"position":[[101,8]]}}}],["state",{"_index":234,"t":{"29":{"position":[[63,5]]}}}],["statement",{"_index":580,"t":{"82":{"position":[[45,10],[221,11],[251,10],[410,10],[557,10]]}}}],["statu",{"_index":171,"t":{"19":{"position":[[169,6]]},"86":{"position":[[217,6]]}}}],["statut",{"_index":712,"t":{"96":{"position":[[2028,7]]}}}],["stay",{"_index":198,"t":{"23":{"position":[[112,7]]}}}],["stealth",{"_index":60,"t":{"7":{"position":[[171,7]]},"118":{"position":[[612,7]]}}}],["stem",{"_index":741,"t":{"100":{"position":[[53,4]]}}}],["stewardship",{"_index":299,"t":{"41":{"position":[[77,11]]}}}],["still",{"_index":411,"t":{"57":{"position":[[134,5]]}}}],["store",{"_index":363,"t":{"49":{"position":[[342,5],[380,5],[851,6]]}}}],["strategi",{"_index":774,"t":{"108":{"position":[[343,10]]}}}],["strengthen",{"_index":130,"t":{"13":{"position":[[322,11]]}}}],["strict",{"_index":629,"t":{"88":{"position":[[66,6]]}}}],["strive",{"_index":252,"t":{"31":{"position":[[194,6]]},"33":{"position":[[3,6]]}}}],["strong",{"_index":238,"t":{"29":{"position":[[153,6]]}}}],["stronger",{"_index":228,"t":{"27":{"position":[[153,9]]}}}],["stylist",{"_index":190,"t":{"21":{"position":[[92,9]]}}}],["subject",{"_index":588,"t":{"82":{"position":[[487,7],[572,7],[1318,7]]},"84":{"position":[[259,7]]}}}],["submit",{"_index":384,"t":{"53":{"position":[[179,6]]},"55":{"position":[[73,9]]}}}],["subsect",{"_index":731,"t":{"98":{"position":[[302,11]]}}}],["substitut",{"_index":634,"t":{"88":{"position":[[165,10]]}}}],["such",{"_index":91,"t":{"11":{"position":[[248,4]]},"49":{"position":[[572,4],[722,4]]},"51":{"position":[[232,4]]},"53":{"position":[[186,4]]},"55":{"position":[[421,4],[477,4]]},"57":{"position":[[764,4]]},"80":{"position":[[584,4],[1622,5]]},"82":{"position":[[432,4]]},"84":{"position":[[291,4]]},"86":{"position":[[190,4],[281,4],[347,4],[456,4],[607,4],[731,4]]},"88":{"position":[[442,4],[498,4]]},"96":{"position":[[823,4],[1136,4]]},"104":{"position":[[181,4]]},"116":{"position":[[434,4]]},"118":{"position":[[285,4]]}}}],["suggest",{"_index":772,"t":{"108":{"position":[[318,10]]},"116":{"position":[[298,8]]}}}],["suitabl",{"_index":541,"t":{"80":{"position":[[463,11]]}}}],["summari",{"_index":600,"t":{"82":{"position":[[837,7]]}}}],["supersed",{"_index":723,"t":{"98":{"position":[[99,9]]}}}],["supplement",{"_index":610,"t":{"82":{"position":[[1358,12]]}}}],["support",{"_index":8,"t":{"2":{"position":[[81,7]]},"86":{"position":[[272,8]]},"100":{"position":[[186,7]]},"104":{"position":[[47,10]]},"112":{"position":[[36,10]]},"116":{"position":[[503,7]]}}}],["surveil",{"_index":222,"t":{"27":{"position":[[60,13]]}}}],["swiss",{"_index":654,"t":{"94":{"position":[[0,5]]},"96":{"position":[[1247,5],[1310,5],[1957,5]]}}}],["switzerland",{"_index":353,"t":{"47":{"position":[[317,11]]},"55":{"position":[[179,12],[330,11],[543,11],[645,11]]},"78":{"position":[[258,11]]},"96":{"position":[[1532,12]]}}}],["symmetri",{"_index":256,"t":{"33":{"position":[[36,8]]}}}],["sync",{"_index":183,"t":{"19":{"position":[[381,4]]}}}],["system",{"_index":419,"t":{"57":{"position":[[426,8]]},"108":{"position":[[484,7]]},"110":{"position":[[16,7],[97,7],[464,7]]},"112":{"position":[[267,8]]}}}],["system(",{"_index":286,"t":{"37":{"position":[[230,9]]}}}],["tailor",{"_index":817,"t":{"114":{"position":[[274,8]]}}}],["take",{"_index":378,"t":{"53":{"position":[[26,4]]},"65":{"position":[[3,4]]},"74":{"position":[[72,6]]},"120":{"position":[[59,6]]}}}],["tax",{"_index":569,"t":{"80":{"position":[[1572,4]]}}}],["team",{"_index":88,"t":{"11":{"position":[[207,4]]},"13":{"position":[[123,4]]},"15":{"position":[[84,4]]},"41":{"position":[[130,4]]},"108":{"position":[[166,5],[383,4]]}}}],["technic",{"_index":7,"t":{"2":{"position":[[71,9]]},"49":{"position":[[754,9]]},"82":{"position":[[303,9],[639,9]]},"104":{"position":[[123,9]]}}}],["techniqu",{"_index":836,"t":{"118":{"position":[[239,11]]}}}],["technolog",{"_index":127,"t":{"13":{"position":[[260,13]]},"29":{"position":[[80,13],[132,12]]},"65":{"position":[[67,10]]},"74":{"position":[[533,12]]},"82":{"position":[[156,11]]},"106":{"position":[[84,13],[390,13]]},"118":{"position":[[409,13]]},"120":{"position":[[497,12]]}}}],["term",{"_index":263,"t":{"33":{"position":[[219,4],[257,4]]},"43":{"position":[[272,5]]},"76":{"position":[[58,5],[81,5],[293,5],[439,5],[492,5]]},"78":{"position":[[34,5]]},"84":{"position":[[328,5]]},"86":{"position":[[82,5]]},"88":{"position":[[308,5]]},"90":{"position":[[271,5]]},"92":{"position":[[50,5],[186,5]]},"94":{"position":[[32,5]]},"96":{"position":[[9,6],[167,5]]},"98":{"position":[[14,5],[331,5],[473,5],[516,5],[610,5],[732,5],[867,5]]}}}],["test",{"_index":783,"t":{"110":{"position":[[24,7],[105,7],[285,8],[472,7]]},"112":{"position":[[115,4],[178,5],[205,5],[371,7],[698,7]]}}}],["theoret",{"_index":782,"t":{"108":{"position":[[495,11]]}}}],["theori",{"_index":86,"t":{"11":{"position":[[182,6]]},"88":{"position":[[112,6]]}}}],["therefor",{"_index":440,"t":{"59":{"position":[[143,9]]}}}],["therein",{"_index":624,"t":{"86":{"position":[[318,8],[385,7]]}}}],["thing",{"_index":592,"t":{"82":{"position":[[612,7]]}}}],["third",{"_index":373,"t":{"51":{"position":[[60,5],[237,5]]},"59":{"position":[[46,5],[74,5],[229,5]]},"86":{"position":[[50,5],[157,5],[195,5],[286,5],[352,5],[461,5],[542,5],[612,5],[736,5]]}}}],["thoren",{"_index":177,"t":{"19":{"position":[[259,6],[326,7],[439,6]]}}}],["thorough",{"_index":790,"t":{"110":{"position":[[265,8]]},"114":{"position":[[429,8]]}}}],["those",{"_index":621,"t":{"86":{"position":[[151,5]]}}}],["thought",{"_index":477,"t":{"67":{"position":[[172,8]]}}}],["thread",{"_index":39,"t":{"5":{"position":[[55,6]]}}}],["through",{"_index":552,"t":{"80":{"position":[[1018,7]]},"82":{"position":[[462,7],[1174,7]]},"86":{"position":[[572,7],[633,7]]},"96":{"position":[[1204,7]]},"112":{"position":[[60,7],[679,7]]}}}],["throughout",{"_index":510,"t":{"74":{"position":[[546,10]]},"120":{"position":[[510,10]]}}}],["time",{"_index":320,"t":{"43":{"position":[[290,5]]},"49":{"position":[[413,4],[869,5]]},"61":{"position":[[64,4]]},"82":{"position":[[1378,5]]},"92":{"position":[[70,4]]},"96":{"position":[[1359,4],[2123,4]]}}}],["timelin",{"_index":597,"t":{"82":{"position":[[755,9],[1273,8]]}}}],["tke",{"_index":767,"t":{"108":{"position":[[225,3]]}}}],["tke'",{"_index":765,"t":{"108":{"position":[[129,5],[363,5]]}}}],["togeth",{"_index":775,"t":{"108":{"position":[[395,8]]}}}],["token",{"_index":308,"t":{"43":{"position":[[102,5]]},"80":{"position":[[1750,6]]},"82":{"position":[[376,6]]},"108":{"position":[[8,5],[87,5]]}}}],["tool",{"_index":824,"t":{"116":{"position":[[122,7],[208,5]]}}}],["total",{"_index":254,"t":{"31":{"position":[[225,5]]}}}],["touch",{"_index":35,"t":{"5":{"position":[[7,5]]}}}],["tradeoff",{"_index":264,"t":{"33":{"position":[[224,9]]}}}],["train",{"_index":160,"t":{"19":{"position":[[8,8]]}}}],["transact",{"_index":247,"t":{"31":{"position":[[134,13]]}}}],["transfer",{"_index":421,"t":{"57":{"position":[[494,11]]}}}],["translat",{"_index":103,"t":{"11":{"position":[[481,9]]}}}],["transmiss",{"_index":404,"t":{"55":{"position":[[584,12]]}}}],["treat",{"_index":571,"t":{"80":{"position":[[1611,7]]}}}],["trial",{"_index":675,"t":{"96":{"position":[[620,5]]}}}],["tribun",{"_index":703,"t":{"96":{"position":[[1627,8]]}}}],["true",{"_index":199,"t":{"23":{"position":[[120,4]]}}}],["trustworthi",{"_index":839,"t":{"118":{"position":[[463,15]]}}}],["unabl",{"_index":685,"t":{"96":{"position":[[1016,6]]}}}],["uncertainti",{"_index":591,"t":{"82":{"position":[[524,12],[1051,11]]}}}],["under",{"_index":221,"t":{"27":{"position":[[54,5]]},"49":{"position":[[220,5]]},"63":{"position":[[138,5]]},"84":{"position":[[48,5]]},"88":{"position":[[34,5]]},"98":{"position":[[951,5]]}}}],["understand",{"_index":726,"t":{"98":{"position":[[139,15]]},"110":{"position":[[176,13]]}}}],["undu",{"_index":605,"t":{"82":{"position":[[1101,5]]}}}],["unenforc",{"_index":736,"t":{"98":{"position":[[548,14]]}}}],["union",{"_index":391,"t":{"55":{"position":[[170,5],[635,5]]}}}],["unit",{"_index":15,"t":{"2":{"position":[[136,6]]},"11":{"position":[[264,6]]},"74":{"position":[[12,4],[264,4]]},"100":{"position":[[250,5]]},"104":{"position":[[18,5]]},"106":{"position":[[20,4],[106,4],[255,4],[412,4]]},"108":{"position":[[24,4]]},"110":{"position":[[50,4],[302,4]]},"112":{"position":[[15,4],[173,4],[283,4],[754,4]]},"114":{"position":[[30,4],[137,4]]},"116":{"position":[[67,4],[185,4],[370,4],[474,4]]},"118":{"position":[[42,4],[259,4]]},"120":{"position":[[12,4],[222,4]]}}}],["unit'",{"_index":794,"t":{"110":{"position":[[432,6]]},"114":{"position":[[422,6]]},"120":{"position":[[333,6]]}}}],["unlawfulli",{"_index":434,"t":{"57":{"position":[[1029,11]]}}}],["unlik",{"_index":385,"t":{"55":{"position":[[90,8]]}}}],["up",{"_index":471,"t":{"67":{"position":[[29,2]]},"72":{"position":[[10,4]]},"114":{"position":[[365,2]]},"116":{"position":[[350,2]]}}}],["updat",{"_index":323,"t":{"45":{"position":[[18,8]]},"57":{"position":[[326,6]]},"76":{"position":[[18,8]]},"82":{"position":[[1212,6]]}}}],["upon",{"_index":449,"t":{"61":{"position":[[197,4]]},"80":{"position":[[1308,4]]},"92":{"position":[[229,4]]}}}],["us",{"_index":175,"t":{"19":{"position":[[242,5]]},"29":{"position":[[59,3]]},"39":{"position":[[86,4]]},"49":{"position":[[529,3],[577,3]]},"51":{"position":[[145,3]]},"55":{"position":[[389,3]]},"76":{"position":[[67,3],[90,5],[160,3],[302,3],[328,3],[356,3],[448,4],[501,4],[529,3]]},"78":{"position":[[43,4]]},"80":{"position":[[58,3],[498,3],[855,3]]},"82":{"position":[[369,3]]},"84":{"position":[[254,4]]},"86":{"position":[[144,3],[409,6],[514,3]]},"88":{"position":[[317,4],[371,3]]},"90":{"position":[[162,3],[280,4]]},"92":{"position":[[59,3],[195,3]]},"94":{"position":[[41,3]]},"96":{"position":[[176,4],[230,3],[713,3]]},"98":{"position":[[23,3],[340,3],[482,4],[525,3],[619,4],[741,4],[876,4]]},"116":{"position":[[25,3],[541,3]]}}}],["user",{"_index":329,"t":{"45":{"position":[[85,5]]},"49":{"position":[[83,5]]},"84":{"position":[[153,5]]}}}],["util",{"_index":540,"t":{"80":{"position":[[441,8]]}}}],["v2",{"_index":159,"t":{"19":{"position":[[5,2],[76,2],[278,2]]}}}],["vac",{"_index":0,"t":{"2":{"position":[[0,3],[110,3]]},"7":{"position":[[128,3]]},"9":{"position":[[0,3]]},"11":{"position":[[0,3],[256,3],[460,3]]},"13":{"position":[[21,3],[304,3]]},"15":{"position":[[26,3],[253,3]]},"17":{"position":[[0,3]]},"19":{"position":[[66,4],[268,4]]},"23":{"position":[[12,3]]},"65":{"position":[[30,3]]},"67":{"position":[[9,3],[211,3]]},"74":{"position":[[4,3],[166,3],[256,3]]},"100":{"position":[[0,3],[263,4],[306,4]]},"106":{"position":[[44,4],[286,3]]},"108":{"position":[[4,3]]},"120":{"position":[[4,3],[214,3]]}}}],["vac'",{"_index":742,"t":{"100":{"position":[[63,5]]},"104":{"position":[[0,5]]},"114":{"position":[[0,5]]}}}],["valid",{"_index":114,"t":{"11":{"position":[[692,9]]},"57":{"position":[[752,8]]}}}],["valu",{"_index":33,"t":{"2":{"position":[[405,6]]}}}],["valuabl",{"_index":834,"t":{"118":{"position":[[127,8]]}}}],["vari",{"_index":598,"t":{"82":{"position":[[771,4]]}}}],["varieti",{"_index":381,"t":{"53":{"position":[[81,7]]}}}],["variou",{"_index":55,"t":{"7":{"position":[[120,7]]},"11":{"position":[[230,7]]}}}],["verif",{"_index":805,"t":{"112":{"position":[[316,12]]}}}],["via",{"_index":269,"t":{"35":{"position":[[62,3]]},"65":{"position":[[135,3]]},"96":{"position":[[1566,3]]}}}],["video",{"_index":700,"t":{"96":{"position":[[1570,5]]}}}],["violat",{"_index":535,"t":{"80":{"position":[[325,9]]},"90":{"position":[[244,9]]}}}],["virtual",{"_index":749,"t":{"102":{"position":[[84,7]]}}}],["virtual/onlin",{"_index":702,"t":{"96":{"position":[[1587,14]]}}}],["visit",{"_index":334,"t":{"45":{"position":[[185,8]]}}}],["vital",{"_index":491,"t":{"74":{"position":[[29,5]]},"106":{"position":[[30,5]]},"120":{"position":[[29,5]]}}}],["vulner",{"_index":464,"t":{"65":{"position":[[194,15]]},"114":{"position":[[537,16]]}}}],["waiv",{"_index":668,"t":{"96":{"position":[[453,6],[588,5],[2192,5]]},"98":{"position":[[778,6]]}}}],["waku",{"_index":158,"t":{"19":{"position":[[0,4],[25,5],[71,4],[248,4],[273,4],[350,4]]},"70":{"position":[[0,5],[95,4]]}}}],["warrant",{"_index":536,"t":{"80":{"position":[[356,7]]}}}],["warranti",{"_index":524,"t":{"80":{"position":[[128,10],[205,10],[1343,8]]},"98":{"position":[[187,11]]}}}],["way",{"_index":137,"t":{"15":{"position":[[98,4]]},"43":{"position":[[231,3]]},"49":{"position":[[646,3]]},"88":{"position":[[275,3]]}}}],["web",{"_index":194,"t":{"23":{"position":[[60,4]]},"118":{"position":[[572,3]]}}}],["websit",{"_index":332,"t":{"45":{"position":[[137,7],[145,12],[198,8]]},"49":{"position":[[96,8],[540,8],[588,7],[819,8]]},"51":{"position":[[130,7]]},"53":{"position":[[117,7]]},"59":{"position":[[8,8],[58,9],[241,9]]},"61":{"position":[[106,7],[221,8]]},"76":{"position":[[50,7],[71,9],[172,8],[238,8],[285,7],[339,7],[367,7],[431,7],[484,7],[537,8]]},"78":{"position":[[26,7]]},"80":{"position":[[4,7],[66,7],[509,8],[538,7],[575,8],[740,7],[866,7],[1031,7],[1644,7]]},"82":{"position":[[4,7],[475,7],[1149,7],[1187,8],[1223,7]]},"84":{"position":[[4,7],[381,8]]},"86":{"position":[[18,7],[62,8],[169,9],[207,9],[298,8],[364,8],[473,8],[554,8],[584,8],[624,8],[645,8],[748,9]]},"88":{"position":[[300,7],[326,8],[354,8],[382,8]]},"90":{"position":[[173,8],[201,8],[263,7]]},"92":{"position":[[42,7],[132,7],[178,7],[253,8]]},"94":{"position":[[24,7]]},"96":{"position":[[159,7],[185,8],[213,8],[241,8]]},"98":{"position":[[6,7],[87,7],[242,8],[323,7],[465,7],[508,7],[602,7],[724,7],[859,7]]}}}],["well",{"_index":248,"t":{"31":{"position":[[151,4]]},"96":{"position":[[1691,4]]}}}],["what’",{"_index":599,"t":{"82":{"position":[[781,6]]}}}],["whenev",{"_index":354,"t":{"47":{"position":[[329,8]]},"78":{"position":[[270,8]]}}}],["wherev",{"_index":409,"t":{"57":{"position":[[98,8]]}}}],["whether",{"_index":561,"t":{"80":{"position":[[1366,7],[1397,7]]},"94":{"position":[[82,7]]}}}],["whisper",{"_index":180,"t":{"19":{"position":[[339,7],[405,7]]}}}],["widespread",{"_index":192,"t":{"23":{"position":[[19,10]]},"39":{"position":[[23,10]]}}}],["withdraw",{"_index":423,"t":{"57":{"position":[[550,8]]}}}],["withdrawn",{"_index":428,"t":{"57":{"position":[[807,9]]}}}],["within",{"_index":77,"t":{"11":{"position":[[81,6],[543,6]]},"13":{"position":[[390,6]]},"15":{"position":[[326,6]]},"33":{"position":[[60,6]]},"43":{"position":[[156,6]]},"74":{"position":[[342,6]]},"96":{"position":[[1055,6],[2078,6]]},"100":{"position":[[256,6],[299,6]]},"106":{"position":[[544,6]]},"110":{"position":[[227,6]]},"120":{"position":[[300,6]]}}}],["without",{"_index":298,"t":{"41":{"position":[[65,7]]},"61":{"position":[[73,7]]},"80":{"position":[[182,7]]},"82":{"position":[[1384,7]]},"90":{"position":[[220,7]]},"92":{"position":[[79,7]]},"94":{"position":[[115,7]]}}}],["withstand",{"_index":798,"t":{"110":{"position":[[554,9]]}}}],["word",{"_index":280,"t":{"37":{"position":[[90,6]]}}}],["work",{"_index":78,"t":{"11":{"position":[[103,4]]},"106":{"position":[[132,5]]},"116":{"position":[[190,5]]}}}],["world",{"_index":244,"t":{"31":{"position":[[58,6]]},"110":{"position":[[584,5]]}}}],["worldwid",{"_index":67,"t":{"9":{"position":[[35,11],[93,11],[150,11]]}}}],["write",{"_index":488,"t":{"72":{"position":[[4,5]]}}}],["written",{"_index":680,"t":{"96":{"position":[[862,7]]},"98":{"position":[[204,7]]}}}],["x",{"_index":476,"t":{"67":{"position":[[129,1]]}}}],["year",{"_index":713,"t":{"96":{"position":[[2089,4]]}}}],["zero",{"_index":68,"t":{"9":{"position":[[47,4],[105,4]]},"11":{"position":[[614,4]]},"13":{"position":[[159,4]]},"102":{"position":[[69,4]]},"118":{"position":[[86,4]]}}}],["zerokit",{"_index":59,"t":{"7":{"position":[[163,7]]},"104":{"position":[[204,8]]},"118":{"position":[[600,7]]}}}],["zk",{"_index":109,"t":{"11":{"position":[[629,5]]},"13":{"position":[[300,3]]},"118":{"position":[[27,2],[101,4],[198,2]]}}}],["zkp",{"_index":118,"t":{"13":{"position":[[16,4]]},"19":{"position":[[113,4]]}}}],["zkpodcast",{"_index":167,"t":{"19":{"position":[[102,10]]}}}],["zug",{"_index":343,"t":{"47":{"position":[[200,3],[313,3]]},"78":{"position":[[140,3],[254,3]]},"96":{"position":[[1527,4]]}}}]],"pipeline":["stemmer"]}}] \ No newline at end of file diff --git a/security/index.html b/security/index.html index 9df7bc3b..94a2818e 100644 --- a/security/index.html +++ b/security/index.html @@ -10,8 +10,8 @@ - - + +
    @@ -20,7 +20,7 @@ ) .lsd-dropdown__trigger:hover .lsd-dropdown__option-label,.lsd-dropdown:not(.lsd-dropdown--disabled):not( .lsd-dropdown--error ) .lsd-dropdown__trigger:focus .lsd-dropdown__option-label{-webkit-text-decoration:underline;text-decoration:underline;}.lsd-dropdown__label{display:block;}.lsd-dropdown__button-container{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-box-pack:justify;-webkit-justify-content:space-between;justify-content:space-between;}.lsd-dropdown__trigger{width:100%;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:row;-ms-flex-direction:row;flex-direction:row;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:justify;-webkit-justify-content:space-between;justify-content:space-between;border:none;cursor:pointer;background:none;}.lsd-dropdown__trigger:focus{outline:none;}.lsd-dropdown__option-label{cursor:inherit;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;}.lsd-dropdown__icons{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:row;-ms-flex-direction:row;flex-direction:row;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:center;-ms-flex-pack:center;-webkit-justify-content:center;justify-content:center;gap:8px;}.lsd-dropdown__icon{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;}.lsd-dropdown__supporting-text{margin:6px 14px;}.lsd-dropdown--error .lsd-dropdown__option-label{-webkit-text-decoration:line-through;text-decoration:line-through;}.lsd-dropdown--disabled{opacity:0.34;cursor:initial;}.lsd-dropdown--large{width:208px;}.lsd-dropdown--large.lsd-dropdown--error{width:230px;}.lsd-dropdown--large .lsd-dropdown__label{margin:0 0 6px 18px;}.lsd-dropdown--large .lsd-dropdown__button-container{height:40px;}.lsd-dropdown--large .lsd-dropdown__trigger{padding:10px 0px 10px 18px;}.lsd-dropdown--large .lsd-dropdown__icons{padding:0px 14px;}.lsd-dropdown--medium{width:188px;}.lsd-dropdown--medium.lsd-dropdown--error{width:210px;}.lsd-dropdown--medium .lsd-dropdown__label{margin:0 0 6px 14px;}.lsd-dropdown--medium .lsd-dropdown__button-container{height:32px;}.lsd-dropdown--medium .lsd-dropdown__trigger{padding:6px 0px 6px 14px;}.lsd-dropdown--medium .lsd-dropdown__icons{padding:0px 12px;}.lsd-dropdown--small{width:164px;}.lsd-dropdown--small.lsd-dropdown--error{width:186px;}.lsd-dropdown--small .lsd-dropdown__label{margin:0 0 6px 12px;}.lsd-dropdown--small .lsd-dropdown__button-container{height:28px;}.lsd-dropdown--small .lsd-dropdown__trigger{padding:6px 0px 6px 12px;}.lsd-dropdown--small .lsd-dropdown__icons{padding:0px 10px;}.lsd-dropdown--outlined .lsd-dropdown__button-container{border:1px solid rgb(var(--lsd-border-primary));}.lsd-dropdown--underlined .lsd-dropdown__button-container{border:1px solid transparent;border-bottom:1px solid rgb(var(--lsd-border-primary));}
    - - + + \ No newline at end of file diff --git a/sitemap.xml b/sitemap.xml index 860175a3..c8095154 100644 --- a/sitemap.xml +++ b/sitemap.xml @@ -1 +1 @@ -https://vac.dev/rlogweekly0.5https://vac.dev/rlog/archiveweekly0.5https://vac.dev/rlog/building-privacy-protecting-infrastructureweekly0.5https://vac.dev/rlog/device-pairing-in-js-waku-and-go-wakuweekly0.5https://vac.dev/rlog/dns-based-discoveryweekly0.5https://vac.dev/rlog/ethics-surveillance-techweekly0.5https://vac.dev/rlog/feasibility-discv5weekly0.5https://vac.dev/rlog/feasibility-semaphore-rate-limiting-zksnarksweekly0.5https://vac.dev/rlog/fixing-whisper-with-wakuweekly0.5https://vac.dev/rlog/future-of-waku-networkweekly0.5https://vac.dev/rlog/GossipSub%20Improvementsweekly0.5https://vac.dev/rlog/introducing-nwakuweekly0.5https://vac.dev/rlog/kademlia-to-discv5weekly0.5https://vac.dev/rlog/membership-with-bloom-filters-and-cuckoo-filtersweekly0.5https://vac.dev/rlog/Nescience-A-zkVM-leveraging-hiding-propertiesweekly0.5https://vac.dev/rlog/Nescience-state-separation-architectureweekly0.5https://vac.dev/rlog/p2p-data-sync-for-mobileweekly0.5https://vac.dev/rlog/page/2weekly0.5https://vac.dev/rlog/page/3weekly0.5https://vac.dev/rlog/page/4weekly0.5https://vac.dev/rlog/presenting-js-wakuweekly0.5https://vac.dev/rlog/remote-logweekly0.5https://vac.dev/rlog/rln-anonymous-dos-preventionweekly0.5https://vac.dev/rlog/rln-light-verifiersweekly0.5https://vac.dev/rlog/rln-relayweekly0.5https://vac.dev/rlog/rln-v3weekly0.5https://vac.dev/rlog/vac-overviewweekly0.5https://vac.dev/rlog/waku-for-allweekly0.5https://vac.dev/rlog/waku-updateweekly0.5https://vac.dev/rlog/waku-v1-v2-bandwidth-comparisonweekly0.5https://vac.dev/rlog/waku-v2-ethereum-coscupweekly0.5https://vac.dev/rlog/waku-v2-ethereum-messagingweekly0.5https://vac.dev/rlog/waku-v2-planweekly0.5https://vac.dev/rlog/waku-v2-updateweekly0.5https://vac.dev/rlog/wakuv2-apdweekly0.5https://vac.dev/rlog/wakuv2-noiseweekly0.5https://vac.dev/rlog/wakuv2-relay-anonweekly0.5https://vac.dev/rlog/wechat-replacement-needweekly0.5https://vac.dev/rlog/zkVM-explorationsweekly0.5https://vac.dev/weekly0.5https://vac.dev/communityweekly0.5https://vac.dev/contributeweekly0.5https://vac.dev/deepresearchweekly0.5https://vac.dev/join-usweekly0.5https://vac.dev/mediaweekly0.5https://vac.dev/principlesweekly0.5https://vac.dev/privacy-policyweekly0.5https://vac.dev/publicationsweekly0.5https://vac.dev/rfcprocessweekly0.5https://vac.dev/securityweekly0.5https://vac.dev/termsweekly0.5https://vac.dev/vipsweekly0.5https://vac.dev/vsusweekly0.5 \ No newline at end of file +https://vac.dev/rlogweekly0.5https://vac.dev/rlog/archiveweekly0.5https://vac.dev/rlog/building-privacy-protecting-infrastructureweekly0.5https://vac.dev/rlog/device-pairing-in-js-waku-and-go-wakuweekly0.5https://vac.dev/rlog/dns-based-discoveryweekly0.5https://vac.dev/rlog/ethics-surveillance-techweekly0.5https://vac.dev/rlog/feasibility-discv5weekly0.5https://vac.dev/rlog/feasibility-semaphore-rate-limiting-zksnarksweekly0.5https://vac.dev/rlog/fixing-whisper-with-wakuweekly0.5https://vac.dev/rlog/future-of-waku-networkweekly0.5https://vac.dev/rlog/GossipSub%20Improvementsweekly0.5https://vac.dev/rlog/introducing-nwakuweekly0.5https://vac.dev/rlog/kademlia-to-discv5weekly0.5https://vac.dev/rlog/membership-with-bloom-filters-and-cuckoo-filtersweekly0.5https://vac.dev/rlog/Nescience-A-zkVM-leveraging-hiding-propertiesweekly0.5https://vac.dev/rlog/Nescience-state-separation-architectureweekly0.5https://vac.dev/rlog/p2p-data-sync-for-mobileweekly0.5https://vac.dev/rlog/page/2weekly0.5https://vac.dev/rlog/page/3weekly0.5https://vac.dev/rlog/page/4weekly0.5https://vac.dev/rlog/presenting-js-wakuweekly0.5https://vac.dev/rlog/remote-logweekly0.5https://vac.dev/rlog/rln-anonymous-dos-preventionweekly0.5https://vac.dev/rlog/rln-light-verifiersweekly0.5https://vac.dev/rlog/rln-relayweekly0.5https://vac.dev/rlog/rln-v3weekly0.5https://vac.dev/rlog/vac-overviewweekly0.5https://vac.dev/rlog/waku-for-allweekly0.5https://vac.dev/rlog/waku-updateweekly0.5https://vac.dev/rlog/waku-v1-v2-bandwidth-comparisonweekly0.5https://vac.dev/rlog/waku-v2-ethereum-coscupweekly0.5https://vac.dev/rlog/waku-v2-ethereum-messagingweekly0.5https://vac.dev/rlog/waku-v2-planweekly0.5https://vac.dev/rlog/waku-v2-updateweekly0.5https://vac.dev/rlog/wakuv2-apdweekly0.5https://vac.dev/rlog/wakuv2-noiseweekly0.5https://vac.dev/rlog/wakuv2-relay-anonweekly0.5https://vac.dev/rlog/wechat-replacement-needweekly0.5https://vac.dev/rlog/zkVM-explorationsweekly0.5https://vac.dev/rlog/zkVM-testingweekly0.5https://vac.dev/weekly0.5https://vac.dev/communityweekly0.5https://vac.dev/contributeweekly0.5https://vac.dev/deepresearchweekly0.5https://vac.dev/join-usweekly0.5https://vac.dev/mediaweekly0.5https://vac.dev/principlesweekly0.5https://vac.dev/privacy-policyweekly0.5https://vac.dev/publicationsweekly0.5https://vac.dev/rfcprocessweekly0.5https://vac.dev/securityweekly0.5https://vac.dev/termsweekly0.5https://vac.dev/vipsweekly0.5https://vac.dev/vsusweekly0.5 \ No newline at end of file diff --git a/terms/index.html b/terms/index.html index ac1a10d5..f8ca031d 100644 --- a/terms/index.html +++ b/terms/index.html @@ -10,8 +10,8 @@ - - + +
    @@ -20,7 +20,7 @@ ) .lsd-dropdown__trigger:hover .lsd-dropdown__option-label,.lsd-dropdown:not(.lsd-dropdown--disabled):not( .lsd-dropdown--error ) .lsd-dropdown__trigger:focus .lsd-dropdown__option-label{-webkit-text-decoration:underline;text-decoration:underline;}.lsd-dropdown__label{display:block;}.lsd-dropdown__button-container{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-box-pack:justify;-webkit-justify-content:space-between;justify-content:space-between;}.lsd-dropdown__trigger{width:100%;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:row;-ms-flex-direction:row;flex-direction:row;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:justify;-webkit-justify-content:space-between;justify-content:space-between;border:none;cursor:pointer;background:none;}.lsd-dropdown__trigger:focus{outline:none;}.lsd-dropdown__option-label{cursor:inherit;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;}.lsd-dropdown__icons{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:row;-ms-flex-direction:row;flex-direction:row;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:center;-ms-flex-pack:center;-webkit-justify-content:center;justify-content:center;gap:8px;}.lsd-dropdown__icon{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;}.lsd-dropdown__supporting-text{margin:6px 14px;}.lsd-dropdown--error .lsd-dropdown__option-label{-webkit-text-decoration:line-through;text-decoration:line-through;}.lsd-dropdown--disabled{opacity:0.34;cursor:initial;}.lsd-dropdown--large{width:208px;}.lsd-dropdown--large.lsd-dropdown--error{width:230px;}.lsd-dropdown--large .lsd-dropdown__label{margin:0 0 6px 18px;}.lsd-dropdown--large .lsd-dropdown__button-container{height:40px;}.lsd-dropdown--large .lsd-dropdown__trigger{padding:10px 0px 10px 18px;}.lsd-dropdown--large .lsd-dropdown__icons{padding:0px 14px;}.lsd-dropdown--medium{width:188px;}.lsd-dropdown--medium.lsd-dropdown--error{width:210px;}.lsd-dropdown--medium .lsd-dropdown__label{margin:0 0 6px 14px;}.lsd-dropdown--medium .lsd-dropdown__button-container{height:32px;}.lsd-dropdown--medium .lsd-dropdown__trigger{padding:6px 0px 6px 14px;}.lsd-dropdown--medium .lsd-dropdown__icons{padding:0px 12px;}.lsd-dropdown--small{width:164px;}.lsd-dropdown--small.lsd-dropdown--error{width:186px;}.lsd-dropdown--small .lsd-dropdown__label{margin:0 0 6px 12px;}.lsd-dropdown--small .lsd-dropdown__button-container{height:28px;}.lsd-dropdown--small .lsd-dropdown__trigger{padding:6px 0px 6px 12px;}.lsd-dropdown--small .lsd-dropdown__icons{padding:0px 10px;}.lsd-dropdown--outlined .lsd-dropdown__button-container{border:1px solid rgb(var(--lsd-border-primary));}.lsd-dropdown--underlined .lsd-dropdown__button-container{border:1px solid transparent;border-bottom:1px solid rgb(var(--lsd-border-primary));}

    Terms of Use

    Last updated: 14 February 2024

    These website terms of use ('Website Terms of Use') are entered into by you and us, and they govern your access and use of this Website, including any content and functionality contained in the Website.

    It is your responsibility to read the Website Terms of Use carefully before your use of the Website and your use of the Website means you have agreed to be bound and comply with these Website Terms of Use.

    If you do not agree with these Website Terms of Use, you must not access or use the Website.

    1) Who we are

    For the purposes of these Website Terms of Use, the relevant entity is the Logos Collective Association, which has its registered office in Zug and its legal domicile address at:

    Logos Collective Association
    c/o PST Consulting GmbH
    Baarerstrasse 10
    6300 Zug
    Switzerland

    Whenever we refer to “Logos”, “we”, “us” or any other similar references, we are referring to the Logos Collective Association.

    2) Disclaimers

    The Website is provided by us on an ‘as is’ basis and you use the Website at your own sole discretion and risk.

    We disclaim all warranties of any kind, express or implied, including without limitation the warranties of merchantability, fitness for a particular purpose, and non-infringement of intellectual property or other violation of rights. We do not warrant or make any representations concerning the completeness, accuracy, legality, utility, reliability, suitability or availability of the use of the Website, the content on this Website or otherwise relating to the Website, such content or on any sites linked to this site.These disclaimers will apply to the maximum extent permitted by applicable law.

    We make no claims that the Website or any of its content is accessible, legally compliant or appropriate in your jurisdiction. Your access or use of the Website is at your own sole discretion and you are solely responsible for complying with any applicable local laws.

    The content herein or as accessible through this website is intended to be made available for informational purposes only and should not be considered as creating any expectations or forming the basis of any contract, commitment or binding obligation with us. No information herein shall be considered to contain or be relied upon as a promise, representation, warranty or guarantee, whether express or implied and whether as to the past, present or the future in relation to the projects and matters described herein.

    The information contained herein does not constitute financial, legal, tax, or other advice and should not be treated as such.

    Nothing in this Website should be construed by you as an offer to buy or sell, or soliciting any offer to buy or sell any tokens or any security.

    3) Forward looking statements

    The Website may also contain forward-looking statements that are based on current expectations, estimates, forecasts, assumptions and projections about the technology, industry and markets in general.

    The forward looking statements, which may include statements about the roadmap, project descriptions, technical details, functionalities, features, the development and use of tokens by projects, and any other statements related to such matters or as accessible through this website are subject to a high degree of risk and uncertainty. The forward looking statements are subject to change based on, among other things, market conditions, technical developments, and regulatory environment. The actual development and results, including the order and the timeline, might vary from what’s presented. The information contained herein is a summary and does not purport to be accurate, reliable or complete and we bear no responsibility for the accuracy, reliability or completeness of information contained herein. Because of the high degree of risk and uncertainty described above, you should not place undue reliance on any matters described in this website or as accessible through this website.

    While we aim to update our website regularly, all information, including the timeline and the specifics of each stage, is subject to change and may be amended or supplemented at any time, without notice and at our sole discretion.

    4) Intellectual property rights

    The Website and its contents are made available under Creative Commons Attribution 4.0 International license (CC-BY 4.0). In essence this licence allows users to copy, modify and distribute the content in any format for any purpose, including commercial use, subject to certain requirements such as attributing us. For the full terms of this licence, please refer to the following website: https://creativecommons.org/licenses/by/4.0/.

    To the extent the Website provides any links to a third party website, then their terms and conditions, including privacy policies, govern your use of those third party websites. By linking such third party websites, Status does not represent or imply that it endorses or supports such third party websites or content therein, or that it believes such third party websites and content therein to be accurate, useful or non-harmful. We have no control over such third party websites and will not be liable for your use of or activities on any third party websites accessed through the Website. If you access such third party websites through the Website, it is at your own risk and you are solely responsible for your activities on such third party websites.

    6) Limitation of liability

    We will not be held liable to you under any contract, negligence, strict liability, or other legal or equitable theory for any lost profits, cost of procurement for substitute services, or any special, incidental, or consequential damages related to, arising from, or in any way connected with these Website Terms of Use, the Website, the content on the Website, or your use of the Website, even if we have been advised of the possibility of such damages. In any event, our aggregate liability for such claims is limited to EUR 100 (one hundred Euros). This limitation of liability will apply to the maximum extent permitted by applicable law.

    7) Indemnity

    You shall indemnify us and hold us harmless from and against any and all claims, damages and expenses, including attorneys’ fees, arising from or related to your use of the Website, the content on the Website, including without limitation your violation of these Website Terms of Use.

    8) Modifications

    We may modify or replace any part of this Website Terms of Use at any time and without notice. You are responsible for checking the Website periodically for any changes. The new Website Terms of Use will be effective immediately upon its posting on the Website.

    9) Governing law

    Swiss law governs these Website Terms of Use and any disputes between you and us, whether in court or arbitration, without regard to conflict of laws provisions.

    10) Disputes

    In these terms, “dispute” has the broadest meaning enforceable by law and includes any claim you make against or controversy you may have in relation to these Website Terms of Use, the Website, the content on the Website, or your use of the Website.

    We prefer arbitration over litigation as we believe it meets our principle of resolving disputes in the most effective and cost effective manner. You are bound by the following arbitration clause, which waives your right to litigation and to be heard by a judge. Please note that court review of an arbitration award is limited. You also waive all your rights to a jury trial (if any) in any and all jurisdictions.

    If a (potential) dispute arises, you must first use your reasonable efforts to resolve it amicably with us. If these efforts do not result in a resolution of such dispute, you shall then send us a written notice of dispute setting out (i) the nature of the dispute, and the claim you are making; and (ii) the remedy you are seeking.

    If we and you are unable to further resolve this dispute within sixty (60) calendar days of us receiving this notice of dispute, then any such dispute will be referred to and finally resolved by you and us through an arbitration administered by the Swiss Chambers’ Arbitration Institution in accordance with the Swiss Rules of International Arbitration for the time being in force, which rules are deemed to be incorporated herein by reference. The arbitral decision may be enforced in any court. The arbitration will be held in Zug, Switzerland, and may be conducted via video conference virtual/online methods if possible. The tribunal will consist of one arbitrator, and all proceedings as well as communications between the parties will be kept confidential. The language of the arbitration will be in English. Payment of all relevant fees in respect of the arbitration, including filing, administration and arbitrator fees will be in accordance with the Swiss Rules of International Arbitration.

    Regardless of any applicable statute of limitations, you must bring any claims within one year after the claim arose or the time when you should have reasonably known about the claim. You also waive the right to participate in a class action lawsuit or a classwide arbitration against us.

    11) About these Website Terms of Use

    These Website Terms of Use cover the entire agreement between you and us regarding the Website and supersede all prior and contemporaneous understandings, agreements, representations and warranties, both written and oral, with respect to the Website.

    The captions and headings identifying sections and subsections of these Website Terms of Use are for reference only and do not define, modify, expand, limit, or affect the interpretation of any provisions of these Website Terms of Use.

    If any part of these Website Terms of Use is held invalid or unenforceable, that part will be severable from these Website Terms of Use, and the remaining portions will remain in full force and effect. If we fail to enforce any of these Website Terms of Use, that does not mean that we have waived our right to enforce them.

    If you have any specific questions about these Website Terms of Use, please contact us at legal@free.technology.

    This document is licensed under CC-BY-SA.

    - - + + \ No newline at end of file diff --git a/vips/index.html b/vips/index.html index 824523a1..37c9e6db 100644 --- a/vips/index.html +++ b/vips/index.html @@ -10,8 +10,8 @@ - - + +
    @@ -23,7 +23,7 @@ These projects are envisioned to eventually become separate IFT projects, benefiting from the support and resources of both the Deep Research and R&D Service Units within Vac. The incubator projects operate within Vac, leveraging the expertise and collaboration available to them.

    Nescience

    Nescience focuses on developing a privacy-preserving general-purpose zero-knowledge virtual machine. It enables privacy-preserving computing, which holds significant importance for IFT programs, especially Logos.

    - - + + \ No newline at end of file diff --git a/vsus/index.html b/vsus/index.html index 40b627b8..8e473fe7 100644 --- a/vsus/index.html +++ b/vsus/index.html @@ -10,8 +10,8 @@ - - + +
    @@ -63,7 +63,7 @@ the Vac RFC unit acts as a linchpin for ensuring standardised and interoperable The RFC unit's expertise and attention to detail contribute to a cohesive and collaborative environment, facilitating seamless integration and advancement of decentralised technologies throughout the IFT and beyond.

    - - + + \ No newline at end of file diff --git a/zkVM-testing/index.html b/zkVM-testing/index.html new file mode 100644 index 00000000..e0c4bbd0 --- /dev/null +++ b/zkVM-testing/index.html @@ -0,0 +1,11 @@ + + + + + + + + + \ No newline at end of file