commit b903eb32cfc84c7ff668a826462ced02a18f7b0b Author: Anael Date: Sun Nov 8 15:17:21 2026 +0100 first commit diff --git a/404.html b/404.html new file mode 100644 index 0000000..7e00068 --- /dev/null +++ b/404.html @@ -0,0 +1,40 @@ + + + +
+ +

+ 404 +

+
+

This page could not be found.

+
+
+ + diff --git a/a-propos/index.html b/a-propos/index.html new file mode 100644 index 0000000..6f2ff58 --- /dev/null +++ b/a-propos/index.html @@ -0,0 +1,574 @@ + + + + + + + + + + +À Propos – MeshEro + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Skip to content
+
+ + +
+ +
+ + + + + +
+
+ + +
+

À Propos

+
+
+ +

Contactez moi +

    +
  • email : hello [@] meshero.fr
  • +
  • xmpp : à venir
  • +
+

Mentions Légales +

Ce site web est hebergé chez OVH. +SAS au capital de 10 069 020 € - RCS Lille Métropole 424 761 419 00045 +Siège social : 2 rue Kellermann - 59100 Roubaix - France +Code APE 2620Z N° TVA : FR 22 424 761 419 +Président : Henryk KLABA +Directeur général : Miroslaw KLABA +Directeur de la publication : Octave KLABA +Directeur général délégué : Octave KLABA +Directeur général délégué : Halina KLABA +Pour contacter OVH : https://www.ovh.com/fr/support/

+

Cookies +

Qu’est-ce que les cookies ? +Les cookies sont des petits fichiers texte qui sont déposés ou lus sur votre terminal (ordinateur, tablette, smartphone, etc…) lorsque vous naviguez sur un site internet.

+

Quels Cookies sont utilisés par meshero.fr ? +Le site meshero.fr utilise 1 cookie technique. Ce cookies est lié à mon hebergeur pour la répartition de charge (son petit nom : SERVERID17573). Il s’agit d’un cookies edité par OVH (voir les mentions légales). Ce cookie n’est pas désactivable. Ce cookie s’auto-detruit lorsque vous fermez votre navigateur.

+

Lorsque vous visitez le site meshero.fr, sont enregistré par OVH dans les log apache votre adresse IP, des informations relatives à votre navigateur internet, le type de connexion (ADSL, fibre …), les ressources demandés ainsi que l’heure.

+ + +
+
+ + +
+
+
+ + + + + + + + + + + diff --git a/android-chrome-192x192.png b/android-chrome-192x192.png new file mode 100644 index 0000000..7f0493c Binary files /dev/null and b/android-chrome-192x192.png differ diff --git a/android-chrome-512x512.png b/android-chrome-512x512.png new file mode 100644 index 0000000..faea4c2 Binary files /dev/null and b/android-chrome-512x512.png differ diff --git a/apple-touch-icon-precomposed.png b/apple-touch-icon-precomposed.png new file mode 100644 index 0000000..0fb5e92 Binary files /dev/null and b/apple-touch-icon-precomposed.png differ diff --git a/apple-touch-icon.png b/apple-touch-icon.png new file mode 100644 index 0000000..eb281cb Binary files /dev/null and b/apple-touch-icon.png differ diff --git a/categories/index.html b/categories/index.html new file mode 100644 index 0000000..868ffbf --- /dev/null +++ b/categories/index.html @@ -0,0 +1,476 @@ + + + + + + + + + + +Categories – MeshEro + + + + + + + + + + + + + + + + + + + + + + + + + Skip to content
+
+ + +
+ +
+ + + + + +
+
+ +
+

Categories

+
+
+ + + +
+
+ +
+ +
+
+
+ + + + + + + + + + + diff --git a/categories/index.xml b/categories/index.xml new file mode 100644 index 0000000..d9fbba6 --- /dev/null +++ b/categories/index.xml @@ -0,0 +1,18 @@ + + + MeshEro – Categories + http://localhost:1313/categories/ + Recent content in Categories on MeshEro + Hugo -- gohugo.io + fr-fr + + + + + + + + + + + diff --git a/css/compiled/main.css b/css/compiled/main.css new file mode 100644 index 0000000..2183b52 --- /dev/null +++ b/css/compiled/main.css @@ -0,0 +1,2 @@ +/*! tailwindcss v4.3.0 | MIT License | https://tailwindcss.com */ +@layer properties{@supports (((-webkit-hyphens:none)) and (not (margin-trim:inline))) or ((-moz-orient:inline) and (not (color:rgb(from red r g b)))){*,:before,:after,::backdrop{--tw-translate-x:0;--tw-translate-y:0;--tw-translate-z:0;--tw-border-style:solid;--tw-gradient-position:initial;--tw-gradient-from:#0000;--tw-gradient-via:#0000;--tw-gradient-to:#0000;--tw-gradient-stops:initial;--tw-gradient-via-stops:initial;--tw-gradient-from-position:0%;--tw-gradient-via-position:50%;--tw-gradient-to-position:100%;--tw-leading:initial;--tw-font-weight:initial;--tw-tracking:initial;--tw-ordinal:initial;--tw-slashed-zero:initial;--tw-numeric-figure:initial;--tw-numeric-spacing:initial;--tw-numeric-fraction:initial;--tw-shadow:0 0 #0000;--tw-shadow-color:initial;--tw-shadow-alpha:100%;--tw-inset-shadow:0 0 #0000;--tw-inset-shadow-color:initial;--tw-inset-shadow-alpha:100%;--tw-ring-color:initial;--tw-ring-shadow:0 0 #0000;--tw-inset-ring-color:initial;--tw-inset-ring-shadow:0 0 #0000;--tw-ring-inset:initial;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-offset-shadow:0 0 #0000;--tw-duration:initial;--tw-ease:initial;--tw-content:"";--tw-blur:initial;--tw-brightness:initial;--tw-contrast:initial;--tw-grayscale:initial;--tw-hue-rotate:initial;--tw-invert:initial;--tw-opacity:initial;--tw-saturate:initial;--tw-sepia:initial;--tw-drop-shadow:initial;--tw-drop-shadow-color:initial;--tw-drop-shadow-alpha:100%;--tw-drop-shadow-size:initial;--tw-backdrop-blur:initial;--tw-backdrop-brightness:initial;--tw-backdrop-contrast:initial;--tw-backdrop-grayscale:initial;--tw-backdrop-hue-rotate:initial;--tw-backdrop-invert:initial;--tw-backdrop-opacity:initial;--tw-backdrop-saturate:initial;--tw-backdrop-sepia:initial;--tw-outline-style:solid;--tw-scroll-snap-strictness:proximity;--tw-scale-x:1;--tw-scale-y:1;--tw-scale-z:1}}}@layer theme{:root,:host{--hx-font-sans:ui-sans-serif, system-ui, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";--hx-font-mono:ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;--hx-color-red-50:oklch(97.1% .013 17.38);--hx-color-red-100:oklch(93.6% .032 17.717);--hx-color-red-200:oklch(88.5% .062 18.334);--hx-color-red-400:oklch(70.4% .191 22.216);--hx-color-red-500:oklch(63.7% .237 25.331);--hx-color-red-600:oklch(57.7% .245 27.325);--hx-color-red-900:oklch(39.6% .141 25.723);--hx-color-red-950:oklch(25.8% .092 26.042);--hx-color-orange-50:oklch(98% .016 73.684);--hx-color-orange-100:oklch(95.4% .038 75.164);--hx-color-orange-300:oklch(83.7% .128 66.29);--hx-color-orange-400:oklch(75% .183 55.934);--hx-color-orange-800:oklch(47% .157 37.304);--hx-color-amber-50:oklch(98.7% .022 95.277);--hx-color-amber-100:oklch(96.2% .059 95.617);--hx-color-amber-200:oklch(92.4% .12 95.746);--hx-color-amber-500:oklch(76.9% .188 70.08);--hx-color-amber-900:oklch(41.4% .112 45.904);--hx-color-amber-950:oklch(27.9% .077 45.635);--hx-color-yellow-50:oklch(98.7% .026 102.212);--hx-color-yellow-100:oklch(97.3% .071 103.193);--hx-color-yellow-200:oklch(94.5% .129 101.54);--hx-color-yellow-700:oklch(55.4% .135 66.442);--hx-color-yellow-900:oklch(42.1% .095 57.708);--hx-color-green-100:oklch(96.2% .044 156.743);--hx-color-green-200:oklch(92.5% .084 155.995);--hx-color-green-900:oklch(39.3% .095 152.535);--hx-color-blue-100:oklch(93.2% .032 255.585);--hx-color-blue-200:oklch(88.2% .059 254.128);--hx-color-blue-400:oklch(70.7% .165 254.624);--hx-color-blue-600:oklch(54.6% .245 262.881);--hx-color-blue-900:oklch(37.9% .146 265.522);--hx-color-indigo-100:oklch(93% .034 272.788);--hx-color-indigo-200:oklch(87% .065 274.039);--hx-color-indigo-900:oklch(35.9% .144 278.697);--hx-color-purple-100:oklch(94.6% .033 307.174);--hx-color-purple-200:oklch(90.2% .063 306.703);--hx-color-purple-900:oklch(38.1% .176 304.987);--hx-color-slate-50:oklch(98.4% .003 247.858);--hx-color-slate-100:oklch(96.8% .007 247.896);--hx-color-slate-900:oklch(20.8% .042 265.755);--hx-color-gray-50:oklch(98.5% .002 247.839);--hx-color-gray-100:oklch(96.7% .003 264.542);--hx-color-gray-200:oklch(92.8% .006 264.531);--hx-color-gray-300:oklch(87.2% .01 258.338);--hx-color-gray-400:oklch(70.7% .022 261.325);--hx-color-gray-500:oklch(55.1% .027 264.364);--hx-color-gray-600:oklch(44.6% .03 256.802);--hx-color-gray-700:oklch(37.3% .034 259.733);--hx-color-gray-800:oklch(27.8% .033 256.848);--hx-color-gray-900:oklch(21% .034 264.665);--hx-color-neutral-50:oklch(98.5% 0 0);--hx-color-neutral-200:oklch(92.2% 0 0);--hx-color-neutral-300:oklch(87% 0 0);--hx-color-neutral-400:oklch(70.8% 0 0);--hx-color-neutral-500:oklch(55.6% 0 0);--hx-color-neutral-600:oklch(43.9% 0 0);--hx-color-neutral-700:oklch(37.1% 0 0);--hx-color-neutral-800:oklch(26.9% 0 0);--hx-color-neutral-900:oklch(20.5% 0 0);--hx-color-black:#000;--hx-color-white:#fff;--hx-spacing:.25rem;--hx-breakpoint-xl:80rem;--hx-text-xs:.75rem;--hx-text-xs--line-height:calc(1 / .75);--hx-text-sm:.875rem;--hx-text-sm--line-height:calc(1.25 / .875);--hx-text-base:1rem;--hx-text-base--line-height:calc(1.5 / 1);--hx-text-lg:1.125rem;--hx-text-lg--line-height:calc(1.75 / 1.125);--hx-text-xl:1.25rem;--hx-text-xl--line-height:calc(1.75 / 1.25);--hx-text-2xl:1.5rem;--hx-text-2xl--line-height:calc(2 / 1.5);--hx-text-3xl:1.875rem;--hx-text-3xl--line-height:calc(2.25 / 1.875);--hx-text-4xl:2.25rem;--hx-text-4xl--line-height:calc(2.5 / 2.25);--hx-text-5xl:3rem;--hx-text-5xl--line-height:1;--hx-font-weight-normal:400;--hx-font-weight-medium:500;--hx-font-weight-semibold:600;--hx-font-weight-bold:700;--hx-font-weight-extrabold:800;--hx-tracking-tighter:-.05em;--hx-tracking-tight:-.025em;--hx-leading-tight:1.25;--hx-radius-xs:.125rem;--hx-radius-sm:.25rem;--hx-radius-md:.375rem;--hx-radius-lg:.5rem;--hx-radius-xl:.75rem;--hx-radius-3xl:1.5rem;--hx-ease-in:cubic-bezier(.4, 0, 1, 1);--hx-ease-out:cubic-bezier(0, 0, .2, 1);--hx-ease-in-out:cubic-bezier(.4, 0, .2, 1);--hx-blur-xs:4px;--hx-blur-md:12px;--hx-default-transition-duration:.15s;--hx-default-transition-timing-function:cubic-bezier(.4, 0, .2, 1);--hx-default-font-family:var(--hx-font-sans);--hx-default-mono-font-family:var(--hx-font-mono);--hx-color-primary-50:hsl(var(--primary-hue) var(--primary-saturation) calc(var(--primary-lightness) + calc(calc(100% - var(--primary-lightness)) / 50) * 47));--hx-color-primary-100:hsl(var(--primary-hue) var(--primary-saturation) calc(var(--primary-lightness) + calc(calc(100% - var(--primary-lightness)) / 50) * 44));--hx-color-primary-200:hsl(var(--primary-hue) var(--primary-saturation) calc(var(--primary-lightness) + calc(calc(100% - var(--primary-lightness)) / 50) * 36));--hx-color-primary-300:hsl(var(--primary-hue) var(--primary-saturation) calc(var(--primary-lightness) + calc(calc(100% - var(--primary-lightness)) / 50) * 27));--hx-color-primary-400:hsl(var(--primary-hue) var(--primary-saturation) calc(var(--primary-lightness) + calc(calc(100% - var(--primary-lightness)) / 50) * 16));--hx-color-primary-500:hsl(var(--primary-hue) var(--primary-saturation) var(--primary-lightness));--hx-color-primary-600:hsl(var(--primary-hue) var(--primary-saturation) calc(calc(var(--primary-lightness) / 50) * 45));--hx-color-primary-700:hsl(var(--primary-hue) var(--primary-saturation) calc(calc(var(--primary-lightness) / 50) * 39));--hx-color-primary-800:hsl(var(--primary-hue) var(--primary-saturation) calc(calc(var(--primary-lightness) / 50) * 32));--hx-color-primary-900:hsl(var(--primary-hue) var(--primary-saturation) calc(calc(var(--primary-lightness) / 50) * 24));--hx-color-dark:#111}}@layer base{*,:after,:before,::backdrop{box-sizing:border-box;border:0 solid;margin:0;padding:0}::file-selector-button{box-sizing:border-box;border:0 solid;margin:0;padding:0}html,:host{-webkit-text-size-adjust:100%;tab-size:4;line-height:1.5;font-family:var(--hx-default-font-family,ui-sans-serif, system-ui, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji");font-feature-settings:var(--hx-default-font-feature-settings,normal);font-variation-settings:var(--hx-default-font-variation-settings,normal);-webkit-tap-highlight-color:transparent}hr{height:0;color:inherit;border-top-width:1px}abbr:where([title]){-webkit-text-decoration:underline dotted;text-decoration:underline dotted}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;-webkit-text-decoration:inherit;-webkit-text-decoration:inherit;-webkit-text-decoration:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,samp,pre{font-family:var(--hx-default-mono-font-family,ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace);font-feature-settings:var(--hx-default-mono-font-feature-settings,normal);font-variation-settings:var(--hx-default-mono-font-variation-settings,normal);font-size:1em}small{font-size:80%}sub,sup{vertical-align:baseline;font-size:75%;line-height:0;position:relative}sub{bottom:-.25em}sup{top:-.5em}table{text-indent:0;border-color:inherit;border-collapse:collapse}:-moz-focusring{outline:auto}progress{vertical-align:baseline}summary{display:list-item}ol,ul,menu{list-style:none}img,svg,video,canvas,audio,iframe,embed,object{vertical-align:middle;display:block}img,video{max-width:100%;height:auto}button,input,select,optgroup,textarea{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}::file-selector-button{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}:where(select:is([multiple],[size])) optgroup{font-weight:bolder}:where(select:is([multiple],[size])) optgroup option{padding-inline-start:20px}::file-selector-button{margin-inline-end:4px}::placeholder{opacity:1}@supports (not ((-webkit-appearance:-apple-pay-button))) or (contain-intrinsic-size:1px){::placeholder{color:currentColor}@supports (color:color-mix(in lab, red, red)){::placeholder{color:color-mix(in oklab, currentcolor 50%, transparent)}}}textarea{resize:vertical}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-date-and-time-value{min-height:1lh;text-align:inherit}::-webkit-datetime-edit{display:inline-flex}::-webkit-datetime-edit-fields-wrapper{padding:0}::-webkit-datetime-edit{padding-block:0}::-webkit-datetime-edit-year-field{padding-block:0}::-webkit-datetime-edit-month-field{padding-block:0}::-webkit-datetime-edit-day-field{padding-block:0}::-webkit-datetime-edit-hour-field{padding-block:0}::-webkit-datetime-edit-minute-field{padding-block:0}::-webkit-datetime-edit-second-field{padding-block:0}::-webkit-datetime-edit-millisecond-field{padding-block:0}::-webkit-datetime-edit-meridiem-field{padding-block:0}::-webkit-calendar-picker-indicator{line-height:1}:-moz-ui-invalid{box-shadow:none}button,input:where([type=button],[type=reset],[type=submit]){appearance:button}::file-selector-button{appearance:button}::-webkit-inner-spin-button{height:auto}::-webkit-outer-spin-button{height:auto}[hidden]:where(:not([hidden=until-found])){display:none!important}abbr:where([title]){cursor:help}:where(a,button,[role=tab],[role=menuitem],[role=menuitemradio],input,select,textarea,[tabindex="0"]):not([class*=hextra-focus-visible]):focus-visible{--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow);--tw-ring-color:var(--hx-color-primary-200);--tw-ring-offset-width:1px;--tw-ring-offset-shadow:var(--tw-ring-inset,) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-offset-color:var(--hx-color-primary-300);--tw-outline-style:none;outline-style:none}:where(a,button,[role=tab],[role=menuitem],[role=menuitemradio],input,select,textarea,[tabindex="0"]):not([class*=hextra-focus-visible]):focus-visible:where(.dark,.dark *){--tw-ring-color:var(--hx-color-primary-800);--tw-ring-offset-color:var(--hx-color-primary-700)}}@layer components;@layer utilities{.hx\:pointer-events-none{pointer-events:none}.hx\:sr-only{clip-path:inset(50%);white-space:nowrap;border-width:0;width:1px;height:1px;margin:-1px;padding:0;position:absolute;overflow:hidden}.hx\:absolute{position:absolute}.hx\:relative{position:relative}.hx\:sticky{position:sticky}.hx\:inset-y-0{inset-block:calc(var(--hx-spacing) * 0)}.hx\:top-0{top:calc(var(--hx-spacing) * 0)}.hx\:top-1\/2{top:50%}.hx\:top-8{top:calc(var(--hx-spacing) * 8)}.hx\:top-\[40\%\]{top:40%}.hx\:top-\[var\(--hextra-navbar-height\)\]{top:var(--hextra-navbar-height)}.hx\:top-full{top:100%}.hx\:right-0{right:calc(var(--hx-spacing) * 0)}.hx\:bottom-0{bottom:calc(var(--hx-spacing) * 0)}.hx\:left-0{left:calc(var(--hx-spacing) * 0)}.hx\:left-\[24px\]{left:24px}.hx\:left-\[36px\]{left:36px}.hx\:z-20{z-index:20}.hx\:z-\[-1\]{z-index:-1}.hx\:order-last{order:9999}.hx\:m-\[11px\]{margin:11px}.hx\:mx-1{margin-inline:calc(var(--hx-spacing) * 1)}.hx\:mx-4{margin-inline:calc(var(--hx-spacing) * 4)}.hx\:mx-auto{margin-inline:auto}.hx\:my-1{margin-block:calc(var(--hx-spacing) * 1)}.hx\:my-2{margin-block:calc(var(--hx-spacing) * 2)}.hx\:-mt-20{margin-top:calc(var(--hx-spacing) * -20)}.hx\:mt-1{margin-top:calc(var(--hx-spacing) * 1)}.hx\:mt-1\.5{margin-top:calc(var(--hx-spacing) * 1.5)}.hx\:mt-2{margin-top:calc(var(--hx-spacing) * 2)}.hx\:mt-4{margin-top:calc(var(--hx-spacing) * 4)}.hx\:mt-5{margin-top:calc(var(--hx-spacing) * 5)}.hx\:mt-6{margin-top:calc(var(--hx-spacing) * 6)}.hx\:mt-8{margin-top:calc(var(--hx-spacing) * 8)}.hx\:mt-12{margin-top:calc(var(--hx-spacing) * 12)}.hx\:mt-16{margin-top:calc(var(--hx-spacing) * 16)}.hx\:mt-auto{margin-top:auto}.hx\:-mr-1{margin-right:calc(var(--hx-spacing) * -1)}.hx\:-mr-2{margin-right:calc(var(--hx-spacing) * -2)}.hx\:mr-1{margin-right:calc(var(--hx-spacing) * 1)}.hx\:mr-2{margin-right:calc(var(--hx-spacing) * 2)}.hx\:-mb-0\.5{margin-bottom:calc(var(--hx-spacing) * -.5)}.hx\:mb-0{margin-bottom:calc(var(--hx-spacing) * 0)}.hx\:mb-2{margin-bottom:calc(var(--hx-spacing) * 2)}.hx\:mb-4{margin-bottom:calc(var(--hx-spacing) * 4)}.hx\:mb-6{margin-bottom:calc(var(--hx-spacing) * 6)}.hx\:mb-8{margin-bottom:calc(var(--hx-spacing) * 8)}.hx\:mb-10{margin-bottom:calc(var(--hx-spacing) * 10)}.hx\:mb-12{margin-bottom:calc(var(--hx-spacing) * 12)}.hx\:mb-16{margin-bottom:calc(var(--hx-spacing) * 16)}.hx\:-ml-2{margin-left:calc(var(--hx-spacing) * -2)}.hx\:ml-2{margin-left:calc(var(--hx-spacing) * 2)}.hx\:ml-4{margin-left:calc(var(--hx-spacing) * 4)}.hx\:line-clamp-3{-webkit-line-clamp:3;-webkit-box-orient:vertical;display:-webkit-box;overflow:hidden}.hx\:block{display:block}.hx\:flex{display:flex}.hx\:grid{display:grid}.hx\:hidden{display:none}.hx\:inline{display:inline}.hx\:inline-block{display:inline-block}.hx\:inline-flex{display:inline-flex}.hx\:aspect-auto{aspect-ratio:auto}.hx\:size-4{width:calc(var(--hx-spacing) * 4);height:calc(var(--hx-spacing) * 4)}.hx\:h-0{height:calc(var(--hx-spacing) * 0)}.hx\:h-2{height:calc(var(--hx-spacing) * 2)}.hx\:h-3\.5{height:calc(var(--hx-spacing) * 3.5)}.hx\:h-4{height:calc(var(--hx-spacing) * 4)}.hx\:h-5{height:calc(var(--hx-spacing) * 5)}.hx\:h-7{height:calc(var(--hx-spacing) * 7)}.hx\:h-10{height:calc(var(--hx-spacing) * 10)}.hx\:h-\[18px\]{height:18px}.hx\:h-\[var\(--hextra-navbar-height\)\]{height:var(--hextra-navbar-height)}.hx\:h-full{height:100%}.hx\:h-px{height:1px}.hx\:max-h-\(--menu-height\){max-height:var(--menu-height)}.hx\:max-h-64{max-height:calc(var(--hx-spacing) * 64)}.hx\:max-h-\[calc\(100vh-var\(--hextra-navbar-height\)-env\(safe-area-inset-bottom\)\)\]{max-height:calc(100vh - var(--hextra-navbar-height) - env(safe-area-inset-bottom))}.hx\:min-h-\[calc\(100vh-var\(--hextra-navbar-height\)\)\]{min-height:calc(100vh - var(--hextra-navbar-height))}.hx\:w-2{width:calc(var(--hx-spacing) * 2)}.hx\:w-3\.5{width:calc(var(--hx-spacing) * 3.5)}.hx\:w-4{width:calc(var(--hx-spacing) * 4)}.hx\:w-10{width:calc(var(--hx-spacing) * 10)}.hx\:w-64{width:calc(var(--hx-spacing) * 64)}.hx\:w-\[110\%\]{width:110%}.hx\:w-\[180\%\]{width:180%}.hx\:w-full{width:100%}.hx\:w-max{width:max-content}.hx\:max-w-\[50\%\]{max-width:50%}.hx\:max-w-\[90rem\]{max-width:90rem}.hx\:max-w-full{max-width:100%}.hx\:max-w-none{max-width:none}.hx\:max-w-screen-xl{max-width:var(--hx-breakpoint-xl)}.hx\:min-w-0{min-width:calc(var(--hx-spacing) * 0)}.hx\:min-w-\[18px\]{min-width:18px}.hx\:min-w-\[24px\]{min-width:24px}.hx\:min-w-full{min-width:100%}.hx\:shrink-0{flex-shrink:0}.hx\:grow{flex-grow:1}.hx\:origin-center{transform-origin:50%}.hx\:-translate-y-1\/2{--tw-translate-y:calc(calc(1 / 2 * 100%) * -1);translate:var(--tw-translate-x) var(--tw-translate-y)}.hx\:cursor-default{cursor:default}.hx\:cursor-pointer{cursor:pointer}.hx\:scroll-my-6{scroll-margin-block:calc(var(--hx-spacing) * 6)}.hx\:scroll-py-6{scroll-padding-block:calc(var(--hx-spacing) * 6)}.hx\:list-none{list-style-type:none}.hx\:grid-cols-1{grid-template-columns:repeat(1,minmax(0,1fr))}.hx\:flex-col{flex-direction:column}.hx\:flex-wrap{flex-wrap:wrap}.hx\:items-baseline{align-items:baseline}.hx\:items-center{align-items:center}.hx\:items-start{align-items:flex-start}.hx\:justify-between{justify-content:space-between}.hx\:justify-center{justify-content:center}.hx\:justify-end{justify-content:flex-end}.hx\:justify-start{justify-content:flex-start}.hx\:justify-items-start{justify-items:start}.hx\:gap-1{gap:calc(var(--hx-spacing) * 1)}.hx\:gap-1\.5{gap:calc(var(--hx-spacing) * 1.5)}.hx\:gap-2{gap:calc(var(--hx-spacing) * 2)}.hx\:gap-4{gap:calc(var(--hx-spacing) * 4)}.hx\:gap-x-1\.5{column-gap:calc(var(--hx-spacing) * 1.5)}.hx\:gap-x-2{column-gap:calc(var(--hx-spacing) * 2)}.hx\:gap-y-1{row-gap:calc(var(--hx-spacing) * 1)}.hx\:gap-y-2{row-gap:calc(var(--hx-spacing) * 2)}.hx\:overflow-auto{overflow:auto}.hx\:overflow-hidden{overflow:hidden}.hx\:overflow-x-auto{overflow-x:auto}.hx\:overflow-x-hidden{overflow-x:hidden}.hx\:overflow-y-auto{overflow-y:auto}.hx\:overflow-y-hidden{overflow-y:hidden}.hx\:overscroll-x-contain{overscroll-behavior-x:contain}.hx\:rounded-3xl{border-radius:var(--hx-radius-3xl)}.hx\:rounded-full{border-radius:3.40282e38px}.hx\:rounded-lg{border-radius:var(--hx-radius-lg)}.hx\:rounded-md{border-radius:var(--hx-radius-md)}.hx\:rounded-sm{border-radius:var(--hx-radius-sm)}.hx\:rounded-xs{border-radius:var(--hx-radius-xs)}.hx\:rounded-t{border-top-left-radius:.25rem;border-top-right-radius:.25rem}.hx\:border{border-style:var(--tw-border-style);border-width:1px}.hx\:border-0{border-style:var(--tw-border-style);border-width:0}.hx\:border-t{border-top-style:var(--tw-border-style);border-top-width:1px}.hx\:border-b{border-bottom-style:var(--tw-border-style);border-bottom-width:1px}.hx\:border-b-2{border-bottom-style:var(--tw-border-style);border-bottom-width:2px}.hx\:border-amber-200{border-color:var(--hx-color-amber-200)}.hx\:border-black\/5{border-color:var(--hx-color-black)}@supports (color:color-mix(in lab, red, red)){.hx\:border-black\/5{border-color:color-mix(in oklab, var(--hx-color-black) 5%, transparent)}}.hx\:border-blue-200{border-color:var(--hx-color-blue-200)}.hx\:border-gray-200{border-color:var(--hx-color-gray-200)}.hx\:border-gray-500{border-color:var(--hx-color-gray-500)}.hx\:border-green-200{border-color:var(--hx-color-green-200)}.hx\:border-indigo-200{border-color:var(--hx-color-indigo-200)}.hx\:border-orange-100{border-color:var(--hx-color-orange-100)}.hx\:border-purple-200{border-color:var(--hx-color-purple-200)}.hx\:border-red-200{border-color:var(--hx-color-red-200)}.hx\:border-transparent{border-color:#0000}.hx\:border-yellow-100{border-color:var(--hx-color-yellow-100)}.hx\:bg-amber-100{background-color:var(--hx-color-amber-100)}.hx\:bg-blue-100{background-color:var(--hx-color-blue-100)}.hx\:bg-gray-100{background-color:var(--hx-color-gray-100)}.hx\:bg-gray-200{background-color:var(--hx-color-gray-200)}.hx\:bg-green-100{background-color:var(--hx-color-green-100)}.hx\:bg-indigo-100{background-color:var(--hx-color-indigo-100)}.hx\:bg-neutral-50{background-color:var(--hx-color-neutral-50)}.hx\:bg-neutral-900{background-color:var(--hx-color-neutral-900)}.hx\:bg-orange-50{background-color:var(--hx-color-orange-50)}.hx\:bg-primary-100{background-color:var(--hx-color-primary-100)}.hx\:bg-primary-400{background-color:var(--hx-color-primary-400)}.hx\:bg-primary-600{background-color:var(--hx-color-primary-600)}.hx\:bg-primary-700\/5{background-color:var(--hx-color-primary-700)}@supports (color:color-mix(in lab, red, red)){.hx\:bg-primary-700\/5{background-color:color-mix(in oklab, var(--hx-color-primary-700) 5%, transparent)}}.hx\:bg-purple-100{background-color:var(--hx-color-purple-100)}.hx\:bg-red-100{background-color:var(--hx-color-red-100)}.hx\:bg-transparent{background-color:#0000}.hx\:bg-white{background-color:var(--hx-color-white)}.hx\:bg-yellow-50{background-color:var(--hx-color-yellow-50)}.hx\:bg-gradient-to-r{--tw-gradient-position:to right in oklab;background-image:linear-gradient(var(--tw-gradient-stops))}.hx\:from-gray-900{--tw-gradient-from:var(--hx-color-gray-900);--tw-gradient-stops:var(--tw-gradient-via-stops,var(--tw-gradient-position), var(--tw-gradient-from) var(--tw-gradient-from-position), var(--tw-gradient-to) var(--tw-gradient-to-position))}.hx\:to-gray-600{--tw-gradient-to:var(--hx-color-gray-600);--tw-gradient-stops:var(--tw-gradient-via-stops,var(--tw-gradient-position), var(--tw-gradient-from) var(--tw-gradient-from-position), var(--tw-gradient-to) var(--tw-gradient-to-position))}.hx\:bg-clip-text{-webkit-background-clip:text;background-clip:text}.hx\:p-0{padding:calc(var(--hx-spacing) * 0)}.hx\:p-0\.5{padding:calc(var(--hx-spacing) * .5)}.hx\:p-1{padding:calc(var(--hx-spacing) * 1)}.hx\:p-1\.5{padding:calc(var(--hx-spacing) * 1.5)}.hx\:p-2{padding:calc(var(--hx-spacing) * 2)}.hx\:p-4{padding:calc(var(--hx-spacing) * 4)}.hx\:p-6{padding:calc(var(--hx-spacing) * 6)}.hx\:px-1\.5{padding-inline:calc(var(--hx-spacing) * 1.5)}.hx\:px-2{padding-inline:calc(var(--hx-spacing) * 2)}.hx\:px-2\.5{padding-inline:calc(var(--hx-spacing) * 2.5)}.hx\:px-3{padding-inline:calc(var(--hx-spacing) * 3)}.hx\:px-4{padding-inline:calc(var(--hx-spacing) * 4)}.hx\:px-6{padding-inline:calc(var(--hx-spacing) * 6)}.hx\:px-8{padding-inline:calc(var(--hx-spacing) * 8)}.hx\:py-1{padding-block:calc(var(--hx-spacing) * 1)}.hx\:py-1\.5{padding-block:calc(var(--hx-spacing) * 1.5)}.hx\:py-2{padding-block:calc(var(--hx-spacing) * 2)}.hx\:py-2\.5{padding-block:calc(var(--hx-spacing) * 2.5)}.hx\:py-3{padding-block:calc(var(--hx-spacing) * 3)}.hx\:py-4{padding-block:calc(var(--hx-spacing) * 4)}.hx\:py-12{padding-block:calc(var(--hx-spacing) * 12)}.hx\:pt-4{padding-top:calc(var(--hx-spacing) * 4)}.hx\:pt-6{padding-top:calc(var(--hx-spacing) * 6)}.hx\:pt-8{padding-top:calc(var(--hx-spacing) * 8)}.hx\:pr-2{padding-right:calc(var(--hx-spacing) * 2)}.hx\:pr-4{padding-right:calc(var(--hx-spacing) * 4)}.hx\:pr-\[calc\(env\(safe-area-inset-right\)-1\.5rem\)\]{padding-right:calc(env(safe-area-inset-right) - 1.5rem)}.hx\:pr-\[max\(env\(safe-area-inset-right\)\,1\.5rem\)\]{padding-right:max(env(safe-area-inset-right), 1.5rem)}.hx\:pb-8{padding-bottom:calc(var(--hx-spacing) * 8)}.hx\:pb-\[env\(safe-area-inset-bottom\)\]{padding-bottom:env(safe-area-inset-bottom)}.hx\:pb-px{padding-bottom:1px}.hx\:pl-6{padding-left:calc(var(--hx-spacing) * 6)}.hx\:pl-\[max\(env\(safe-area-inset-left\)\,1\.5rem\)\]{padding-left:max(env(safe-area-inset-left), 1.5rem)}.hx\:text-center{text-align:center}.hx\:text-left{text-align:left}.hx\:align-\[-2\.5px\]{vertical-align:-2.5px}.hx\:align-baseline{vertical-align:baseline}.hx\:align-middle{vertical-align:middle}.hx\:align-text-bottom{vertical-align:text-bottom}.hx\:text-2xl{font-size:var(--hx-text-2xl);line-height:var(--tw-leading,var(--hx-text-2xl--line-height))}.hx\:text-4xl{font-size:var(--hx-text-4xl);line-height:var(--tw-leading,var(--hx-text-4xl--line-height))}.hx\:text-base{font-size:var(--hx-text-base);line-height:var(--tw-leading,var(--hx-text-base--line-height))}.hx\:text-lg{font-size:var(--hx-text-lg);line-height:var(--tw-leading,var(--hx-text-lg--line-height))}.hx\:text-sm{font-size:var(--hx-text-sm);line-height:var(--tw-leading,var(--hx-text-sm--line-height))}.hx\:text-xl{font-size:var(--hx-text-xl);line-height:var(--tw-leading,var(--hx-text-xl--line-height))}.hx\:text-xs{font-size:var(--hx-text-xs);line-height:var(--tw-leading,var(--hx-text-xs--line-height))}.hx\:text-\[\.65rem\]{font-size:.65rem}.hx\:leading-5{--tw-leading:calc(var(--hx-spacing) * 5);line-height:calc(var(--hx-spacing) * 5)}.hx\:leading-6{--tw-leading:calc(var(--hx-spacing) * 6);line-height:calc(var(--hx-spacing) * 6)}.hx\:leading-7{--tw-leading:calc(var(--hx-spacing) * 7);line-height:calc(var(--hx-spacing) * 7)}.hx\:leading-none{--tw-leading:1;line-height:1}.hx\:font-bold{--tw-font-weight:var(--hx-font-weight-bold);font-weight:var(--hx-font-weight-bold)}.hx\:font-extrabold{--tw-font-weight:var(--hx-font-weight-extrabold);font-weight:var(--hx-font-weight-extrabold)}.hx\:font-medium{--tw-font-weight:var(--hx-font-weight-medium);font-weight:var(--hx-font-weight-medium)}.hx\:font-normal{--tw-font-weight:var(--hx-font-weight-normal);font-weight:var(--hx-font-weight-normal)}.hx\:font-semibold{--tw-font-weight:var(--hx-font-weight-semibold);font-weight:var(--hx-font-weight-semibold)}.hx\:tracking-tight{--tw-tracking:var(--hx-tracking-tight);letter-spacing:var(--hx-tracking-tight)}.hx\:tracking-tighter{--tw-tracking:var(--hx-tracking-tighter);letter-spacing:var(--hx-tracking-tighter)}.hx\:break-words,.hx\:wrap-break-word{overflow-wrap:break-word}.hx\:text-ellipsis{text-overflow:ellipsis}.hx\:whitespace-nowrap{white-space:nowrap}.hx\:text-\[color\:hsl\(var\(--primary-hue\)\,100\%\,50\%\)\]{color:hsl(var(--primary-hue),100%,50%)}.hx\:text-amber-900{color:var(--hx-color-amber-900)}.hx\:text-blue-900{color:var(--hx-color-blue-900)}.hx\:text-current{color:currentColor}.hx\:text-gray-500{color:var(--hx-color-gray-500)}.hx\:text-gray-600{color:var(--hx-color-gray-600)}.hx\:text-gray-700{color:var(--hx-color-gray-700)}.hx\:text-gray-800{color:var(--hx-color-gray-800)}.hx\:text-gray-900{color:var(--hx-color-gray-900)}.hx\:text-green-900{color:var(--hx-color-green-900)}.hx\:text-indigo-900{color:var(--hx-color-indigo-900)}.hx\:text-orange-800{color:var(--hx-color-orange-800)}.hx\:text-primary-800{color:var(--hx-color-primary-800)}.hx\:text-purple-900{color:var(--hx-color-purple-900)}.hx\:text-red-900{color:var(--hx-color-red-900)}.hx\:text-slate-50{color:var(--hx-color-slate-50)}.hx\:text-slate-900{color:var(--hx-color-slate-900)}.hx\:text-transparent{color:#0000}.hx\:text-white{color:var(--hx-color-white)}.hx\:text-yellow-900{color:var(--hx-color-yellow-900)}.hx\:capitalize{text-transform:capitalize}.hx\:tabular-nums{--tw-numeric-spacing:tabular-nums;font-variant-numeric:var(--tw-ordinal,) var(--tw-slashed-zero,) var(--tw-numeric-figure,) var(--tw-numeric-spacing,) var(--tw-numeric-fraction,)}.hx\:no-underline{text-decoration-line:none}.hx\:underline{text-decoration-line:underline}.hx\:decoration-from-font{text-decoration-thickness:from-font}.hx\:underline-offset-2{text-underline-offset:2px}.hx\:opacity-0{opacity:0}.hx\:opacity-50{opacity:.5}.hx\:opacity-80{opacity:.8}.hx\:shadow-\[0_-12px_16px_\#fff\]{--tw-shadow:0 -12px 16px var(--tw-shadow-color,#fff);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.hx\:shadow-\[0_-12px_16px_white\]{--tw-shadow:0 -12px 16px var(--tw-shadow-color,white);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.hx\:shadow-\[0_2px_4px_rgba\(0\,0\,0\,\.02\)\,0_1px_0_rgba\(0\,0\,0\,\.06\)\]{--tw-shadow:0 2px 4px var(--tw-shadow-color,#00000005), 0 1px 0 var(--tw-shadow-color,#0000000f);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.hx\:shadow-lg{--tw-shadow:0 10px 15px -3px var(--tw-shadow-color,#0000001a), 0 4px 6px -4px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.hx\:shadow-sm{--tw-shadow:0 1px 3px 0 var(--tw-shadow-color,#0000001a), 0 1px 2px -1px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.hx\:shadow-xs{--tw-shadow:0 1px 2px 0 var(--tw-shadow-color,#0000000d);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.hx\:hextra-focus-visible:focus-visible{--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow);--tw-ring-color:var(--hx-color-primary-200);--tw-ring-offset-width:1px;--tw-ring-offset-shadow:var(--tw-ring-inset,) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-offset-color:var(--hx-color-primary-300);--tw-outline-style:none;outline-style:none}.hx\:hextra-focus-visible:where(.dark,.dark *):focus-visible{--tw-ring-color:var(--hx-color-primary-800);--tw-ring-offset-color:var(--hx-color-primary-700)}.hx\:hextra-focus-visible-inset:focus-visible{--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow);--tw-ring-color:var(--hx-color-primary-200);--tw-ring-offset-width:0px;--tw-ring-offset-shadow:var(--tw-ring-inset,) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-outline-style:none;--tw-ring-inset:inset;outline-style:none}.hx\:hextra-focus-visible-inset:where(.dark,.dark *):focus-visible{--tw-ring-color:var(--hx-color-primary-800)}.hx\:shadow-gray-100{--tw-shadow-color:var(--hx-color-gray-100)}@supports (color:color-mix(in lab, red, red)){.hx\:shadow-gray-100{--tw-shadow-color:color-mix(in oklab, var(--hx-color-gray-100) var(--tw-shadow-alpha), transparent)}}.hx\:transition{transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to,opacity,box-shadow,transform,translate,scale,rotate,filter,-webkit-backdrop-filter,backdrop-filter,display,content-visibility,overlay,pointer-events;transition-timing-function:var(--tw-ease,var(--hx-default-transition-timing-function));transition-duration:var(--tw-duration,var(--hx-default-transition-duration))}.hx\:transition-all{transition-property:all;transition-timing-function:var(--tw-ease,var(--hx-default-transition-timing-function));transition-duration:var(--tw-duration,var(--hx-default-transition-duration))}.hx\:transition-colors{transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to;transition-timing-function:var(--tw-ease,var(--hx-default-transition-timing-function));transition-duration:var(--tw-duration,var(--hx-default-transition-duration))}.hx\:transition-transform{transition-property:transform,translate,scale,rotate;transition-timing-function:var(--tw-ease,var(--hx-default-transition-timing-function));transition-duration:var(--tw-duration,var(--hx-default-transition-duration))}.hx\:duration-75{--tw-duration:75ms;transition-duration:75ms}.hx\:duration-150{--tw-duration:.15s;transition-duration:.15s}.hx\:duration-200{--tw-duration:.2s;transition-duration:.2s}.hx\:ease-in{--tw-ease:var(--hx-ease-in);transition-timing-function:var(--hx-ease-in)}.hx\:ease-in-out{--tw-ease:var(--hx-ease-in-out);transition-timing-function:var(--hx-ease-in-out)}.hx\:outline-none{--tw-outline-style:none;outline-style:none}.hx\:select-none{-webkit-user-select:none;user-select:none}@media (hover:hover){.hx\:group-hover\:text-gray-900:is(:where(.hx\:group):hover *){color:var(--hx-color-gray-900)}.hx\:group-hover\:underline:is(:where(.hx\:group):hover *){text-decoration-line:underline}.hx\:group-hover\/code\:opacity-100:is(:where(.hx\:group\/code):hover *){opacity:1}}.hx\:group-data-\[active\=true\]\:text-primary-800:is(:where(.hx\:group)[data-active=true] *){color:var(--hx-color-primary-800)}.hx\:group-data-\[theme\=dark\]\:hidden:is(:where(.hx\:group)[data-theme=dark] *),.hx\:group-data-\[theme\=light\]\:hidden:is(:where(.hx\:group)[data-theme=light] *),.hx\:group-data-\[theme\=system\]\:hidden:is(:where(.hx\:group)[data-theme=system] *){display:none}.hx\:group-\[\.copied\]\/copybtn\:block:is(:where(.hx\:group\/copybtn).copied *){display:block}.hx\:group-\[\.copied\]\/copybtn\:hidden:is(:where(.hx\:group\/copybtn).copied *){display:none}.hx\:before\:pointer-events-none:before{content:var(--tw-content);pointer-events:none}.hx\:before\:absolute:before{content:var(--tw-content);position:absolute}.hx\:before\:inset-0:before{content:var(--tw-content);inset:calc(var(--hx-spacing) * 0)}.hx\:before\:inset-y-1:before{content:var(--tw-content);inset-block:calc(var(--hx-spacing) * 1)}.hx\:before\:mr-1:before{content:var(--tw-content);margin-right:calc(var(--hx-spacing) * 1)}.hx\:before\:inline-block:before{content:var(--tw-content);display:inline-block}.hx\:before\:w-px:before{content:var(--tw-content);width:1px}.hx\:before\:bg-gray-200:before{content:var(--tw-content);background-color:var(--hx-color-gray-200)}.hx\:before\:opacity-25:before{content:var(--tw-content);opacity:.25}.hx\:before\:transition-transform:before{content:var(--tw-content);transition-property:transform,translate,scale,rotate;transition-timing-function:var(--tw-ease,var(--hx-default-transition-timing-function));transition-duration:var(--tw-duration,var(--hx-default-transition-duration))}.hx\:before\:content-\[\"\"\]:before{--tw-content:"";content:var(--tw-content)}.hx\:before\:content-\[\'\#\'\]:before{--tw-content:"#";content:var(--tw-content)}.hx\:before\:content-\[\'\'\]:before{--tw-content:"";content:var(--tw-content)}.hx\:before\:content-\[\\\"\\\"\]:before{--tw-content:\"\";content:var(--tw-content)}.hx\:group-open\:before\:rotate-90:is(:where(.hx\:group):is([open],:popover-open,:open) *):before{content:var(--tw-content);rotate:90deg}.hx\:first\:mt-0:first-child{margin-top:calc(var(--hx-spacing) * 0)}.hx\:last-of-type\:mb-0:last-of-type{margin-bottom:calc(var(--hx-spacing) * 0)}@media (hover:hover){.hx\:hover\:border-gray-200:hover{border-color:var(--hx-color-gray-200)}.hx\:hover\:border-gray-300:hover{border-color:var(--hx-color-gray-300)}.hx\:hover\:border-gray-400:hover{border-color:var(--hx-color-gray-400)}.hx\:hover\:border-gray-900:hover{border-color:var(--hx-color-gray-900)}.hx\:hover\:bg-gray-100:hover{background-color:var(--hx-color-gray-100)}.hx\:hover\:bg-gray-800\/5:hover{background-color:var(--hx-color-gray-800)}@supports (color:color-mix(in lab, red, red)){.hx\:hover\:bg-gray-800\/5:hover{background-color:color-mix(in oklab, var(--hx-color-gray-800) 5%, transparent)}}.hx\:hover\:bg-primary-700:hover{background-color:var(--hx-color-primary-700)}.hx\:hover\:bg-slate-50:hover{background-color:var(--hx-color-slate-50)}.hx\:hover\:text-black:hover{color:var(--hx-color-black)}.hx\:hover\:text-gray-700:hover{color:var(--hx-color-gray-700)}.hx\:hover\:text-gray-800:hover{color:var(--hx-color-gray-800)}.hx\:hover\:text-gray-900:hover{color:var(--hx-color-gray-900)}.hx\:hover\:text-primary-600:hover{color:var(--hx-color-primary-600)}.hx\:hover\:opacity-60:hover{opacity:.6}.hx\:hover\:opacity-75:hover{opacity:.75}.hx\:hover\:shadow-lg:hover{--tw-shadow:0 10px 15px -3px var(--tw-shadow-color,#0000001a), 0 4px 6px -4px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.hx\:hover\:shadow-md:hover{--tw-shadow:0 4px 6px -1px var(--tw-shadow-color,#0000001a), 0 2px 4px -2px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.hx\:hover\:shadow-gray-100:hover{--tw-shadow-color:var(--hx-color-gray-100)}@supports (color:color-mix(in lab, red, red)){.hx\:hover\:shadow-gray-100:hover{--tw-shadow-color:color-mix(in oklab, var(--hx-color-gray-100) var(--tw-shadow-alpha), transparent)}}}.hx\:focus-visible\:not-sr-only:focus-visible{clip-path:none;white-space:normal;width:auto;height:auto;margin:0;padding:0;position:static;overflow:visible}.hx\:focus-visible\:fixed:focus-visible{position:fixed}.hx\:focus-visible\:top-2:focus-visible{top:calc(var(--hx-spacing) * 2)}.hx\:focus-visible\:left-2:focus-visible{left:calc(var(--hx-spacing) * 2)}.hx\:focus-visible\:z-50:focus-visible{z-index:50}.hx\:focus-visible\:rounded-md:focus-visible{border-radius:var(--hx-radius-md)}.hx\:focus-visible\:bg-primary-500:focus-visible{background-color:var(--hx-color-primary-500)}.hx\:focus-visible\:px-4:focus-visible{padding-inline:calc(var(--hx-spacing) * 4)}.hx\:focus-visible\:py-2:focus-visible{padding-block:calc(var(--hx-spacing) * 2)}.hx\:focus-visible\:text-sm:focus-visible{font-size:var(--hx-text-sm);line-height:var(--tw-leading,var(--hx-text-sm--line-height))}.hx\:focus-visible\:font-medium:focus-visible{--tw-font-weight:var(--hx-font-weight-medium);font-weight:var(--hx-font-weight-medium)}.hx\:focus-visible\:text-white:focus-visible{color:var(--hx-color-white)}.hx\:active\:bg-gray-400\/20:active{background-color:var(--hx-color-gray-400)}@supports (color:color-mix(in lab, red, red)){.hx\:active\:bg-gray-400\/20:active{background-color:color-mix(in oklab, var(--hx-color-gray-400) 20%, transparent)}}.hx\:active\:opacity-50:active{opacity:.5}.hx\:active\:shadow-sm:active{--tw-shadow:0 1px 3px 0 var(--tw-shadow-color,#0000001a), 0 1px 2px -1px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.hx\:active\:shadow-gray-200:active{--tw-shadow-color:var(--hx-color-gray-200)}@supports (color:color-mix(in lab, red, red)){.hx\:active\:shadow-gray-200:active{--tw-shadow-color:color-mix(in oklab, var(--hx-color-gray-200) var(--tw-shadow-alpha), transparent)}}.hx\:data-\[state\=closed\]\:hidden[data-state=closed],.hx\:data-\[state\=open\]\:hidden[data-state=open]{display:none}.hx\:data-\[state\=selected\]\:block[data-state=selected]{display:block}.hx\:data-\[state\=selected\]\:border-primary-500[data-state=selected]{border-color:var(--hx-color-primary-500)}.hx\:data-\[state\=selected\]\:text-primary-600[data-state=selected]{color:var(--hx-color-primary-600)}@media (prefers-contrast:more){.hx\:contrast-more\:border{border-style:var(--tw-border-style);border-width:1px}.hx\:contrast-more\:border-t{border-top-style:var(--tw-border-style);border-top-width:1px}.hx\:contrast-more\:border-current{border-color:currentColor}.hx\:contrast-more\:border-gray-800{border-color:var(--hx-color-gray-800)}.hx\:contrast-more\:border-neutral-400{border-color:var(--hx-color-neutral-400)}.hx\:contrast-more\:border-primary-500{border-color:var(--hx-color-primary-500)}.hx\:contrast-more\:border-transparent{border-color:#0000}.hx\:contrast-more\:font-bold{--tw-font-weight:var(--hx-font-weight-bold);font-weight:var(--hx-font-weight-bold)}.hx\:contrast-more\:text-current{color:currentColor}.hx\:contrast-more\:text-gray-700{color:var(--hx-color-gray-700)}.hx\:contrast-more\:text-gray-800{color:var(--hx-color-gray-800)}.hx\:contrast-more\:text-gray-900{color:var(--hx-color-gray-900)}.hx\:contrast-more\:underline{text-decoration-line:underline}.hx\:contrast-more\:shadow-\[0_0_0_1px_\#000\]{--tw-shadow:0 0 0 1px var(--tw-shadow-color,#000);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.hx\:contrast-more\:shadow-none{--tw-shadow:0 0 #0000;box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}@media (hover:hover){.hx\:contrast-more\:hover\:border-gray-900:hover{border-color:var(--hx-color-gray-900)}}}@media not all and (min-width:80rem){.hx\:max-xl\:hidden{display:none}}@media not all and (min-width:64rem){.hx\:max-lg\:min-h-\[340px\]{min-height:340px}}@media not all and (min-width:48rem){.hx\:max-md\:sticky{position:sticky}.hx\:max-md\:hidden{display:none}.hx\:max-md\:min-h-\[340px\]{min-height:340px}.hx\:max-md\:\[transform\:translate3d\(0\,-100\%\,0\)\]{transform:translateY(-100%)}.hx\:max-md\:\[transform\:translate3d\(0\,0\,0\)\]{transform:translate(0)}}@media not all and (min-width:40rem){.hx\:max-sm\:grid-cols-1{grid-template-columns:repeat(1,minmax(0,1fr))}}@media (min-width:40rem){.hx\:sm\:right-0{right:calc(var(--hx-spacing) * 0)}.hx\:sm\:left-auto{left:auto}.hx\:sm\:block{display:block}.hx\:sm\:w-\[110\%\]{width:110%}.hx\:sm\:flex-row{flex-direction:row}.hx\:sm\:items-center{align-items:center}.hx\:sm\:items-start{align-items:flex-start}.hx\:sm\:justify-between{justify-content:space-between}.hx\:sm\:text-xl{font-size:var(--hx-text-xl);line-height:var(--tw-leading,var(--hx-text-xl--line-height))}@media not all and (min-width:64rem){.hx\:sm\:max-lg\:grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}}}@media (min-width:48rem){.hx\:md\:sticky{position:sticky}.hx\:md\:top-\[var\(--hextra-navbar-height\)\]{top:var(--hextra-navbar-height)}.hx\:md\:mr-0{margin-right:calc(var(--hx-spacing) * 0)}.hx\:md\:hidden{display:none}.hx\:md\:inline-block{display:inline-block}.hx\:md\:inline-flex{display:inline-flex}.hx\:md\:aspect-\[1\.1\/1\]{aspect-ratio:1.1}.hx\:md\:h-\[calc\(100vh-var\(--hextra-navbar-height\)-var\(--menu-height\)\)\]{height:calc(100vh - var(--hextra-navbar-height) - var(--menu-height))}.hx\:md\:w-64{width:calc(var(--hx-spacing) * 64)}.hx\:md\:shrink-0{flex-shrink:0}.hx\:md\:grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.hx\:md\:justify-start{justify-content:flex-start}.hx\:md\:gap-2{gap:calc(var(--hx-spacing) * 2)}.hx\:md\:self-start{align-self:flex-start}.hx\:md\:overflow-auto{overflow:auto}.hx\:md\:p-2{padding:calc(var(--hx-spacing) * 2)}.hx\:md\:px-12{padding-inline:calc(var(--hx-spacing) * 12)}.hx\:md\:pt-12{padding-top:calc(var(--hx-spacing) * 12)}.hx\:md\:text-3xl{font-size:var(--hx-text-3xl);line-height:var(--tw-leading,var(--hx-text-3xl--line-height))}.hx\:md\:text-5xl{font-size:var(--hx-text-5xl);line-height:var(--tw-leading,var(--hx-text-5xl--line-height))}.hx\:md\:text-lg{font-size:var(--hx-text-lg);line-height:var(--tw-leading,var(--hx-text-lg--line-height))}}@media (min-width:64rem){.hx\:lg\:grid-cols-3{grid-template-columns:repeat(3,minmax(0,1fr))}}@media (min-width:80rem){.hx\:xl\:block{display:block}.hx\:xl\:grid-cols-4{grid-template-columns:repeat(4,minmax(0,1fr))}}.hx\:ltr\:right-2:where(:dir(ltr),[dir=ltr],[dir=ltr] *){right:calc(var(--hx-spacing) * 2)}.hx\:ltr\:right-3:where(:dir(ltr),[dir=ltr],[dir=ltr] *){right:calc(var(--hx-spacing) * 3)}.hx\:ltr\:-mr-4:where(:dir(ltr),[dir=ltr],[dir=ltr] *){margin-right:calc(var(--hx-spacing) * -4)}.hx\:ltr\:mr-auto:where(:dir(ltr),[dir=ltr],[dir=ltr] *){margin-right:auto}.hx\:ltr\:ml-1:where(:dir(ltr),[dir=ltr],[dir=ltr] *){margin-left:calc(var(--hx-spacing) * 1)}.hx\:ltr\:ml-3:where(:dir(ltr),[dir=ltr],[dir=ltr] *){margin-left:calc(var(--hx-spacing) * 3)}.hx\:ltr\:ml-auto:where(:dir(ltr),[dir=ltr],[dir=ltr] *){margin-left:auto}.hx\:ltr\:rotate-180:where(:dir(ltr),[dir=ltr],[dir=ltr] *){rotate:180deg}.hx\:ltr\:rounded-l-lg:where(:dir(ltr),[dir=ltr],[dir=ltr] *){border-top-left-radius:var(--hx-radius-lg);border-bottom-left-radius:var(--hx-radius-lg)}.hx\:ltr\:rounded-r-lg:where(:dir(ltr),[dir=ltr],[dir=ltr] *){border-top-right-radius:var(--hx-radius-lg);border-bottom-right-radius:var(--hx-radius-lg)}.hx\:ltr\:border-l:where(:dir(ltr),[dir=ltr],[dir=ltr] *){border-left-style:var(--tw-border-style);border-left-width:1px}.hx\:ltr\:pr-0:where(:dir(ltr),[dir=ltr],[dir=ltr] *){padding-right:calc(var(--hx-spacing) * 0)}.hx\:ltr\:pr-2:where(:dir(ltr),[dir=ltr],[dir=ltr] *){padding-right:calc(var(--hx-spacing) * 2)}.hx\:ltr\:pr-4:where(:dir(ltr),[dir=ltr],[dir=ltr] *){padding-right:calc(var(--hx-spacing) * 4)}.hx\:ltr\:pr-8:where(:dir(ltr),[dir=ltr],[dir=ltr] *){padding-right:calc(var(--hx-spacing) * 8)}.hx\:ltr\:pr-9:where(:dir(ltr),[dir=ltr],[dir=ltr] *){padding-right:calc(var(--hx-spacing) * 9)}.hx\:ltr\:pl-3:where(:dir(ltr),[dir=ltr],[dir=ltr] *){padding-left:calc(var(--hx-spacing) * 3)}.hx\:ltr\:pl-4:where(:dir(ltr),[dir=ltr],[dir=ltr] *){padding-left:calc(var(--hx-spacing) * 4)}.hx\:ltr\:pl-5:where(:dir(ltr),[dir=ltr],[dir=ltr] *){padding-left:calc(var(--hx-spacing) * 5)}.hx\:ltr\:pl-6:where(:dir(ltr),[dir=ltr],[dir=ltr] *){padding-left:calc(var(--hx-spacing) * 6)}.hx\:ltr\:pl-8:where(:dir(ltr),[dir=ltr],[dir=ltr] *){padding-left:calc(var(--hx-spacing) * 8)}.hx\:ltr\:pl-12:where(:dir(ltr),[dir=ltr],[dir=ltr] *){padding-left:calc(var(--hx-spacing) * 12)}.hx\:ltr\:pl-16:where(:dir(ltr),[dir=ltr],[dir=ltr] *){padding-left:calc(var(--hx-spacing) * 16)}.hx\:ltr\:text-right:where(:dir(ltr),[dir=ltr],[dir=ltr] *){text-align:right}.hx\:ltr\:before\:left-0:where(:dir(ltr),[dir=ltr],[dir=ltr] *):before{content:var(--tw-content);left:calc(var(--hx-spacing) * 0)}.hx\:rtl\:left-2:where(:dir(rtl),[dir=rtl],[dir=rtl] *){left:calc(var(--hx-spacing) * 2)}.hx\:rtl\:left-3:where(:dir(rtl),[dir=rtl],[dir=rtl] *){left:calc(var(--hx-spacing) * 3)}.hx\:rtl\:mr-1:where(:dir(rtl),[dir=rtl],[dir=rtl] *){margin-right:calc(var(--hx-spacing) * 1)}.hx\:rtl\:mr-3:where(:dir(rtl),[dir=rtl],[dir=rtl] *){margin-right:calc(var(--hx-spacing) * 3)}.hx\:rtl\:mr-auto:where(:dir(rtl),[dir=rtl],[dir=rtl] *){margin-right:auto}.hx\:rtl\:-ml-4:where(:dir(rtl),[dir=rtl],[dir=rtl] *){margin-left:calc(var(--hx-spacing) * -4)}.hx\:rtl\:ml-auto:where(:dir(rtl),[dir=rtl],[dir=rtl] *){margin-left:auto}.hx\:rtl\:-rotate-180:where(:dir(rtl),[dir=rtl],[dir=rtl] *){rotate:-180deg}.hx\:rtl\:rotate-270:where(:dir(rtl),[dir=rtl],[dir=rtl] *){rotate:270deg}.hx\:rtl\:rounded-l-lg:where(:dir(rtl),[dir=rtl],[dir=rtl] *){border-top-left-radius:var(--hx-radius-lg);border-bottom-left-radius:var(--hx-radius-lg)}.hx\:rtl\:rounded-r-lg:where(:dir(rtl),[dir=rtl],[dir=rtl] *){border-top-right-radius:var(--hx-radius-lg);border-bottom-right-radius:var(--hx-radius-lg)}.hx\:rtl\:border-r:where(:dir(rtl),[dir=rtl],[dir=rtl] *){border-right-style:var(--tw-border-style);border-right-width:1px}.hx\:rtl\:pr-3:where(:dir(rtl),[dir=rtl],[dir=rtl] *){padding-right:calc(var(--hx-spacing) * 3)}.hx\:rtl\:pr-4:where(:dir(rtl),[dir=rtl],[dir=rtl] *){padding-right:calc(var(--hx-spacing) * 4)}.hx\:rtl\:pr-5:where(:dir(rtl),[dir=rtl],[dir=rtl] *){padding-right:calc(var(--hx-spacing) * 5)}.hx\:rtl\:pr-6:where(:dir(rtl),[dir=rtl],[dir=rtl] *){padding-right:calc(var(--hx-spacing) * 6)}.hx\:rtl\:pr-8:where(:dir(rtl),[dir=rtl],[dir=rtl] *){padding-right:calc(var(--hx-spacing) * 8)}.hx\:rtl\:pr-12:where(:dir(rtl),[dir=rtl],[dir=rtl] *){padding-right:calc(var(--hx-spacing) * 12)}.hx\:rtl\:pr-16:where(:dir(rtl),[dir=rtl],[dir=rtl] *){padding-right:calc(var(--hx-spacing) * 16)}.hx\:rtl\:pl-0:where(:dir(rtl),[dir=rtl],[dir=rtl] *){padding-left:calc(var(--hx-spacing) * 0)}.hx\:rtl\:pl-2:where(:dir(rtl),[dir=rtl],[dir=rtl] *){padding-left:calc(var(--hx-spacing) * 2)}.hx\:rtl\:pl-4:where(:dir(rtl),[dir=rtl],[dir=rtl] *){padding-left:calc(var(--hx-spacing) * 4)}.hx\:rtl\:pl-8:where(:dir(rtl),[dir=rtl],[dir=rtl] *){padding-left:calc(var(--hx-spacing) * 8)}.hx\:rtl\:pl-9:where(:dir(rtl),[dir=rtl],[dir=rtl] *){padding-left:calc(var(--hx-spacing) * 9)}.hx\:rtl\:text-left:where(:dir(rtl),[dir=rtl],[dir=rtl] *){text-align:left}.hx\:rtl\:before\:right-0:where(:dir(rtl),[dir=rtl],[dir=rtl] *):before{content:var(--tw-content);right:calc(var(--hx-spacing) * 0)}.hx\:rtl\:before\:rotate-180:where(:dir(rtl),[dir=rtl],[dir=rtl] *):before{content:var(--tw-content);rotate:180deg}.hx\:dark\:block:where(.dark,.dark *){display:block}.hx\:dark\:hidden:where(.dark,.dark *){display:none}.hx\:dark\:border-amber-200\/30:where(.dark,.dark *){border-color:var(--hx-color-amber-200)}@supports (color:color-mix(in lab, red, red)){.hx\:dark\:border-amber-200\/30:where(.dark,.dark *){border-color:color-mix(in oklab, var(--hx-color-amber-200) 30%, transparent)}}.hx\:dark\:border-blue-200\/30:where(.dark,.dark *){border-color:var(--hx-color-blue-200)}@supports (color:color-mix(in lab, red, red)){.hx\:dark\:border-blue-200\/30:where(.dark,.dark *){border-color:color-mix(in oklab, var(--hx-color-blue-200) 30%, transparent)}}.hx\:dark\:border-gray-400:where(.dark,.dark *){border-color:var(--hx-color-gray-400)}.hx\:dark\:border-green-200\/30:where(.dark,.dark *){border-color:var(--hx-color-green-200)}@supports (color:color-mix(in lab, red, red)){.hx\:dark\:border-green-200\/30:where(.dark,.dark *){border-color:color-mix(in oklab, var(--hx-color-green-200) 30%, transparent)}}.hx\:dark\:border-indigo-200\/30:where(.dark,.dark *){border-color:var(--hx-color-indigo-200)}@supports (color:color-mix(in lab, red, red)){.hx\:dark\:border-indigo-200\/30:where(.dark,.dark *){border-color:color-mix(in oklab, var(--hx-color-indigo-200) 30%, transparent)}}.hx\:dark\:border-neutral-700:where(.dark,.dark *){border-color:var(--hx-color-neutral-700)}.hx\:dark\:border-neutral-800:where(.dark,.dark *){border-color:var(--hx-color-neutral-800)}.hx\:dark\:border-orange-400\/30:where(.dark,.dark *){border-color:var(--hx-color-orange-400)}@supports (color:color-mix(in lab, red, red)){.hx\:dark\:border-orange-400\/30:where(.dark,.dark *){border-color:color-mix(in oklab, var(--hx-color-orange-400) 30%, transparent)}}.hx\:dark\:border-purple-200\/30:where(.dark,.dark *){border-color:var(--hx-color-purple-200)}@supports (color:color-mix(in lab, red, red)){.hx\:dark\:border-purple-200\/30:where(.dark,.dark *){border-color:color-mix(in oklab, var(--hx-color-purple-200) 30%, transparent)}}.hx\:dark\:border-red-200\/30:where(.dark,.dark *){border-color:var(--hx-color-red-200)}@supports (color:color-mix(in lab, red, red)){.hx\:dark\:border-red-200\/30:where(.dark,.dark *){border-color:color-mix(in oklab, var(--hx-color-red-200) 30%, transparent)}}.hx\:dark\:border-white\/10:where(.dark,.dark *){border-color:var(--hx-color-white)}@supports (color:color-mix(in lab, red, red)){.hx\:dark\:border-white\/10:where(.dark,.dark *){border-color:color-mix(in oklab, var(--hx-color-white) 10%, transparent)}}.hx\:dark\:border-yellow-200\/30:where(.dark,.dark *){border-color:var(--hx-color-yellow-200)}@supports (color:color-mix(in lab, red, red)){.hx\:dark\:border-yellow-200\/30:where(.dark,.dark *){border-color:color-mix(in oklab, var(--hx-color-yellow-200) 30%, transparent)}}.hx\:dark\:bg-amber-900\/30:where(.dark,.dark *){background-color:var(--hx-color-amber-900)}@supports (color:color-mix(in lab, red, red)){.hx\:dark\:bg-amber-900\/30:where(.dark,.dark *){background-color:color-mix(in oklab, var(--hx-color-amber-900) 30%, transparent)}}.hx\:dark\:bg-blue-900\/30:where(.dark,.dark *){background-color:var(--hx-color-blue-900)}@supports (color:color-mix(in lab, red, red)){.hx\:dark\:bg-blue-900\/30:where(.dark,.dark *){background-color:color-mix(in oklab, var(--hx-color-blue-900) 30%, transparent)}}.hx\:dark\:bg-dark:where(.dark,.dark *){background-color:var(--hx-color-dark)}.hx\:dark\:bg-green-900\/30:where(.dark,.dark *){background-color:var(--hx-color-green-900)}@supports (color:color-mix(in lab, red, red)){.hx\:dark\:bg-green-900\/30:where(.dark,.dark *){background-color:color-mix(in oklab, var(--hx-color-green-900) 30%, transparent)}}.hx\:dark\:bg-indigo-900\/30:where(.dark,.dark *){background-color:var(--hx-color-indigo-900)}@supports (color:color-mix(in lab, red, red)){.hx\:dark\:bg-indigo-900\/30:where(.dark,.dark *){background-color:color-mix(in oklab, var(--hx-color-indigo-900) 30%, transparent)}}.hx\:dark\:bg-neutral-700:where(.dark,.dark *){background-color:var(--hx-color-neutral-700)}.hx\:dark\:bg-neutral-800:where(.dark,.dark *){background-color:var(--hx-color-neutral-800)}.hx\:dark\:bg-neutral-900:where(.dark,.dark *){background-color:var(--hx-color-neutral-900)}.hx\:dark\:bg-orange-400\/20:where(.dark,.dark *){background-color:var(--hx-color-orange-400)}@supports (color:color-mix(in lab, red, red)){.hx\:dark\:bg-orange-400\/20:where(.dark,.dark *){background-color:color-mix(in oklab, var(--hx-color-orange-400) 20%, transparent)}}.hx\:dark\:bg-primary-300\/10:where(.dark,.dark *){background-color:var(--hx-color-primary-300)}@supports (color:color-mix(in lab, red, red)){.hx\:dark\:bg-primary-300\/10:where(.dark,.dark *){background-color:color-mix(in oklab, var(--hx-color-primary-300) 10%, transparent)}}.hx\:dark\:bg-primary-400\/10:where(.dark,.dark *){background-color:var(--hx-color-primary-400)}@supports (color:color-mix(in lab, red, red)){.hx\:dark\:bg-primary-400\/10:where(.dark,.dark *){background-color:color-mix(in oklab, var(--hx-color-primary-400) 10%, transparent)}}.hx\:dark\:bg-primary-600:where(.dark,.dark *){background-color:var(--hx-color-primary-600)}.hx\:dark\:bg-purple-900\/30:where(.dark,.dark *){background-color:var(--hx-color-purple-900)}@supports (color:color-mix(in lab, red, red)){.hx\:dark\:bg-purple-900\/30:where(.dark,.dark *){background-color:color-mix(in oklab, var(--hx-color-purple-900) 30%, transparent)}}.hx\:dark\:bg-red-900\/30:where(.dark,.dark *){background-color:var(--hx-color-red-900)}@supports (color:color-mix(in lab, red, red)){.hx\:dark\:bg-red-900\/30:where(.dark,.dark *){background-color:color-mix(in oklab, var(--hx-color-red-900) 30%, transparent)}}.hx\:dark\:bg-yellow-700\/30:where(.dark,.dark *){background-color:var(--hx-color-yellow-700)}@supports (color:color-mix(in lab, red, red)){.hx\:dark\:bg-yellow-700\/30:where(.dark,.dark *){background-color:color-mix(in oklab, var(--hx-color-yellow-700) 30%, transparent)}}.hx\:dark\:from-gray-100:where(.dark,.dark *){--tw-gradient-from:var(--hx-color-gray-100);--tw-gradient-stops:var(--tw-gradient-via-stops,var(--tw-gradient-position), var(--tw-gradient-from) var(--tw-gradient-from-position), var(--tw-gradient-to) var(--tw-gradient-to-position))}.hx\:dark\:to-gray-400:where(.dark,.dark *){--tw-gradient-to:var(--hx-color-gray-400);--tw-gradient-stops:var(--tw-gradient-via-stops,var(--tw-gradient-position), var(--tw-gradient-from) var(--tw-gradient-from-position), var(--tw-gradient-to) var(--tw-gradient-to-position))}.hx\:dark\:text-amber-200:where(.dark,.dark *){color:var(--hx-color-amber-200)}.hx\:dark\:text-blue-200:where(.dark,.dark *){color:var(--hx-color-blue-200)}.hx\:dark\:text-gray-50:where(.dark,.dark *){color:var(--hx-color-gray-50)}.hx\:dark\:text-gray-100:where(.dark,.dark *){color:var(--hx-color-gray-100)}.hx\:dark\:text-gray-200:where(.dark,.dark *){color:var(--hx-color-gray-200)}.hx\:dark\:text-gray-300:where(.dark,.dark *){color:var(--hx-color-gray-300)}.hx\:dark\:text-gray-400:where(.dark,.dark *){color:var(--hx-color-gray-400)}.hx\:dark\:text-green-200:where(.dark,.dark *){color:var(--hx-color-green-200)}.hx\:dark\:text-indigo-200:where(.dark,.dark *){color:var(--hx-color-indigo-200)}.hx\:dark\:text-neutral-200:where(.dark,.dark *){color:var(--hx-color-neutral-200)}.hx\:dark\:text-neutral-400:where(.dark,.dark *){color:var(--hx-color-neutral-400)}.hx\:dark\:text-orange-300:where(.dark,.dark *){color:var(--hx-color-orange-300)}.hx\:dark\:text-primary-600:where(.dark,.dark *){color:var(--hx-color-primary-600)}.hx\:dark\:text-purple-200:where(.dark,.dark *){color:var(--hx-color-purple-200)}.hx\:dark\:text-red-200:where(.dark,.dark *){color:var(--hx-color-red-200)}.hx\:dark\:text-slate-100:where(.dark,.dark *){color:var(--hx-color-slate-100)}.hx\:dark\:text-white:where(.dark,.dark *){color:var(--hx-color-white)}.hx\:dark\:text-yellow-200:where(.dark,.dark *){color:var(--hx-color-yellow-200)}.hx\:dark\:opacity-80:where(.dark,.dark *){opacity:.8}.hx\:dark\:shadow-\[0_-1px_0_rgba\(255\,255\,255\,\.1\)_inset\]:where(.dark,.dark *){--tw-shadow:0 -1px 0 var(--tw-shadow-color,#ffffff1a) inset;box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.hx\:dark\:shadow-\[0_-12px_16px_\#111\]:where(.dark,.dark *){--tw-shadow:0 -12px 16px var(--tw-shadow-color,#111);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.hx\:dark\:shadow-none:where(.dark,.dark *){--tw-shadow:0 0 #0000;box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}@media (hover:hover){.hx\:dark\:group-hover\:text-gray-50:where(.dark,.dark *):is(:where(.hx\:group):hover *){color:var(--hx-color-gray-50)}}.hx\:group-data-\[active\=true\]\:dark\:text-primary-600:is(:where(.hx\:group)[data-active=true] *):where(.dark,.dark *){color:var(--hx-color-primary-600)}.hx\:dark\:before\:bg-neutral-800:where(.dark,.dark *):before{content:var(--tw-content);background-color:var(--hx-color-neutral-800)}.hx\:dark\:before\:invert:where(.dark,.dark *):before{content:var(--tw-content);--tw-invert:invert(100%);filter:var(--tw-blur,) var(--tw-brightness,) var(--tw-contrast,) var(--tw-grayscale,) var(--tw-hue-rotate,) var(--tw-invert,) var(--tw-saturate,) var(--tw-sepia,) var(--tw-drop-shadow,)}@media (hover:hover){.hx\:dark\:hover\:border-gray-100:where(.dark,.dark *):hover{border-color:var(--hx-color-gray-100)}.hx\:dark\:hover\:border-gray-600:where(.dark,.dark *):hover{border-color:var(--hx-color-gray-600)}.hx\:dark\:hover\:border-neutral-500:where(.dark,.dark *):hover{border-color:var(--hx-color-neutral-500)}.hx\:dark\:hover\:border-neutral-700:where(.dark,.dark *):hover{border-color:var(--hx-color-neutral-700)}.hx\:dark\:hover\:border-neutral-800:where(.dark,.dark *):hover{border-color:var(--hx-color-neutral-800)}.hx\:dark\:hover\:bg-gray-100\/5:where(.dark,.dark *):hover{background-color:var(--hx-color-gray-100)}@supports (color:color-mix(in lab, red, red)){.hx\:dark\:hover\:bg-gray-100\/5:where(.dark,.dark *):hover{background-color:color-mix(in oklab, var(--hx-color-gray-100) 5%, transparent)}}.hx\:dark\:hover\:bg-neutral-700:where(.dark,.dark *):hover{background-color:var(--hx-color-neutral-700)}.hx\:dark\:hover\:bg-neutral-800:where(.dark,.dark *):hover{background-color:var(--hx-color-neutral-800)}.hx\:dark\:hover\:bg-neutral-900:where(.dark,.dark *):hover{background-color:var(--hx-color-neutral-900)}.hx\:dark\:hover\:bg-primary-100\/5:where(.dark,.dark *):hover{background-color:var(--hx-color-primary-100)}@supports (color:color-mix(in lab, red, red)){.hx\:dark\:hover\:bg-primary-100\/5:where(.dark,.dark *):hover{background-color:color-mix(in oklab, var(--hx-color-primary-100) 5%, transparent)}}.hx\:dark\:hover\:bg-primary-700:where(.dark,.dark *):hover{background-color:var(--hx-color-primary-700)}.hx\:dark\:hover\:text-gray-50:where(.dark,.dark *):hover{color:var(--hx-color-gray-50)}.hx\:dark\:hover\:text-gray-100:where(.dark,.dark *):hover{color:var(--hx-color-gray-100)}.hx\:dark\:hover\:text-gray-200:where(.dark,.dark *):hover{color:var(--hx-color-gray-200)}.hx\:dark\:hover\:text-gray-300:where(.dark,.dark *):hover{color:var(--hx-color-gray-300)}.hx\:dark\:hover\:text-neutral-50:where(.dark,.dark *):hover{color:var(--hx-color-neutral-50)}.hx\:dark\:hover\:text-primary-400:where(.dark,.dark *):hover{color:var(--hx-color-primary-400)}.hx\:dark\:hover\:text-white:where(.dark,.dark *):hover{color:var(--hx-color-white)}.hx\:dark\:hover\:shadow-none:where(.dark,.dark *):hover{--tw-shadow:0 0 #0000;box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}}.hx\:data-\[state\=selected\]\:dark\:border-primary-500[data-state=selected]:where(.dark,.dark *){border-color:var(--hx-color-primary-500)}.hx\:data-\[state\=selected\]\:dark\:text-primary-600[data-state=selected]:where(.dark,.dark *){color:var(--hx-color-primary-600)}@media (prefers-contrast:more){.hx\:contrast-more\:dark\:border-current:where(.dark,.dark *){border-color:currentColor}.hx\:contrast-more\:dark\:border-gray-50:where(.dark,.dark *){border-color:var(--hx-color-gray-50)}.hx\:contrast-more\:dark\:border-neutral-400:where(.dark,.dark *){border-color:var(--hx-color-neutral-400)}.hx\:contrast-more\:dark\:border-primary-500:where(.dark,.dark *){border-color:var(--hx-color-primary-500)}.hx\:dark\:contrast-more\:border-neutral-400:where(.dark,.dark *){border-color:var(--hx-color-neutral-400)}.hx\:contrast-more\:dark\:text-current:where(.dark,.dark *){color:currentColor}.hx\:contrast-more\:dark\:text-gray-50:where(.dark,.dark *){color:var(--hx-color-gray-50)}.hx\:contrast-more\:dark\:text-gray-100:where(.dark,.dark *){color:var(--hx-color-gray-100)}.hx\:contrast-more\:dark\:shadow-\[0_0_0_1px_\#fff\]:where(.dark,.dark *){--tw-shadow:0 0 0 1px var(--tw-shadow-color,#fff);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.hx\:contrast-more\:dark\:shadow-none:where(.dark,.dark *){--tw-shadow:0 0 #0000;box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}@media (hover:hover){.hx\:contrast-more\:dark\:hover\:border-gray-50:where(.dark,.dark *):hover{border-color:var(--hx-color-gray-50)}}}@media print{.hx\:print\:\[display\:none\],.hx\:print\:hidden{display:none}.hx\:print\:bg-transparent{background-color:#0000}}}html{font-size:var(--hx-text-base);line-height:var(--tw-leading,var(--hx-text-base--line-height));-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}body{background-color:var(--hx-color-white);width:100%}body:where(.dark,.dark *){background-color:var(--hx-color-dark);color:var(--hx-color-gray-100)}:root{--primary-hue:212deg;--primary-saturation:100%;--primary-lightness:50%;--hextra-navbar-height:3.5rem;--hextra-banner-height:2rem;--menu-height:3.75rem}.dark{--primary-hue:204deg;--primary-saturation:100%;--primary-lightness:50%}@media (prefers-reduced-motion:reduce){*,:before,:after{scroll-behavior:auto!important;transition-duration:.01ms!important;animation-duration:.01ms!important;animation-iteration-count:1!important}svg,svg *{transition-duration:0s!important}}.content :where(h1):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:calc(var(--hx-spacing) * 2);font-size:var(--hx-text-4xl);line-height:var(--tw-leading,var(--hx-text-4xl--line-height));--tw-font-weight:var(--hx-font-weight-bold);font-weight:var(--hx-font-weight-bold);--tw-tracking:var(--hx-tracking-tight);letter-spacing:var(--hx-tracking-tight);color:var(--hx-color-slate-900)}.content :where(h1):not(:where([class~=not-prose],[class~=not-prose] *)):where(.dark,.dark *){color:var(--hx-color-slate-100)}.content :where(h2):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:calc(var(--hx-spacing) * 10);border-bottom-style:var(--tw-border-style);border-bottom-width:1px;border-color:var(--hx-color-neutral-200)}@supports (color:color-mix(in lab, red, red)){.content :where(h2):not(:where([class~=not-prose],[class~=not-prose] *)){border-color:color-mix(in oklab, var(--hx-color-neutral-200) 70%, transparent)}}.content :where(h2):not(:where([class~=not-prose],[class~=not-prose] *)){padding-bottom:calc(var(--hx-spacing) * 1);font-size:var(--hx-text-3xl);line-height:var(--tw-leading,var(--hx-text-3xl--line-height));--tw-font-weight:var(--hx-font-weight-semibold);font-weight:var(--hx-font-weight-semibold);--tw-tracking:var(--hx-tracking-tight);letter-spacing:var(--hx-tracking-tight);color:var(--hx-color-slate-900)}@media (prefers-contrast:more){.content :where(h2):not(:where([class~=not-prose],[class~=not-prose] *)){border-color:var(--hx-color-neutral-400)}}.content :where(h2):not(:where([class~=not-prose],[class~=not-prose] *)):where(.dark,.dark *){border-color:var(--hx-color-primary-100)}@supports (color:color-mix(in lab, red, red)){.content :where(h2):not(:where([class~=not-prose],[class~=not-prose] *)):where(.dark,.dark *){border-color:color-mix(in oklab, var(--hx-color-primary-100) 10%, transparent)}}.content :where(h2):not(:where([class~=not-prose],[class~=not-prose] *)):where(.dark,.dark *){color:var(--hx-color-slate-100)}@media (prefers-contrast:more){.content :where(h2):not(:where([class~=not-prose],[class~=not-prose] *)):where(.dark,.dark *){border-color:var(--hx-color-neutral-400)}}.content :where(h3):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:calc(var(--hx-spacing) * 8);font-size:var(--hx-text-2xl);line-height:var(--tw-leading,var(--hx-text-2xl--line-height));--tw-font-weight:var(--hx-font-weight-semibold);font-weight:var(--hx-font-weight-semibold);--tw-tracking:var(--hx-tracking-tight);letter-spacing:var(--hx-tracking-tight);color:var(--hx-color-slate-900)}.content :where(h3):not(:where([class~=not-prose],[class~=not-prose] *)):where(.dark,.dark *){color:var(--hx-color-slate-100)}.content :where(h4):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:calc(var(--hx-spacing) * 8);font-size:var(--hx-text-xl);line-height:var(--tw-leading,var(--hx-text-xl--line-height));--tw-font-weight:var(--hx-font-weight-semibold);font-weight:var(--hx-font-weight-semibold);--tw-tracking:var(--hx-tracking-tight);letter-spacing:var(--hx-tracking-tight);color:var(--hx-color-slate-900)}.content :where(h4):not(:where([class~=not-prose],[class~=not-prose] *)):where(.dark,.dark *){color:var(--hx-color-slate-100)}.content :where(h5):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:calc(var(--hx-spacing) * 8);font-size:var(--hx-text-lg);line-height:var(--tw-leading,var(--hx-text-lg--line-height));--tw-font-weight:var(--hx-font-weight-semibold);font-weight:var(--hx-font-weight-semibold);--tw-tracking:var(--hx-tracking-tight);letter-spacing:var(--hx-tracking-tight);color:var(--hx-color-slate-900)}.content :where(h5):not(:where([class~=not-prose],[class~=not-prose] *)):where(.dark,.dark *){color:var(--hx-color-slate-100)}.content :where(h6):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:calc(var(--hx-spacing) * 8);font-size:var(--hx-text-base);line-height:var(--tw-leading,var(--hx-text-base--line-height));--tw-font-weight:var(--hx-font-weight-semibold);font-weight:var(--hx-font-weight-semibold);--tw-tracking:var(--hx-tracking-tight);letter-spacing:var(--hx-tracking-tight);color:var(--hx-color-slate-900)}.content :where(h6):not(:where([class~=not-prose],[class~=not-prose] *)):where(.dark,.dark *){color:var(--hx-color-slate-100)}.content :where(p):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:calc(var(--hx-spacing) * 6);--tw-leading:calc(var(--hx-spacing) * 7);line-height:calc(var(--hx-spacing) * 7)}.content :where(p):not(:where([class~=not-prose],[class~=not-prose] *)):first-child{margin-top:calc(var(--hx-spacing) * 0)}.content :where(a):not(:where([class~=not-prose],[class~=not-prose] *)){color:var(--hx-color-primary-600);text-decoration-line:underline;text-decoration-thickness:from-font}.content :where(blockquote):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:calc(var(--hx-spacing) * 6);border-color:var(--hx-color-gray-300);color:var(--hx-color-gray-700);font-style:italic}.content :where(blockquote):not(:where([class~=not-prose],[class~=not-prose] *)):first-child{margin-top:calc(var(--hx-spacing) * 0)}.content :where(blockquote):not(:where([class~=not-prose],[class~=not-prose] *)):where(:dir(ltr),[dir=ltr],[dir=ltr] *){border-left-style:var(--tw-border-style);padding-left:calc(var(--hx-spacing) * 6);border-left-width:2px}.content :where(blockquote):not(:where([class~=not-prose],[class~=not-prose] *)):where(:dir(rtl),[dir=rtl],[dir=rtl] *){border-right-style:var(--tw-border-style);padding-right:calc(var(--hx-spacing) * 6);border-right-width:2px}.content :where(blockquote):not(:where([class~=not-prose],[class~=not-prose] *)):where(.dark,.dark *){border-color:var(--hx-color-gray-700);color:var(--hx-color-gray-400)}.content :where(pre):not(:where(.hextra-code-block pre,[class~=not-prose],[class~=not-prose] *)){margin-bottom:calc(var(--hx-spacing) * 4);border-radius:var(--hx-radius-xl);background-color:var(--hx-color-primary-700);overflow-x:auto}@supports (color:color-mix(in lab, red, red)){.content :where(pre):not(:where(.hextra-code-block pre,[class~=not-prose],[class~=not-prose] *)){background-color:color-mix(in oklab, var(--hx-color-primary-700) 5%, transparent)}}.content :where(pre):not(:where(.hextra-code-block pre,[class~=not-prose],[class~=not-prose] *)){padding-block:calc(var(--hx-spacing) * 4);--tw-font-weight:var(--hx-font-weight-medium);font-size:.9em;font-weight:var(--hx-font-weight-medium);-webkit-font-smoothing:auto;-moz-osx-font-smoothing:auto}@media (prefers-contrast:more){.content :where(pre):not(:where(.hextra-code-block pre,[class~=not-prose],[class~=not-prose] *)){border-style:var(--tw-border-style);border-width:1px;border-color:var(--hx-color-primary-900)}@supports (color:color-mix(in lab, red, red)){.content :where(pre):not(:where(.hextra-code-block pre,[class~=not-prose],[class~=not-prose] *)){border-color:color-mix(in oklab, var(--hx-color-primary-900) 20%, transparent)}}.content :where(pre):not(:where(.hextra-code-block pre,[class~=not-prose],[class~=not-prose] *)){--tw-contrast:contrast(150%);filter:var(--tw-blur,) var(--tw-brightness,) var(--tw-contrast,) var(--tw-grayscale,) var(--tw-hue-rotate,) var(--tw-invert,) var(--tw-saturate,) var(--tw-sepia,) var(--tw-drop-shadow,)}}.content :where(pre):not(:where(.hextra-code-block pre,[class~=not-prose],[class~=not-prose] *)):where(.dark,.dark *){background-color:var(--hx-color-primary-300)}@supports (color:color-mix(in lab, red, red)){.content :where(pre):not(:where(.hextra-code-block pre,[class~=not-prose],[class~=not-prose] *)):where(.dark,.dark *){background-color:color-mix(in oklab, var(--hx-color-primary-300) 10%, transparent)}}@media (prefers-contrast:more){.content :where(pre):not(:where(.hextra-code-block pre,[class~=not-prose],[class~=not-prose] *)):where(.dark,.dark *){border-color:var(--hx-color-primary-100)}@supports (color:color-mix(in lab, red, red)){.content :where(pre):not(:where(.hextra-code-block pre,[class~=not-prose],[class~=not-prose] *)):where(.dark,.dark *){border-color:color-mix(in oklab, var(--hx-color-primary-100) 40%, transparent)}}}.content :where(code):not(:where(.hextra-code-block code,[class~=not-prose],[class~=not-prose] *)){border-radius:var(--hx-radius-md);border-style:var(--tw-border-style);border-width:1px;border-color:var(--hx-color-black)}@supports (color:color-mix(in lab, red, red)){.content :where(code):not(:where(.hextra-code-block code,[class~=not-prose],[class~=not-prose] *)){border-color:color-mix(in oklab, var(--hx-color-black) 4%, transparent)}}.content :where(code):not(:where(.hextra-code-block code,[class~=not-prose],[class~=not-prose] *)){background-color:var(--hx-color-black)}@supports (color:color-mix(in lab, red, red)){.content :where(code):not(:where(.hextra-code-block code,[class~=not-prose],[class~=not-prose] *)){background-color:color-mix(in oklab, var(--hx-color-black) 3%, transparent)}}.content :where(code):not(:where(.hextra-code-block code,[class~=not-prose],[class~=not-prose] *)){padding-inline:.25em;padding-block:calc(var(--hx-spacing) * .5);overflow-wrap:break-word;font-size:.9em}.content :where(code):not(:where(.hextra-code-block code,[class~=not-prose],[class~=not-prose] *)):where(.dark,.dark *){border-color:var(--hx-color-white)}@supports (color:color-mix(in lab, red, red)){.content :where(code):not(:where(.hextra-code-block code,[class~=not-prose],[class~=not-prose] *)):where(.dark,.dark *){border-color:color-mix(in oklab, var(--hx-color-white) 10%, transparent)}}.content :where(code):not(:where(.hextra-code-block code,[class~=not-prose],[class~=not-prose] *)):where(.dark,.dark *){background-color:var(--hx-color-white)}@supports (color:color-mix(in lab, red, red)){.content :where(code):not(:where(.hextra-code-block code,[class~=not-prose],[class~=not-prose] *)):where(.dark,.dark *){background-color:color-mix(in oklab, var(--hx-color-white) 10%, transparent)}}.content :where(table):not(:where(.hextra-code-block table,[class~=not-prose],[class~=not-prose] *)){margin-block:calc(var(--hx-spacing) * 6);border-collapse:collapse;width:100%;padding:calc(var(--hx-spacing) * 0);font-size:var(--hx-text-sm);line-height:var(--tw-leading,var(--hx-text-sm--line-height));--tw-leading:calc(var(--hx-spacing) * 5);line-height:calc(var(--hx-spacing) * 5);display:block;overflow-x:auto}.content :where(table):not(:where(.hextra-code-block table,[class~=not-prose],[class~=not-prose] *)):first-child{margin-top:calc(var(--hx-spacing) * 0)}.content :where(table):not(:where(.hextra-code-block table,[class~=not-prose],[class~=not-prose] *)) thead{background-color:var(--hx-color-gray-50)}.content :where(table):not(:where(.hextra-code-block table,[class~=not-prose],[class~=not-prose] *)) thead:where(.dark,.dark *){background-color:var(--hx-color-gray-600)}@supports (color:color-mix(in lab, red, red)){.content :where(table):not(:where(.hextra-code-block table,[class~=not-prose],[class~=not-prose] *)) thead:where(.dark,.dark *){background-color:color-mix(in oklab, var(--hx-color-gray-600) 20%, transparent)}}.content :where(table):not(:where(.hextra-code-block table,[class~=not-prose],[class~=not-prose] *)) tr{margin:calc(var(--hx-spacing) * 0);border-top-style:var(--tw-border-style);border-top-width:1px;border-color:var(--hx-color-gray-300);padding:calc(var(--hx-spacing) * 0)}.content :where(table):not(:where(.hextra-code-block table,[class~=not-prose],[class~=not-prose] *)) tr:where(.dark,.dark *){border-color:var(--hx-color-gray-600)}.content :where(table):not(:where(.hextra-code-block table,[class~=not-prose],[class~=not-prose] *)) th{margin:calc(var(--hx-spacing) * 0);border-style:var(--tw-border-style);border-width:1px;border-color:var(--hx-color-gray-300);padding:calc(var(--hx-spacing) * 2);--tw-font-weight:var(--hx-font-weight-semibold);font-weight:var(--hx-font-weight-semibold)}.content :where(table):not(:where(.hextra-code-block table,[class~=not-prose],[class~=not-prose] *)) th:where(.dark,.dark *){border-color:var(--hx-color-gray-600)}.content :where(table):not(:where(.hextra-code-block table,[class~=not-prose],[class~=not-prose] *)) td{margin:calc(var(--hx-spacing) * 0);border-style:var(--tw-border-style);border-width:1px;border-color:var(--hx-color-gray-300);padding:calc(var(--hx-spacing) * 2)}.content :where(table):not(:where(.hextra-code-block table,[class~=not-prose],[class~=not-prose] *)) td:where(.dark,.dark *){border-color:var(--hx-color-gray-600)}.content :where(ol):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:calc(var(--hx-spacing) * 6);list-style-type:decimal}.content :where(ol):not(:where([class~=not-prose],[class~=not-prose] *)):first-child{margin-top:calc(var(--hx-spacing) * 0)}.content :where(ol):not(:where([class~=not-prose],[class~=not-prose] *)):where(:dir(ltr),[dir=ltr],[dir=ltr] *){margin-left:calc(var(--hx-spacing) * 6)}.content :where(ol):not(:where([class~=not-prose],[class~=not-prose] *)):where(:dir(rtl),[dir=rtl],[dir=rtl] *){margin-right:calc(var(--hx-spacing) * 6)}.content :where(ol):not(:where([class~=not-prose],[class~=not-prose] *)) li{margin-block:calc(var(--hx-spacing) * 2)}.content :where(ul):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:calc(var(--hx-spacing) * 6);list-style-type:disc}.content :where(ul):not(:where([class~=not-prose],[class~=not-prose] *)):first-child{margin-top:calc(var(--hx-spacing) * 0)}.content :where(ul):not(:where([class~=not-prose],[class~=not-prose] *)):where(:dir(ltr),[dir=ltr],[dir=ltr] *){margin-left:calc(var(--hx-spacing) * 6)}.content :where(ul):not(:where([class~=not-prose],[class~=not-prose] *)):where(:dir(rtl),[dir=rtl],[dir=rtl] *){margin-right:calc(var(--hx-spacing) * 6)}.content :where(ul):not(:where([class~=not-prose],[class~=not-prose] *)) li{margin-block:calc(var(--hx-spacing) * 2)}.content :where(ul):not(:where([class~=not-prose],[class~=not-prose] *)):has(li input[type=checkbox]){list-style-type:none}.content :where(ul,ol)>li>:where(ul,ol):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:calc(var(--hx-spacing) * 0)}.content :where(kbd):not(:where([class~=not-prose],[class~=not-prose] *)){border-radius:var(--hx-radius-md);border-style:var(--tw-border-style);border-width:1px;border-color:var(--hx-color-black)}@supports (color:color-mix(in lab, red, red)){.content :where(kbd):not(:where([class~=not-prose],[class~=not-prose] *)){border-color:color-mix(in oklab, var(--hx-color-black) 4%, transparent)}}.content :where(kbd):not(:where([class~=not-prose],[class~=not-prose] *)){background-color:var(--hx-color-black)}@supports (color:color-mix(in lab, red, red)){.content :where(kbd):not(:where([class~=not-prose],[class~=not-prose] *)){background-color:color-mix(in oklab, var(--hx-color-black) 3%, transparent)}}.content :where(kbd):not(:where([class~=not-prose],[class~=not-prose] *)){padding-inline:.25em;padding-block:calc(var(--hx-spacing) * .5);overflow-wrap:break-word;font-size:.9em}.content :where(kbd):not(:where([class~=not-prose],[class~=not-prose] *)):where(.dark,.dark *){border-color:var(--hx-color-white)}@supports (color:color-mix(in lab, red, red)){.content :where(kbd):not(:where([class~=not-prose],[class~=not-prose] *)):where(.dark,.dark *){border-color:color-mix(in oklab, var(--hx-color-white) 10%, transparent)}}.content :where(kbd):not(:where([class~=not-prose],[class~=not-prose] *)):where(.dark,.dark *){background-color:var(--hx-color-white)}@supports (color:color-mix(in lab, red, red)){.content :where(kbd):not(:where([class~=not-prose],[class~=not-prose] *)):where(.dark,.dark *){background-color:color-mix(in oklab, var(--hx-color-white) 10%, transparent)}}.content :where(pre.mermaid):not(:where(.hextra-code-block pre,[class~=not-prose],[class~=not-prose] *)){background-color:#0000;border-radius:0}.content :where(pre.mermaid):not(:where(.hextra-code-block pre,[class~=not-prose],[class~=not-prose] *)):where(.dark,.dark *){background-color:#0000}.content :where(img):not(:where([class~=not-prose],[class~=not-prose] *)){margin-inline:auto;margin-block:calc(var(--hx-spacing) * 4);border-radius:var(--hx-radius-md)}.content :where(figure):not(:where([class~=not-prose],[class~=not-prose] *)) figcaption{margin-top:calc(var(--hx-spacing) * 2);text-align:center;font-size:var(--hx-text-sm);line-height:var(--tw-leading,var(--hx-text-sm--line-height));color:var(--hx-color-gray-500);display:block}.content :where(figure):not(:where([class~=not-prose],[class~=not-prose] *)) figcaption:where(.dark,.dark *){color:var(--hx-color-gray-400)}.content :where(dl):not(:where([class~=not-prose],[class~=not-prose] *)) dt{margin-top:calc(var(--hx-spacing) * 6);--tw-font-weight:var(--hx-font-weight-semibold);font-weight:var(--hx-font-weight-semibold)}.content :where(dl):not(:where([class~=not-prose],[class~=not-prose] *)) dd{margin-block:calc(var(--hx-spacing) * 2);padding-inline-start:calc(var(--hx-spacing) * 6)}.content :where(hr):not(:where([class~=not-prose],[class~=not-prose] *)){margin-block:calc(var(--hx-spacing) * 10);border-color:var(--hx-color-gray-200)}.content :where(hr):not(:where([class~=not-prose],[class~=not-prose] *)):first-child{margin-top:calc(var(--hx-spacing) * 0)}.content :where(hr):not(:where([class~=not-prose],[class~=not-prose] *)):last-child{margin-bottom:calc(var(--hx-spacing) * 0)}.content :where(hr):not(:where([class~=not-prose],[class~=not-prose] *)):where(.dark,.dark *){border-color:var(--hx-color-neutral-800)}.content .footnotes{margin-top:calc(var(--hx-spacing) * 12);font-size:var(--hx-text-sm);line-height:var(--tw-leading,var(--hx-text-sm--line-height))}.content .footnotes hr{border-color:var(--hx-color-gray-200)}.content .footnotes hr:where(.dark,.dark *){border-color:var(--hx-color-neutral-800)}.content .subheading-anchor{opacity:0;transition-property:opacity;transition-timing-function:var(--tw-ease,var(--hx-default-transition-timing-function));transition-duration:var(--tw-duration,var(--hx-default-transition-duration))}.content .subheading-anchor:where(:dir(ltr),[dir=ltr],[dir=ltr] *){margin-left:calc(var(--hx-spacing) * 1)}.content .subheading-anchor:where(:dir(rtl),[dir=rtl],[dir=rtl] *){margin-right:calc(var(--hx-spacing) * 1)}span:target+:is(.content .subheading-anchor),:hover>:is(.content .subheading-anchor),.content .subheading-anchor:focus-visible{opacity:1}span+:is(.content .subheading-anchor),:hover>:is(.content .subheading-anchor){text-decoration-line:none!important}.content .subheading-anchor:after{content:var(--tw-content);color:var(--hx-color-gray-300)}.content .subheading-anchor:where(.dark,.dark *):after{content:var(--tw-content);color:var(--hx-color-neutral-700)}.content .subheading-anchor:after{padding-inline:calc(var(--hx-spacing) * 1);--tw-content:"#";content:var(--tw-content)}span:target+:is(){color:var(--hx-color-gray-400)}span:target+:is():where(.dark,.dark *){color:var(--hx-color-neutral-500)}article details>summary::-webkit-details-marker{display:none}article details>summary:before{vertical-align:-4px;background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' class='hx:h-5 hx:w-5' viewBox='0 0 20 20' fill='currentColor'%3E%3Cpath fill-rule='evenodd' d='M7.293 14.707a1 1 0 010-1.414L10.586 10 7.293 6.707a1 1 0 011.414-1.414l4 4a1 1 0 010 1.414l-4 4a1 1 0 01-1.414 0z' clip-rule='evenodd' /%3E%3C/svg%3E");width:1.2em;height:1.2em;padding:0 .6em}:lang(fa) ol{list-style-type:persian}.highlight .chroma .err{color:#a61717;background-color:#e3d2d2}.highlight .chroma .lnlinks{color:inherit;outline:none;text-decoration:none}.highlight .chroma .line{display:flex}.highlight .chroma .k,.highlight .chroma .kc,.highlight .chroma .kd,.highlight .chroma .kn,.highlight .chroma .kp,.highlight .chroma .kr{color:#000;font-weight:700}.highlight .chroma .kt{color:#458;font-weight:700}.highlight .chroma .na{color:teal}.highlight .chroma .nb{color:#0086b3}.highlight .chroma .bp{color:#999}.highlight .chroma .nc{color:#458;font-weight:700}.highlight .chroma .no{color:teal}.highlight .chroma .nd{color:#3c5d5d;font-weight:700}.highlight .chroma .ni{color:purple}.highlight .chroma .ne,.highlight .chroma .nf,.highlight .chroma .nl{color:#900;font-weight:700}.highlight .chroma .nn{color:#555}.highlight .chroma .nt{color:navy}.highlight .chroma .nv,.highlight .chroma .vc,.highlight .chroma .vg,.highlight .chroma .vi{color:teal}.highlight .chroma .s,.highlight .chroma .sa,.highlight .chroma .sb,.highlight .chroma .sc,.highlight .chroma .dl,.highlight .chroma .sd,.highlight .chroma .s2,.highlight .chroma .se,.highlight .chroma .sh,.highlight .chroma .si,.highlight .chroma .sx{color:#d14}.highlight .chroma .sr{color:#009926}.highlight .chroma .s1{color:#d14}.highlight .chroma .ss{color:#990073}.highlight .chroma .m,.highlight .chroma .mb,.highlight .chroma .mf,.highlight .chroma .mh,.highlight .chroma .mi,.highlight .chroma .il,.highlight .chroma .mo{color:#099}.highlight .chroma .o,.highlight .chroma .ow{color:#000;font-weight:700}.highlight .chroma .c,.highlight .chroma .ch,.highlight .chroma .cm,.highlight .chroma .c1{color:#998;font-style:italic}.highlight .chroma .cs,.highlight .chroma .cp,.highlight .chroma .cpf{color:#999;font-style:italic;font-weight:700}.highlight .chroma .gd{color:#000;background-color:#fdd}.highlight .chroma .ge{color:#000;font-style:italic}.highlight .chroma .gr{color:#a00}.highlight .chroma .gh{color:#999}.highlight .chroma .gi{color:#000;background-color:#dfd}.highlight .chroma .go{color:#888}.highlight .chroma .gp{color:#555}.highlight .chroma .gs{font-weight:700}.highlight .chroma .gu{color:#aaa}.highlight .chroma .gt{color:#a00}.highlight .chroma .gl{text-decoration:underline}.highlight .chroma .w{color:#bbb}.dark .highlight .chroma .err{color:#f85149}.dark .highlight .chroma .lnlinks{color:inherit;outline:none;text-decoration:none}.dark .highlight .chroma .line{display:flex}.dark .highlight .chroma .k{color:#ff7b72}.dark .highlight .chroma .kc{color:#79c0ff}.dark .highlight .chroma .kd,.dark .highlight .chroma .kn{color:#ff7b72}.dark .highlight .chroma .kp{color:#79c0ff}.dark .highlight .chroma .kr,.dark .highlight .chroma .kt{color:#ff7b72}.dark .highlight .chroma .nc{color:#f0883e;font-weight:700}.dark .highlight .chroma .no{color:#79c0ff;font-weight:700}.dark .highlight .chroma .nd{color:#d2a8ff;font-weight:700}.dark .highlight .chroma .ni{color:#ffa657}.dark .highlight .chroma .ne{color:#f0883e;font-weight:700}.dark .highlight .chroma .nf{color:#d2a8ff;font-weight:700}.dark .highlight .chroma .nl{color:#79c0ff;font-weight:700}.dark .highlight .chroma .nn{color:#ff7b72}.dark .highlight .chroma .py{color:#79c0ff}.dark .highlight .chroma .nt{color:#7ee787}.dark .highlight .chroma .nv{color:#79c0ff}.dark .highlight .chroma .l{color:#a5d6ff}.dark .highlight .chroma .ld{color:#79c0ff}.dark .highlight .chroma .s{color:#a5d6ff}.dark .highlight .chroma .sa{color:#79c0ff}.dark .highlight .chroma .sb,.dark .highlight .chroma .sc{color:#a5d6ff}.dark .highlight .chroma .dl{color:#79c0ff}.dark .highlight .chroma .sd,.dark .highlight .chroma .s2{color:#a5d6ff}.dark .highlight .chroma .se,.dark .highlight .chroma .sh{color:#79c0ff}.dark .highlight .chroma .si,.dark .highlight .chroma .sx{color:#a5d6ff}.dark .highlight .chroma .sr{color:#79c0ff}.dark .highlight .chroma .s1,.dark .highlight .chroma .ss,.dark .highlight .chroma .m,.dark .highlight .chroma .mb,.dark .highlight .chroma .mf,.dark .highlight .chroma .mh,.dark .highlight .chroma .mi,.dark .highlight .chroma .il,.dark .highlight .chroma .mo{color:#a5d6ff}.dark .highlight .chroma .o,.dark .highlight .chroma .ow{color:#ff7b72;font-weight:700}.dark .highlight .chroma .c,.dark .highlight .chroma .ch,.dark .highlight .chroma .cm,.dark .highlight .chroma .c1{color:#8b949e;font-style:italic}.dark .highlight .chroma .cs,.dark .highlight .chroma .cp,.dark .highlight .chroma .cpf{color:#8b949e;font-style:italic;font-weight:700}.dark .highlight .chroma .gd{color:#ffa198;background-color:#490202}.dark .highlight .chroma .ge{color:inherit;font-style:italic}.dark .highlight .chroma .gr{color:#ffa198}.dark .highlight .chroma .gh{color:#79c0ff;font-weight:700}.dark .highlight .chroma .gi{color:#56d364;background-color:#0f5323}.dark .highlight .chroma .go,.dark .highlight .chroma .gp{color:#8b949e}.dark .highlight .chroma .gs{font-weight:700}.dark .highlight .chroma .gu{color:#79c0ff}.dark .highlight .chroma .gt{color:#ff7b72}.dark .highlight .chroma .gl{text-decoration:underline}.dark .highlight .chroma .w{color:#6e7681}.hextra-code-block{--tw-leading:calc(var(--hx-spacing) * 5);font-size:.9em;line-height:calc(var(--hx-spacing) * 5)}.hextra-code-block pre{background-color:var(--hx-color-primary-700);overflow-x:auto}@supports (color:color-mix(in lab, red, red)){.hextra-code-block pre{background-color:color-mix(in oklab, var(--hx-color-primary-700) 5%, transparent)}}.hextra-code-block pre{--tw-font-weight:var(--hx-font-weight-medium);font-size:.9em;font-weight:var(--hx-font-weight-medium);-webkit-font-smoothing:auto;-moz-osx-font-smoothing:auto}@media (prefers-contrast:more){.hextra-code-block pre{border-style:var(--tw-border-style);border-width:1px;border-color:var(--hx-color-primary-900)}@supports (color:color-mix(in lab, red, red)){.hextra-code-block pre{border-color:color-mix(in oklab, var(--hx-color-primary-900) 20%, transparent)}}.hextra-code-block pre{--tw-contrast:contrast(150%);filter:var(--tw-blur,) var(--tw-brightness,) var(--tw-contrast,) var(--tw-grayscale,) var(--tw-hue-rotate,) var(--tw-invert,) var(--tw-saturate,) var(--tw-sepia,) var(--tw-drop-shadow,)}}.hextra-code-block pre:where(.dark,.dark *){background-color:var(--hx-color-primary-300)}@supports (color:color-mix(in lab, red, red)){.hextra-code-block pre:where(.dark,.dark *){background-color:color-mix(in oklab, var(--hx-color-primary-300) 10%, transparent)}}@media (prefers-contrast:more){.hextra-code-block pre:where(.dark,.dark *){border-color:var(--hx-color-primary-100)}@supports (color:color-mix(in lab, red, red)){.hextra-code-block pre:where(.dark,.dark *){border-color:color-mix(in oklab, var(--hx-color-primary-100) 40%, transparent)}}}.hextra-code-block .hextra-code-filename{top:calc(var(--hx-spacing) * 0);z-index:1;text-overflow:ellipsis;white-space:nowrap;border-top-left-radius:var(--hx-radius-xl);border-top-right-radius:var(--hx-radius-xl);background-color:var(--hx-color-primary-700);width:100%;position:absolute;overflow:hidden}@supports (color:color-mix(in lab, red, red)){.hextra-code-block .hextra-code-filename{background-color:color-mix(in oklab, var(--hx-color-primary-700) 5%, transparent)}}.hextra-code-block .hextra-code-filename{padding-inline:calc(var(--hx-spacing) * 4);padding-block:calc(var(--hx-spacing) * 2);font-size:var(--hx-text-xs);line-height:var(--tw-leading,var(--hx-text-xs--line-height));color:var(--hx-color-gray-700)}.hextra-code-block .hextra-code-filename:where(.dark,.dark *){background-color:var(--hx-color-primary-300)}@supports (color:color-mix(in lab, red, red)){.hextra-code-block .hextra-code-filename:where(.dark,.dark *){background-color:color-mix(in oklab, var(--hx-color-primary-300) 10%, transparent)}}.hextra-code-block .hextra-code-filename:where(.dark,.dark *){color:var(--hx-color-gray-200)}.hextra-code-block .hextra-code-filename+pre:not(.lntable pre){padding-top:calc(var(--hx-spacing) * 12)}.hextra-code-block pre:not(.lntable pre){margin-bottom:calc(var(--hx-spacing) * 4);border-radius:var(--hx-radius-xl);padding-inline:calc(var(--hx-spacing) * 4);padding-block:calc(var(--hx-spacing) * 4)}.hextra-code-block div:nth-of-type(2) pre{padding-top:calc(var(--hx-spacing) * 12);padding-bottom:calc(var(--hx-spacing) * 4)}.chroma .lntable{margin:calc(var(--hx-spacing) * 0);border-radius:var(--hx-radius-xl);width:auto;display:block;overflow:auto}.chroma .lntable pre{padding-top:calc(var(--hx-spacing) * 4);padding-bottom:calc(var(--hx-spacing) * 4)}.chroma .ln,.chroma .lnt:not(.hl>.lnt),.chroma .hl:not(.line){min-width:2.6rem;padding-right:calc(var(--hx-spacing) * 4);padding-left:calc(var(--hx-spacing) * 4);color:var(--hx-color-neutral-600)}:is(.chroma .ln,.chroma .lnt:not(.hl>.lnt),.chroma .hl:not(.line)):where(.dark,.dark *){color:var(--hx-color-neutral-300)}.chroma .lntd{padding:calc(var(--hx-spacing) * 0);vertical-align:top}.chroma .lntd:last-of-type{width:100%}.chroma .hl{background-color:var(--hx-color-primary-800);width:100%;display:block}@supports (color:color-mix(in lab, red, red)){.chroma .hl{background-color:color-mix(in oklab, var(--hx-color-primary-800) 10%, transparent)}}.hextra-alert{margin-top:calc(var(--hx-spacing) * 6);border-radius:var(--hx-radius-lg);border-style:var(--tw-border-style);padding-inline:calc(var(--hx-spacing) * 4);padding-block:calc(var(--hx-spacing) * 4);border-width:1px;flex-direction:column;display:flex;overflow-x:auto}@media (prefers-contrast:more){.hextra-alert,.hextra-alert:where(.dark,.dark *){border-color:currentColor}}.hextra-alert{border-color:var(--hx-color-green-200);background-color:var(--hx-color-green-100);color:var(--hx-color-green-900)}.hextra-alert:where(.dark,.dark *){border-color:var(--hx-color-green-200)}@supports (color:color-mix(in lab, red, red)){.hextra-alert:where(.dark,.dark *){border-color:color-mix(in oklab, var(--hx-color-green-200) 30%, transparent)}}.hextra-alert:where(.dark,.dark *){background-color:var(--hx-color-green-900)}@supports (color:color-mix(in lab, red, red)){.hextra-alert:where(.dark,.dark *){background-color:color-mix(in oklab, var(--hx-color-green-900) 30%, transparent)}}.hextra-alert:where(.dark,.dark *){color:var(--hx-color-green-200)}.hextra-alert[data-alert=note]{border-color:var(--hx-color-blue-200);background-color:var(--hx-color-blue-100);color:var(--hx-color-blue-900)}.hextra-alert[data-alert=note]:where(.dark,.dark *){border-color:var(--hx-color-blue-200)}@supports (color:color-mix(in lab, red, red)){.hextra-alert[data-alert=note]:where(.dark,.dark *){border-color:color-mix(in oklab, var(--hx-color-blue-200) 30%, transparent)}}.hextra-alert[data-alert=note]:where(.dark,.dark *){background-color:var(--hx-color-blue-900)}@supports (color:color-mix(in lab, red, red)){.hextra-alert[data-alert=note]:where(.dark,.dark *){background-color:color-mix(in oklab, var(--hx-color-blue-900) 30%, transparent)}}.hextra-alert[data-alert=note]:where(.dark,.dark *){color:var(--hx-color-blue-200)}.hextra-alert[data-alert=tip]{border-color:var(--hx-color-green-200);background-color:var(--hx-color-green-100);color:var(--hx-color-green-900)}.hextra-alert[data-alert=tip]:where(.dark,.dark *){border-color:var(--hx-color-green-200)}@supports (color:color-mix(in lab, red, red)){.hextra-alert[data-alert=tip]:where(.dark,.dark *){border-color:color-mix(in oklab, var(--hx-color-green-200) 30%, transparent)}}.hextra-alert[data-alert=tip]:where(.dark,.dark *){background-color:var(--hx-color-green-900)}@supports (color:color-mix(in lab, red, red)){.hextra-alert[data-alert=tip]:where(.dark,.dark *){background-color:color-mix(in oklab, var(--hx-color-green-900) 30%, transparent)}}.hextra-alert[data-alert=tip]:where(.dark,.dark *){color:var(--hx-color-green-200)}.hextra-alert[data-alert=important]{border-color:var(--hx-color-purple-200);background-color:var(--hx-color-purple-100);color:var(--hx-color-purple-900)}.hextra-alert[data-alert=important]:where(.dark,.dark *){border-color:var(--hx-color-purple-200)}@supports (color:color-mix(in lab, red, red)){.hextra-alert[data-alert=important]:where(.dark,.dark *){border-color:color-mix(in oklab, var(--hx-color-purple-200) 30%, transparent)}}.hextra-alert[data-alert=important]:where(.dark,.dark *){background-color:var(--hx-color-purple-900)}@supports (color:color-mix(in lab, red, red)){.hextra-alert[data-alert=important]:where(.dark,.dark *){background-color:color-mix(in oklab, var(--hx-color-purple-900) 30%, transparent)}}.hextra-alert[data-alert=important]:where(.dark,.dark *){color:var(--hx-color-purple-200)}.hextra-alert[data-alert=warning]{border-color:var(--hx-color-amber-200);background-color:var(--hx-color-amber-100);color:var(--hx-color-amber-900)}.hextra-alert[data-alert=warning]:where(.dark,.dark *){border-color:var(--hx-color-amber-200)}@supports (color:color-mix(in lab, red, red)){.hextra-alert[data-alert=warning]:where(.dark,.dark *){border-color:color-mix(in oklab, var(--hx-color-amber-200) 30%, transparent)}}.hextra-alert[data-alert=warning]:where(.dark,.dark *){background-color:var(--hx-color-amber-900)}@supports (color:color-mix(in lab, red, red)){.hextra-alert[data-alert=warning]:where(.dark,.dark *){background-color:color-mix(in oklab, var(--hx-color-amber-900) 30%, transparent)}}.hextra-alert[data-alert=warning]:where(.dark,.dark *){color:var(--hx-color-amber-200)}.hextra-alert[data-alert=caution]{border-color:var(--hx-color-red-200);background-color:var(--hx-color-red-100);color:var(--hx-color-red-900)}.hextra-alert[data-alert=caution]:where(.dark,.dark *){border-color:var(--hx-color-red-200)}@supports (color:color-mix(in lab, red, red)){.hextra-alert[data-alert=caution]:where(.dark,.dark *){border-color:color-mix(in oklab, var(--hx-color-red-200) 30%, transparent)}}.hextra-alert[data-alert=caution]:where(.dark,.dark *){background-color:var(--hx-color-red-900)}@supports (color:color-mix(in lab, red, red)){.hextra-alert[data-alert=caution]:where(.dark,.dark *){background-color:color-mix(in oklab, var(--hx-color-red-900) 30%, transparent)}}.hextra-alert[data-alert=caution]:where(.dark,.dark *){color:var(--hx-color-red-200)}.hextra-alert-title{min-width:calc(var(--hx-spacing) * 0);--tw-font-weight:var(--hx-font-weight-medium);font-weight:var(--hx-font-weight-medium);align-items:center;display:flex}.hextra-alert-title-text{min-width:calc(var(--hx-spacing) * 0);word-break:break-word}.hextra-alert-icon{margin-right:calc(var(--hx-spacing) * 2);vertical-align:middle;flex-shrink:0;display:inline-block}.hextra-alert-toggle{cursor:pointer;align-items:center;gap:calc(var(--hx-spacing) * 3);text-align:left;--tw-font-weight:var(--hx-font-weight-medium);width:100%;font-weight:var(--hx-font-weight-medium);display:flex}.hextra-alert-toggle:focus-visible{--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow);--tw-ring-color:var(--hx-color-primary-200);--tw-ring-offset-width:0px;--tw-ring-offset-shadow:var(--tw-ring-inset,) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-outline-style:none;--tw-ring-inset:inset;outline-style:none}.hextra-alert-toggle:where(.dark,.dark *):focus-visible{--tw-ring-color:var(--hx-color-primary-800)}.hextra-alert-chevron{height:calc(var(--hx-spacing) * 4.5);min-width:calc(var(--hx-spacing) * 4.5);border-radius:var(--hx-radius-xs);padding:calc(var(--hx-spacing) * .5);flex-shrink:0}.hextra-alert-chevron:where(:dir(ltr),[dir=ltr],[dir=ltr] *){margin-left:auto}.hextra-alert-chevron:where(:dir(rtl),[dir=rtl],[dir=rtl] *){margin-right:auto}.hextra-alert-chevron>path{transform-origin:50%;transition-property:transform,translate,scale,rotate;transition-timing-function:var(--tw-ease,var(--hx-default-transition-timing-function));transition-duration:var(--tw-duration,var(--hx-default-transition-duration))}.hextra-alert-chevron>path:where(:dir(rtl),[dir=rtl],[dir=rtl] *){rotate:-180deg}.hextra-alert-content{width:100%;min-width:calc(var(--hx-spacing) * 0);--tw-leading:calc(var(--hx-spacing) * 7);line-height:calc(var(--hx-spacing) * 7)}.hextra-alert[data-alert-fold]>.hextra-alert-content{grid-template-rows:0fr;display:grid;overflow:hidden}.hextra-alert[data-alert-fold]>.hextra-alert-content>.hextra-alert-content-inner{min-height:0}.hextra-alert[data-alert-fold][data-alert-fold=\+]>.hextra-alert-toggle>.hextra-alert-chevron>path{rotate:90deg}.hextra-alert[data-alert-fold][data-alert-fold=\+]>.hextra-alert-content{grid-template-rows:1fr}@media (prefers-reduced-motion:no-preference){.hextra-alert[data-alert-fold]>.hextra-alert-content{transition:grid-template-rows .2s cubic-bezier(.52,.16,.04,1)}}@media (prefers-reduced-motion:reduce){.hextra-alert-chevron>path{transition:none}}@media print{.hextra-alert[data-alert-fold]>.hextra-alert-content{grid-template-rows:1fr}}.hextra-cards{grid-template-columns:repeat(auto-fill, minmax(max(250px, calc((100% - 1rem * 2) / var(--hextra-cards-grid-cols))), 1fr))}.hextra-card{position:relative}.hextra-card img{-webkit-user-select:none;user-select:none}.hextra-card:hover .hextra-card-icon svg{color:currentColor}.hextra-card .hextra-card-icon svg{color:#0003;width:1.5rem;transition:color .3s}.hextra-card p{margin-top:.5rem;position:relative}.dark .hextra-card .hextra-card-icon svg{color:#fff6}.dark .hextra-card:hover .hextra-card-icon svg{color:currentColor}.hextra-card-tag{z-index:10;position:absolute;top:5px}.hextra-card-tag:where(:dir(ltr)){right:5px}.hextra-card-tag:where(:dir(rtl)){left:5px}.hextra-steps :where(h2,h3,h4,h5,h6):not(.no-step-marker){counter-increment:step}.hextra-steps :where(h2,h3,h4,h5,h6):not(.no-step-marker):where(:dir(ltr),[dir=ltr],[dir=ltr] *):before{content:var(--tw-content);margin-left:-41px}.hextra-steps :where(h2,h3,h4,h5,h6):not(.no-step-marker):where(:dir(rtl),[dir=rtl],[dir=rtl] *):before{content:var(--tw-content);margin-right:-44px}.hextra-steps :where(h2,h3,h4,h5,h6):not(.no-step-marker):before{content:var(--tw-content);background-color:var(--hx-color-gray-100)}.hextra-steps :where(h2,h3,h4,h5,h6):not(.no-step-marker):where(.dark,.dark *):before{content:var(--tw-content);background-color:var(--hx-color-neutral-800)}.hextra-steps :where(h2,h3,h4,h5,h6):not(.no-step-marker):before{content:var(--tw-content);border-style:var(--tw-border-style);content:var(--tw-content);border-width:4px;border-color:var(--hx-color-white)}.hextra-steps :where(h2,h3,h4,h5,h6):not(.no-step-marker):where(.dark,.dark *):before{content:var(--tw-content);border-color:var(--hx-color-dark)}.hextra-steps :where(h2,h3,h4,h5,h6):not(.no-step-marker):before{content:counter(step);text-align:center;text-indent:-1px;width:33px;height:33px;font-size:var(--hx-text-base);line-height:var(--tw-leading,var(--hx-text-base--line-height));--tw-font-weight:var(--hx-font-weight-normal);font-weight:var(--hx-font-weight-normal);color:var(--hx-color-neutral-400);border-radius:3.40282e38px;position:absolute}:lang(fa) .hextra-steps :where(h2,h3,h4,h5,h6):not(.no-step-marker):before{content:counter(step, persian)}.hextra-search-trigger{cursor:pointer;border-radius:var(--hx-radius-lg);padding:calc(var(--hx-spacing) * 1);color:currentColor;justify-content:center;align-items:center;display:inline-flex}.hextra-search-trigger:focus-visible{--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow);--tw-ring-color:var(--hx-color-primary-200);--tw-ring-offset-width:1px;--tw-ring-offset-shadow:var(--tw-ring-inset,) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-offset-color:var(--hx-color-primary-300);--tw-outline-style:none;outline-style:none}.hextra-search-trigger:where(.dark,.dark *):focus-visible{--tw-ring-color:var(--hx-color-primary-800);--tw-ring-offset-color:var(--hx-color-primary-700)}.hextra-search-trigger{transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to;transition-timing-function:var(--tw-ease,var(--hx-default-transition-timing-function));transition-duration:var(--tw-duration,var(--hx-default-transition-duration))}@media (min-width:48rem){.hextra-search-trigger{width:calc(var(--hx-spacing) * 48);justify-content:flex-start;gap:calc(var(--hx-spacing) * 2);background-color:var(--hx-color-black)}@supports (color:color-mix(in lab, red, red)){.hextra-search-trigger{background-color:color-mix(in oklab, var(--hx-color-black) 5%, transparent)}}.hextra-search-trigger{padding:calc(var(--hx-spacing) * 0);padding-inline:calc(var(--hx-spacing) * 3);padding-block:calc(var(--hx-spacing) * 2);font-size:var(--hx-text-sm);line-height:var(--tw-leading,var(--hx-text-sm--line-height));--tw-leading:var(--hx-leading-tight);line-height:var(--hx-leading-tight);color:var(--hx-color-gray-500)}@media (hover:hover){.hextra-search-trigger:hover{color:var(--hx-color-gray-900)}}.hextra-search-trigger:where(.dark,.dark *){background-color:var(--hx-color-gray-50)}@supports (color:color-mix(in lab, red, red)){.hextra-search-trigger:where(.dark,.dark *){background-color:color-mix(in oklab, var(--hx-color-gray-50) 10%, transparent)}}.hextra-search-trigger:where(.dark,.dark *){color:var(--hx-color-gray-400)}@media (hover:hover){.hextra-search-trigger:where(.dark,.dark *):hover{color:var(--hx-color-gray-50)}}}.hextra-search-trigger-icon{height:calc(var(--hx-spacing) * 6);width:calc(var(--hx-spacing) * 6);flex-shrink:0}@media (min-width:48rem){.hextra-search-trigger-icon{height:calc(var(--hx-spacing) * 4);width:calc(var(--hx-spacing) * 4);opacity:.6}}.hextra-search-trigger-label{text-align:start;flex-grow:1;display:none}@media (min-width:48rem){.hextra-search-trigger-label{display:inline}}.hextra-search-trigger-kbd{align-items:center;gap:calc(var(--hx-spacing) * .5);border-radius:var(--hx-radius-sm);border-style:var(--tw-border-style);border-width:1px;border-color:var(--hx-color-gray-200);background-color:var(--hx-color-white);padding-inline:calc(var(--hx-spacing) * 1.5);font-family:var(--hx-font-mono);--tw-font-weight:var(--hx-font-weight-medium);font-size:10px;font-weight:var(--hx-font-weight-medium);color:var(--hx-color-gray-500);-webkit-user-select:none;user-select:none;display:none}@media (min-width:48rem){.hextra-search-trigger-kbd{display:inline-flex}}.hextra-search-trigger-kbd:where(.dark,.dark *){border-color:var(--hx-color-gray-100)}@supports (color:color-mix(in lab, red, red)){.hextra-search-trigger-kbd:where(.dark,.dark *){border-color:color-mix(in oklab, var(--hx-color-gray-100) 20%, transparent)}}.hextra-search-trigger-kbd:where(.dark,.dark *){background-color:var(--hx-color-dark)}@supports (color:color-mix(in lab, red, red)){.hextra-search-trigger-kbd:where(.dark,.dark *){background-color:color-mix(in oklab, var(--hx-color-dark) 50%, transparent)}}.hextra-search-dialog{--hextra-search-results-max-height:min(28rem, calc(100vh - 7rem));border-radius:var(--hx-radius-xl);border-style:var(--tw-border-style);border-width:1px;border-color:var(--hx-color-gray-200);background-color:var(--hx-color-white);padding:calc(var(--hx-spacing) * 0);color:var(--hx-color-gray-900);overflow:hidden}.hextra-search-dialog:where(.dark,.dark *){border-color:var(--hx-color-neutral-800);background-color:var(--hx-color-neutral-900);color:var(--hx-color-gray-100)}.hextra-search-dialog{width:calc(100% - 1rem);max-width:640px;max-height:min(500px,100vh - 4rem);margin:0;position:fixed;top:max(1rem,50% - 250px);left:50%;transform:translate(-50%);box-shadow:0 25px 50px -12px #00000080}.hextra-search-dialog::backdrop{background-color:var(--hx-color-black)}@supports (color:color-mix(in lab, red, red)){.hextra-search-dialog::backdrop{background-color:color-mix(in oklab, var(--hx-color-black) 20%, transparent)}}.hextra-search-dialog::backdrop{--tw-backdrop-blur:blur(var(--hx-blur-xs));-webkit-backdrop-filter:var(--tw-backdrop-blur,) var(--tw-backdrop-brightness,) var(--tw-backdrop-contrast,) var(--tw-backdrop-grayscale,) var(--tw-backdrop-hue-rotate,) var(--tw-backdrop-invert,) var(--tw-backdrop-opacity,) var(--tw-backdrop-saturate,) var(--tw-backdrop-sepia,);backdrop-filter:var(--tw-backdrop-blur,) var(--tw-backdrop-brightness,) var(--tw-backdrop-contrast,) var(--tw-backdrop-grayscale,) var(--tw-backdrop-hue-rotate,) var(--tw-backdrop-invert,) var(--tw-backdrop-opacity,) var(--tw-backdrop-saturate,) var(--tw-backdrop-sepia,)}.hextra-search-dialog[open]{transform-origin:50%}@media (prefers-reduced-motion:no-preference){.hextra-search-dialog[open]:not([data-state=closing]){animation:.3s cubic-bezier(.16,1,.3,1) hextra-search-dialog-in}.hextra-search-dialog[open]:not([data-state=closing])::backdrop{will-change:opacity;animation:.3s hextra-search-backdrop-in}}.hextra-search-dialog[data-state=closing]{animation:.3s cubic-bezier(.16,1,.3,1) forwards hextra-search-dialog-out}.hextra-search-dialog[data-state=closing]::backdrop{will-change:opacity;animation:.3s forwards hextra-search-backdrop-out}@keyframes hextra-search-dialog-in{0%{opacity:0;transform:translate(-50%)scale(1.06)}to{opacity:1;transform:translate(-50%)scale(1)}}@keyframes hextra-search-dialog-out{0%{opacity:1;transform:translate(-50%)scale(1)}to{opacity:0;transform:translate(-50%)scale(1.04)}}@keyframes hextra-search-backdrop-in{0%{opacity:0}to{opacity:1}}@keyframes hextra-search-backdrop-out{0%{opacity:1}to{opacity:0}}.hextra-search{flex-direction:column;display:flex;overflow:hidden}.hextra-search-input-wrapper{align-items:center;gap:calc(var(--hx-spacing) * 3);border-bottom-style:var(--tw-border-style);border-bottom-width:1px;border-color:var(--hx-color-gray-100);padding-inline:calc(var(--hx-spacing) * 4);display:flex}.hextra-search-input-wrapper:where(.dark,.dark *){border-color:var(--hx-color-neutral-800)}.hextra-search-input-icon{height:calc(var(--hx-spacing) * 5);width:calc(var(--hx-spacing) * 5);color:var(--hx-color-gray-400);flex-shrink:0}.hextra-search-input-icon:where(.dark,.dark *){color:var(--hx-color-gray-500)}.hextra-search-input{height:calc(var(--hx-spacing) * 12);padding-block:calc(var(--hx-spacing) * 3);font-size:var(--hx-text-base);line-height:var(--tw-leading,var(--hx-text-base--line-height));color:var(--hx-color-gray-900);background-color:#0000;flex-grow:1}.hextra-search-input::placeholder{color:var(--hx-color-gray-400)}.hextra-search-input:focus{--tw-outline-style:none;outline-style:none}.hextra-search-input:where(.dark,.dark *){color:var(--hx-color-gray-100)}.hextra-search-input:where(.dark,.dark *)::placeholder{color:var(--hx-color-gray-500)}.hextra-search-input:focus,.hextra-search-input:focus-visible{box-shadow:none;--tw-ring-shadow:0 0 #0000;--tw-ring-offset-shadow:0 0 #0000;outline:none}.hextra-search-input::-webkit-search-cancel-button{display:none}.hextra-search-input-kbd{cursor:pointer;border-radius:var(--hx-radius-sm);border-style:var(--tw-border-style);border-width:1px;border-color:var(--hx-color-gray-200);background-color:var(--hx-color-white);padding-inline:calc(var(--hx-spacing) * 1.5);font-family:var(--hx-font-mono);--tw-font-weight:var(--hx-font-weight-medium);font-size:10px;font-weight:var(--hx-font-weight-medium);color:var(--hx-color-gray-500);align-items:center;display:none}.hextra-search-input-kbd:focus-visible{--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow);--tw-ring-color:var(--hx-color-primary-200);--tw-ring-offset-width:1px;--tw-ring-offset-shadow:var(--tw-ring-inset,) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-offset-color:var(--hx-color-primary-300);--tw-outline-style:none;outline-style:none}.hextra-search-input-kbd:where(.dark,.dark *):focus-visible{--tw-ring-color:var(--hx-color-primary-800);--tw-ring-offset-color:var(--hx-color-primary-700)}.hextra-search-input-kbd{transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to;transition-timing-function:var(--tw-ease,var(--hx-default-transition-timing-function));transition-duration:var(--tw-duration,var(--hx-default-transition-duration));-webkit-user-select:none;user-select:none}@media (hover:hover){.hextra-search-input-kbd:hover{border-color:var(--hx-color-gray-300);color:var(--hx-color-gray-900)}}@media (min-width:40rem){.hextra-search-input-kbd{display:inline-flex}}.hextra-search-input-kbd:where(.dark,.dark *){border-color:var(--hx-color-gray-100)}@supports (color:color-mix(in lab, red, red)){.hextra-search-input-kbd:where(.dark,.dark *){border-color:color-mix(in oklab, var(--hx-color-gray-100) 20%, transparent)}}.hextra-search-input-kbd:where(.dark,.dark *){background-color:var(--hx-color-dark)}@supports (color:color-mix(in lab, red, red)){.hextra-search-input-kbd:where(.dark,.dark *){background-color:color-mix(in oklab, var(--hx-color-dark) 50%, transparent)}}.hextra-search-input-kbd:where(.dark,.dark *){color:var(--hx-color-gray-400)}@media (hover:hover){.hextra-search-input-kbd:where(.dark,.dark *):hover{border-color:var(--hx-color-gray-100)}@supports (color:color-mix(in lab, red, red)){.hextra-search-input-kbd:where(.dark,.dark *):hover{border-color:color-mix(in oklab, var(--hx-color-gray-100) 30%, transparent)}}.hextra-search-input-kbd:where(.dark,.dark *):hover{color:var(--hx-color-gray-100)}}.hextra-search-results-viewport{max-height:0;transition:max-height .2s cubic-bezier(.16,1,.3,1);overflow:hidden}.hextra-search-results-viewport[data-expanded=true]{max-height:var(--hextra-search-results-max-height)}.hextra-search-results-inner{overscroll-behavior:contain;padding:calc(var(--hx-spacing) * 1);max-height:var(--hextra-search-results-max-height);overflow-y:auto}.hextra-search-results{margin:calc(var(--hx-spacing) * 0);padding:calc(var(--hx-spacing) * 0);list-style-type:none}.hextra-search-results>li{list-style-type:none;position:relative}.hextra-search-results>li>a{cursor:pointer;gap:calc(var(--hx-spacing) * .5);border-radius:var(--hx-radius-lg);padding-inline:calc(var(--hx-spacing) * 2.5);padding-block:calc(var(--hx-spacing) * 2);font-size:var(--hx-text-sm);line-height:var(--tw-leading,var(--hx-text-sm--line-height));color:var(--hx-color-gray-800);flex-direction:column;text-decoration-line:none;display:flex;position:relative}.hextra-search-results>li>a:where(.dark,.dark *){color:var(--hx-color-gray-200)}.hextra-search-results>li>a{z-index:1}.hextra-search-results>li>a[aria-selected=true]{background-color:var(--hx-color-primary-100)}@supports (color:color-mix(in lab, red, red)){.hextra-search-results>li>a[aria-selected=true]{background-color:color-mix(in oklab, var(--hx-color-primary-100) 80%, transparent)}}.hextra-search-results>li>a[aria-selected=true]{color:var(--hx-color-gray-900)}.hextra-search-results>li>a[aria-selected=true]:where(.dark,.dark *){background-color:var(--hx-color-primary-400)}@supports (color:color-mix(in lab, red, red)){.hextra-search-results>li>a[aria-selected=true]:where(.dark,.dark *){background-color:color-mix(in oklab, var(--hx-color-primary-400) 15%, transparent)}}.hextra-search-results>li>a[aria-selected=true]:where(.dark,.dark *){color:var(--hx-color-gray-50)}.hextra-search-crumb{align-items:center;gap:calc(var(--hx-spacing) * .5);font-size:var(--hx-text-xs);line-height:var(--tw-leading,var(--hx-text-xs--line-height));--tw-leading:calc(var(--hx-spacing) * 4);line-height:calc(var(--hx-spacing) * 4);color:var(--hx-color-gray-600);display:flex}.hextra-search-crumb:where(.dark,.dark *){color:var(--hx-color-gray-400)}.hextra-search-crumb-separator{height:calc(var(--hx-spacing) * 3.5);width:calc(var(--hx-spacing) * 3.5);color:var(--hx-color-gray-400);flex-shrink:0}.hextra-search-crumb-separator:where(.dark,.dark *){color:var(--hx-color-gray-500)}[dir=rtl] .hextra-search-crumb-separator{transform:rotate(180deg)}.hextra-search-title{font-size:var(--hx-text-sm);line-height:var(--tw-leading,var(--hx-text-sm--line-height));--tw-leading:calc(var(--hx-spacing) * 5);line-height:calc(var(--hx-spacing) * 5);--tw-font-weight:var(--hx-font-weight-medium);font-weight:var(--hx-font-weight-medium)}.hextra-search-excerpt{font-size:var(--hx-text-sm);line-height:var(--tw-leading,var(--hx-text-sm--line-height));--tw-leading:calc(var(--hx-spacing) * 5);line-height:calc(var(--hx-spacing) * 5);color:var(--hx-color-gray-700);overflow:hidden}.hextra-search-excerpt:where(.dark,.dark *){color:var(--hx-color-gray-300)}.hextra-search-excerpt{-webkit-line-clamp:1;line-clamp:1;-webkit-box-orient:vertical;display:-webkit-box}.hextra-search-results>li.hextra-search-child>a>*{padding-inline-start:1rem}.hextra-search-results>li.hextra-search-child:before{content:"";background-color:var(--hx-color-gray-200);inset-inline-start:.75rem;width:1px;position:absolute;top:0;bottom:0}.dark .hextra-search-results>li.hextra-search-child:before{background-color:var(--hx-color-neutral-700)}.hextra-search-match{--tw-font-weight:var(--hx-font-weight-semibold);font-weight:var(--hx-font-weight-semibold);color:var(--hx-color-primary-600)}.hextra-search-empty{padding-inline:calc(var(--hx-spacing) * 3);padding-block:calc(var(--hx-spacing) * 10);text-align:center;font-size:var(--hx-text-sm);line-height:var(--tw-leading,var(--hx-text-sm--line-height));color:var(--hx-color-gray-500)}.hextra-search-empty:where(.dark,.dark *){color:var(--hx-color-gray-400)}@media (max-width:640px){.hextra-search-dialog{max-height:calc(100vh - 2rem);top:1rem}}@media (max-width:48rem){.hextra-sidebar-container{top:calc(var(--hx-spacing) * 0);bottom:calc(var(--hx-spacing) * 0);z-index:15;overscroll-behavior:contain;background-color:var(--hx-color-white);width:100%;padding-top:calc(var(--hextra-navbar-height) + var(--hextra-banner-height));position:fixed}.hextra-sidebar-container:where(.dark,.dark *){background-color:var(--hx-color-dark)}.hextra-sidebar-container{will-change:transform, opacity;contain:layout style;backface-visibility:hidden;transition:transform .4s cubic-bezier(.52,.16,.04,1)}}.hextra-sidebar-container li>.hextra-sidebar-children{height:calc(var(--hx-spacing) * 0)}.hextra-sidebar-container li.open>.hextra-sidebar-children{height:auto;padding-top:calc(var(--hx-spacing) * 1)}.hextra-sidebar-container li.open>.hextra-sidebar-item>.hextra-sidebar-collapsible-button>svg>path{rotate:90deg}.hextra-banner-hidden .hextra-banner{display:none}.hextra-banner :where(a):not(:where([class~=not-prose],[class~=not-prose] *)){text-decoration-line:underline;text-decoration-thickness:from-font}.hextra-banner :where(p):not(:where([class~=not-prose],[class~=not-prose] *)){--tw-leading:calc(var(--hx-spacing) * 7);line-height:calc(var(--hx-spacing) * 7)}.hextra-banner :where(p):not(:where([class~=not-prose],[class~=not-prose] *)):first-child{margin-top:calc(var(--hx-spacing) * 0)}@supports ((-webkit-backdrop-filter:blur(1px)) or (backdrop-filter:blur(1px))){.hextra-nav-container-blur{background-color:var(--hx-color-white)}@supports (color:color-mix(in lab, red, red)){.hextra-nav-container-blur{background-color:color-mix(in oklab, var(--hx-color-white) 85%, transparent)}}.hextra-nav-container-blur{--tw-backdrop-blur:blur(var(--hx-blur-md));-webkit-backdrop-filter:var(--tw-backdrop-blur,) var(--tw-backdrop-brightness,) var(--tw-backdrop-contrast,) var(--tw-backdrop-grayscale,) var(--tw-backdrop-hue-rotate,) var(--tw-backdrop-invert,) var(--tw-backdrop-opacity,) var(--tw-backdrop-saturate,) var(--tw-backdrop-sepia,);backdrop-filter:var(--tw-backdrop-blur,) var(--tw-backdrop-brightness,) var(--tw-backdrop-contrast,) var(--tw-backdrop-grayscale,) var(--tw-backdrop-hue-rotate,) var(--tw-backdrop-invert,) var(--tw-backdrop-opacity,) var(--tw-backdrop-saturate,) var(--tw-backdrop-sepia,)}.hextra-nav-container-blur:where(.dark,.dark *){background-color:var(--hx-color-dark)!important}@supports (color:color-mix(in lab, red, red)){.hextra-nav-container-blur:where(.dark,.dark *){background-color:color-mix(in oklab, var(--hx-color-dark) 80%, transparent)!important}}}@media (max-width:48rem){[data-hextra-banner=visible] .hextra-nav-container-blur{height:max(100%, var(--hextra-banner-height));background-color:var(--hx-color-white)!important}.dark[data-hextra-banner=visible] .hextra-nav-container-blur{background-color:var(--hx-color-dark)!important}}.hextra-hamburger-menu svg g{transform-origin:50%;transition-property:all;transition-timing-function:var(--tw-ease,var(--hx-default-transition-timing-function));transition-duration:var(--tw-duration,var(--hx-default-transition-duration));--tw-duration:.1s;--tw-ease:var(--hx-ease-out);transition-duration:.1s;transition-timing-function:var(--hx-ease-out)}.hextra-hamburger-menu svg path{opacity:1;transition-property:all;transition-timing-function:var(--tw-ease,var(--hx-default-transition-timing-function));transition-duration:var(--tw-duration,var(--hx-default-transition-duration));--tw-duration:.1s;--tw-ease:var(--hx-ease-out);transition-duration:.1s;transition-delay:.1s;transition-timing-function:var(--hx-ease-out)}.hextra-hamburger-menu svg.open path{transition-property:transform,translate,scale,rotate;transition-timing-function:var(--tw-ease,var(--hx-default-transition-timing-function));transition-duration:var(--tw-duration,var(--hx-default-transition-duration));--tw-duration:.1s;--tw-ease:var(--hx-ease-out);transition-duration:.1s;transition-delay:0s;transition-timing-function:var(--hx-ease-out)}.hextra-hamburger-menu svg.open g{transition-property:transform,translate,scale,rotate;transition-timing-function:var(--tw-ease,var(--hx-default-transition-timing-function));transition-duration:var(--tw-duration,var(--hx-default-transition-duration));--tw-duration:.1s;--tw-ease:var(--hx-ease-out);transition-duration:.1s;transition-delay:.1s;transition-timing-function:var(--hx-ease-out)}.hextra-hamburger-menu svg.open>path{opacity:0}.hextra-hamburger-menu svg.open>g:first-of-type{rotate:45deg}.hextra-hamburger-menu svg.open>g:first-of-type path{--tw-translate-y:calc(var(--hx-spacing) * 1);translate:var(--tw-translate-x) var(--tw-translate-y)}.hextra-hamburger-menu svg.open>g:nth-of-type(2){rotate:-45deg}.hextra-hamburger-menu svg.open>g:nth-of-type(2) path{--tw-translate-y:calc(var(--hx-spacing) * -1);translate:var(--tw-translate-x) var(--tw-translate-y)}.hextra-scrollbar,.hextra-scrollbar *{scrollbar-width:thin;scrollbar-color:oklch(55.55% 0 0/.4) transparent;scrollbar-gutter:stable}:is(.hextra-scrollbar,.hextra-scrollbar *)::-webkit-scrollbar{height:calc(var(--hx-spacing) * 3);width:calc(var(--hx-spacing) * 3)}:is(.hextra-scrollbar,.hextra-scrollbar *)::-webkit-scrollbar-track{background-color:#0000}:is(.hextra-scrollbar,.hextra-scrollbar *)::-webkit-scrollbar-thumb{border-radius:10px}:is(.hextra-scrollbar,.hextra-scrollbar *):hover::-webkit-scrollbar-thumb{background-color:var(--tw-shadow-color);--tw-shadow-color:var(--hx-color-neutral-500);background-clip:content-box;border:3px solid #0000}@supports (color:color-mix(in lab, red, red)){:is(.hextra-scrollbar,.hextra-scrollbar *):hover::-webkit-scrollbar-thumb{--tw-shadow-color:color-mix(in oklab, color-mix(in oklab, var(--hx-color-neutral-500) 20%, transparent) var(--tw-shadow-alpha), transparent)}}@media (hover:hover){:is(.hextra-scrollbar,.hextra-scrollbar *):hover::-webkit-scrollbar-thumb:hover{--tw-shadow-color:var(--hx-color-neutral-500)}@supports (color:color-mix(in lab, red, red)){:is(.hextra-scrollbar,.hextra-scrollbar *):hover::-webkit-scrollbar-thumb:hover{--tw-shadow-color:color-mix(in oklab, color-mix(in oklab, var(--hx-color-neutral-500) 40%, transparent) var(--tw-shadow-alpha), transparent)}}}@supports ((-webkit-backdrop-filter:blur(1px)) or (backdrop-filter:blur(1px))){.hextra-code-copy-btn{opacity:.85;--tw-backdrop-blur:blur(var(--hx-blur-md));-webkit-backdrop-filter:var(--tw-backdrop-blur,) var(--tw-backdrop-brightness,) var(--tw-backdrop-contrast,) var(--tw-backdrop-grayscale,) var(--tw-backdrop-hue-rotate,) var(--tw-backdrop-invert,) var(--tw-backdrop-opacity,) var(--tw-backdrop-saturate,) var(--tw-backdrop-sepia,);backdrop-filter:var(--tw-backdrop-blur,) var(--tw-backdrop-brightness,) var(--tw-backdrop-contrast,) var(--tw-backdrop-grayscale,) var(--tw-backdrop-hue-rotate,) var(--tw-backdrop-invert,) var(--tw-backdrop-opacity,) var(--tw-backdrop-saturate,) var(--tw-backdrop-sepia,)}.hextra-code-copy-btn:where(.dark,.dark *){opacity:.8}}@media (min-width:1024px){.hextra-feature-grid{grid-template-columns:repeat(var(--hextra-feature-grid-cols), minmax(0, 1fr))}}.hextra-jupyter-code-cell{scrollbar-gutter:auto;margin-top:calc(var(--hx-spacing) * 6)}.hextra-jupyter-code-cell .hextra-jupyter-code-cell-outputs-container{font-size:var(--hx-text-xs);line-height:var(--tw-leading,var(--hx-text-xs--line-height));overflow:hidden}.hextra-jupyter-code-cell .hextra-jupyter-code-cell-outputs-container .hextra-jupyter-code-cell-outputs{max-height:50vh;overflow:auto}.hextra-jupyter-code-cell .hextra-jupyter-code-cell-outputs-container .hextra-jupyter-code-cell-outputs pre{max-width:100%;font-size:var(--hx-text-xs);line-height:var(--tw-leading,var(--hx-text-xs--line-height));overflow:auto}.hextra-jupyter-code-cell .hextra-jupyter-code-cell-outputs-container .hextra-jupyter-code-cell-outputs-scrolled{max-height:calc(var(--hx-spacing) * 64)}.hextra-jupyter-code-cell .hextra-jupyter-code-cell-outputs-container .hextra-jupyter-code-cell-outputs-unscrolled{max-height:none}.hextra-jupyter-isolated-output{height:calc(var(--hx-spacing) * 64);border-radius:var(--hx-radius-md);border-style:var(--tw-border-style);border-width:1px;border-color:var(--hx-color-gray-200);background-color:var(--hx-color-white);width:100%}.hextra-jupyter-isolated-output:where(.dark,.dark *){border-color:var(--hx-color-neutral-800)}.hextra-jupyter-notebook :where(p>img[src^="data:image/"]):not(:where([class~=not-prose],[class~=not-prose] *)){vertical-align:middle;display:inline-block}.hextra-jupyter-notebook :where(h2):not(:where([class~=not-prose],[class~=not-prose] *)){border-bottom-style:var(--tw-border-style);border-bottom-width:1px;border-color:var(--hx-color-neutral-200)}@supports (color:color-mix(in lab, red, red)){.hextra-jupyter-notebook :where(h2):not(:where([class~=not-prose],[class~=not-prose] *)){border-color:color-mix(in oklab, var(--hx-color-neutral-200) 70%, transparent)}}.hextra-jupyter-notebook :where(h2):not(:where([class~=not-prose],[class~=not-prose] *)){padding-bottom:calc(var(--hx-spacing) * 1)}@media (prefers-contrast:more){.hextra-jupyter-notebook :where(h2):not(:where([class~=not-prose],[class~=not-prose] *)){border-color:var(--hx-color-neutral-400)}}.hextra-jupyter-notebook :where(h2):not(:where([class~=not-prose],[class~=not-prose] *)):where(.dark,.dark *){border-color:var(--hx-color-primary-100)}@supports (color:color-mix(in lab, red, red)){.hextra-jupyter-notebook :where(h2):not(:where([class~=not-prose],[class~=not-prose] *)):where(.dark,.dark *){border-color:color-mix(in oklab, var(--hx-color-primary-100) 10%, transparent)}}@media (prefers-contrast:more){.hextra-jupyter-notebook :where(h2):not(:where([class~=not-prose],[class~=not-prose] *)):where(.dark,.dark *){border-color:var(--hx-color-neutral-400)}}.hextra-jupyter-notebook :where(hr):not(:where([class~=not-prose],[class~=not-prose] *)){margin-block:calc(var(--hx-spacing) * 6)}.hextra-jupyter-notebook :where(hr):not(:where([class~=not-prose],[class~=not-prose] *)):first-child{margin-top:calc(var(--hx-spacing) * 0)}.hextra-jupyter-notebook :where(hr):not(:where([class~=not-prose],[class~=not-prose] *)):last-child{margin-bottom:calc(var(--hx-spacing) * 0)}.hextra-jupyter-stream-stderr{border-left-style:var(--tw-border-style);border-left-width:2px;border-color:var(--hx-color-amber-500);background-color:var(--hx-color-amber-50)}@supports (color:color-mix(in lab, red, red)){.hextra-jupyter-stream-stderr{background-color:color-mix(in oklab, var(--hx-color-amber-50) 50%, transparent)}}.hextra-jupyter-stream-stderr{padding-left:calc(var(--hx-spacing) * 3)}.hextra-jupyter-stream-stderr:where(.dark,.dark *){background-color:var(--hx-color-amber-950)}@supports (color:color-mix(in lab, red, red)){.hextra-jupyter-stream-stderr:where(.dark,.dark *){background-color:color-mix(in oklab, var(--hx-color-amber-950) 20%, transparent)}}.hextra-jupyter-error{border-left-style:var(--tw-border-style);border-left-width:2px;border-color:var(--hx-color-red-500);background-color:var(--hx-color-red-50)}@supports (color:color-mix(in lab, red, red)){.hextra-jupyter-error{background-color:color-mix(in oklab, var(--hx-color-red-50) 50%, transparent)}}.hextra-jupyter-error{padding-left:calc(var(--hx-spacing) * 3)}.hextra-jupyter-error:where(.dark,.dark *){background-color:var(--hx-color-red-950)}@supports (color:color-mix(in lab, red, red)){.hextra-jupyter-error:where(.dark,.dark *){background-color:color-mix(in oklab, var(--hx-color-red-950) 20%, transparent)}}.hextra-jupyter-html{max-width:100%;overflow-x:auto}.hextra-jupyter-html table{margin-block:calc(var(--hx-spacing) * 0);border-collapse:collapse;font-size:var(--hx-text-xs);line-height:var(--tw-leading,var(--hx-text-xs--line-height))}.hextra-jupyter-html table th,.hextra-jupyter-html table td{border-style:var(--tw-border-style);border-width:1px;border-color:var(--hx-color-gray-200);padding-inline:calc(var(--hx-spacing) * 3);padding-block:calc(var(--hx-spacing) * 1.5);text-align:left}:is(.hextra-jupyter-html table th,.hextra-jupyter-html table td):where(.dark,.dark *){border-color:var(--hx-color-neutral-700)}.hextra-jupyter-html table thead th{background-color:var(--hx-color-gray-50);--tw-font-weight:var(--hx-font-weight-semibold);font-weight:var(--hx-font-weight-semibold)}.hextra-jupyter-html table thead th:where(.dark,.dark *){background-color:var(--hx-color-neutral-800)}.hextra-jupyter-html table tbody tr:nth-child(2n){background-color:var(--hx-color-gray-50)}@supports (color:color-mix(in lab, red, red)){.hextra-jupyter-html table tbody tr:nth-child(2n){background-color:color-mix(in oklab, var(--hx-color-gray-50) 50%, transparent)}}.hextra-jupyter-html table tbody tr:nth-child(2n):where(.dark,.dark *){background-color:var(--hx-color-neutral-800)}@supports (color:color-mix(in lab, red, red)){.hextra-jupyter-html table tbody tr:nth-child(2n):where(.dark,.dark *){background-color:color-mix(in oklab, var(--hx-color-neutral-800) 50%, transparent)}}.hextra-jupyter-html table tbody tr:hover{background-color:var(--hx-color-primary-50)}.hextra-jupyter-html table tbody tr:hover:where(.dark,.dark *){background-color:var(--hx-color-primary-900)}@supports (color:color-mix(in lab, red, red)){.hextra-jupyter-html table tbody tr:hover:where(.dark,.dark *){background-color:color-mix(in oklab, var(--hx-color-primary-900) 20%, transparent)}}.hextra-jupyter-svg{max-width:100%;overflow-x:auto}.hextra-jupyter-svg svg{max-width:100%;height:auto}.hextra-jupyter-latex{margin-block:calc(var(--hx-spacing) * 2);overflow-x:auto}.hextra-jupyter-output-summary{margin-bottom:calc(var(--hx-spacing) * 2);cursor:pointer;font-size:var(--hx-text-xs);line-height:var(--tw-leading,var(--hx-text-xs--line-height));--tw-font-weight:var(--hx-font-weight-medium);font-weight:var(--hx-font-weight-medium);color:var(--hx-color-gray-500)}.hextra-jupyter-output-summary:where(.dark,.dark *){color:var(--hx-color-neutral-400)}.hextra-jupyter-raw-cell{margin-block:calc(var(--hx-spacing) * 4);border-radius:var(--hx-radius-md);background-color:var(--hx-color-gray-100);max-width:100%;padding-inline:calc(var(--hx-spacing) * 3);padding-block:calc(var(--hx-spacing) * 2);font-size:var(--hx-text-xs);line-height:var(--tw-leading,var(--hx-text-xs--line-height));overflow:auto}.hextra-jupyter-raw-cell:where(.dark,.dark *){background-color:var(--hx-color-neutral-800)}.hextra-jupyter-prompt-row{margin-top:calc(var(--hx-spacing) * 6);align-items:flex-start;display:flex}.hextra-jupyter-prompt-row:first-child{margin-top:calc(var(--hx-spacing) * 0)}.hextra-jupyter-prompt-row .hextra-jupyter-prompt{width:calc(var(--hx-spacing) * 20);padding-top:calc(var(--hx-spacing) * 4);padding-right:calc(var(--hx-spacing) * 2);text-align:right;font-family:var(--hx-font-mono);font-size:var(--hx-text-xs);line-height:var(--tw-leading,var(--hx-text-xs--line-height));--tw-leading:calc(var(--hx-spacing) * 5);line-height:calc(var(--hx-spacing) * 5);color:var(--hx-color-gray-400);-webkit-user-select:none;user-select:none;flex-shrink:0}.hextra-jupyter-prompt-row .hextra-jupyter-prompt:where(.dark,.dark *){color:var(--hx-color-neutral-500)}.hextra-jupyter-prompt-row .hextra-jupyter-prompt-in{--tw-font-weight:var(--hx-font-weight-bold);font-weight:var(--hx-font-weight-bold);color:var(--hx-color-blue-600)}.hextra-jupyter-prompt-row .hextra-jupyter-prompt-in:where(.dark,.dark *){color:var(--hx-color-blue-400)}.hextra-jupyter-prompt-row .hextra-jupyter-prompt-out{--tw-font-weight:var(--hx-font-weight-bold);font-weight:var(--hx-font-weight-bold);color:var(--hx-color-red-600)}.hextra-jupyter-prompt-row .hextra-jupyter-prompt-out:where(.dark,.dark *){color:var(--hx-color-red-400)}.hextra-jupyter-prompt-row .hextra-jupyter-prompt-content{min-width:calc(var(--hx-spacing) * 0);flex:1}.hextra-jupyter-prompt-row .hextra-jupyter-prompt-content>.hextra-code-block,.hextra-jupyter-prompt-row .hextra-jupyter-prompt-content>.hextra-jupyter-code-cell{margin-top:calc(var(--hx-spacing) * 0)}.hextra-badge{align-items:center;display:inline-flex}.hextra-toc a.hextra-toc-active{transition-property:all;transition-timing-function:var(--tw-ease,var(--hx-default-transition-timing-function));transition-duration:var(--tw-duration,var(--hx-default-transition-duration));--tw-duration:.2s;transition-duration:.2s;color:var(--hx-color-gray-900)!important}.hextra-toc a.hextra-toc-active:where(.dark,.dark *){color:var(--hx-color-gray-50)!important}.hextra-archive-timeline{border-left-style:var(--tw-border-style);border-left-width:2px;border-color:var(--hx-color-black)}@supports (color:color-mix(in lab, red, red)){.hextra-archive-timeline{border-color:color-mix(in oklab, var(--hx-color-black) 15%, transparent)}}.hextra-archive-timeline:where(.dark,.dark *){border-color:var(--hx-color-white)}@supports (color:color-mix(in lab, red, red)){.hextra-archive-timeline:where(.dark,.dark *){border-color:color-mix(in oklab, var(--hx-color-white) 15%, transparent)}}.hextra-gallery{--hextra-gallery-cols:3;--hextra-gallery-gap:.5rem;margin-block:calc(var(--hx-spacing) * 6)}.hextra-gallery__item{margin:calc(var(--hx-spacing) * 0);break-inside:avoid;border-radius:var(--hx-radius-md);background-color:var(--hx-color-gray-100);position:relative;overflow:hidden}.hextra-gallery__item:where(.dark,.dark *){background-color:var(--hx-color-neutral-800)}.hextra-gallery__link{cursor:zoom-in;--tw-outline-style:none;outline-style:none;width:100%;height:100%;display:block}.hextra-gallery__link--linked{cursor:pointer}.hextra-gallery__link:focus-visible{outline-style:var(--tw-outline-style);outline-offset:2px;outline-width:2px;outline-color:var(--hx-color-primary-500)}.hextra-gallery__item img{object-fit:cover;width:100%;height:100%;transition-property:transform,translate,scale,rotate;transition-timing-function:var(--tw-ease,var(--hx-default-transition-timing-function));transition-duration:var(--tw-duration,var(--hx-default-transition-duration));--tw-duration:.3s;transition-duration:.3s;display:block}.hextra-gallery__link:hover img{scale:1.03}.hextra-gallery__caption{pointer-events:none;inset-inline:calc(var(--hx-spacing) * 0);bottom:calc(var(--hx-spacing) * 0);margin:calc(var(--hx-spacing) * 0);padding-inline:calc(var(--hx-spacing) * 3);padding-block:calc(var(--hx-spacing) * 2);--tw-leading:1.3;color:var(--hx-color-white);--tw-gradient-position:to top;font-size:.8rem;line-height:1.3;position:absolute}@supports (background-image:linear-gradient(in lab, red, red)){.hextra-gallery__caption{--tw-gradient-position:to top in oklab}}.hextra-gallery__caption{background-image:linear-gradient(var(--tw-gradient-stops));--tw-gradient-from:color-mix(in oklab, var(--hx-color-black) 70%, transparent);--tw-gradient-to:transparent;--tw-gradient-stops:var(--tw-gradient-via-stops,var(--tw-gradient-position), var(--tw-gradient-from) var(--tw-gradient-from-position), var(--tw-gradient-to) var(--tw-gradient-to-position))}.hextra-gallery__caption :where(p){margin:calc(var(--hx-spacing) * 0)}.hextra-gallery--grid{grid-template-columns:repeat(var(--hextra-gallery-cols), minmax(0, 1fr));gap:var(--hextra-gallery-gap);display:grid}.hextra-gallery--grid .hextra-gallery__item{aspect-ratio:1}@media (max-width:768px){.hextra-gallery--grid{grid-template-columns:repeat(2,minmax(0,1fr))}}@media (max-width:480px){.hextra-gallery--grid{grid-template-columns:1fr}}.hextra-gallery--mosaic{grid-template-columns:repeat(var(--hextra-gallery-cols), minmax(0, 1fr));grid-auto-rows:10rem;grid-auto-flow:dense;gap:var(--hextra-gallery-gap);display:grid}.hextra-gallery--mosaic .hextra-gallery__item{height:100%}.hextra-gallery--mosaic .hextra-gallery__item--wide{grid-column:span 2}.hextra-gallery--mosaic .hextra-gallery__item--tall{grid-row:span 2}.hextra-gallery--mosaic .hextra-gallery__item--large{grid-area:span 2/span 2}@media (max-width:768px){.hextra-gallery--mosaic{grid-template-columns:repeat(2,minmax(0,1fr))}.hextra-gallery--mosaic .hextra-gallery__item--wide,.hextra-gallery--mosaic .hextra-gallery__item--large{grid-column:span 2}}@media (max-width:480px){.hextra-gallery--mosaic{grid-template-columns:1fr}.hextra-gallery--mosaic .hextra-gallery__item--wide,.hextra-gallery--mosaic .hextra-gallery__item--large{grid-column:span 1}.hextra-gallery--mosaic .hextra-gallery__item--tall,.hextra-gallery--mosaic .hextra-gallery__item--large{grid-row:span 1}}.hextra-gallery--masonry{column-count:var(--hextra-gallery-cols);column-gap:var(--hextra-gallery-gap)}.hextra-gallery--masonry .hextra-gallery__item{margin-bottom:var(--hextra-gallery-gap);display:block}.hextra-gallery--masonry .hextra-gallery__item img{object-fit:initial;height:auto}@media (max-width:768px){.hextra-gallery--masonry{column-count:2}}@media (max-width:480px){.hextra-gallery--masonry{column-count:1}}.hextra-gallery--carousel{position:relative}.hextra-gallery__track{gap:var(--hextra-gallery-gap);scroll-snap-type:x var(--tw-scroll-snap-strictness);--tw-scroll-snap-strictness:mandatory;scroll-behavior:smooth;padding-bottom:calc(var(--hx-spacing) * 1);-webkit-overflow-scrolling:touch;display:flex;overflow-x:auto}.hextra-gallery__track:focus-visible{border-radius:var(--hx-radius-md);outline-style:var(--tw-outline-style);outline-offset:2px;outline-width:2px;outline-color:var(--hx-color-primary-500)}.hextra-gallery--carousel .hextra-gallery__item{flex:0 0 calc((100% - var(--hextra-gallery-gap) * (var(--hextra-gallery-cols) - 1)) / var(--hextra-gallery-cols));scroll-snap-align:start;aspect-ratio:4/3}@media (max-width:768px){.hextra-gallery--carousel .hextra-gallery__item{flex:0 0 calc((100% - var(--hextra-gallery-gap)) / 2)}}@media (max-width:480px){.hextra-gallery--carousel .hextra-gallery__item{flex:0 0 100%}}.hextra-gallery__nav{--tw-translate-y:calc(calc(1 / 2 * 100%) * -1);translate:var(--tw-translate-x) var(--tw-translate-y);z-index:10;height:calc(var(--hx-spacing) * 9);width:calc(var(--hx-spacing) * 9);cursor:pointer;--tw-shadow:0 1px 3px 0 var(--tw-shadow-color,#0000001a), 0 1px 2px -1px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow);border-style:var(--tw-border-style);border-width:1px;border-color:var(--hx-color-black);border-radius:3.40282e38px;justify-content:center;align-items:center;display:inline-flex;position:absolute;top:50%}@supports (color:color-mix(in lab, red, red)){.hextra-gallery__nav{border-color:color-mix(in oklab, var(--hx-color-black) 10%, transparent)}}.hextra-gallery__nav{background-color:var(--hx-color-white)}@supports (color:color-mix(in lab, red, red)){.hextra-gallery__nav{background-color:color-mix(in oklab, var(--hx-color-white) 90%, transparent)}}.hextra-gallery__nav{color:var(--hx-color-gray-800);transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to;transition-timing-function:var(--tw-ease,var(--hx-default-transition-timing-function));transition-duration:var(--tw-duration,var(--hx-default-transition-duration));--tw-duration:.2s;transition-duration:.2s}@media (hover:hover){.hextra-gallery__nav:hover{background-color:var(--hx-color-white)}}.hextra-gallery__nav:where(.dark,.dark *){border-color:var(--hx-color-white)}@supports (color:color-mix(in lab, red, red)){.hextra-gallery__nav:where(.dark,.dark *){border-color:color-mix(in oklab, var(--hx-color-white) 10%, transparent)}}.hextra-gallery__nav:where(.dark,.dark *){background-color:var(--hx-color-neutral-800)}@supports (color:color-mix(in lab, red, red)){.hextra-gallery__nav:where(.dark,.dark *){background-color:color-mix(in oklab, var(--hx-color-neutral-800) 90%, transparent)}}.hextra-gallery__nav:where(.dark,.dark *){color:var(--hx-color-gray-200)}@media (hover:hover){.hextra-gallery__nav:where(.dark,.dark *):hover{background-color:var(--hx-color-neutral-800)}}.hextra-gallery__nav:active{--tw-scale-x:95%;--tw-scale-y:95%;--tw-scale-z:95%;scale:var(--tw-scale-x) var(--tw-scale-y)}.hextra-gallery__nav:focus-visible{outline-style:var(--tw-outline-style);outline-offset:2px;outline-width:2px;outline-color:var(--hx-color-primary-500)}.hextra-gallery__nav--prev{inset-inline-start:-.5rem}.hextra-gallery__nav--next{inset-inline-end:-.5rem}[dir=rtl] .hextra-gallery__nav svg{transform:scaleX(-1)}.pswp__caption{pointer-events:none;inset-inline:calc(var(--hx-spacing) * 0);bottom:calc(var(--hx-spacing) * 0);padding-inline:calc(var(--hx-spacing) * 5);padding-block:calc(var(--hx-spacing) * 4);text-align:center;color:var(--hx-color-white);--tw-gradient-position:to top;font-size:.95rem;position:absolute}@supports (background-image:linear-gradient(in lab, red, red)){.pswp__caption{--tw-gradient-position:to top in oklab}}.pswp__caption{background-image:linear-gradient(var(--tw-gradient-stops));--tw-gradient-from:color-mix(in oklab, var(--hx-color-black) 70%, transparent);--tw-gradient-to:transparent;--tw-gradient-stops:var(--tw-gradient-via-stops,var(--tw-gradient-position), var(--tw-gradient-from) var(--tw-gradient-from-position), var(--tw-gradient-to) var(--tw-gradient-to-position))}.hextra-openapi{margin-block:calc(var(--hx-spacing) * 6)}.hextra-openapi .swagger-ui .wrapper{padding-inline:calc(var(--hx-spacing) * 0)}:root.dark-mode,html.dark-mode .hextra-openapi .swagger-ui{background:0 0}.hextra-openapi .swagger-ui select:focus-visible,.hextra-openapi .swagger-ui .opblock-summary-control:focus-visible,.hextra-openapi .swagger-ui .model-box-control:focus-visible,.hextra-openapi .swagger-ui .models-control:focus-visible{outline-offset:2px;outline:2px solid var(--hx-color-primary-500)!important}.hextra-openapi .swagger-ui .opblock.opblock-deprecated{opacity:1}.hextra-openapi .swagger-ui .opblock.opblock-deprecated .opblock-summary-method{background:#737373}html.dark-mode .hextra-openapi .swagger-ui .opblock.opblock-deprecated .opblock-summary-method{background:#d4d4d4}html.dark-mode .hextra-openapi .swagger-ui .opblock.opblock-put .opblock-section-header{background:#3b2a1d}@property --tw-translate-x{syntax:"*";inherits:false;initial-value:0}@property --tw-translate-y{syntax:"*";inherits:false;initial-value:0}@property --tw-translate-z{syntax:"*";inherits:false;initial-value:0}@property --tw-border-style{syntax:"*";inherits:false;initial-value:solid}@property --tw-gradient-position{syntax:"*";inherits:false}@property --tw-gradient-from{syntax:"";inherits:false;initial-value:#0000}@property --tw-gradient-via{syntax:"";inherits:false;initial-value:#0000}@property --tw-gradient-to{syntax:"";inherits:false;initial-value:#0000}@property --tw-gradient-stops{syntax:"*";inherits:false}@property --tw-gradient-via-stops{syntax:"*";inherits:false}@property --tw-gradient-from-position{syntax:"";inherits:false;initial-value:0%}@property --tw-gradient-via-position{syntax:"";inherits:false;initial-value:50%}@property --tw-gradient-to-position{syntax:"";inherits:false;initial-value:100%}@property --tw-leading{syntax:"*";inherits:false}@property --tw-font-weight{syntax:"*";inherits:false}@property --tw-tracking{syntax:"*";inherits:false}@property --tw-ordinal{syntax:"*";inherits:false}@property --tw-slashed-zero{syntax:"*";inherits:false}@property --tw-numeric-figure{syntax:"*";inherits:false}@property --tw-numeric-spacing{syntax:"*";inherits:false}@property --tw-numeric-fraction{syntax:"*";inherits:false}@property --tw-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-shadow-color{syntax:"*";inherits:false}@property --tw-shadow-alpha{syntax:"";inherits:false;initial-value:100%}@property --tw-inset-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-inset-shadow-color{syntax:"*";inherits:false}@property --tw-inset-shadow-alpha{syntax:"";inherits:false;initial-value:100%}@property --tw-ring-color{syntax:"*";inherits:false}@property --tw-ring-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-inset-ring-color{syntax:"*";inherits:false}@property --tw-inset-ring-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-ring-inset{syntax:"*";inherits:false}@property --tw-ring-offset-width{syntax:"";inherits:false;initial-value:0}@property --tw-ring-offset-color{syntax:"*";inherits:false;initial-value:#fff}@property --tw-ring-offset-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-duration{syntax:"*";inherits:false}@property --tw-ease{syntax:"*";inherits:false}@property --tw-content{syntax:"*";inherits:false;initial-value:""}@property --tw-blur{syntax:"*";inherits:false}@property --tw-brightness{syntax:"*";inherits:false}@property --tw-contrast{syntax:"*";inherits:false}@property --tw-grayscale{syntax:"*";inherits:false}@property --tw-hue-rotate{syntax:"*";inherits:false}@property --tw-invert{syntax:"*";inherits:false}@property --tw-opacity{syntax:"*";inherits:false}@property --tw-saturate{syntax:"*";inherits:false}@property --tw-sepia{syntax:"*";inherits:false}@property --tw-drop-shadow{syntax:"*";inherits:false}@property --tw-drop-shadow-color{syntax:"*";inherits:false}@property --tw-drop-shadow-alpha{syntax:"";inherits:false;initial-value:100%}@property --tw-drop-shadow-size{syntax:"*";inherits:false}@property --tw-backdrop-blur{syntax:"*";inherits:false}@property --tw-backdrop-brightness{syntax:"*";inherits:false}@property --tw-backdrop-contrast{syntax:"*";inherits:false}@property --tw-backdrop-grayscale{syntax:"*";inherits:false}@property --tw-backdrop-hue-rotate{syntax:"*";inherits:false}@property --tw-backdrop-invert{syntax:"*";inherits:false}@property --tw-backdrop-opacity{syntax:"*";inherits:false}@property --tw-backdrop-saturate{syntax:"*";inherits:false}@property --tw-backdrop-sepia{syntax:"*";inherits:false}@property --tw-outline-style{syntax:"*";inherits:false;initial-value:solid}@property --tw-scroll-snap-strictness{syntax:"*";inherits:false;initial-value:proximity}@property --tw-scale-x{syntax:"*";inherits:false;initial-value:1}@property --tw-scale-y{syntax:"*";inherits:false;initial-value:1}@property --tw-scale-z{syntax:"*";inherits:false;initial-value:1} diff --git a/css/compiled/main.min.d13ea1494cc9c158f5c7c65f750e1d0b8fde5f8fd422f7d68e408238e7f21ea6.css b/css/compiled/main.min.d13ea1494cc9c158f5c7c65f750e1d0b8fde5f8fd422f7d68e408238e7f21ea6.css new file mode 100644 index 0000000..41a9544 --- /dev/null +++ b/css/compiled/main.min.d13ea1494cc9c158f5c7c65f750e1d0b8fde5f8fd422f7d68e408238e7f21ea6.css @@ -0,0 +1 @@ +:root{--hextra-max-page-width:80rem;--hextra-max-content-width:72rem;--hextra-max-navbar-width:80rem;--hextra-max-footer-width:80rem}.hextra-max-page-width{max-width:var(--hextra-max-page-width)}.hextra-max-content-width{max-width:var(--hextra-max-content-width)}.hextra-max-navbar-width{max-width:var(--hextra-max-navbar-width)}.hextra-max-footer-width{max-width:var(--hextra-max-footer-width)}/*!tailwindcss v4.3.0 | MIT License | https://tailwindcss.com*/@layer properties{@supports(((-webkit-hyphens:none)) and (not (margin-trim:inline))) or ((-moz-orient:inline) and (not (color:rgb(from red r g b)))){*,:before,:after,::backdrop{--tw-translate-x:0;--tw-translate-y:0;--tw-translate-z:0;--tw-border-style:solid;--tw-gradient-position:initial;--tw-gradient-from:#0000;--tw-gradient-via:#0000;--tw-gradient-to:#0000;--tw-gradient-stops:initial;--tw-gradient-via-stops:initial;--tw-gradient-from-position:0%;--tw-gradient-via-position:50%;--tw-gradient-to-position:100%;--tw-leading:initial;--tw-font-weight:initial;--tw-tracking:initial;--tw-ordinal:initial;--tw-slashed-zero:initial;--tw-numeric-figure:initial;--tw-numeric-spacing:initial;--tw-numeric-fraction:initial;--tw-shadow:0 0 #0000;--tw-shadow-color:initial;--tw-shadow-alpha:100%;--tw-inset-shadow:0 0 #0000;--tw-inset-shadow-color:initial;--tw-inset-shadow-alpha:100%;--tw-ring-color:initial;--tw-ring-shadow:0 0 #0000;--tw-inset-ring-color:initial;--tw-inset-ring-shadow:0 0 #0000;--tw-ring-inset:initial;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-offset-shadow:0 0 #0000;--tw-duration:initial;--tw-ease:initial;--tw-content:"";--tw-blur:initial;--tw-brightness:initial;--tw-contrast:initial;--tw-grayscale:initial;--tw-hue-rotate:initial;--tw-invert:initial;--tw-opacity:initial;--tw-saturate:initial;--tw-sepia:initial;--tw-drop-shadow:initial;--tw-drop-shadow-color:initial;--tw-drop-shadow-alpha:100%;--tw-drop-shadow-size:initial;--tw-backdrop-blur:initial;--tw-backdrop-brightness:initial;--tw-backdrop-contrast:initial;--tw-backdrop-grayscale:initial;--tw-backdrop-hue-rotate:initial;--tw-backdrop-invert:initial;--tw-backdrop-opacity:initial;--tw-backdrop-saturate:initial;--tw-backdrop-sepia:initial;--tw-outline-style:solid;--tw-scroll-snap-strictness:proximity;--tw-scale-x:1;--tw-scale-y:1;--tw-scale-z:1}}}@layer theme{:root,:host{--hx-font-sans:ui-sans-serif, system-ui, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";--hx-font-mono:ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;--hx-color-red-50:oklch(97.1% .013 17.38);--hx-color-red-100:oklch(93.6% .032 17.717);--hx-color-red-200:oklch(88.5% .062 18.334);--hx-color-red-400:oklch(70.4% .191 22.216);--hx-color-red-500:oklch(63.7% .237 25.331);--hx-color-red-600:oklch(57.7% .245 27.325);--hx-color-red-900:oklch(39.6% .141 25.723);--hx-color-red-950:oklch(25.8% .092 26.042);--hx-color-orange-50:oklch(98% .016 73.684);--hx-color-orange-100:oklch(95.4% .038 75.164);--hx-color-orange-300:oklch(83.7% .128 66.29);--hx-color-orange-400:oklch(75% .183 55.934);--hx-color-orange-800:oklch(47% .157 37.304);--hx-color-amber-50:oklch(98.7% .022 95.277);--hx-color-amber-100:oklch(96.2% .059 95.617);--hx-color-amber-200:oklch(92.4% .12 95.746);--hx-color-amber-500:oklch(76.9% .188 70.08);--hx-color-amber-900:oklch(41.4% .112 45.904);--hx-color-amber-950:oklch(27.9% .077 45.635);--hx-color-yellow-50:oklch(98.7% .026 102.212);--hx-color-yellow-100:oklch(97.3% .071 103.193);--hx-color-yellow-200:oklch(94.5% .129 101.54);--hx-color-yellow-700:oklch(55.4% .135 66.442);--hx-color-yellow-900:oklch(42.1% .095 57.708);--hx-color-green-100:oklch(96.2% .044 156.743);--hx-color-green-200:oklch(92.5% .084 155.995);--hx-color-green-900:oklch(39.3% .095 152.535);--hx-color-blue-100:oklch(93.2% .032 255.585);--hx-color-blue-200:oklch(88.2% .059 254.128);--hx-color-blue-400:oklch(70.7% .165 254.624);--hx-color-blue-600:oklch(54.6% .245 262.881);--hx-color-blue-900:oklch(37.9% .146 265.522);--hx-color-indigo-100:oklch(93% .034 272.788);--hx-color-indigo-200:oklch(87% .065 274.039);--hx-color-indigo-900:oklch(35.9% .144 278.697);--hx-color-purple-100:oklch(94.6% .033 307.174);--hx-color-purple-200:oklch(90.2% .063 306.703);--hx-color-purple-900:oklch(38.1% .176 304.987);--hx-color-slate-50:oklch(98.4% .003 247.858);--hx-color-slate-100:oklch(96.8% .007 247.896);--hx-color-slate-900:oklch(20.8% .042 265.755);--hx-color-gray-50:oklch(98.5% .002 247.839);--hx-color-gray-100:oklch(96.7% .003 264.542);--hx-color-gray-200:oklch(92.8% .006 264.531);--hx-color-gray-300:oklch(87.2% .01 258.338);--hx-color-gray-400:oklch(70.7% .022 261.325);--hx-color-gray-500:oklch(55.1% .027 264.364);--hx-color-gray-600:oklch(44.6% .03 256.802);--hx-color-gray-700:oklch(37.3% .034 259.733);--hx-color-gray-800:oklch(27.8% .033 256.848);--hx-color-gray-900:oklch(21% .034 264.665);--hx-color-neutral-50:oklch(98.5% 0 0);--hx-color-neutral-200:oklch(92.2% 0 0);--hx-color-neutral-300:oklch(87% 0 0);--hx-color-neutral-400:oklch(70.8% 0 0);--hx-color-neutral-500:oklch(55.6% 0 0);--hx-color-neutral-600:oklch(43.9% 0 0);--hx-color-neutral-700:oklch(37.1% 0 0);--hx-color-neutral-800:oklch(26.9% 0 0);--hx-color-neutral-900:oklch(20.5% 0 0);--hx-color-black:#000;--hx-color-white:#fff;--hx-spacing:.25rem;--hx-breakpoint-xl:80rem;--hx-text-xs:.75rem;--hx-text-xs--line-height:calc(1 / .75);--hx-text-sm:.875rem;--hx-text-sm--line-height:calc(1.25 / .875);--hx-text-base:1rem;--hx-text-base--line-height:calc(1.5 / 1);--hx-text-lg:1.125rem;--hx-text-lg--line-height:calc(1.75 / 1.125);--hx-text-xl:1.25rem;--hx-text-xl--line-height:calc(1.75 / 1.25);--hx-text-2xl:1.5rem;--hx-text-2xl--line-height:calc(2 / 1.5);--hx-text-3xl:1.875rem;--hx-text-3xl--line-height:calc(2.25 / 1.875);--hx-text-4xl:2.25rem;--hx-text-4xl--line-height:calc(2.5 / 2.25);--hx-text-5xl:3rem;--hx-text-5xl--line-height:1;--hx-font-weight-normal:400;--hx-font-weight-medium:500;--hx-font-weight-semibold:600;--hx-font-weight-bold:700;--hx-font-weight-extrabold:800;--hx-tracking-tighter:-.05em;--hx-tracking-tight:-.025em;--hx-leading-tight:1.25;--hx-radius-xs:.125rem;--hx-radius-sm:.25rem;--hx-radius-md:.375rem;--hx-radius-lg:.5rem;--hx-radius-xl:.75rem;--hx-radius-3xl:1.5rem;--hx-ease-in:cubic-bezier(.4, 0, 1, 1);--hx-ease-out:cubic-bezier(0, 0, .2, 1);--hx-ease-in-out:cubic-bezier(.4, 0, .2, 1);--hx-blur-xs:4px;--hx-blur-md:12px;--hx-default-transition-duration:.15s;--hx-default-transition-timing-function:cubic-bezier(.4, 0, .2, 1);--hx-default-font-family:var(--hx-font-sans);--hx-default-mono-font-family:var(--hx-font-mono);--hx-color-primary-50:hsl(var(--primary-hue) var(--primary-saturation) calc(var(--primary-lightness) + calc(calc(100% - var(--primary-lightness)) / 50) * 47));--hx-color-primary-100:hsl(var(--primary-hue) var(--primary-saturation) calc(var(--primary-lightness) + calc(calc(100% - var(--primary-lightness)) / 50) * 44));--hx-color-primary-200:hsl(var(--primary-hue) var(--primary-saturation) calc(var(--primary-lightness) + calc(calc(100% - var(--primary-lightness)) / 50) * 36));--hx-color-primary-300:hsl(var(--primary-hue) var(--primary-saturation) calc(var(--primary-lightness) + calc(calc(100% - var(--primary-lightness)) / 50) * 27));--hx-color-primary-400:hsl(var(--primary-hue) var(--primary-saturation) calc(var(--primary-lightness) + calc(calc(100% - var(--primary-lightness)) / 50) * 16));--hx-color-primary-500:hsl(var(--primary-hue) var(--primary-saturation) var(--primary-lightness));--hx-color-primary-600:hsl(var(--primary-hue) var(--primary-saturation) calc(calc(var(--primary-lightness) / 50) * 45));--hx-color-primary-700:hsl(var(--primary-hue) var(--primary-saturation) calc(calc(var(--primary-lightness) / 50) * 39));--hx-color-primary-800:hsl(var(--primary-hue) var(--primary-saturation) calc(calc(var(--primary-lightness) / 50) * 32));--hx-color-primary-900:hsl(var(--primary-hue) var(--primary-saturation) calc(calc(var(--primary-lightness) / 50) * 24));--hx-color-dark:#111}}@layer base{*,:after,:before,::backdrop{box-sizing:border-box;border:0 solid;margin:0;padding:0}::file-selector-button{box-sizing:border-box;border:0 solid;margin:0;padding:0}html,:host{-webkit-text-size-adjust:100%;tab-size:4;line-height:1.5;font-family:var(--hx-default-font-family,ui-sans-serif,system-ui,sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji");font-feature-settings:var(--hx-default-font-feature-settings,normal);font-variation-settings:var(--hx-default-font-variation-settings,normal);-webkit-tap-highlight-color:transparent}hr{height:0;color:inherit;border-top-width:1px}abbr:where([title]){-webkit-text-decoration:underline dotted;text-decoration:underline dotted}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;-webkit-text-decoration:inherit;-webkit-text-decoration:inherit;-webkit-text-decoration:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,samp,pre{font-family:var(--hx-default-mono-font-family,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace);font-feature-settings:var(--hx-default-mono-font-feature-settings,normal);font-variation-settings:var(--hx-default-mono-font-variation-settings,normal);font-size:1em}small{font-size:80%}sub,sup{vertical-align:baseline;font-size:75%;line-height:0;position:relative}sub{bottom:-.25em}sup{top:-.5em}table{text-indent:0;border-color:inherit;border-collapse:collapse}:-moz-focusring{outline:auto}progress{vertical-align:baseline}summary{display:list-item}ol,ul,menu{list-style:none}img,svg,video,canvas,audio,iframe,embed,object{vertical-align:middle;display:block}img,video{max-width:100%;height:auto}button,input,select,optgroup,textarea{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}::file-selector-button{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}:where(select:is([multiple],[size])) optgroup{font-weight:bolder}:where(select:is([multiple],[size])) optgroup option{padding-inline-start:20px}::file-selector-button{margin-inline-end:4px}::placeholder{opacity:1}@supports(not ((-webkit-appearance:-apple-pay-button))) or (contain-intrinsic-size:1px){::placeholder{color:currentColor}@supports(color:color-mix(in lab,red,red)){::placeholder{color:color-mix(in oklab,currentcolor 50%,transparent)}}}textarea{resize:vertical}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-date-and-time-value{min-height:1lh;text-align:inherit}::-webkit-datetime-edit{display:inline-flex}::-webkit-datetime-edit-fields-wrapper{padding:0}::-webkit-datetime-edit{padding-block:0}::-webkit-datetime-edit-year-field{padding-block:0}::-webkit-datetime-edit-month-field{padding-block:0}::-webkit-datetime-edit-day-field{padding-block:0}::-webkit-datetime-edit-hour-field{padding-block:0}::-webkit-datetime-edit-minute-field{padding-block:0}::-webkit-datetime-edit-second-field{padding-block:0}::-webkit-datetime-edit-millisecond-field{padding-block:0}::-webkit-datetime-edit-meridiem-field{padding-block:0}::-webkit-calendar-picker-indicator{line-height:1}:-moz-ui-invalid{box-shadow:none}button,input:where([type=button],[type=reset],[type=submit]){appearance:button}::file-selector-button{appearance:button}::-webkit-inner-spin-button{height:auto}::-webkit-outer-spin-button{height:auto}[hidden]:where(:not([hidden=until-found])){display:none!important}abbr:where([title]){cursor:help}:where(a,button,[role=tab],[role=menuitem],[role=menuitemradio],input,select,textarea,[tabindex="0"]):not([class*=hextra-focus-visible]):focus-visible{--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow);--tw-ring-color:var(--hx-color-primary-200);--tw-ring-offset-width:1px;--tw-ring-offset-shadow:var(--tw-ring-inset,) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-offset-color:var(--hx-color-primary-300);--tw-outline-style:none;outline-style:none}:where(a,button,[role=tab],[role=menuitem],[role=menuitemradio],input,select,textarea,[tabindex="0"]):not([class*=hextra-focus-visible]):focus-visible:where(.dark,.dark *){--tw-ring-color:var(--hx-color-primary-800);--tw-ring-offset-color:var(--hx-color-primary-700)}}@layer components;@layer utilities{.hx\:pointer-events-none{pointer-events:none}.hx\:sr-only{clip-path:inset(50%);white-space:nowrap;border-width:0;width:1px;height:1px;margin:-1px;padding:0;position:absolute;overflow:hidden}.hx\:absolute{position:absolute}.hx\:relative{position:relative}.hx\:sticky{position:sticky}.hx\:inset-y-0{inset-block:calc(var(--hx-spacing) * 0)}.hx\:top-0{top:calc(var(--hx-spacing) * 0)}.hx\:top-1\/2{top:50%}.hx\:top-8{top:calc(var(--hx-spacing) * 8)}.hx\:top-\[40\%\]{top:40%}.hx\:top-\[var\(--hextra-navbar-height\)\]{top:var(--hextra-navbar-height)}.hx\:top-full{top:100%}.hx\:right-0{right:calc(var(--hx-spacing) * 0)}.hx\:bottom-0{bottom:calc(var(--hx-spacing) * 0)}.hx\:left-0{left:calc(var(--hx-spacing) * 0)}.hx\:left-\[24px\]{left:24px}.hx\:left-\[36px\]{left:36px}.hx\:z-20{z-index:20}.hx\:z-\[-1\]{z-index:-1}.hx\:order-last{order:9999}.hx\:m-\[11px\]{margin:11px}.hx\:mx-1{margin-inline:calc(var(--hx-spacing) * 1)}.hx\:mx-4{margin-inline:calc(var(--hx-spacing) * 4)}.hx\:mx-auto{margin-inline:auto}.hx\:my-1{margin-block:calc(var(--hx-spacing) * 1)}.hx\:my-2{margin-block:calc(var(--hx-spacing) * 2)}.hx\:-mt-20{margin-top:calc(var(--hx-spacing) * -20)}.hx\:mt-1{margin-top:calc(var(--hx-spacing) * 1)}.hx\:mt-1\.5{margin-top:calc(var(--hx-spacing) * 1.5)}.hx\:mt-2{margin-top:calc(var(--hx-spacing) * 2)}.hx\:mt-4{margin-top:calc(var(--hx-spacing) * 4)}.hx\:mt-5{margin-top:calc(var(--hx-spacing) * 5)}.hx\:mt-6{margin-top:calc(var(--hx-spacing) * 6)}.hx\:mt-8{margin-top:calc(var(--hx-spacing) * 8)}.hx\:mt-12{margin-top:calc(var(--hx-spacing) * 12)}.hx\:mt-16{margin-top:calc(var(--hx-spacing) * 16)}.hx\:mt-auto{margin-top:auto}.hx\:-mr-1{margin-right:calc(var(--hx-spacing) * -1)}.hx\:-mr-2{margin-right:calc(var(--hx-spacing) * -2)}.hx\:mr-1{margin-right:calc(var(--hx-spacing) * 1)}.hx\:mr-2{margin-right:calc(var(--hx-spacing) * 2)}.hx\:-mb-0\.5{margin-bottom:calc(var(--hx-spacing) * -.5)}.hx\:mb-0{margin-bottom:calc(var(--hx-spacing) * 0)}.hx\:mb-2{margin-bottom:calc(var(--hx-spacing) * 2)}.hx\:mb-4{margin-bottom:calc(var(--hx-spacing) * 4)}.hx\:mb-6{margin-bottom:calc(var(--hx-spacing) * 6)}.hx\:mb-8{margin-bottom:calc(var(--hx-spacing) * 8)}.hx\:mb-10{margin-bottom:calc(var(--hx-spacing) * 10)}.hx\:mb-12{margin-bottom:calc(var(--hx-spacing) * 12)}.hx\:mb-16{margin-bottom:calc(var(--hx-spacing) * 16)}.hx\:-ml-2{margin-left:calc(var(--hx-spacing) * -2)}.hx\:ml-2{margin-left:calc(var(--hx-spacing) * 2)}.hx\:ml-4{margin-left:calc(var(--hx-spacing) * 4)}.hx\:line-clamp-3{-webkit-line-clamp:3;-webkit-box-orient:vertical;display:-webkit-box;overflow:hidden}.hx\:block{display:block}.hx\:flex{display:flex}.hx\:grid{display:grid}.hx\:hidden{display:none}.hx\:inline{display:inline}.hx\:inline-block{display:inline-block}.hx\:inline-flex{display:inline-flex}.hx\:aspect-auto{aspect-ratio:auto}.hx\:size-4{width:calc(var(--hx-spacing) * 4);height:calc(var(--hx-spacing) * 4)}.hx\:h-0{height:calc(var(--hx-spacing) * 0)}.hx\:h-2{height:calc(var(--hx-spacing) * 2)}.hx\:h-3\.5{height:calc(var(--hx-spacing) * 3.5)}.hx\:h-4{height:calc(var(--hx-spacing) * 4)}.hx\:h-5{height:calc(var(--hx-spacing) * 5)}.hx\:h-7{height:calc(var(--hx-spacing) * 7)}.hx\:h-10{height:calc(var(--hx-spacing) * 10)}.hx\:h-\[18px\]{height:18px}.hx\:h-\[var\(--hextra-navbar-height\)\]{height:var(--hextra-navbar-height)}.hx\:h-full{height:100%}.hx\:h-px{height:1px}.hx\:max-h-\(--menu-height\){max-height:var(--menu-height)}.hx\:max-h-64{max-height:calc(var(--hx-spacing) * 64)}.hx\:max-h-\[calc\(100vh-var\(--hextra-navbar-height\)-env\(safe-area-inset-bottom\)\)\]{max-height:calc(100vh - var(--hextra-navbar-height) - env(safe-area-inset-bottom))}.hx\:min-h-\[calc\(100vh-var\(--hextra-navbar-height\)\)\]{min-height:calc(100vh - var(--hextra-navbar-height))}.hx\:w-2{width:calc(var(--hx-spacing) * 2)}.hx\:w-3\.5{width:calc(var(--hx-spacing) * 3.5)}.hx\:w-4{width:calc(var(--hx-spacing) * 4)}.hx\:w-10{width:calc(var(--hx-spacing) * 10)}.hx\:w-64{width:calc(var(--hx-spacing) * 64)}.hx\:w-\[110\%\]{width:110%}.hx\:w-\[180\%\]{width:180%}.hx\:w-full{width:100%}.hx\:w-max{width:max-content}.hx\:max-w-\[50\%\]{max-width:50%}.hx\:max-w-\[90rem\]{max-width:90rem}.hx\:max-w-full{max-width:100%}.hx\:max-w-none{max-width:none}.hx\:max-w-screen-xl{max-width:var(--hx-breakpoint-xl)}.hx\:min-w-0{min-width:calc(var(--hx-spacing) * 0)}.hx\:min-w-\[18px\]{min-width:18px}.hx\:min-w-\[24px\]{min-width:24px}.hx\:min-w-full{min-width:100%}.hx\:shrink-0{flex-shrink:0}.hx\:grow{flex-grow:1}.hx\:origin-center{transform-origin:50%}.hx\:-translate-y-1\/2{--tw-translate-y:calc(calc(1 / 2 * 100%) * -1);translate:var(--tw-translate-x)var(--tw-translate-y)}.hx\:cursor-default{cursor:default}.hx\:cursor-pointer{cursor:pointer}.hx\:scroll-my-6{scroll-margin-block:calc(var(--hx-spacing) * 6)}.hx\:scroll-py-6{scroll-padding-block:calc(var(--hx-spacing) * 6)}.hx\:list-none{list-style-type:none}.hx\:grid-cols-1{grid-template-columns:repeat(1,minmax(0,1fr))}.hx\:flex-col{flex-direction:column}.hx\:flex-wrap{flex-wrap:wrap}.hx\:items-baseline{align-items:baseline}.hx\:items-center{align-items:center}.hx\:items-start{align-items:flex-start}.hx\:justify-between{justify-content:space-between}.hx\:justify-center{justify-content:center}.hx\:justify-end{justify-content:flex-end}.hx\:justify-start{justify-content:flex-start}.hx\:justify-items-start{justify-items:start}.hx\:gap-1{gap:calc(var(--hx-spacing) * 1)}.hx\:gap-1\.5{gap:calc(var(--hx-spacing) * 1.5)}.hx\:gap-2{gap:calc(var(--hx-spacing) * 2)}.hx\:gap-4{gap:calc(var(--hx-spacing) * 4)}.hx\:gap-x-1\.5{column-gap:calc(var(--hx-spacing) * 1.5)}.hx\:gap-x-2{column-gap:calc(var(--hx-spacing) * 2)}.hx\:gap-y-1{row-gap:calc(var(--hx-spacing) * 1)}.hx\:gap-y-2{row-gap:calc(var(--hx-spacing) * 2)}.hx\:overflow-auto{overflow:auto}.hx\:overflow-hidden{overflow:hidden}.hx\:overflow-x-auto{overflow-x:auto}.hx\:overflow-x-hidden{overflow-x:hidden}.hx\:overflow-y-auto{overflow-y:auto}.hx\:overflow-y-hidden{overflow-y:hidden}.hx\:overscroll-x-contain{overscroll-behavior-x:contain}.hx\:rounded-3xl{border-radius:var(--hx-radius-3xl)}.hx\:rounded-full{border-radius:340282e33px}.hx\:rounded-lg{border-radius:var(--hx-radius-lg)}.hx\:rounded-md{border-radius:var(--hx-radius-md)}.hx\:rounded-sm{border-radius:var(--hx-radius-sm)}.hx\:rounded-xs{border-radius:var(--hx-radius-xs)}.hx\:rounded-t{border-top-left-radius:.25rem;border-top-right-radius:.25rem}.hx\:border{border-style:var(--tw-border-style);border-width:1px}.hx\:border-0{border-style:var(--tw-border-style);border-width:0}.hx\:border-t{border-top-style:var(--tw-border-style);border-top-width:1px}.hx\:border-b{border-bottom-style:var(--tw-border-style);border-bottom-width:1px}.hx\:border-b-2{border-bottom-style:var(--tw-border-style);border-bottom-width:2px}.hx\:border-amber-200{border-color:var(--hx-color-amber-200)}.hx\:border-black\/5{border-color:var(--hx-color-black)}@supports(color:color-mix(in lab,red,red)){.hx\:border-black\/5{border-color:color-mix(in oklab,var(--hx-color-black) 5%,transparent)}}.hx\:border-blue-200{border-color:var(--hx-color-blue-200)}.hx\:border-gray-200{border-color:var(--hx-color-gray-200)}.hx\:border-gray-500{border-color:var(--hx-color-gray-500)}.hx\:border-green-200{border-color:var(--hx-color-green-200)}.hx\:border-indigo-200{border-color:var(--hx-color-indigo-200)}.hx\:border-orange-100{border-color:var(--hx-color-orange-100)}.hx\:border-purple-200{border-color:var(--hx-color-purple-200)}.hx\:border-red-200{border-color:var(--hx-color-red-200)}.hx\:border-transparent{border-color:#0000}.hx\:border-yellow-100{border-color:var(--hx-color-yellow-100)}.hx\:bg-amber-100{background-color:var(--hx-color-amber-100)}.hx\:bg-blue-100{background-color:var(--hx-color-blue-100)}.hx\:bg-gray-100{background-color:var(--hx-color-gray-100)}.hx\:bg-gray-200{background-color:var(--hx-color-gray-200)}.hx\:bg-green-100{background-color:var(--hx-color-green-100)}.hx\:bg-indigo-100{background-color:var(--hx-color-indigo-100)}.hx\:bg-neutral-50{background-color:var(--hx-color-neutral-50)}.hx\:bg-neutral-900{background-color:var(--hx-color-neutral-900)}.hx\:bg-orange-50{background-color:var(--hx-color-orange-50)}.hx\:bg-primary-100{background-color:var(--hx-color-primary-100)}.hx\:bg-primary-400{background-color:var(--hx-color-primary-400)}.hx\:bg-primary-600{background-color:var(--hx-color-primary-600)}.hx\:bg-primary-700\/5{background-color:var(--hx-color-primary-700)}@supports(color:color-mix(in lab,red,red)){.hx\:bg-primary-700\/5{background-color:color-mix(in oklab,var(--hx-color-primary-700) 5%,transparent)}}.hx\:bg-purple-100{background-color:var(--hx-color-purple-100)}.hx\:bg-red-100{background-color:var(--hx-color-red-100)}.hx\:bg-transparent{background-color:#0000}.hx\:bg-white{background-color:var(--hx-color-white)}.hx\:bg-yellow-50{background-color:var(--hx-color-yellow-50)}.hx\:bg-gradient-to-r{--tw-gradient-position:to right in oklab;background-image:linear-gradient(var(--tw-gradient-stops))}.hx\:from-gray-900{--tw-gradient-from:var(--hx-color-gray-900);--tw-gradient-stops:var(--tw-gradient-via-stops,var(--tw-gradient-position), var(--tw-gradient-from) var(--tw-gradient-from-position), var(--tw-gradient-to) var(--tw-gradient-to-position))}.hx\:to-gray-600{--tw-gradient-to:var(--hx-color-gray-600);--tw-gradient-stops:var(--tw-gradient-via-stops,var(--tw-gradient-position), var(--tw-gradient-from) var(--tw-gradient-from-position), var(--tw-gradient-to) var(--tw-gradient-to-position))}.hx\:bg-clip-text{-webkit-background-clip:text;background-clip:text}.hx\:p-0{padding:calc(var(--hx-spacing) * 0)}.hx\:p-0\.5{padding:calc(var(--hx-spacing) * .5)}.hx\:p-1{padding:calc(var(--hx-spacing) * 1)}.hx\:p-1\.5{padding:calc(var(--hx-spacing) * 1.5)}.hx\:p-2{padding:calc(var(--hx-spacing) * 2)}.hx\:p-4{padding:calc(var(--hx-spacing) * 4)}.hx\:p-6{padding:calc(var(--hx-spacing) * 6)}.hx\:px-1\.5{padding-inline:calc(var(--hx-spacing) * 1.5)}.hx\:px-2{padding-inline:calc(var(--hx-spacing) * 2)}.hx\:px-2\.5{padding-inline:calc(var(--hx-spacing) * 2.5)}.hx\:px-3{padding-inline:calc(var(--hx-spacing) * 3)}.hx\:px-4{padding-inline:calc(var(--hx-spacing) * 4)}.hx\:px-6{padding-inline:calc(var(--hx-spacing) * 6)}.hx\:px-8{padding-inline:calc(var(--hx-spacing) * 8)}.hx\:py-1{padding-block:calc(var(--hx-spacing) * 1)}.hx\:py-1\.5{padding-block:calc(var(--hx-spacing) * 1.5)}.hx\:py-2{padding-block:calc(var(--hx-spacing) * 2)}.hx\:py-2\.5{padding-block:calc(var(--hx-spacing) * 2.5)}.hx\:py-3{padding-block:calc(var(--hx-spacing) * 3)}.hx\:py-4{padding-block:calc(var(--hx-spacing) * 4)}.hx\:py-12{padding-block:calc(var(--hx-spacing) * 12)}.hx\:pt-4{padding-top:calc(var(--hx-spacing) * 4)}.hx\:pt-6{padding-top:calc(var(--hx-spacing) * 6)}.hx\:pt-8{padding-top:calc(var(--hx-spacing) * 8)}.hx\:pr-2{padding-right:calc(var(--hx-spacing) * 2)}.hx\:pr-4{padding-right:calc(var(--hx-spacing) * 4)}.hx\:pr-\[calc\(env\(safe-area-inset-right\)-1\.5rem\)\]{padding-right:calc(env(safe-area-inset-right) - 1.5rem)}.hx\:pr-\[max\(env\(safe-area-inset-right\)\,1\.5rem\)\]{padding-right:max(env(safe-area-inset-right),1.5rem)}.hx\:pb-8{padding-bottom:calc(var(--hx-spacing) * 8)}.hx\:pb-\[env\(safe-area-inset-bottom\)\]{padding-bottom:env(safe-area-inset-bottom)}.hx\:pb-px{padding-bottom:1px}.hx\:pl-6{padding-left:calc(var(--hx-spacing) * 6)}.hx\:pl-\[max\(env\(safe-area-inset-left\)\,1\.5rem\)\]{padding-left:max(env(safe-area-inset-left),1.5rem)}.hx\:text-center{text-align:center}.hx\:text-left{text-align:left}.hx\:align-\[-2\.5px\]{vertical-align:-2.5px}.hx\:align-baseline{vertical-align:baseline}.hx\:align-middle{vertical-align:middle}.hx\:align-text-bottom{vertical-align:text-bottom}.hx\:text-2xl{font-size:var(--hx-text-2xl);line-height:var(--tw-leading,var(--hx-text-2xl--line-height))}.hx\:text-4xl{font-size:var(--hx-text-4xl);line-height:var(--tw-leading,var(--hx-text-4xl--line-height))}.hx\:text-base{font-size:var(--hx-text-base);line-height:var(--tw-leading,var(--hx-text-base--line-height))}.hx\:text-lg{font-size:var(--hx-text-lg);line-height:var(--tw-leading,var(--hx-text-lg--line-height))}.hx\:text-sm{font-size:var(--hx-text-sm);line-height:var(--tw-leading,var(--hx-text-sm--line-height))}.hx\:text-xl{font-size:var(--hx-text-xl);line-height:var(--tw-leading,var(--hx-text-xl--line-height))}.hx\:text-xs{font-size:var(--hx-text-xs);line-height:var(--tw-leading,var(--hx-text-xs--line-height))}.hx\:text-\[\.65rem\]{font-size:.65rem}.hx\:leading-5{--tw-leading:calc(var(--hx-spacing) * 5);line-height:calc(var(--hx-spacing) * 5)}.hx\:leading-6{--tw-leading:calc(var(--hx-spacing) * 6);line-height:calc(var(--hx-spacing) * 6)}.hx\:leading-7{--tw-leading:calc(var(--hx-spacing) * 7);line-height:calc(var(--hx-spacing) * 7)}.hx\:leading-none{--tw-leading:1;line-height:1}.hx\:font-bold{--tw-font-weight:var(--hx-font-weight-bold);font-weight:var(--hx-font-weight-bold)}.hx\:font-extrabold{--tw-font-weight:var(--hx-font-weight-extrabold);font-weight:var(--hx-font-weight-extrabold)}.hx\:font-medium{--tw-font-weight:var(--hx-font-weight-medium);font-weight:var(--hx-font-weight-medium)}.hx\:font-normal{--tw-font-weight:var(--hx-font-weight-normal);font-weight:var(--hx-font-weight-normal)}.hx\:font-semibold{--tw-font-weight:var(--hx-font-weight-semibold);font-weight:var(--hx-font-weight-semibold)}.hx\:tracking-tight{--tw-tracking:var(--hx-tracking-tight);letter-spacing:var(--hx-tracking-tight)}.hx\:tracking-tighter{--tw-tracking:var(--hx-tracking-tighter);letter-spacing:var(--hx-tracking-tighter)}.hx\:break-words,.hx\:wrap-break-word{overflow-wrap:break-word}.hx\:text-ellipsis{text-overflow:ellipsis}.hx\:whitespace-nowrap{white-space:nowrap}.hx\:text-\[color\:hsl\(var\(--primary-hue\)\,100\%\,50\%\)\]{color:hsl(var(--primary-hue),100%,50%)}.hx\:text-amber-900{color:var(--hx-color-amber-900)}.hx\:text-blue-900{color:var(--hx-color-blue-900)}.hx\:text-current{color:currentColor}.hx\:text-gray-500{color:var(--hx-color-gray-500)}.hx\:text-gray-600{color:var(--hx-color-gray-600)}.hx\:text-gray-700{color:var(--hx-color-gray-700)}.hx\:text-gray-800{color:var(--hx-color-gray-800)}.hx\:text-gray-900{color:var(--hx-color-gray-900)}.hx\:text-green-900{color:var(--hx-color-green-900)}.hx\:text-indigo-900{color:var(--hx-color-indigo-900)}.hx\:text-orange-800{color:var(--hx-color-orange-800)}.hx\:text-primary-800{color:var(--hx-color-primary-800)}.hx\:text-purple-900{color:var(--hx-color-purple-900)}.hx\:text-red-900{color:var(--hx-color-red-900)}.hx\:text-slate-50{color:var(--hx-color-slate-50)}.hx\:text-slate-900{color:var(--hx-color-slate-900)}.hx\:text-transparent{color:#0000}.hx\:text-white{color:var(--hx-color-white)}.hx\:text-yellow-900{color:var(--hx-color-yellow-900)}.hx\:capitalize{text-transform:capitalize}.hx\:tabular-nums{--tw-numeric-spacing:tabular-nums;font-variant-numeric:var(--tw-ordinal,)var(--tw-slashed-zero,)var(--tw-numeric-figure,)var(--tw-numeric-spacing,)var(--tw-numeric-fraction,)}.hx\:no-underline{text-decoration-line:none}.hx\:underline{text-decoration-line:underline}.hx\:decoration-from-font{text-decoration-thickness:from-font}.hx\:underline-offset-2{text-underline-offset:2px}.hx\:opacity-0{opacity:0}.hx\:opacity-50{opacity:.5}.hx\:opacity-80{opacity:.8}.hx\:shadow-\[0_-12px_16px_\#fff\]{--tw-shadow:0 -12px 16px var(--tw-shadow-color,#fff);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.hx\:shadow-\[0_-12px_16px_white\]{--tw-shadow:0 -12px 16px var(--tw-shadow-color,white);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.hx\:shadow-\[0_2px_4px_rgba\(0\,0\,0\,\.02\)\,0_1px_0_rgba\(0\,0\,0\,\.06\)\]{--tw-shadow:0 2px 4px var(--tw-shadow-color,#00000005), 0 1px 0 var(--tw-shadow-color,#0000000f);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.hx\:shadow-lg{--tw-shadow:0 10px 15px -3px var(--tw-shadow-color,#0000001a), 0 4px 6px -4px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.hx\:shadow-sm{--tw-shadow:0 1px 3px 0 var(--tw-shadow-color,#0000001a), 0 1px 2px -1px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.hx\:shadow-xs{--tw-shadow:0 1px 2px 0 var(--tw-shadow-color,#0000000d);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.hx\:hextra-focus-visible:focus-visible{--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow);--tw-ring-color:var(--hx-color-primary-200);--tw-ring-offset-width:1px;--tw-ring-offset-shadow:var(--tw-ring-inset,) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-offset-color:var(--hx-color-primary-300);--tw-outline-style:none;outline-style:none}.hx\:hextra-focus-visible:where(.dark,.dark *):focus-visible{--tw-ring-color:var(--hx-color-primary-800);--tw-ring-offset-color:var(--hx-color-primary-700)}.hx\:hextra-focus-visible-inset:focus-visible{--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow);--tw-ring-color:var(--hx-color-primary-200);--tw-ring-offset-width:0px;--tw-ring-offset-shadow:var(--tw-ring-inset,) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-outline-style:none;--tw-ring-inset:inset;outline-style:none}.hx\:hextra-focus-visible-inset:where(.dark,.dark *):focus-visible{--tw-ring-color:var(--hx-color-primary-800)}.hx\:shadow-gray-100{--tw-shadow-color:var(--hx-color-gray-100)}@supports(color:color-mix(in lab,red,red)){.hx\:shadow-gray-100{--tw-shadow-color:color-mix(in oklab, var(--hx-color-gray-100) var(--tw-shadow-alpha), transparent)}}.hx\:transition{transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to,opacity,box-shadow,transform,translate,scale,rotate,filter,-webkit-backdrop-filter,backdrop-filter,display,content-visibility,overlay,pointer-events;transition-timing-function:var(--tw-ease,var(--hx-default-transition-timing-function));transition-duration:var(--tw-duration,var(--hx-default-transition-duration))}.hx\:transition-all{transition-property:all;transition-timing-function:var(--tw-ease,var(--hx-default-transition-timing-function));transition-duration:var(--tw-duration,var(--hx-default-transition-duration))}.hx\:transition-colors{transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to;transition-timing-function:var(--tw-ease,var(--hx-default-transition-timing-function));transition-duration:var(--tw-duration,var(--hx-default-transition-duration))}.hx\:transition-transform{transition-property:transform,translate,scale,rotate;transition-timing-function:var(--tw-ease,var(--hx-default-transition-timing-function));transition-duration:var(--tw-duration,var(--hx-default-transition-duration))}.hx\:duration-75{--tw-duration:75ms;transition-duration:75ms}.hx\:duration-150{--tw-duration:.15s;transition-duration:.15s}.hx\:duration-200{--tw-duration:.2s;transition-duration:.2s}.hx\:ease-in{--tw-ease:var(--hx-ease-in);transition-timing-function:var(--hx-ease-in)}.hx\:ease-in-out{--tw-ease:var(--hx-ease-in-out);transition-timing-function:var(--hx-ease-in-out)}.hx\:outline-none{--tw-outline-style:none;outline-style:none}.hx\:select-none{-webkit-user-select:none;user-select:none}@media(hover:hover){.hx\:group-hover\:text-gray-900:is(:where(.hx\:group):hover *){color:var(--hx-color-gray-900)}.hx\:group-hover\:underline:is(:where(.hx\:group):hover *){text-decoration-line:underline}.hx\:group-hover\/code\:opacity-100:is(:where(.hx\:group\/code):hover *){opacity:1}}.hx\:group-data-\[active\=true\]\:text-primary-800:is(:where(.hx\:group)[data-active=true] *){color:var(--hx-color-primary-800)}.hx\:group-data-\[theme\=dark\]\:hidden:is(:where(.hx\:group)[data-theme=dark] *),.hx\:group-data-\[theme\=light\]\:hidden:is(:where(.hx\:group)[data-theme=light] *),.hx\:group-data-\[theme\=system\]\:hidden:is(:where(.hx\:group)[data-theme=system] *){display:none}.hx\:group-\[\.copied\]\/copybtn\:block:is(:where(.hx\:group\/copybtn).copied *){display:block}.hx\:group-\[\.copied\]\/copybtn\:hidden:is(:where(.hx\:group\/copybtn).copied *){display:none}.hx\:before\:pointer-events-none:before{content:var(--tw-content);pointer-events:none}.hx\:before\:absolute:before{content:var(--tw-content);position:absolute}.hx\:before\:inset-0:before{content:var(--tw-content);inset:calc(var(--hx-spacing) * 0)}.hx\:before\:inset-y-1:before{content:var(--tw-content);inset-block:calc(var(--hx-spacing) * 1)}.hx\:before\:mr-1:before{content:var(--tw-content);margin-right:calc(var(--hx-spacing) * 1)}.hx\:before\:inline-block:before{content:var(--tw-content);display:inline-block}.hx\:before\:w-px:before{content:var(--tw-content);width:1px}.hx\:before\:bg-gray-200:before{content:var(--tw-content);background-color:var(--hx-color-gray-200)}.hx\:before\:opacity-25:before{content:var(--tw-content);opacity:.25}.hx\:before\:transition-transform:before{content:var(--tw-content);transition-property:transform,translate,scale,rotate;transition-timing-function:var(--tw-ease,var(--hx-default-transition-timing-function));transition-duration:var(--tw-duration,var(--hx-default-transition-duration))}.hx\:before\:content-\[\"\"\]:before{--tw-content:"";content:var(--tw-content)}.hx\:before\:content-\[\'\#\'\]:before{--tw-content:"#";content:var(--tw-content)}.hx\:before\:content-\[\'\'\]:before{--tw-content:"";content:var(--tw-content)}.hx\:before\:content-\[\\\"\\\"\]:before{--tw-content:\"\";content:var(--tw-content)}.hx\:group-open\:before\:rotate-90:is(:where(.hx\:group):is([open],:popover-open,:open) *):before{content:var(--tw-content);rotate:90deg}.hx\:first\:mt-0:first-child{margin-top:calc(var(--hx-spacing) * 0)}.hx\:last-of-type\:mb-0:last-of-type{margin-bottom:calc(var(--hx-spacing) * 0)}@media(hover:hover){.hx\:hover\:border-gray-200:hover{border-color:var(--hx-color-gray-200)}.hx\:hover\:border-gray-300:hover{border-color:var(--hx-color-gray-300)}.hx\:hover\:border-gray-400:hover{border-color:var(--hx-color-gray-400)}.hx\:hover\:border-gray-900:hover{border-color:var(--hx-color-gray-900)}.hx\:hover\:bg-gray-100:hover{background-color:var(--hx-color-gray-100)}.hx\:hover\:bg-gray-800\/5:hover{background-color:var(--hx-color-gray-800)}@supports(color:color-mix(in lab,red,red)){.hx\:hover\:bg-gray-800\/5:hover{background-color:color-mix(in oklab,var(--hx-color-gray-800) 5%,transparent)}}.hx\:hover\:bg-primary-700:hover{background-color:var(--hx-color-primary-700)}.hx\:hover\:bg-slate-50:hover{background-color:var(--hx-color-slate-50)}.hx\:hover\:text-black:hover{color:var(--hx-color-black)}.hx\:hover\:text-gray-700:hover{color:var(--hx-color-gray-700)}.hx\:hover\:text-gray-800:hover{color:var(--hx-color-gray-800)}.hx\:hover\:text-gray-900:hover{color:var(--hx-color-gray-900)}.hx\:hover\:text-primary-600:hover{color:var(--hx-color-primary-600)}.hx\:hover\:opacity-60:hover{opacity:.6}.hx\:hover\:opacity-75:hover{opacity:.75}.hx\:hover\:shadow-lg:hover{--tw-shadow:0 10px 15px -3px var(--tw-shadow-color,#0000001a), 0 4px 6px -4px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.hx\:hover\:shadow-md:hover{--tw-shadow:0 4px 6px -1px var(--tw-shadow-color,#0000001a), 0 2px 4px -2px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.hx\:hover\:shadow-gray-100:hover{--tw-shadow-color:var(--hx-color-gray-100)}@supports(color:color-mix(in lab,red,red)){.hx\:hover\:shadow-gray-100:hover{--tw-shadow-color:color-mix(in oklab, var(--hx-color-gray-100) var(--tw-shadow-alpha), transparent)}}}.hx\:focus-visible\:not-sr-only:focus-visible{clip-path:none;white-space:normal;width:auto;height:auto;margin:0;padding:0;position:static;overflow:visible}.hx\:focus-visible\:fixed:focus-visible{position:fixed}.hx\:focus-visible\:top-2:focus-visible{top:calc(var(--hx-spacing) * 2)}.hx\:focus-visible\:left-2:focus-visible{left:calc(var(--hx-spacing) * 2)}.hx\:focus-visible\:z-50:focus-visible{z-index:50}.hx\:focus-visible\:rounded-md:focus-visible{border-radius:var(--hx-radius-md)}.hx\:focus-visible\:bg-primary-500:focus-visible{background-color:var(--hx-color-primary-500)}.hx\:focus-visible\:px-4:focus-visible{padding-inline:calc(var(--hx-spacing) * 4)}.hx\:focus-visible\:py-2:focus-visible{padding-block:calc(var(--hx-spacing) * 2)}.hx\:focus-visible\:text-sm:focus-visible{font-size:var(--hx-text-sm);line-height:var(--tw-leading,var(--hx-text-sm--line-height))}.hx\:focus-visible\:font-medium:focus-visible{--tw-font-weight:var(--hx-font-weight-medium);font-weight:var(--hx-font-weight-medium)}.hx\:focus-visible\:text-white:focus-visible{color:var(--hx-color-white)}.hx\:active\:bg-gray-400\/20:active{background-color:var(--hx-color-gray-400)}@supports(color:color-mix(in lab,red,red)){.hx\:active\:bg-gray-400\/20:active{background-color:color-mix(in oklab,var(--hx-color-gray-400) 20%,transparent)}}.hx\:active\:opacity-50:active{opacity:.5}.hx\:active\:shadow-sm:active{--tw-shadow:0 1px 3px 0 var(--tw-shadow-color,#0000001a), 0 1px 2px -1px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.hx\:active\:shadow-gray-200:active{--tw-shadow-color:var(--hx-color-gray-200)}@supports(color:color-mix(in lab,red,red)){.hx\:active\:shadow-gray-200:active{--tw-shadow-color:color-mix(in oklab, var(--hx-color-gray-200) var(--tw-shadow-alpha), transparent)}}.hx\:data-\[state\=closed\]\:hidden[data-state=closed],.hx\:data-\[state\=open\]\:hidden[data-state=open]{display:none}.hx\:data-\[state\=selected\]\:block[data-state=selected]{display:block}.hx\:data-\[state\=selected\]\:border-primary-500[data-state=selected]{border-color:var(--hx-color-primary-500)}.hx\:data-\[state\=selected\]\:text-primary-600[data-state=selected]{color:var(--hx-color-primary-600)}@media(prefers-contrast:more){.hx\:contrast-more\:border{border-style:var(--tw-border-style);border-width:1px}.hx\:contrast-more\:border-t{border-top-style:var(--tw-border-style);border-top-width:1px}.hx\:contrast-more\:border-current{border-color:initial}.hx\:contrast-more\:border-gray-800{border-color:var(--hx-color-gray-800)}.hx\:contrast-more\:border-neutral-400{border-color:var(--hx-color-neutral-400)}.hx\:contrast-more\:border-primary-500{border-color:var(--hx-color-primary-500)}.hx\:contrast-more\:border-transparent{border-color:#0000}.hx\:contrast-more\:font-bold{--tw-font-weight:var(--hx-font-weight-bold);font-weight:var(--hx-font-weight-bold)}.hx\:contrast-more\:text-current{color:currentColor}.hx\:contrast-more\:text-gray-700{color:var(--hx-color-gray-700)}.hx\:contrast-more\:text-gray-800{color:var(--hx-color-gray-800)}.hx\:contrast-more\:text-gray-900{color:var(--hx-color-gray-900)}.hx\:contrast-more\:underline{text-decoration-line:underline}.hx\:contrast-more\:shadow-\[0_0_0_1px_\#000\]{--tw-shadow:0 0 0 1px var(--tw-shadow-color,#000);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.hx\:contrast-more\:shadow-none{--tw-shadow:0 0 #0000;box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}@media(hover:hover){.hx\:contrast-more\:hover\:border-gray-900:hover{border-color:var(--hx-color-gray-900)}}}@media not all and (min-width:80rem){.hx\:max-xl\:hidden{display:none}}@media not all and (min-width:64rem){.hx\:max-lg\:min-h-\[340px\]{min-height:340px}}@media not all and (min-width:48rem){.hx\:max-md\:sticky{position:sticky}.hx\:max-md\:hidden{display:none}.hx\:max-md\:min-h-\[340px\]{min-height:340px}.hx\:max-md\:\[transform\:translate3d\(0\,-100\%\,0\)\]{transform:translateY(-100%)}.hx\:max-md\:\[transform\:translate3d\(0\,0\,0\)\]{transform:translate(0)}}@media not all and (min-width:40rem){.hx\:max-sm\:grid-cols-1{grid-template-columns:repeat(1,minmax(0,1fr))}}@media(min-width:40rem){.hx\:sm\:right-0{right:calc(var(--hx-spacing) * 0)}.hx\:sm\:left-auto{left:auto}.hx\:sm\:block{display:block}.hx\:sm\:w-\[110\%\]{width:110%}.hx\:sm\:flex-row{flex-direction:row}.hx\:sm\:items-center{align-items:center}.hx\:sm\:items-start{align-items:flex-start}.hx\:sm\:justify-between{justify-content:space-between}.hx\:sm\:text-xl{font-size:var(--hx-text-xl);line-height:var(--tw-leading,var(--hx-text-xl--line-height))}@media not all and (min-width:64rem){.hx\:sm\:max-lg\:grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}}}@media(min-width:48rem){.hx\:md\:sticky{position:sticky}.hx\:md\:top-\[var\(--hextra-navbar-height\)\]{top:var(--hextra-navbar-height)}.hx\:md\:mr-0{margin-right:calc(var(--hx-spacing) * 0)}.hx\:md\:hidden{display:none}.hx\:md\:inline-block{display:inline-block}.hx\:md\:inline-flex{display:inline-flex}.hx\:md\:aspect-\[1\.1\/1\]{aspect-ratio:1.1}.hx\:md\:h-\[calc\(100vh-var\(--hextra-navbar-height\)-var\(--menu-height\)\)\]{height:calc(100vh - var(--hextra-navbar-height) - var(--menu-height))}.hx\:md\:w-64{width:calc(var(--hx-spacing) * 64)}.hx\:md\:shrink-0{flex-shrink:0}.hx\:md\:grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.hx\:md\:justify-start{justify-content:flex-start}.hx\:md\:gap-2{gap:calc(var(--hx-spacing) * 2)}.hx\:md\:self-start{align-self:flex-start}.hx\:md\:overflow-auto{overflow:auto}.hx\:md\:p-2{padding:calc(var(--hx-spacing) * 2)}.hx\:md\:px-12{padding-inline:calc(var(--hx-spacing) * 12)}.hx\:md\:pt-12{padding-top:calc(var(--hx-spacing) * 12)}.hx\:md\:text-3xl{font-size:var(--hx-text-3xl);line-height:var(--tw-leading,var(--hx-text-3xl--line-height))}.hx\:md\:text-5xl{font-size:var(--hx-text-5xl);line-height:var(--tw-leading,var(--hx-text-5xl--line-height))}.hx\:md\:text-lg{font-size:var(--hx-text-lg);line-height:var(--tw-leading,var(--hx-text-lg--line-height))}}@media(min-width:64rem){.hx\:lg\:grid-cols-3{grid-template-columns:repeat(3,minmax(0,1fr))}}@media(min-width:80rem){.hx\:xl\:block{display:block}.hx\:xl\:grid-cols-4{grid-template-columns:repeat(4,minmax(0,1fr))}}.hx\:ltr\:right-2:where(:dir(ltr),[dir=ltr],[dir=ltr] *){right:calc(var(--hx-spacing) * 2)}.hx\:ltr\:right-3:where(:dir(ltr),[dir=ltr],[dir=ltr] *){right:calc(var(--hx-spacing) * 3)}.hx\:ltr\:-mr-4:where(:dir(ltr),[dir=ltr],[dir=ltr] *){margin-right:calc(var(--hx-spacing) * -4)}.hx\:ltr\:mr-auto:where(:dir(ltr),[dir=ltr],[dir=ltr] *){margin-right:auto}.hx\:ltr\:ml-1:where(:dir(ltr),[dir=ltr],[dir=ltr] *){margin-left:calc(var(--hx-spacing) * 1)}.hx\:ltr\:ml-3:where(:dir(ltr),[dir=ltr],[dir=ltr] *){margin-left:calc(var(--hx-spacing) * 3)}.hx\:ltr\:ml-auto:where(:dir(ltr),[dir=ltr],[dir=ltr] *){margin-left:auto}.hx\:ltr\:rotate-180:where(:dir(ltr),[dir=ltr],[dir=ltr] *){rotate:180deg}.hx\:ltr\:rounded-l-lg:where(:dir(ltr),[dir=ltr],[dir=ltr] *){border-top-left-radius:var(--hx-radius-lg);border-bottom-left-radius:var(--hx-radius-lg)}.hx\:ltr\:rounded-r-lg:where(:dir(ltr),[dir=ltr],[dir=ltr] *){border-top-right-radius:var(--hx-radius-lg);border-bottom-right-radius:var(--hx-radius-lg)}.hx\:ltr\:border-l:where(:dir(ltr),[dir=ltr],[dir=ltr] *){border-left-style:var(--tw-border-style);border-left-width:1px}.hx\:ltr\:pr-0:where(:dir(ltr),[dir=ltr],[dir=ltr] *){padding-right:calc(var(--hx-spacing) * 0)}.hx\:ltr\:pr-2:where(:dir(ltr),[dir=ltr],[dir=ltr] *){padding-right:calc(var(--hx-spacing) * 2)}.hx\:ltr\:pr-4:where(:dir(ltr),[dir=ltr],[dir=ltr] *){padding-right:calc(var(--hx-spacing) * 4)}.hx\:ltr\:pr-8:where(:dir(ltr),[dir=ltr],[dir=ltr] *){padding-right:calc(var(--hx-spacing) * 8)}.hx\:ltr\:pr-9:where(:dir(ltr),[dir=ltr],[dir=ltr] *){padding-right:calc(var(--hx-spacing) * 9)}.hx\:ltr\:pl-3:where(:dir(ltr),[dir=ltr],[dir=ltr] *){padding-left:calc(var(--hx-spacing) * 3)}.hx\:ltr\:pl-4:where(:dir(ltr),[dir=ltr],[dir=ltr] *){padding-left:calc(var(--hx-spacing) * 4)}.hx\:ltr\:pl-5:where(:dir(ltr),[dir=ltr],[dir=ltr] *){padding-left:calc(var(--hx-spacing) * 5)}.hx\:ltr\:pl-6:where(:dir(ltr),[dir=ltr],[dir=ltr] *){padding-left:calc(var(--hx-spacing) * 6)}.hx\:ltr\:pl-8:where(:dir(ltr),[dir=ltr],[dir=ltr] *){padding-left:calc(var(--hx-spacing) * 8)}.hx\:ltr\:pl-12:where(:dir(ltr),[dir=ltr],[dir=ltr] *){padding-left:calc(var(--hx-spacing) * 12)}.hx\:ltr\:pl-16:where(:dir(ltr),[dir=ltr],[dir=ltr] *){padding-left:calc(var(--hx-spacing) * 16)}.hx\:ltr\:text-right:where(:dir(ltr),[dir=ltr],[dir=ltr] *){text-align:right}.hx\:ltr\:before\:left-0:where(:dir(ltr),[dir=ltr],[dir=ltr] *):before{content:var(--tw-content);left:calc(var(--hx-spacing) * 0)}.hx\:rtl\:left-2:where(:dir(rtl),[dir=rtl],[dir=rtl] *){left:calc(var(--hx-spacing) * 2)}.hx\:rtl\:left-3:where(:dir(rtl),[dir=rtl],[dir=rtl] *){left:calc(var(--hx-spacing) * 3)}.hx\:rtl\:mr-1:where(:dir(rtl),[dir=rtl],[dir=rtl] *){margin-right:calc(var(--hx-spacing) * 1)}.hx\:rtl\:mr-3:where(:dir(rtl),[dir=rtl],[dir=rtl] *){margin-right:calc(var(--hx-spacing) * 3)}.hx\:rtl\:mr-auto:where(:dir(rtl),[dir=rtl],[dir=rtl] *){margin-right:auto}.hx\:rtl\:-ml-4:where(:dir(rtl),[dir=rtl],[dir=rtl] *){margin-left:calc(var(--hx-spacing) * -4)}.hx\:rtl\:ml-auto:where(:dir(rtl),[dir=rtl],[dir=rtl] *){margin-left:auto}.hx\:rtl\:-rotate-180:where(:dir(rtl),[dir=rtl],[dir=rtl] *){rotate:-180deg}.hx\:rtl\:rotate-270:where(:dir(rtl),[dir=rtl],[dir=rtl] *){rotate:270deg}.hx\:rtl\:rounded-l-lg:where(:dir(rtl),[dir=rtl],[dir=rtl] *){border-top-left-radius:var(--hx-radius-lg);border-bottom-left-radius:var(--hx-radius-lg)}.hx\:rtl\:rounded-r-lg:where(:dir(rtl),[dir=rtl],[dir=rtl] *){border-top-right-radius:var(--hx-radius-lg);border-bottom-right-radius:var(--hx-radius-lg)}.hx\:rtl\:border-r:where(:dir(rtl),[dir=rtl],[dir=rtl] *){border-right-style:var(--tw-border-style);border-right-width:1px}.hx\:rtl\:pr-3:where(:dir(rtl),[dir=rtl],[dir=rtl] *){padding-right:calc(var(--hx-spacing) * 3)}.hx\:rtl\:pr-4:where(:dir(rtl),[dir=rtl],[dir=rtl] *){padding-right:calc(var(--hx-spacing) * 4)}.hx\:rtl\:pr-5:where(:dir(rtl),[dir=rtl],[dir=rtl] *){padding-right:calc(var(--hx-spacing) * 5)}.hx\:rtl\:pr-6:where(:dir(rtl),[dir=rtl],[dir=rtl] *){padding-right:calc(var(--hx-spacing) * 6)}.hx\:rtl\:pr-8:where(:dir(rtl),[dir=rtl],[dir=rtl] *){padding-right:calc(var(--hx-spacing) * 8)}.hx\:rtl\:pr-12:where(:dir(rtl),[dir=rtl],[dir=rtl] *){padding-right:calc(var(--hx-spacing) * 12)}.hx\:rtl\:pr-16:where(:dir(rtl),[dir=rtl],[dir=rtl] *){padding-right:calc(var(--hx-spacing) * 16)}.hx\:rtl\:pl-0:where(:dir(rtl),[dir=rtl],[dir=rtl] *){padding-left:calc(var(--hx-spacing) * 0)}.hx\:rtl\:pl-2:where(:dir(rtl),[dir=rtl],[dir=rtl] *){padding-left:calc(var(--hx-spacing) * 2)}.hx\:rtl\:pl-4:where(:dir(rtl),[dir=rtl],[dir=rtl] *){padding-left:calc(var(--hx-spacing) * 4)}.hx\:rtl\:pl-8:where(:dir(rtl),[dir=rtl],[dir=rtl] *){padding-left:calc(var(--hx-spacing) * 8)}.hx\:rtl\:pl-9:where(:dir(rtl),[dir=rtl],[dir=rtl] *){padding-left:calc(var(--hx-spacing) * 9)}.hx\:rtl\:text-left:where(:dir(rtl),[dir=rtl],[dir=rtl] *){text-align:left}.hx\:rtl\:before\:right-0:where(:dir(rtl),[dir=rtl],[dir=rtl] *):before{content:var(--tw-content);right:calc(var(--hx-spacing) * 0)}.hx\:rtl\:before\:rotate-180:where(:dir(rtl),[dir=rtl],[dir=rtl] *):before{content:var(--tw-content);rotate:180deg}.hx\:dark\:block:where(.dark,.dark *){display:block}.hx\:dark\:hidden:where(.dark,.dark *){display:none}.hx\:dark\:border-amber-200\/30:where(.dark,.dark *){border-color:var(--hx-color-amber-200)}@supports(color:color-mix(in lab,red,red)){.hx\:dark\:border-amber-200\/30:where(.dark,.dark *){border-color:color-mix(in oklab,var(--hx-color-amber-200) 30%,transparent)}}.hx\:dark\:border-blue-200\/30:where(.dark,.dark *){border-color:var(--hx-color-blue-200)}@supports(color:color-mix(in lab,red,red)){.hx\:dark\:border-blue-200\/30:where(.dark,.dark *){border-color:color-mix(in oklab,var(--hx-color-blue-200) 30%,transparent)}}.hx\:dark\:border-gray-400:where(.dark,.dark *){border-color:var(--hx-color-gray-400)}.hx\:dark\:border-green-200\/30:where(.dark,.dark *){border-color:var(--hx-color-green-200)}@supports(color:color-mix(in lab,red,red)){.hx\:dark\:border-green-200\/30:where(.dark,.dark *){border-color:color-mix(in oklab,var(--hx-color-green-200) 30%,transparent)}}.hx\:dark\:border-indigo-200\/30:where(.dark,.dark *){border-color:var(--hx-color-indigo-200)}@supports(color:color-mix(in lab,red,red)){.hx\:dark\:border-indigo-200\/30:where(.dark,.dark *){border-color:color-mix(in oklab,var(--hx-color-indigo-200) 30%,transparent)}}.hx\:dark\:border-neutral-700:where(.dark,.dark *){border-color:var(--hx-color-neutral-700)}.hx\:dark\:border-neutral-800:where(.dark,.dark *){border-color:var(--hx-color-neutral-800)}.hx\:dark\:border-orange-400\/30:where(.dark,.dark *){border-color:var(--hx-color-orange-400)}@supports(color:color-mix(in lab,red,red)){.hx\:dark\:border-orange-400\/30:where(.dark,.dark *){border-color:color-mix(in oklab,var(--hx-color-orange-400) 30%,transparent)}}.hx\:dark\:border-purple-200\/30:where(.dark,.dark *){border-color:var(--hx-color-purple-200)}@supports(color:color-mix(in lab,red,red)){.hx\:dark\:border-purple-200\/30:where(.dark,.dark *){border-color:color-mix(in oklab,var(--hx-color-purple-200) 30%,transparent)}}.hx\:dark\:border-red-200\/30:where(.dark,.dark *){border-color:var(--hx-color-red-200)}@supports(color:color-mix(in lab,red,red)){.hx\:dark\:border-red-200\/30:where(.dark,.dark *){border-color:color-mix(in oklab,var(--hx-color-red-200) 30%,transparent)}}.hx\:dark\:border-white\/10:where(.dark,.dark *){border-color:var(--hx-color-white)}@supports(color:color-mix(in lab,red,red)){.hx\:dark\:border-white\/10:where(.dark,.dark *){border-color:color-mix(in oklab,var(--hx-color-white) 10%,transparent)}}.hx\:dark\:border-yellow-200\/30:where(.dark,.dark *){border-color:var(--hx-color-yellow-200)}@supports(color:color-mix(in lab,red,red)){.hx\:dark\:border-yellow-200\/30:where(.dark,.dark *){border-color:color-mix(in oklab,var(--hx-color-yellow-200) 30%,transparent)}}.hx\:dark\:bg-amber-900\/30:where(.dark,.dark *){background-color:var(--hx-color-amber-900)}@supports(color:color-mix(in lab,red,red)){.hx\:dark\:bg-amber-900\/30:where(.dark,.dark *){background-color:color-mix(in oklab,var(--hx-color-amber-900) 30%,transparent)}}.hx\:dark\:bg-blue-900\/30:where(.dark,.dark *){background-color:var(--hx-color-blue-900)}@supports(color:color-mix(in lab,red,red)){.hx\:dark\:bg-blue-900\/30:where(.dark,.dark *){background-color:color-mix(in oklab,var(--hx-color-blue-900) 30%,transparent)}}.hx\:dark\:bg-dark:where(.dark,.dark *){background-color:var(--hx-color-dark)}.hx\:dark\:bg-green-900\/30:where(.dark,.dark *){background-color:var(--hx-color-green-900)}@supports(color:color-mix(in lab,red,red)){.hx\:dark\:bg-green-900\/30:where(.dark,.dark *){background-color:color-mix(in oklab,var(--hx-color-green-900) 30%,transparent)}}.hx\:dark\:bg-indigo-900\/30:where(.dark,.dark *){background-color:var(--hx-color-indigo-900)}@supports(color:color-mix(in lab,red,red)){.hx\:dark\:bg-indigo-900\/30:where(.dark,.dark *){background-color:color-mix(in oklab,var(--hx-color-indigo-900) 30%,transparent)}}.hx\:dark\:bg-neutral-700:where(.dark,.dark *){background-color:var(--hx-color-neutral-700)}.hx\:dark\:bg-neutral-800:where(.dark,.dark *){background-color:var(--hx-color-neutral-800)}.hx\:dark\:bg-neutral-900:where(.dark,.dark *){background-color:var(--hx-color-neutral-900)}.hx\:dark\:bg-orange-400\/20:where(.dark,.dark *){background-color:var(--hx-color-orange-400)}@supports(color:color-mix(in lab,red,red)){.hx\:dark\:bg-orange-400\/20:where(.dark,.dark *){background-color:color-mix(in oklab,var(--hx-color-orange-400) 20%,transparent)}}.hx\:dark\:bg-primary-300\/10:where(.dark,.dark *){background-color:var(--hx-color-primary-300)}@supports(color:color-mix(in lab,red,red)){.hx\:dark\:bg-primary-300\/10:where(.dark,.dark *){background-color:color-mix(in oklab,var(--hx-color-primary-300) 10%,transparent)}}.hx\:dark\:bg-primary-400\/10:where(.dark,.dark *){background-color:var(--hx-color-primary-400)}@supports(color:color-mix(in lab,red,red)){.hx\:dark\:bg-primary-400\/10:where(.dark,.dark *){background-color:color-mix(in oklab,var(--hx-color-primary-400) 10%,transparent)}}.hx\:dark\:bg-primary-600:where(.dark,.dark *){background-color:var(--hx-color-primary-600)}.hx\:dark\:bg-purple-900\/30:where(.dark,.dark *){background-color:var(--hx-color-purple-900)}@supports(color:color-mix(in lab,red,red)){.hx\:dark\:bg-purple-900\/30:where(.dark,.dark *){background-color:color-mix(in oklab,var(--hx-color-purple-900) 30%,transparent)}}.hx\:dark\:bg-red-900\/30:where(.dark,.dark *){background-color:var(--hx-color-red-900)}@supports(color:color-mix(in lab,red,red)){.hx\:dark\:bg-red-900\/30:where(.dark,.dark *){background-color:color-mix(in oklab,var(--hx-color-red-900) 30%,transparent)}}.hx\:dark\:bg-yellow-700\/30:where(.dark,.dark *){background-color:var(--hx-color-yellow-700)}@supports(color:color-mix(in lab,red,red)){.hx\:dark\:bg-yellow-700\/30:where(.dark,.dark *){background-color:color-mix(in oklab,var(--hx-color-yellow-700) 30%,transparent)}}.hx\:dark\:from-gray-100:where(.dark,.dark *){--tw-gradient-from:var(--hx-color-gray-100);--tw-gradient-stops:var(--tw-gradient-via-stops,var(--tw-gradient-position), var(--tw-gradient-from) var(--tw-gradient-from-position), var(--tw-gradient-to) var(--tw-gradient-to-position))}.hx\:dark\:to-gray-400:where(.dark,.dark *){--tw-gradient-to:var(--hx-color-gray-400);--tw-gradient-stops:var(--tw-gradient-via-stops,var(--tw-gradient-position), var(--tw-gradient-from) var(--tw-gradient-from-position), var(--tw-gradient-to) var(--tw-gradient-to-position))}.hx\:dark\:text-amber-200:where(.dark,.dark *){color:var(--hx-color-amber-200)}.hx\:dark\:text-blue-200:where(.dark,.dark *){color:var(--hx-color-blue-200)}.hx\:dark\:text-gray-50:where(.dark,.dark *){color:var(--hx-color-gray-50)}.hx\:dark\:text-gray-100:where(.dark,.dark *){color:var(--hx-color-gray-100)}.hx\:dark\:text-gray-200:where(.dark,.dark *){color:var(--hx-color-gray-200)}.hx\:dark\:text-gray-300:where(.dark,.dark *){color:var(--hx-color-gray-300)}.hx\:dark\:text-gray-400:where(.dark,.dark *){color:var(--hx-color-gray-400)}.hx\:dark\:text-green-200:where(.dark,.dark *){color:var(--hx-color-green-200)}.hx\:dark\:text-indigo-200:where(.dark,.dark *){color:var(--hx-color-indigo-200)}.hx\:dark\:text-neutral-200:where(.dark,.dark *){color:var(--hx-color-neutral-200)}.hx\:dark\:text-neutral-400:where(.dark,.dark *){color:var(--hx-color-neutral-400)}.hx\:dark\:text-orange-300:where(.dark,.dark *){color:var(--hx-color-orange-300)}.hx\:dark\:text-primary-600:where(.dark,.dark *){color:var(--hx-color-primary-600)}.hx\:dark\:text-purple-200:where(.dark,.dark *){color:var(--hx-color-purple-200)}.hx\:dark\:text-red-200:where(.dark,.dark *){color:var(--hx-color-red-200)}.hx\:dark\:text-slate-100:where(.dark,.dark *){color:var(--hx-color-slate-100)}.hx\:dark\:text-white:where(.dark,.dark *){color:var(--hx-color-white)}.hx\:dark\:text-yellow-200:where(.dark,.dark *){color:var(--hx-color-yellow-200)}.hx\:dark\:opacity-80:where(.dark,.dark *){opacity:.8}.hx\:dark\:shadow-\[0_-1px_0_rgba\(255\,255\,255\,\.1\)_inset\]:where(.dark,.dark *){--tw-shadow:0 -1px 0 var(--tw-shadow-color,#ffffff1a) inset;box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.hx\:dark\:shadow-\[0_-12px_16px_\#111\]:where(.dark,.dark *){--tw-shadow:0 -12px 16px var(--tw-shadow-color,#111);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.hx\:dark\:shadow-none:where(.dark,.dark *){--tw-shadow:0 0 #0000;box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}@media(hover:hover){.hx\:dark\:group-hover\:text-gray-50:where(.dark,.dark *):is(:where(.hx\:group):hover *){color:var(--hx-color-gray-50)}}.hx\:group-data-\[active\=true\]\:dark\:text-primary-600:is(:where(.hx\:group)[data-active=true] *):where(.dark,.dark *){color:var(--hx-color-primary-600)}.hx\:dark\:before\:bg-neutral-800:where(.dark,.dark *):before{content:var(--tw-content);background-color:var(--hx-color-neutral-800)}.hx\:dark\:before\:invert:where(.dark,.dark *):before{content:var(--tw-content);--tw-invert:invert(100%);filter:var(--tw-blur,)var(--tw-brightness,)var(--tw-contrast,)var(--tw-grayscale,)var(--tw-hue-rotate,)var(--tw-invert,)var(--tw-saturate,)var(--tw-sepia,)var(--tw-drop-shadow,)}@media(hover:hover){.hx\:dark\:hover\:border-gray-100:where(.dark,.dark *):hover{border-color:var(--hx-color-gray-100)}.hx\:dark\:hover\:border-gray-600:where(.dark,.dark *):hover{border-color:var(--hx-color-gray-600)}.hx\:dark\:hover\:border-neutral-500:where(.dark,.dark *):hover{border-color:var(--hx-color-neutral-500)}.hx\:dark\:hover\:border-neutral-700:where(.dark,.dark *):hover{border-color:var(--hx-color-neutral-700)}.hx\:dark\:hover\:border-neutral-800:where(.dark,.dark *):hover{border-color:var(--hx-color-neutral-800)}.hx\:dark\:hover\:bg-gray-100\/5:where(.dark,.dark *):hover{background-color:var(--hx-color-gray-100)}@supports(color:color-mix(in lab,red,red)){.hx\:dark\:hover\:bg-gray-100\/5:where(.dark,.dark *):hover{background-color:color-mix(in oklab,var(--hx-color-gray-100) 5%,transparent)}}.hx\:dark\:hover\:bg-neutral-700:where(.dark,.dark *):hover{background-color:var(--hx-color-neutral-700)}.hx\:dark\:hover\:bg-neutral-800:where(.dark,.dark *):hover{background-color:var(--hx-color-neutral-800)}.hx\:dark\:hover\:bg-neutral-900:where(.dark,.dark *):hover{background-color:var(--hx-color-neutral-900)}.hx\:dark\:hover\:bg-primary-100\/5:where(.dark,.dark *):hover{background-color:var(--hx-color-primary-100)}@supports(color:color-mix(in lab,red,red)){.hx\:dark\:hover\:bg-primary-100\/5:where(.dark,.dark *):hover{background-color:color-mix(in oklab,var(--hx-color-primary-100) 5%,transparent)}}.hx\:dark\:hover\:bg-primary-700:where(.dark,.dark *):hover{background-color:var(--hx-color-primary-700)}.hx\:dark\:hover\:text-gray-50:where(.dark,.dark *):hover{color:var(--hx-color-gray-50)}.hx\:dark\:hover\:text-gray-100:where(.dark,.dark *):hover{color:var(--hx-color-gray-100)}.hx\:dark\:hover\:text-gray-200:where(.dark,.dark *):hover{color:var(--hx-color-gray-200)}.hx\:dark\:hover\:text-gray-300:where(.dark,.dark *):hover{color:var(--hx-color-gray-300)}.hx\:dark\:hover\:text-neutral-50:where(.dark,.dark *):hover{color:var(--hx-color-neutral-50)}.hx\:dark\:hover\:text-primary-400:where(.dark,.dark *):hover{color:var(--hx-color-primary-400)}.hx\:dark\:hover\:text-white:where(.dark,.dark *):hover{color:var(--hx-color-white)}.hx\:dark\:hover\:shadow-none:where(.dark,.dark *):hover{--tw-shadow:0 0 #0000;box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}}.hx\:data-\[state\=selected\]\:dark\:border-primary-500[data-state=selected]:where(.dark,.dark *){border-color:var(--hx-color-primary-500)}.hx\:data-\[state\=selected\]\:dark\:text-primary-600[data-state=selected]:where(.dark,.dark *){color:var(--hx-color-primary-600)}@media(prefers-contrast:more){.hx\:contrast-more\:dark\:border-current:where(.dark,.dark *){border-color:initial}.hx\:contrast-more\:dark\:border-gray-50:where(.dark,.dark *){border-color:var(--hx-color-gray-50)}.hx\:contrast-more\:dark\:border-neutral-400:where(.dark,.dark *){border-color:var(--hx-color-neutral-400)}.hx\:contrast-more\:dark\:border-primary-500:where(.dark,.dark *){border-color:var(--hx-color-primary-500)}.hx\:dark\:contrast-more\:border-neutral-400:where(.dark,.dark *){border-color:var(--hx-color-neutral-400)}.hx\:contrast-more\:dark\:text-current:where(.dark,.dark *){color:currentColor}.hx\:contrast-more\:dark\:text-gray-50:where(.dark,.dark *){color:var(--hx-color-gray-50)}.hx\:contrast-more\:dark\:text-gray-100:where(.dark,.dark *){color:var(--hx-color-gray-100)}.hx\:contrast-more\:dark\:shadow-\[0_0_0_1px_\#fff\]:where(.dark,.dark *){--tw-shadow:0 0 0 1px var(--tw-shadow-color,#fff);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.hx\:contrast-more\:dark\:shadow-none:where(.dark,.dark *){--tw-shadow:0 0 #0000;box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}@media(hover:hover){.hx\:contrast-more\:dark\:hover\:border-gray-50:where(.dark,.dark *):hover{border-color:var(--hx-color-gray-50)}}}@media print{.hx\:print\:\[display\:none\],.hx\:print\:hidden{display:none}.hx\:print\:bg-transparent{background-color:#0000}}}html{font-size:var(--hx-text-base);line-height:var(--tw-leading,var(--hx-text-base--line-height));-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}body{background-color:var(--hx-color-white);width:100%}body:where(.dark,.dark *){background-color:var(--hx-color-dark);color:var(--hx-color-gray-100)}:root{--primary-hue:212deg;--primary-saturation:100%;--primary-lightness:50%;--hextra-navbar-height:3.5rem;--hextra-banner-height:2rem;--menu-height:3.75rem}.dark{--primary-hue:204deg;--primary-saturation:100%;--primary-lightness:50%}@media(prefers-reduced-motion:reduce){*,:before,:after{scroll-behavior:auto!important;transition-duration:.01ms!important;animation-duration:.01ms!important;animation-iteration-count:1!important}svg,svg *{transition-duration:0s!important}}.content :where(h1):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:calc(var(--hx-spacing) * 2);font-size:var(--hx-text-4xl);line-height:var(--tw-leading,var(--hx-text-4xl--line-height));--tw-font-weight:var(--hx-font-weight-bold);font-weight:var(--hx-font-weight-bold);--tw-tracking:var(--hx-tracking-tight);letter-spacing:var(--hx-tracking-tight);color:var(--hx-color-slate-900)}.content :where(h1):not(:where([class~=not-prose],[class~=not-prose] *)):where(.dark,.dark *){color:var(--hx-color-slate-100)}.content :where(h2):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:calc(var(--hx-spacing) * 10);border-bottom-style:var(--tw-border-style);border-bottom-width:1px;border-color:var(--hx-color-neutral-200)}@supports(color:color-mix(in lab,red,red)){.content :where(h2):not(:where([class~=not-prose],[class~=not-prose] *)){border-color:color-mix(in oklab,var(--hx-color-neutral-200) 70%,transparent)}}.content :where(h2):not(:where([class~=not-prose],[class~=not-prose] *)){padding-bottom:calc(var(--hx-spacing) * 1);font-size:var(--hx-text-3xl);line-height:var(--tw-leading,var(--hx-text-3xl--line-height));--tw-font-weight:var(--hx-font-weight-semibold);font-weight:var(--hx-font-weight-semibold);--tw-tracking:var(--hx-tracking-tight);letter-spacing:var(--hx-tracking-tight);color:var(--hx-color-slate-900)}@media(prefers-contrast:more){.content :where(h2):not(:where([class~=not-prose],[class~=not-prose] *)){border-color:var(--hx-color-neutral-400)}}.content :where(h2):not(:where([class~=not-prose],[class~=not-prose] *)):where(.dark,.dark *){border-color:var(--hx-color-primary-100)}@supports(color:color-mix(in lab,red,red)){.content :where(h2):not(:where([class~=not-prose],[class~=not-prose] *)):where(.dark,.dark *){border-color:color-mix(in oklab,var(--hx-color-primary-100) 10%,transparent)}}.content :where(h2):not(:where([class~=not-prose],[class~=not-prose] *)):where(.dark,.dark *){color:var(--hx-color-slate-100)}@media(prefers-contrast:more){.content :where(h2):not(:where([class~=not-prose],[class~=not-prose] *)):where(.dark,.dark *){border-color:var(--hx-color-neutral-400)}}.content :where(h3):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:calc(var(--hx-spacing) * 8);font-size:var(--hx-text-2xl);line-height:var(--tw-leading,var(--hx-text-2xl--line-height));--tw-font-weight:var(--hx-font-weight-semibold);font-weight:var(--hx-font-weight-semibold);--tw-tracking:var(--hx-tracking-tight);letter-spacing:var(--hx-tracking-tight);color:var(--hx-color-slate-900)}.content :where(h3):not(:where([class~=not-prose],[class~=not-prose] *)):where(.dark,.dark *){color:var(--hx-color-slate-100)}.content :where(h4):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:calc(var(--hx-spacing) * 8);font-size:var(--hx-text-xl);line-height:var(--tw-leading,var(--hx-text-xl--line-height));--tw-font-weight:var(--hx-font-weight-semibold);font-weight:var(--hx-font-weight-semibold);--tw-tracking:var(--hx-tracking-tight);letter-spacing:var(--hx-tracking-tight);color:var(--hx-color-slate-900)}.content :where(h4):not(:where([class~=not-prose],[class~=not-prose] *)):where(.dark,.dark *){color:var(--hx-color-slate-100)}.content :where(h5):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:calc(var(--hx-spacing) * 8);font-size:var(--hx-text-lg);line-height:var(--tw-leading,var(--hx-text-lg--line-height));--tw-font-weight:var(--hx-font-weight-semibold);font-weight:var(--hx-font-weight-semibold);--tw-tracking:var(--hx-tracking-tight);letter-spacing:var(--hx-tracking-tight);color:var(--hx-color-slate-900)}.content :where(h5):not(:where([class~=not-prose],[class~=not-prose] *)):where(.dark,.dark *){color:var(--hx-color-slate-100)}.content :where(h6):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:calc(var(--hx-spacing) * 8);font-size:var(--hx-text-base);line-height:var(--tw-leading,var(--hx-text-base--line-height));--tw-font-weight:var(--hx-font-weight-semibold);font-weight:var(--hx-font-weight-semibold);--tw-tracking:var(--hx-tracking-tight);letter-spacing:var(--hx-tracking-tight);color:var(--hx-color-slate-900)}.content :where(h6):not(:where([class~=not-prose],[class~=not-prose] *)):where(.dark,.dark *){color:var(--hx-color-slate-100)}.content :where(p):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:calc(var(--hx-spacing) * 6);--tw-leading:calc(var(--hx-spacing) * 7);line-height:calc(var(--hx-spacing) * 7)}.content :where(p):not(:where([class~=not-prose],[class~=not-prose] *)):first-child{margin-top:calc(var(--hx-spacing) * 0)}.content :where(a):not(:where([class~=not-prose],[class~=not-prose] *)){color:var(--hx-color-primary-600);text-decoration-line:underline;text-decoration-thickness:from-font}.content :where(blockquote):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:calc(var(--hx-spacing) * 6);border-color:var(--hx-color-gray-300);color:var(--hx-color-gray-700);font-style:italic}.content :where(blockquote):not(:where([class~=not-prose],[class~=not-prose] *)):first-child{margin-top:calc(var(--hx-spacing) * 0)}.content :where(blockquote):not(:where([class~=not-prose],[class~=not-prose] *)):where(:dir(ltr),[dir=ltr],[dir=ltr] *){border-left-style:var(--tw-border-style);padding-left:calc(var(--hx-spacing) * 6);border-left-width:2px}.content :where(blockquote):not(:where([class~=not-prose],[class~=not-prose] *)):where(:dir(rtl),[dir=rtl],[dir=rtl] *){border-right-style:var(--tw-border-style);padding-right:calc(var(--hx-spacing) * 6);border-right-width:2px}.content :where(blockquote):not(:where([class~=not-prose],[class~=not-prose] *)):where(.dark,.dark *){border-color:var(--hx-color-gray-700);color:var(--hx-color-gray-400)}.content :where(pre):not(:where(.hextra-code-block pre,[class~=not-prose],[class~=not-prose] *)){margin-bottom:calc(var(--hx-spacing) * 4);border-radius:var(--hx-radius-xl);background-color:var(--hx-color-primary-700);overflow-x:auto}@supports(color:color-mix(in lab,red,red)){.content :where(pre):not(:where(.hextra-code-block pre,[class~=not-prose],[class~=not-prose] *)){background-color:color-mix(in oklab,var(--hx-color-primary-700) 5%,transparent)}}.content :where(pre):not(:where(.hextra-code-block pre,[class~=not-prose],[class~=not-prose] *)){padding-block:calc(var(--hx-spacing) * 4);--tw-font-weight:var(--hx-font-weight-medium);font-size:.9em;font-weight:var(--hx-font-weight-medium);-webkit-font-smoothing:auto;-moz-osx-font-smoothing:auto}@media(prefers-contrast:more){.content :where(pre):not(:where(.hextra-code-block pre,[class~=not-prose],[class~=not-prose] *)){border-style:var(--tw-border-style);border-width:1px;border-color:var(--hx-color-primary-900)}@supports(color:color-mix(in lab,red,red)){.content :where(pre):not(:where(.hextra-code-block pre,[class~=not-prose],[class~=not-prose] *)){border-color:color-mix(in oklab,var(--hx-color-primary-900) 20%,transparent)}}.content :where(pre):not(:where(.hextra-code-block pre,[class~=not-prose],[class~=not-prose] *)){--tw-contrast:contrast(150%);filter:var(--tw-blur,)var(--tw-brightness,)var(--tw-contrast,)var(--tw-grayscale,)var(--tw-hue-rotate,)var(--tw-invert,)var(--tw-saturate,)var(--tw-sepia,)var(--tw-drop-shadow,)}}.content :where(pre):not(:where(.hextra-code-block pre,[class~=not-prose],[class~=not-prose] *)):where(.dark,.dark *){background-color:var(--hx-color-primary-300)}@supports(color:color-mix(in lab,red,red)){.content :where(pre):not(:where(.hextra-code-block pre,[class~=not-prose],[class~=not-prose] *)):where(.dark,.dark *){background-color:color-mix(in oklab,var(--hx-color-primary-300) 10%,transparent)}}@media(prefers-contrast:more){.content :where(pre):not(:where(.hextra-code-block pre,[class~=not-prose],[class~=not-prose] *)):where(.dark,.dark *){border-color:var(--hx-color-primary-100)}@supports(color:color-mix(in lab,red,red)){.content :where(pre):not(:where(.hextra-code-block pre,[class~=not-prose],[class~=not-prose] *)):where(.dark,.dark *){border-color:color-mix(in oklab,var(--hx-color-primary-100) 40%,transparent)}}}.content :where(code):not(:where(.hextra-code-block code,[class~=not-prose],[class~=not-prose] *)){border-radius:var(--hx-radius-md);border-style:var(--tw-border-style);border-width:1px;border-color:var(--hx-color-black)}@supports(color:color-mix(in lab,red,red)){.content :where(code):not(:where(.hextra-code-block code,[class~=not-prose],[class~=not-prose] *)){border-color:color-mix(in oklab,var(--hx-color-black) 4%,transparent)}}.content :where(code):not(:where(.hextra-code-block code,[class~=not-prose],[class~=not-prose] *)){background-color:var(--hx-color-black)}@supports(color:color-mix(in lab,red,red)){.content :where(code):not(:where(.hextra-code-block code,[class~=not-prose],[class~=not-prose] *)){background-color:color-mix(in oklab,var(--hx-color-black) 3%,transparent)}}.content :where(code):not(:where(.hextra-code-block code,[class~=not-prose],[class~=not-prose] *)){padding-inline:.25em;padding-block:calc(var(--hx-spacing) * .5);overflow-wrap:break-word;font-size:.9em}.content :where(code):not(:where(.hextra-code-block code,[class~=not-prose],[class~=not-prose] *)):where(.dark,.dark *){border-color:var(--hx-color-white)}@supports(color:color-mix(in lab,red,red)){.content :where(code):not(:where(.hextra-code-block code,[class~=not-prose],[class~=not-prose] *)):where(.dark,.dark *){border-color:color-mix(in oklab,var(--hx-color-white) 10%,transparent)}}.content :where(code):not(:where(.hextra-code-block code,[class~=not-prose],[class~=not-prose] *)):where(.dark,.dark *){background-color:var(--hx-color-white)}@supports(color:color-mix(in lab,red,red)){.content :where(code):not(:where(.hextra-code-block code,[class~=not-prose],[class~=not-prose] *)):where(.dark,.dark *){background-color:color-mix(in oklab,var(--hx-color-white) 10%,transparent)}}.content :where(table):not(:where(.hextra-code-block table,[class~=not-prose],[class~=not-prose] *)){margin-block:calc(var(--hx-spacing) * 6);border-collapse:collapse;width:100%;padding:calc(var(--hx-spacing) * 0);font-size:var(--hx-text-sm);line-height:var(--tw-leading,var(--hx-text-sm--line-height));--tw-leading:calc(var(--hx-spacing) * 5);line-height:calc(var(--hx-spacing) * 5);display:block;overflow-x:auto}.content :where(table):not(:where(.hextra-code-block table,[class~=not-prose],[class~=not-prose] *)):first-child{margin-top:calc(var(--hx-spacing) * 0)}.content :where(table):not(:where(.hextra-code-block table,[class~=not-prose],[class~=not-prose] *)) thead{background-color:var(--hx-color-gray-50)}.content :where(table):not(:where(.hextra-code-block table,[class~=not-prose],[class~=not-prose] *)) thead:where(.dark,.dark *){background-color:var(--hx-color-gray-600)}@supports(color:color-mix(in lab,red,red)){.content :where(table):not(:where(.hextra-code-block table,[class~=not-prose],[class~=not-prose] *)) thead:where(.dark,.dark *){background-color:color-mix(in oklab,var(--hx-color-gray-600) 20%,transparent)}}.content :where(table):not(:where(.hextra-code-block table,[class~=not-prose],[class~=not-prose] *)) tr{margin:calc(var(--hx-spacing) * 0);border-top-style:var(--tw-border-style);border-top-width:1px;border-color:var(--hx-color-gray-300);padding:calc(var(--hx-spacing) * 0)}.content :where(table):not(:where(.hextra-code-block table,[class~=not-prose],[class~=not-prose] *)) tr:where(.dark,.dark *){border-color:var(--hx-color-gray-600)}.content :where(table):not(:where(.hextra-code-block table,[class~=not-prose],[class~=not-prose] *)) th{margin:calc(var(--hx-spacing) * 0);border-style:var(--tw-border-style);border-width:1px;border-color:var(--hx-color-gray-300);padding:calc(var(--hx-spacing) * 2);--tw-font-weight:var(--hx-font-weight-semibold);font-weight:var(--hx-font-weight-semibold)}.content :where(table):not(:where(.hextra-code-block table,[class~=not-prose],[class~=not-prose] *)) th:where(.dark,.dark *){border-color:var(--hx-color-gray-600)}.content :where(table):not(:where(.hextra-code-block table,[class~=not-prose],[class~=not-prose] *)) td{margin:calc(var(--hx-spacing) * 0);border-style:var(--tw-border-style);border-width:1px;border-color:var(--hx-color-gray-300);padding:calc(var(--hx-spacing) * 2)}.content :where(table):not(:where(.hextra-code-block table,[class~=not-prose],[class~=not-prose] *)) td:where(.dark,.dark *){border-color:var(--hx-color-gray-600)}.content :where(ol):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:calc(var(--hx-spacing) * 6);list-style-type:decimal}.content :where(ol):not(:where([class~=not-prose],[class~=not-prose] *)):first-child{margin-top:calc(var(--hx-spacing) * 0)}.content :where(ol):not(:where([class~=not-prose],[class~=not-prose] *)):where(:dir(ltr),[dir=ltr],[dir=ltr] *){margin-left:calc(var(--hx-spacing) * 6)}.content :where(ol):not(:where([class~=not-prose],[class~=not-prose] *)):where(:dir(rtl),[dir=rtl],[dir=rtl] *){margin-right:calc(var(--hx-spacing) * 6)}.content :where(ol):not(:where([class~=not-prose],[class~=not-prose] *)) li{margin-block:calc(var(--hx-spacing) * 2)}.content :where(ul):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:calc(var(--hx-spacing) * 6);list-style-type:disc}.content :where(ul):not(:where([class~=not-prose],[class~=not-prose] *)):first-child{margin-top:calc(var(--hx-spacing) * 0)}.content :where(ul):not(:where([class~=not-prose],[class~=not-prose] *)):where(:dir(ltr),[dir=ltr],[dir=ltr] *){margin-left:calc(var(--hx-spacing) * 6)}.content :where(ul):not(:where([class~=not-prose],[class~=not-prose] *)):where(:dir(rtl),[dir=rtl],[dir=rtl] *){margin-right:calc(var(--hx-spacing) * 6)}.content :where(ul):not(:where([class~=not-prose],[class~=not-prose] *)) li{margin-block:calc(var(--hx-spacing) * 2)}.content :where(ul):not(:where([class~=not-prose],[class~=not-prose] *)):has(li input[type=checkbox]){list-style-type:none}.content :where(ul,ol)>li>:where(ul,ol):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:calc(var(--hx-spacing) * 0)}.content :where(kbd):not(:where([class~=not-prose],[class~=not-prose] *)){border-radius:var(--hx-radius-md);border-style:var(--tw-border-style);border-width:1px;border-color:var(--hx-color-black)}@supports(color:color-mix(in lab,red,red)){.content :where(kbd):not(:where([class~=not-prose],[class~=not-prose] *)){border-color:color-mix(in oklab,var(--hx-color-black) 4%,transparent)}}.content :where(kbd):not(:where([class~=not-prose],[class~=not-prose] *)){background-color:var(--hx-color-black)}@supports(color:color-mix(in lab,red,red)){.content :where(kbd):not(:where([class~=not-prose],[class~=not-prose] *)){background-color:color-mix(in oklab,var(--hx-color-black) 3%,transparent)}}.content :where(kbd):not(:where([class~=not-prose],[class~=not-prose] *)){padding-inline:.25em;padding-block:calc(var(--hx-spacing) * .5);overflow-wrap:break-word;font-size:.9em}.content :where(kbd):not(:where([class~=not-prose],[class~=not-prose] *)):where(.dark,.dark *){border-color:var(--hx-color-white)}@supports(color:color-mix(in lab,red,red)){.content :where(kbd):not(:where([class~=not-prose],[class~=not-prose] *)):where(.dark,.dark *){border-color:color-mix(in oklab,var(--hx-color-white) 10%,transparent)}}.content :where(kbd):not(:where([class~=not-prose],[class~=not-prose] *)):where(.dark,.dark *){background-color:var(--hx-color-white)}@supports(color:color-mix(in lab,red,red)){.content :where(kbd):not(:where([class~=not-prose],[class~=not-prose] *)):where(.dark,.dark *){background-color:color-mix(in oklab,var(--hx-color-white) 10%,transparent)}}.content :where(pre.mermaid):not(:where(.hextra-code-block pre,[class~=not-prose],[class~=not-prose] *)){background-color:#0000;border-radius:0}.content :where(pre.mermaid):not(:where(.hextra-code-block pre,[class~=not-prose],[class~=not-prose] *)):where(.dark,.dark *){background-color:#0000}.content :where(img):not(:where([class~=not-prose],[class~=not-prose] *)){margin-inline:auto;margin-block:calc(var(--hx-spacing) * 4);border-radius:var(--hx-radius-md)}.content :where(figure):not(:where([class~=not-prose],[class~=not-prose] *)) figcaption{margin-top:calc(var(--hx-spacing) * 2);text-align:center;font-size:var(--hx-text-sm);line-height:var(--tw-leading,var(--hx-text-sm--line-height));color:var(--hx-color-gray-500);display:block}.content :where(figure):not(:where([class~=not-prose],[class~=not-prose] *)) figcaption:where(.dark,.dark *){color:var(--hx-color-gray-400)}.content :where(dl):not(:where([class~=not-prose],[class~=not-prose] *)) dt{margin-top:calc(var(--hx-spacing) * 6);--tw-font-weight:var(--hx-font-weight-semibold);font-weight:var(--hx-font-weight-semibold)}.content :where(dl):not(:where([class~=not-prose],[class~=not-prose] *)) dd{margin-block:calc(var(--hx-spacing) * 2);padding-inline-start:calc(var(--hx-spacing) * 6)}.content :where(hr):not(:where([class~=not-prose],[class~=not-prose] *)){margin-block:calc(var(--hx-spacing) * 10);border-color:var(--hx-color-gray-200)}.content :where(hr):not(:where([class~=not-prose],[class~=not-prose] *)):first-child{margin-top:calc(var(--hx-spacing) * 0)}.content :where(hr):not(:where([class~=not-prose],[class~=not-prose] *)):last-child{margin-bottom:calc(var(--hx-spacing) * 0)}.content :where(hr):not(:where([class~=not-prose],[class~=not-prose] *)):where(.dark,.dark *){border-color:var(--hx-color-neutral-800)}.content .footnotes{margin-top:calc(var(--hx-spacing) * 12);font-size:var(--hx-text-sm);line-height:var(--tw-leading,var(--hx-text-sm--line-height))}.content .footnotes hr{border-color:var(--hx-color-gray-200)}.content .footnotes hr:where(.dark,.dark *){border-color:var(--hx-color-neutral-800)}.content .subheading-anchor{opacity:0;transition-property:opacity;transition-timing-function:var(--tw-ease,var(--hx-default-transition-timing-function));transition-duration:var(--tw-duration,var(--hx-default-transition-duration))}.content .subheading-anchor:where(:dir(ltr),[dir=ltr],[dir=ltr] *){margin-left:calc(var(--hx-spacing) * 1)}.content .subheading-anchor:where(:dir(rtl),[dir=rtl],[dir=rtl] *){margin-right:calc(var(--hx-spacing) * 1)}span:target+:is(.content .subheading-anchor),:hover>:is(.content .subheading-anchor),.content .subheading-anchor:focus-visible{opacity:1}span+:is(.content .subheading-anchor),:hover>:is(.content .subheading-anchor){text-decoration-line:none!important}.content .subheading-anchor:after{content:var(--tw-content);color:var(--hx-color-gray-300)}.content .subheading-anchor:where(.dark,.dark *):after{content:var(--tw-content);color:var(--hx-color-neutral-700)}.content .subheading-anchor:after{padding-inline:calc(var(--hx-spacing) * 1);--tw-content:"#";content:var(--tw-content)}span:target+:is(){color:var(--hx-color-gray-400)}span:target+:is():where(.dark,.dark *){color:var(--hx-color-neutral-500)}article details>summary::-webkit-details-marker{display:none}article details>summary:before{vertical-align:-4px;background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' class='hx:h-5 hx:w-5' viewBox='0 0 20 20' fill='currentColor'%3E%3Cpath fill-rule='evenodd' d='M7.293 14.707a1 1 0 010-1.414L10.586 10 7.293 6.707a1 1 0 011.414-1.414l4 4a1 1 0 010 1.414l-4 4a1 1 0 01-1.414 0z' clip-rule='evenodd' /%3E%3C/svg%3E");width:1.2em;height:1.2em;padding:0 .6em}:lang(fa) ol{list-style-type:persian}.highlight .chroma .err{color:#a61717;background-color:#e3d2d2}.highlight .chroma .lnlinks{color:inherit;outline:none;text-decoration:none}.highlight .chroma .line{display:flex}.highlight .chroma .k,.highlight .chroma .kc,.highlight .chroma .kd,.highlight .chroma .kn,.highlight .chroma .kp,.highlight .chroma .kr{color:#000;font-weight:700}.highlight .chroma .kt{color:#458;font-weight:700}.highlight .chroma .na{color:teal}.highlight .chroma .nb{color:#0086b3}.highlight .chroma .bp{color:#999}.highlight .chroma .nc{color:#458;font-weight:700}.highlight .chroma .no{color:teal}.highlight .chroma .nd{color:#3c5d5d;font-weight:700}.highlight .chroma .ni{color:purple}.highlight .chroma .ne,.highlight .chroma .nf,.highlight .chroma .nl{color:#900;font-weight:700}.highlight .chroma .nn{color:#555}.highlight .chroma .nt{color:navy}.highlight .chroma .nv,.highlight .chroma .vc,.highlight .chroma .vg,.highlight .chroma .vi{color:teal}.highlight .chroma .s,.highlight .chroma .sa,.highlight .chroma .sb,.highlight .chroma .sc,.highlight .chroma .dl,.highlight .chroma .sd,.highlight .chroma .s2,.highlight .chroma .se,.highlight .chroma .sh,.highlight .chroma .si,.highlight .chroma .sx{color:#d14}.highlight .chroma .sr{color:#009926}.highlight .chroma .s1{color:#d14}.highlight .chroma .ss{color:#990073}.highlight .chroma .m,.highlight .chroma .mb,.highlight .chroma .mf,.highlight .chroma .mh,.highlight .chroma .mi,.highlight .chroma .il,.highlight .chroma .mo{color:#099}.highlight .chroma .o,.highlight .chroma .ow{color:#000;font-weight:700}.highlight .chroma .c,.highlight .chroma .ch,.highlight .chroma .cm,.highlight .chroma .c1{color:#998;font-style:italic}.highlight .chroma .cs,.highlight .chroma .cp,.highlight .chroma .cpf{color:#999;font-style:italic;font-weight:700}.highlight .chroma .gd{color:#000;background-color:#fdd}.highlight .chroma .ge{color:#000;font-style:italic}.highlight .chroma .gr{color:#a00}.highlight .chroma .gh{color:#999}.highlight .chroma .gi{color:#000;background-color:#dfd}.highlight .chroma .go{color:#888}.highlight .chroma .gp{color:#555}.highlight .chroma .gs{font-weight:700}.highlight .chroma .gu{color:#aaa}.highlight .chroma .gt{color:#a00}.highlight .chroma .gl{text-decoration:underline}.highlight .chroma .w{color:#bbb}.dark .highlight .chroma .err{color:#f85149}.dark .highlight .chroma .lnlinks{color:inherit;outline:none;text-decoration:none}.dark .highlight .chroma .line{display:flex}.dark .highlight .chroma .k{color:#ff7b72}.dark .highlight .chroma .kc{color:#79c0ff}.dark .highlight .chroma .kd,.dark .highlight .chroma .kn{color:#ff7b72}.dark .highlight .chroma .kp{color:#79c0ff}.dark .highlight .chroma .kr,.dark .highlight .chroma .kt{color:#ff7b72}.dark .highlight .chroma .nc{color:#f0883e;font-weight:700}.dark .highlight .chroma .no{color:#79c0ff;font-weight:700}.dark .highlight .chroma .nd{color:#d2a8ff;font-weight:700}.dark .highlight .chroma .ni{color:#ffa657}.dark .highlight .chroma .ne{color:#f0883e;font-weight:700}.dark .highlight .chroma .nf{color:#d2a8ff;font-weight:700}.dark .highlight .chroma .nl{color:#79c0ff;font-weight:700}.dark .highlight .chroma .nn{color:#ff7b72}.dark .highlight .chroma .py{color:#79c0ff}.dark .highlight .chroma .nt{color:#7ee787}.dark .highlight .chroma .nv{color:#79c0ff}.dark .highlight .chroma .l{color:#a5d6ff}.dark .highlight .chroma .ld{color:#79c0ff}.dark .highlight .chroma .s{color:#a5d6ff}.dark .highlight .chroma .sa{color:#79c0ff}.dark .highlight .chroma .sb,.dark .highlight .chroma .sc{color:#a5d6ff}.dark .highlight .chroma .dl{color:#79c0ff}.dark .highlight .chroma .sd,.dark .highlight .chroma .s2{color:#a5d6ff}.dark .highlight .chroma .se,.dark .highlight .chroma .sh{color:#79c0ff}.dark .highlight .chroma .si,.dark .highlight .chroma .sx{color:#a5d6ff}.dark .highlight .chroma .sr{color:#79c0ff}.dark .highlight .chroma .s1,.dark .highlight .chroma .ss,.dark .highlight .chroma .m,.dark .highlight .chroma .mb,.dark .highlight .chroma .mf,.dark .highlight .chroma .mh,.dark .highlight .chroma .mi,.dark .highlight .chroma .il,.dark .highlight .chroma .mo{color:#a5d6ff}.dark .highlight .chroma .o,.dark .highlight .chroma .ow{color:#ff7b72;font-weight:700}.dark .highlight .chroma .c,.dark .highlight .chroma .ch,.dark .highlight .chroma .cm,.dark .highlight .chroma .c1{color:#8b949e;font-style:italic}.dark .highlight .chroma .cs,.dark .highlight .chroma .cp,.dark .highlight .chroma .cpf{color:#8b949e;font-style:italic;font-weight:700}.dark .highlight .chroma .gd{color:#ffa198;background-color:#490202}.dark .highlight .chroma .ge{color:inherit;font-style:italic}.dark .highlight .chroma .gr{color:#ffa198}.dark .highlight .chroma .gh{color:#79c0ff;font-weight:700}.dark .highlight .chroma .gi{color:#56d364;background-color:#0f5323}.dark .highlight .chroma .go,.dark .highlight .chroma .gp{color:#8b949e}.dark .highlight .chroma .gs{font-weight:700}.dark .highlight .chroma .gu{color:#79c0ff}.dark .highlight .chroma .gt{color:#ff7b72}.dark .highlight .chroma .gl{text-decoration:underline}.dark .highlight .chroma .w{color:#6e7681}.hextra-code-block{--tw-leading:calc(var(--hx-spacing) * 5);font-size:.9em;line-height:calc(var(--hx-spacing) * 5)}.hextra-code-block pre{background-color:var(--hx-color-primary-700);overflow-x:auto}@supports(color:color-mix(in lab,red,red)){.hextra-code-block pre{background-color:color-mix(in oklab,var(--hx-color-primary-700) 5%,transparent)}}.hextra-code-block pre{--tw-font-weight:var(--hx-font-weight-medium);font-size:.9em;font-weight:var(--hx-font-weight-medium);-webkit-font-smoothing:auto;-moz-osx-font-smoothing:auto}@media(prefers-contrast:more){.hextra-code-block pre{border-style:var(--tw-border-style);border-width:1px;border-color:var(--hx-color-primary-900)}@supports(color:color-mix(in lab,red,red)){.hextra-code-block pre{border-color:color-mix(in oklab,var(--hx-color-primary-900) 20%,transparent)}}.hextra-code-block pre{--tw-contrast:contrast(150%);filter:var(--tw-blur,)var(--tw-brightness,)var(--tw-contrast,)var(--tw-grayscale,)var(--tw-hue-rotate,)var(--tw-invert,)var(--tw-saturate,)var(--tw-sepia,)var(--tw-drop-shadow,)}}.hextra-code-block pre:where(.dark,.dark *){background-color:var(--hx-color-primary-300)}@supports(color:color-mix(in lab,red,red)){.hextra-code-block pre:where(.dark,.dark *){background-color:color-mix(in oklab,var(--hx-color-primary-300) 10%,transparent)}}@media(prefers-contrast:more){.hextra-code-block pre:where(.dark,.dark *){border-color:var(--hx-color-primary-100)}@supports(color:color-mix(in lab,red,red)){.hextra-code-block pre:where(.dark,.dark *){border-color:color-mix(in oklab,var(--hx-color-primary-100) 40%,transparent)}}}.hextra-code-block .hextra-code-filename{top:calc(var(--hx-spacing) * 0);z-index:1;text-overflow:ellipsis;white-space:nowrap;border-top-left-radius:var(--hx-radius-xl);border-top-right-radius:var(--hx-radius-xl);background-color:var(--hx-color-primary-700);width:100%;position:absolute;overflow:hidden}@supports(color:color-mix(in lab,red,red)){.hextra-code-block .hextra-code-filename{background-color:color-mix(in oklab,var(--hx-color-primary-700) 5%,transparent)}}.hextra-code-block .hextra-code-filename{padding-inline:calc(var(--hx-spacing) * 4);padding-block:calc(var(--hx-spacing) * 2);font-size:var(--hx-text-xs);line-height:var(--tw-leading,var(--hx-text-xs--line-height));color:var(--hx-color-gray-700)}.hextra-code-block .hextra-code-filename:where(.dark,.dark *){background-color:var(--hx-color-primary-300)}@supports(color:color-mix(in lab,red,red)){.hextra-code-block .hextra-code-filename:where(.dark,.dark *){background-color:color-mix(in oklab,var(--hx-color-primary-300) 10%,transparent)}}.hextra-code-block .hextra-code-filename:where(.dark,.dark *){color:var(--hx-color-gray-200)}.hextra-code-block .hextra-code-filename+pre:not(.lntable pre){padding-top:calc(var(--hx-spacing) * 12)}.hextra-code-block pre:not(.lntable pre){margin-bottom:calc(var(--hx-spacing) * 4);border-radius:var(--hx-radius-xl);padding-inline:calc(var(--hx-spacing) * 4);padding-block:calc(var(--hx-spacing) * 4)}.hextra-code-block div:nth-of-type(2) pre{padding-top:calc(var(--hx-spacing) * 12);padding-bottom:calc(var(--hx-spacing) * 4)}.chroma .lntable{margin:calc(var(--hx-spacing) * 0);border-radius:var(--hx-radius-xl);width:auto;display:block;overflow:auto}.chroma .lntable pre{padding-top:calc(var(--hx-spacing) * 4);padding-bottom:calc(var(--hx-spacing) * 4)}.chroma .ln,.chroma .lnt:not(.hl>.lnt),.chroma .hl:not(.line){min-width:2.6rem;padding-right:calc(var(--hx-spacing) * 4);padding-left:calc(var(--hx-spacing) * 4);color:var(--hx-color-neutral-600)}:is(.chroma .ln,.chroma .lnt:not(.hl>.lnt),.chroma .hl:not(.line)):where(.dark,.dark *){color:var(--hx-color-neutral-300)}.chroma .lntd{padding:calc(var(--hx-spacing) * 0);vertical-align:top}.chroma .lntd:last-of-type{width:100%}.chroma .hl{background-color:var(--hx-color-primary-800);width:100%;display:block}@supports(color:color-mix(in lab,red,red)){.chroma .hl{background-color:color-mix(in oklab,var(--hx-color-primary-800) 10%,transparent)}}.hextra-alert{margin-top:calc(var(--hx-spacing) * 6);border-radius:var(--hx-radius-lg);border-style:var(--tw-border-style);padding-inline:calc(var(--hx-spacing) * 4);padding-block:calc(var(--hx-spacing) * 4);border-width:1px;flex-direction:column;display:flex;overflow-x:auto}@media(prefers-contrast:more){.hextra-alert,.hextra-alert:where(.dark,.dark *){border-color:initial}}.hextra-alert{border-color:var(--hx-color-green-200);background-color:var(--hx-color-green-100);color:var(--hx-color-green-900)}.hextra-alert:where(.dark,.dark *){border-color:var(--hx-color-green-200)}@supports(color:color-mix(in lab,red,red)){.hextra-alert:where(.dark,.dark *){border-color:color-mix(in oklab,var(--hx-color-green-200) 30%,transparent)}}.hextra-alert:where(.dark,.dark *){background-color:var(--hx-color-green-900)}@supports(color:color-mix(in lab,red,red)){.hextra-alert:where(.dark,.dark *){background-color:color-mix(in oklab,var(--hx-color-green-900) 30%,transparent)}}.hextra-alert:where(.dark,.dark *){color:var(--hx-color-green-200)}.hextra-alert[data-alert=note]{border-color:var(--hx-color-blue-200);background-color:var(--hx-color-blue-100);color:var(--hx-color-blue-900)}.hextra-alert[data-alert=note]:where(.dark,.dark *){border-color:var(--hx-color-blue-200)}@supports(color:color-mix(in lab,red,red)){.hextra-alert[data-alert=note]:where(.dark,.dark *){border-color:color-mix(in oklab,var(--hx-color-blue-200) 30%,transparent)}}.hextra-alert[data-alert=note]:where(.dark,.dark *){background-color:var(--hx-color-blue-900)}@supports(color:color-mix(in lab,red,red)){.hextra-alert[data-alert=note]:where(.dark,.dark *){background-color:color-mix(in oklab,var(--hx-color-blue-900) 30%,transparent)}}.hextra-alert[data-alert=note]:where(.dark,.dark *){color:var(--hx-color-blue-200)}.hextra-alert[data-alert=tip]{border-color:var(--hx-color-green-200);background-color:var(--hx-color-green-100);color:var(--hx-color-green-900)}.hextra-alert[data-alert=tip]:where(.dark,.dark *){border-color:var(--hx-color-green-200)}@supports(color:color-mix(in lab,red,red)){.hextra-alert[data-alert=tip]:where(.dark,.dark *){border-color:color-mix(in oklab,var(--hx-color-green-200) 30%,transparent)}}.hextra-alert[data-alert=tip]:where(.dark,.dark *){background-color:var(--hx-color-green-900)}@supports(color:color-mix(in lab,red,red)){.hextra-alert[data-alert=tip]:where(.dark,.dark *){background-color:color-mix(in oklab,var(--hx-color-green-900) 30%,transparent)}}.hextra-alert[data-alert=tip]:where(.dark,.dark *){color:var(--hx-color-green-200)}.hextra-alert[data-alert=important]{border-color:var(--hx-color-purple-200);background-color:var(--hx-color-purple-100);color:var(--hx-color-purple-900)}.hextra-alert[data-alert=important]:where(.dark,.dark *){border-color:var(--hx-color-purple-200)}@supports(color:color-mix(in lab,red,red)){.hextra-alert[data-alert=important]:where(.dark,.dark *){border-color:color-mix(in oklab,var(--hx-color-purple-200) 30%,transparent)}}.hextra-alert[data-alert=important]:where(.dark,.dark *){background-color:var(--hx-color-purple-900)}@supports(color:color-mix(in lab,red,red)){.hextra-alert[data-alert=important]:where(.dark,.dark *){background-color:color-mix(in oklab,var(--hx-color-purple-900) 30%,transparent)}}.hextra-alert[data-alert=important]:where(.dark,.dark *){color:var(--hx-color-purple-200)}.hextra-alert[data-alert=warning]{border-color:var(--hx-color-amber-200);background-color:var(--hx-color-amber-100);color:var(--hx-color-amber-900)}.hextra-alert[data-alert=warning]:where(.dark,.dark *){border-color:var(--hx-color-amber-200)}@supports(color:color-mix(in lab,red,red)){.hextra-alert[data-alert=warning]:where(.dark,.dark *){border-color:color-mix(in oklab,var(--hx-color-amber-200) 30%,transparent)}}.hextra-alert[data-alert=warning]:where(.dark,.dark *){background-color:var(--hx-color-amber-900)}@supports(color:color-mix(in lab,red,red)){.hextra-alert[data-alert=warning]:where(.dark,.dark *){background-color:color-mix(in oklab,var(--hx-color-amber-900) 30%,transparent)}}.hextra-alert[data-alert=warning]:where(.dark,.dark *){color:var(--hx-color-amber-200)}.hextra-alert[data-alert=caution]{border-color:var(--hx-color-red-200);background-color:var(--hx-color-red-100);color:var(--hx-color-red-900)}.hextra-alert[data-alert=caution]:where(.dark,.dark *){border-color:var(--hx-color-red-200)}@supports(color:color-mix(in lab,red,red)){.hextra-alert[data-alert=caution]:where(.dark,.dark *){border-color:color-mix(in oklab,var(--hx-color-red-200) 30%,transparent)}}.hextra-alert[data-alert=caution]:where(.dark,.dark *){background-color:var(--hx-color-red-900)}@supports(color:color-mix(in lab,red,red)){.hextra-alert[data-alert=caution]:where(.dark,.dark *){background-color:color-mix(in oklab,var(--hx-color-red-900) 30%,transparent)}}.hextra-alert[data-alert=caution]:where(.dark,.dark *){color:var(--hx-color-red-200)}.hextra-alert-title{min-width:calc(var(--hx-spacing) * 0);--tw-font-weight:var(--hx-font-weight-medium);font-weight:var(--hx-font-weight-medium);align-items:center;display:flex}.hextra-alert-title-text{min-width:calc(var(--hx-spacing) * 0);word-break:break-word}.hextra-alert-icon{margin-right:calc(var(--hx-spacing) * 2);vertical-align:middle;flex-shrink:0;display:inline-block}.hextra-alert-toggle{cursor:pointer;align-items:center;gap:calc(var(--hx-spacing) * 3);text-align:left;--tw-font-weight:var(--hx-font-weight-medium);width:100%;font-weight:var(--hx-font-weight-medium);display:flex}.hextra-alert-toggle:focus-visible{--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow);--tw-ring-color:var(--hx-color-primary-200);--tw-ring-offset-width:0px;--tw-ring-offset-shadow:var(--tw-ring-inset,) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-outline-style:none;--tw-ring-inset:inset;outline-style:none}.hextra-alert-toggle:where(.dark,.dark *):focus-visible{--tw-ring-color:var(--hx-color-primary-800)}.hextra-alert-chevron{height:calc(var(--hx-spacing) * 4.5);min-width:calc(var(--hx-spacing) * 4.5);border-radius:var(--hx-radius-xs);padding:calc(var(--hx-spacing) * .5);flex-shrink:0}.hextra-alert-chevron:where(:dir(ltr),[dir=ltr],[dir=ltr] *){margin-left:auto}.hextra-alert-chevron:where(:dir(rtl),[dir=rtl],[dir=rtl] *){margin-right:auto}.hextra-alert-chevron>path{transform-origin:50%;transition-property:transform,translate,scale,rotate;transition-timing-function:var(--tw-ease,var(--hx-default-transition-timing-function));transition-duration:var(--tw-duration,var(--hx-default-transition-duration))}.hextra-alert-chevron>path:where(:dir(rtl),[dir=rtl],[dir=rtl] *){rotate:-180deg}.hextra-alert-content{width:100%;min-width:calc(var(--hx-spacing) * 0);--tw-leading:calc(var(--hx-spacing) * 7);line-height:calc(var(--hx-spacing) * 7)}.hextra-alert[data-alert-fold]>.hextra-alert-content{grid-template-rows:0fr;display:grid;overflow:hidden}.hextra-alert[data-alert-fold]>.hextra-alert-content>.hextra-alert-content-inner{min-height:0}.hextra-alert[data-alert-fold][data-alert-fold=\+]>.hextra-alert-toggle>.hextra-alert-chevron>path{rotate:90deg}.hextra-alert[data-alert-fold][data-alert-fold=\+]>.hextra-alert-content{grid-template-rows:1fr}@media(prefers-reduced-motion:no-preference){.hextra-alert[data-alert-fold]>.hextra-alert-content{transition:grid-template-rows .2s cubic-bezier(.52,.16,.04,1)}}@media(prefers-reduced-motion:reduce){.hextra-alert-chevron>path{transition:none}}@media print{.hextra-alert[data-alert-fold]>.hextra-alert-content{grid-template-rows:1fr}}.hextra-cards{grid-template-columns:repeat(auto-fill,minmax(max(250px,calc((100% - 1rem * 2)/var(--hextra-cards-grid-cols))),1fr))}.hextra-card{position:relative}.hextra-card img{-webkit-user-select:none;user-select:none}.hextra-card:hover .hextra-card-icon svg{color:currentColor}.hextra-card .hextra-card-icon svg{color:#0003;width:1.5rem;transition:color .3s}.hextra-card p{margin-top:.5rem;position:relative}.dark .hextra-card .hextra-card-icon svg{color:#fff6}.dark .hextra-card:hover .hextra-card-icon svg{color:currentColor}.hextra-card-tag{z-index:10;position:absolute;top:5px}.hextra-card-tag:where(:dir(ltr)){right:5px}.hextra-card-tag:where(:dir(rtl)){left:5px}.hextra-steps :where(h2,h3,h4,h5,h6):not(.no-step-marker){counter-increment:step}.hextra-steps :where(h2,h3,h4,h5,h6):not(.no-step-marker):where(:dir(ltr),[dir=ltr],[dir=ltr] *):before{content:var(--tw-content);margin-left:-41px}.hextra-steps :where(h2,h3,h4,h5,h6):not(.no-step-marker):where(:dir(rtl),[dir=rtl],[dir=rtl] *):before{content:var(--tw-content);margin-right:-44px}.hextra-steps :where(h2,h3,h4,h5,h6):not(.no-step-marker):before{content:var(--tw-content);background-color:var(--hx-color-gray-100)}.hextra-steps :where(h2,h3,h4,h5,h6):not(.no-step-marker):where(.dark,.dark *):before{content:var(--tw-content);background-color:var(--hx-color-neutral-800)}.hextra-steps :where(h2,h3,h4,h5,h6):not(.no-step-marker):before{content:var(--tw-content);border-style:var(--tw-border-style);content:var(--tw-content);border-width:4px;border-color:var(--hx-color-white)}.hextra-steps :where(h2,h3,h4,h5,h6):not(.no-step-marker):where(.dark,.dark *):before{content:var(--tw-content);border-color:var(--hx-color-dark)}.hextra-steps :where(h2,h3,h4,h5,h6):not(.no-step-marker):before{content:counter(step);text-align:center;text-indent:-1px;width:33px;height:33px;font-size:var(--hx-text-base);line-height:var(--tw-leading,var(--hx-text-base--line-height));--tw-font-weight:var(--hx-font-weight-normal);font-weight:var(--hx-font-weight-normal);color:var(--hx-color-neutral-400);border-radius:340282e33px;position:absolute}:lang(fa) .hextra-steps :where(h2,h3,h4,h5,h6):not(.no-step-marker):before{content:counter(step,persian)}.hextra-search-trigger{cursor:pointer;border-radius:var(--hx-radius-lg);padding:calc(var(--hx-spacing) * 1);color:currentColor;justify-content:center;align-items:center;display:inline-flex}.hextra-search-trigger:focus-visible{--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow);--tw-ring-color:var(--hx-color-primary-200);--tw-ring-offset-width:1px;--tw-ring-offset-shadow:var(--tw-ring-inset,) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-offset-color:var(--hx-color-primary-300);--tw-outline-style:none;outline-style:none}.hextra-search-trigger:where(.dark,.dark *):focus-visible{--tw-ring-color:var(--hx-color-primary-800);--tw-ring-offset-color:var(--hx-color-primary-700)}.hextra-search-trigger{transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to;transition-timing-function:var(--tw-ease,var(--hx-default-transition-timing-function));transition-duration:var(--tw-duration,var(--hx-default-transition-duration))}@media(min-width:48rem){.hextra-search-trigger{width:calc(var(--hx-spacing) * 48);justify-content:flex-start;gap:calc(var(--hx-spacing) * 2);background-color:var(--hx-color-black)}@supports(color:color-mix(in lab,red,red)){.hextra-search-trigger{background-color:color-mix(in oklab,var(--hx-color-black) 5%,transparent)}}.hextra-search-trigger{padding:calc(var(--hx-spacing) * 0);padding-inline:calc(var(--hx-spacing) * 3);padding-block:calc(var(--hx-spacing) * 2);font-size:var(--hx-text-sm);line-height:var(--tw-leading,var(--hx-text-sm--line-height));--tw-leading:var(--hx-leading-tight);line-height:var(--hx-leading-tight);color:var(--hx-color-gray-500)}@media(hover:hover){.hextra-search-trigger:hover{color:var(--hx-color-gray-900)}}.hextra-search-trigger:where(.dark,.dark *){background-color:var(--hx-color-gray-50)}@supports(color:color-mix(in lab,red,red)){.hextra-search-trigger:where(.dark,.dark *){background-color:color-mix(in oklab,var(--hx-color-gray-50) 10%,transparent)}}.hextra-search-trigger:where(.dark,.dark *){color:var(--hx-color-gray-400)}@media(hover:hover){.hextra-search-trigger:where(.dark,.dark *):hover{color:var(--hx-color-gray-50)}}}.hextra-search-trigger-icon{height:calc(var(--hx-spacing) * 6);width:calc(var(--hx-spacing) * 6);flex-shrink:0}@media(min-width:48rem){.hextra-search-trigger-icon{height:calc(var(--hx-spacing) * 4);width:calc(var(--hx-spacing) * 4);opacity:.6}}.hextra-search-trigger-label{text-align:start;flex-grow:1;display:none}@media(min-width:48rem){.hextra-search-trigger-label{display:inline}}.hextra-search-trigger-kbd{align-items:center;gap:calc(var(--hx-spacing) * .5);border-radius:var(--hx-radius-sm);border-style:var(--tw-border-style);border-width:1px;border-color:var(--hx-color-gray-200);background-color:var(--hx-color-white);padding-inline:calc(var(--hx-spacing) * 1.5);font-family:var(--hx-font-mono);--tw-font-weight:var(--hx-font-weight-medium);font-size:10px;font-weight:var(--hx-font-weight-medium);color:var(--hx-color-gray-500);-webkit-user-select:none;user-select:none;display:none}@media(min-width:48rem){.hextra-search-trigger-kbd{display:inline-flex}}.hextra-search-trigger-kbd:where(.dark,.dark *){border-color:var(--hx-color-gray-100)}@supports(color:color-mix(in lab,red,red)){.hextra-search-trigger-kbd:where(.dark,.dark *){border-color:color-mix(in oklab,var(--hx-color-gray-100) 20%,transparent)}}.hextra-search-trigger-kbd:where(.dark,.dark *){background-color:var(--hx-color-dark)}@supports(color:color-mix(in lab,red,red)){.hextra-search-trigger-kbd:where(.dark,.dark *){background-color:color-mix(in oklab,var(--hx-color-dark) 50%,transparent)}}.hextra-search-dialog{--hextra-search-results-max-height:min(28rem, calc(100vh - 7rem));border-radius:var(--hx-radius-xl);border-style:var(--tw-border-style);border-width:1px;border-color:var(--hx-color-gray-200);background-color:var(--hx-color-white);padding:calc(var(--hx-spacing) * 0);color:var(--hx-color-gray-900);overflow:hidden}.hextra-search-dialog:where(.dark,.dark *){border-color:var(--hx-color-neutral-800);background-color:var(--hx-color-neutral-900);color:var(--hx-color-gray-100)}.hextra-search-dialog{width:calc(100% - 1rem);max-width:640px;max-height:min(500px,100vh - 4rem);margin:0;position:fixed;top:max(1rem,50% - 250px);left:50%;transform:translate(-50%);box-shadow:0 25px 50px -12px #00000080}.hextra-search-dialog::backdrop{background-color:var(--hx-color-black)}@supports(color:color-mix(in lab,red,red)){.hextra-search-dialog::backdrop{background-color:color-mix(in oklab,var(--hx-color-black) 20%,transparent)}}.hextra-search-dialog::backdrop{--tw-backdrop-blur:blur(var(--hx-blur-xs));-webkit-backdrop-filter:var(--tw-backdrop-blur,)var(--tw-backdrop-brightness,)var(--tw-backdrop-contrast,)var(--tw-backdrop-grayscale,)var(--tw-backdrop-hue-rotate,)var(--tw-backdrop-invert,)var(--tw-backdrop-opacity,)var(--tw-backdrop-saturate,)var(--tw-backdrop-sepia,);backdrop-filter:var(--tw-backdrop-blur,)var(--tw-backdrop-brightness,)var(--tw-backdrop-contrast,)var(--tw-backdrop-grayscale,)var(--tw-backdrop-hue-rotate,)var(--tw-backdrop-invert,)var(--tw-backdrop-opacity,)var(--tw-backdrop-saturate,)var(--tw-backdrop-sepia,)}.hextra-search-dialog[open]{transform-origin:50%}@media(prefers-reduced-motion:no-preference){.hextra-search-dialog[open]:not([data-state=closing]){animation:.3s cubic-bezier(.16,1,.3,1)hextra-search-dialog-in}.hextra-search-dialog[open]:not([data-state=closing])::backdrop{will-change:opacity;animation:.3s hextra-search-backdrop-in}}.hextra-search-dialog[data-state=closing]{animation:.3s cubic-bezier(.16,1,.3,1)forwards hextra-search-dialog-out}.hextra-search-dialog[data-state=closing]::backdrop{will-change:opacity;animation:.3s forwards hextra-search-backdrop-out}@keyframes hextra-search-dialog-in{0%{opacity:0;transform:translate(-50%)scale(1.06)}to{opacity:1;transform:translate(-50%)scale(1)}}@keyframes hextra-search-dialog-out{0%{opacity:1;transform:translate(-50%)scale(1)}to{opacity:0;transform:translate(-50%)scale(1.04)}}@keyframes hextra-search-backdrop-in{0%{opacity:0}to{opacity:1}}@keyframes hextra-search-backdrop-out{0%{opacity:1}to{opacity:0}}.hextra-search{flex-direction:column;display:flex;overflow:hidden}.hextra-search-input-wrapper{align-items:center;gap:calc(var(--hx-spacing) * 3);border-bottom-style:var(--tw-border-style);border-bottom-width:1px;border-color:var(--hx-color-gray-100);padding-inline:calc(var(--hx-spacing) * 4);display:flex}.hextra-search-input-wrapper:where(.dark,.dark *){border-color:var(--hx-color-neutral-800)}.hextra-search-input-icon{height:calc(var(--hx-spacing) * 5);width:calc(var(--hx-spacing) * 5);color:var(--hx-color-gray-400);flex-shrink:0}.hextra-search-input-icon:where(.dark,.dark *){color:var(--hx-color-gray-500)}.hextra-search-input{height:calc(var(--hx-spacing) * 12);padding-block:calc(var(--hx-spacing) * 3);font-size:var(--hx-text-base);line-height:var(--tw-leading,var(--hx-text-base--line-height));color:var(--hx-color-gray-900);background-color:#0000;flex-grow:1}.hextra-search-input::placeholder{color:var(--hx-color-gray-400)}.hextra-search-input:focus{--tw-outline-style:none;outline-style:none}.hextra-search-input:where(.dark,.dark *){color:var(--hx-color-gray-100)}.hextra-search-input:where(.dark,.dark *)::placeholder{color:var(--hx-color-gray-500)}.hextra-search-input:focus,.hextra-search-input:focus-visible{box-shadow:none;--tw-ring-shadow:0 0 #0000;--tw-ring-offset-shadow:0 0 #0000;outline:none}.hextra-search-input::-webkit-search-cancel-button{display:none}.hextra-search-input-kbd{cursor:pointer;border-radius:var(--hx-radius-sm);border-style:var(--tw-border-style);border-width:1px;border-color:var(--hx-color-gray-200);background-color:var(--hx-color-white);padding-inline:calc(var(--hx-spacing) * 1.5);font-family:var(--hx-font-mono);--tw-font-weight:var(--hx-font-weight-medium);font-size:10px;font-weight:var(--hx-font-weight-medium);color:var(--hx-color-gray-500);align-items:center;display:none}.hextra-search-input-kbd:focus-visible{--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow);--tw-ring-color:var(--hx-color-primary-200);--tw-ring-offset-width:1px;--tw-ring-offset-shadow:var(--tw-ring-inset,) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-offset-color:var(--hx-color-primary-300);--tw-outline-style:none;outline-style:none}.hextra-search-input-kbd:where(.dark,.dark *):focus-visible{--tw-ring-color:var(--hx-color-primary-800);--tw-ring-offset-color:var(--hx-color-primary-700)}.hextra-search-input-kbd{transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to;transition-timing-function:var(--tw-ease,var(--hx-default-transition-timing-function));transition-duration:var(--tw-duration,var(--hx-default-transition-duration));-webkit-user-select:none;user-select:none}@media(hover:hover){.hextra-search-input-kbd:hover{border-color:var(--hx-color-gray-300);color:var(--hx-color-gray-900)}}@media(min-width:40rem){.hextra-search-input-kbd{display:inline-flex}}.hextra-search-input-kbd:where(.dark,.dark *){border-color:var(--hx-color-gray-100)}@supports(color:color-mix(in lab,red,red)){.hextra-search-input-kbd:where(.dark,.dark *){border-color:color-mix(in oklab,var(--hx-color-gray-100) 20%,transparent)}}.hextra-search-input-kbd:where(.dark,.dark *){background-color:var(--hx-color-dark)}@supports(color:color-mix(in lab,red,red)){.hextra-search-input-kbd:where(.dark,.dark *){background-color:color-mix(in oklab,var(--hx-color-dark) 50%,transparent)}}.hextra-search-input-kbd:where(.dark,.dark *){color:var(--hx-color-gray-400)}@media(hover:hover){.hextra-search-input-kbd:where(.dark,.dark *):hover{border-color:var(--hx-color-gray-100)}@supports(color:color-mix(in lab,red,red)){.hextra-search-input-kbd:where(.dark,.dark *):hover{border-color:color-mix(in oklab,var(--hx-color-gray-100) 30%,transparent)}}.hextra-search-input-kbd:where(.dark,.dark *):hover{color:var(--hx-color-gray-100)}}.hextra-search-results-viewport{max-height:0;transition:max-height .2s cubic-bezier(.16,1,.3,1);overflow:hidden}.hextra-search-results-viewport[data-expanded=true]{max-height:var(--hextra-search-results-max-height)}.hextra-search-results-inner{overscroll-behavior:contain;padding:calc(var(--hx-spacing) * 1);max-height:var(--hextra-search-results-max-height);overflow-y:auto}.hextra-search-results{margin:calc(var(--hx-spacing) * 0);padding:calc(var(--hx-spacing) * 0);list-style-type:none}.hextra-search-results>li{list-style-type:none;position:relative}.hextra-search-results>li>a{cursor:pointer;gap:calc(var(--hx-spacing) * .5);border-radius:var(--hx-radius-lg);padding-inline:calc(var(--hx-spacing) * 2.5);padding-block:calc(var(--hx-spacing) * 2);font-size:var(--hx-text-sm);line-height:var(--tw-leading,var(--hx-text-sm--line-height));color:var(--hx-color-gray-800);flex-direction:column;text-decoration-line:none;display:flex;position:relative}.hextra-search-results>li>a:where(.dark,.dark *){color:var(--hx-color-gray-200)}.hextra-search-results>li>a{z-index:1}.hextra-search-results>li>a[aria-selected=true]{background-color:var(--hx-color-primary-100)}@supports(color:color-mix(in lab,red,red)){.hextra-search-results>li>a[aria-selected=true]{background-color:color-mix(in oklab,var(--hx-color-primary-100) 80%,transparent)}}.hextra-search-results>li>a[aria-selected=true]{color:var(--hx-color-gray-900)}.hextra-search-results>li>a[aria-selected=true]:where(.dark,.dark *){background-color:var(--hx-color-primary-400)}@supports(color:color-mix(in lab,red,red)){.hextra-search-results>li>a[aria-selected=true]:where(.dark,.dark *){background-color:color-mix(in oklab,var(--hx-color-primary-400) 15%,transparent)}}.hextra-search-results>li>a[aria-selected=true]:where(.dark,.dark *){color:var(--hx-color-gray-50)}.hextra-search-crumb{align-items:center;gap:calc(var(--hx-spacing) * .5);font-size:var(--hx-text-xs);line-height:var(--tw-leading,var(--hx-text-xs--line-height));--tw-leading:calc(var(--hx-spacing) * 4);line-height:calc(var(--hx-spacing) * 4);color:var(--hx-color-gray-600);display:flex}.hextra-search-crumb:where(.dark,.dark *){color:var(--hx-color-gray-400)}.hextra-search-crumb-separator{height:calc(var(--hx-spacing) * 3.5);width:calc(var(--hx-spacing) * 3.5);color:var(--hx-color-gray-400);flex-shrink:0}.hextra-search-crumb-separator:where(.dark,.dark *){color:var(--hx-color-gray-500)}[dir=rtl] .hextra-search-crumb-separator{transform:rotate(180deg)}.hextra-search-title{font-size:var(--hx-text-sm);line-height:var(--tw-leading,var(--hx-text-sm--line-height));--tw-leading:calc(var(--hx-spacing) * 5);line-height:calc(var(--hx-spacing) * 5);--tw-font-weight:var(--hx-font-weight-medium);font-weight:var(--hx-font-weight-medium)}.hextra-search-excerpt{font-size:var(--hx-text-sm);line-height:var(--tw-leading,var(--hx-text-sm--line-height));--tw-leading:calc(var(--hx-spacing) * 5);line-height:calc(var(--hx-spacing) * 5);color:var(--hx-color-gray-700);overflow:hidden}.hextra-search-excerpt:where(.dark,.dark *){color:var(--hx-color-gray-300)}.hextra-search-excerpt{-webkit-line-clamp:1;line-clamp:1;-webkit-box-orient:vertical;display:-webkit-box}.hextra-search-results>li.hextra-search-child>a>*{padding-inline-start:1rem}.hextra-search-results>li.hextra-search-child:before{content:"";background-color:var(--hx-color-gray-200);inset-inline-start:.75rem;width:1px;position:absolute;top:0;bottom:0}.dark .hextra-search-results>li.hextra-search-child:before{background-color:var(--hx-color-neutral-700)}.hextra-search-match{--tw-font-weight:var(--hx-font-weight-semibold);font-weight:var(--hx-font-weight-semibold);color:var(--hx-color-primary-600)}.hextra-search-empty{padding-inline:calc(var(--hx-spacing) * 3);padding-block:calc(var(--hx-spacing) * 10);text-align:center;font-size:var(--hx-text-sm);line-height:var(--tw-leading,var(--hx-text-sm--line-height));color:var(--hx-color-gray-500)}.hextra-search-empty:where(.dark,.dark *){color:var(--hx-color-gray-400)}@media(max-width:640px){.hextra-search-dialog{max-height:calc(100vh - 2rem);top:1rem}}@media(max-width:48rem){.hextra-sidebar-container{top:calc(var(--hx-spacing) * 0);bottom:calc(var(--hx-spacing) * 0);z-index:15;overscroll-behavior:contain;background-color:var(--hx-color-white);width:100%;padding-top:calc(var(--hextra-navbar-height) + var(--hextra-banner-height));position:fixed}.hextra-sidebar-container:where(.dark,.dark *){background-color:var(--hx-color-dark)}.hextra-sidebar-container{will-change:transform,opacity;contain:layout style;backface-visibility:hidden;transition:transform .4s cubic-bezier(.52,.16,.04,1)}}.hextra-sidebar-container li>.hextra-sidebar-children{height:calc(var(--hx-spacing) * 0)}.hextra-sidebar-container li.open>.hextra-sidebar-children{height:auto;padding-top:calc(var(--hx-spacing) * 1)}.hextra-sidebar-container li.open>.hextra-sidebar-item>.hextra-sidebar-collapsible-button>svg>path{rotate:90deg}.hextra-banner-hidden .hextra-banner{display:none}.hextra-banner :where(a):not(:where([class~=not-prose],[class~=not-prose] *)){text-decoration-line:underline;text-decoration-thickness:from-font}.hextra-banner :where(p):not(:where([class~=not-prose],[class~=not-prose] *)){--tw-leading:calc(var(--hx-spacing) * 7);line-height:calc(var(--hx-spacing) * 7)}.hextra-banner :where(p):not(:where([class~=not-prose],[class~=not-prose] *)):first-child{margin-top:calc(var(--hx-spacing) * 0)}@supports((-webkit-backdrop-filter:blur(1px)) or (backdrop-filter:blur(1px))){.hextra-nav-container-blur{background-color:var(--hx-color-white)}@supports(color:color-mix(in lab,red,red)){.hextra-nav-container-blur{background-color:color-mix(in oklab,var(--hx-color-white) 85%,transparent)}}.hextra-nav-container-blur{--tw-backdrop-blur:blur(var(--hx-blur-md));-webkit-backdrop-filter:var(--tw-backdrop-blur,)var(--tw-backdrop-brightness,)var(--tw-backdrop-contrast,)var(--tw-backdrop-grayscale,)var(--tw-backdrop-hue-rotate,)var(--tw-backdrop-invert,)var(--tw-backdrop-opacity,)var(--tw-backdrop-saturate,)var(--tw-backdrop-sepia,);backdrop-filter:var(--tw-backdrop-blur,)var(--tw-backdrop-brightness,)var(--tw-backdrop-contrast,)var(--tw-backdrop-grayscale,)var(--tw-backdrop-hue-rotate,)var(--tw-backdrop-invert,)var(--tw-backdrop-opacity,)var(--tw-backdrop-saturate,)var(--tw-backdrop-sepia,)}.hextra-nav-container-blur:where(.dark,.dark *){background-color:var(--hx-color-dark)!important}@supports(color:color-mix(in lab,red,red)){.hextra-nav-container-blur:where(.dark,.dark *){background-color:color-mix(in oklab,var(--hx-color-dark) 80%,transparent)!important}}}@media(max-width:48rem){[data-hextra-banner=visible] .hextra-nav-container-blur{height:max(100%,var(--hextra-banner-height));background-color:var(--hx-color-white)!important}.dark[data-hextra-banner=visible] .hextra-nav-container-blur{background-color:var(--hx-color-dark)!important}}.hextra-hamburger-menu svg g{transform-origin:50%;transition-property:all;transition-timing-function:var(--tw-ease,var(--hx-default-transition-timing-function));transition-duration:var(--tw-duration,var(--hx-default-transition-duration));--tw-duration:.1s;--tw-ease:var(--hx-ease-out);transition-duration:.1s;transition-timing-function:var(--hx-ease-out)}.hextra-hamburger-menu svg path{opacity:1;transition-property:all;transition-timing-function:var(--tw-ease,var(--hx-default-transition-timing-function));transition-duration:var(--tw-duration,var(--hx-default-transition-duration));--tw-duration:.1s;--tw-ease:var(--hx-ease-out);transition-duration:.1s;transition-delay:.1s;transition-timing-function:var(--hx-ease-out)}.hextra-hamburger-menu svg.open path{transition-property:transform,translate,scale,rotate;transition-timing-function:var(--tw-ease,var(--hx-default-transition-timing-function));transition-duration:var(--tw-duration,var(--hx-default-transition-duration));--tw-duration:.1s;--tw-ease:var(--hx-ease-out);transition-duration:.1s;transition-delay:0s;transition-timing-function:var(--hx-ease-out)}.hextra-hamburger-menu svg.open g{transition-property:transform,translate,scale,rotate;transition-timing-function:var(--tw-ease,var(--hx-default-transition-timing-function));transition-duration:var(--tw-duration,var(--hx-default-transition-duration));--tw-duration:.1s;--tw-ease:var(--hx-ease-out);transition-duration:.1s;transition-delay:.1s;transition-timing-function:var(--hx-ease-out)}.hextra-hamburger-menu svg.open>path{opacity:0}.hextra-hamburger-menu svg.open>g:first-of-type{rotate:45deg}.hextra-hamburger-menu svg.open>g:first-of-type path{--tw-translate-y:calc(var(--hx-spacing) * 1);translate:var(--tw-translate-x)var(--tw-translate-y)}.hextra-hamburger-menu svg.open>g:nth-of-type(2){rotate:-45deg}.hextra-hamburger-menu svg.open>g:nth-of-type(2) path{--tw-translate-y:calc(var(--hx-spacing) * -1);translate:var(--tw-translate-x)var(--tw-translate-y)}.hextra-scrollbar,.hextra-scrollbar *{scrollbar-width:thin;scrollbar-color:oklch(55.55% 0 0/.4)transparent;scrollbar-gutter:stable}:is(.hextra-scrollbar,.hextra-scrollbar *)::-webkit-scrollbar{height:calc(var(--hx-spacing) * 3);width:calc(var(--hx-spacing) * 3)}:is(.hextra-scrollbar,.hextra-scrollbar *)::-webkit-scrollbar-track{background-color:#0000}:is(.hextra-scrollbar,.hextra-scrollbar *)::-webkit-scrollbar-thumb{border-radius:10px}:is(.hextra-scrollbar,.hextra-scrollbar *):hover::-webkit-scrollbar-thumb{background-color:var(--tw-shadow-color);--tw-shadow-color:var(--hx-color-neutral-500);background-clip:content-box;border:3px solid #0000}@supports(color:color-mix(in lab,red,red)){:is(.hextra-scrollbar,.hextra-scrollbar *):hover::-webkit-scrollbar-thumb{--tw-shadow-color:color-mix(in oklab, color-mix(in oklab, var(--hx-color-neutral-500) 20%, transparent) var(--tw-shadow-alpha), transparent)}}@media(hover:hover){:is(.hextra-scrollbar,.hextra-scrollbar *):hover::-webkit-scrollbar-thumb:hover{--tw-shadow-color:var(--hx-color-neutral-500)}@supports(color:color-mix(in lab,red,red)){:is(.hextra-scrollbar,.hextra-scrollbar *):hover::-webkit-scrollbar-thumb:hover{--tw-shadow-color:color-mix(in oklab, color-mix(in oklab, var(--hx-color-neutral-500) 40%, transparent) var(--tw-shadow-alpha), transparent)}}}@supports((-webkit-backdrop-filter:blur(1px)) or (backdrop-filter:blur(1px))){.hextra-code-copy-btn{opacity:.85;--tw-backdrop-blur:blur(var(--hx-blur-md));-webkit-backdrop-filter:var(--tw-backdrop-blur,)var(--tw-backdrop-brightness,)var(--tw-backdrop-contrast,)var(--tw-backdrop-grayscale,)var(--tw-backdrop-hue-rotate,)var(--tw-backdrop-invert,)var(--tw-backdrop-opacity,)var(--tw-backdrop-saturate,)var(--tw-backdrop-sepia,);backdrop-filter:var(--tw-backdrop-blur,)var(--tw-backdrop-brightness,)var(--tw-backdrop-contrast,)var(--tw-backdrop-grayscale,)var(--tw-backdrop-hue-rotate,)var(--tw-backdrop-invert,)var(--tw-backdrop-opacity,)var(--tw-backdrop-saturate,)var(--tw-backdrop-sepia,)}.hextra-code-copy-btn:where(.dark,.dark *){opacity:.8}}@media(min-width:1024px){.hextra-feature-grid{grid-template-columns:repeat(var(--hextra-feature-grid-cols),minmax(0,1fr))}}.hextra-jupyter-code-cell{scrollbar-gutter:auto;margin-top:calc(var(--hx-spacing) * 6)}.hextra-jupyter-code-cell .hextra-jupyter-code-cell-outputs-container{font-size:var(--hx-text-xs);line-height:var(--tw-leading,var(--hx-text-xs--line-height));overflow:hidden}.hextra-jupyter-code-cell .hextra-jupyter-code-cell-outputs-container .hextra-jupyter-code-cell-outputs{max-height:50vh;overflow:auto}.hextra-jupyter-code-cell .hextra-jupyter-code-cell-outputs-container .hextra-jupyter-code-cell-outputs pre{max-width:100%;font-size:var(--hx-text-xs);line-height:var(--tw-leading,var(--hx-text-xs--line-height));overflow:auto}.hextra-jupyter-code-cell .hextra-jupyter-code-cell-outputs-container .hextra-jupyter-code-cell-outputs-scrolled{max-height:calc(var(--hx-spacing) * 64)}.hextra-jupyter-code-cell .hextra-jupyter-code-cell-outputs-container .hextra-jupyter-code-cell-outputs-unscrolled{max-height:none}.hextra-jupyter-isolated-output{height:calc(var(--hx-spacing) * 64);border-radius:var(--hx-radius-md);border-style:var(--tw-border-style);border-width:1px;border-color:var(--hx-color-gray-200);background-color:var(--hx-color-white);width:100%}.hextra-jupyter-isolated-output:where(.dark,.dark *){border-color:var(--hx-color-neutral-800)}.hextra-jupyter-notebook :where(p>img[src^="data:image/"]):not(:where([class~=not-prose],[class~=not-prose] *)){vertical-align:middle;display:inline-block}.hextra-jupyter-notebook :where(h2):not(:where([class~=not-prose],[class~=not-prose] *)){border-bottom-style:var(--tw-border-style);border-bottom-width:1px;border-color:var(--hx-color-neutral-200)}@supports(color:color-mix(in lab,red,red)){.hextra-jupyter-notebook :where(h2):not(:where([class~=not-prose],[class~=not-prose] *)){border-color:color-mix(in oklab,var(--hx-color-neutral-200) 70%,transparent)}}.hextra-jupyter-notebook :where(h2):not(:where([class~=not-prose],[class~=not-prose] *)){padding-bottom:calc(var(--hx-spacing) * 1)}@media(prefers-contrast:more){.hextra-jupyter-notebook :where(h2):not(:where([class~=not-prose],[class~=not-prose] *)){border-color:var(--hx-color-neutral-400)}}.hextra-jupyter-notebook :where(h2):not(:where([class~=not-prose],[class~=not-prose] *)):where(.dark,.dark *){border-color:var(--hx-color-primary-100)}@supports(color:color-mix(in lab,red,red)){.hextra-jupyter-notebook :where(h2):not(:where([class~=not-prose],[class~=not-prose] *)):where(.dark,.dark *){border-color:color-mix(in oklab,var(--hx-color-primary-100) 10%,transparent)}}@media(prefers-contrast:more){.hextra-jupyter-notebook :where(h2):not(:where([class~=not-prose],[class~=not-prose] *)):where(.dark,.dark *){border-color:var(--hx-color-neutral-400)}}.hextra-jupyter-notebook :where(hr):not(:where([class~=not-prose],[class~=not-prose] *)){margin-block:calc(var(--hx-spacing) * 6)}.hextra-jupyter-notebook :where(hr):not(:where([class~=not-prose],[class~=not-prose] *)):first-child{margin-top:calc(var(--hx-spacing) * 0)}.hextra-jupyter-notebook :where(hr):not(:where([class~=not-prose],[class~=not-prose] *)):last-child{margin-bottom:calc(var(--hx-spacing) * 0)}.hextra-jupyter-stream-stderr{border-left-style:var(--tw-border-style);border-left-width:2px;border-color:var(--hx-color-amber-500);background-color:var(--hx-color-amber-50)}@supports(color:color-mix(in lab,red,red)){.hextra-jupyter-stream-stderr{background-color:color-mix(in oklab,var(--hx-color-amber-50) 50%,transparent)}}.hextra-jupyter-stream-stderr{padding-left:calc(var(--hx-spacing) * 3)}.hextra-jupyter-stream-stderr:where(.dark,.dark *){background-color:var(--hx-color-amber-950)}@supports(color:color-mix(in lab,red,red)){.hextra-jupyter-stream-stderr:where(.dark,.dark *){background-color:color-mix(in oklab,var(--hx-color-amber-950) 20%,transparent)}}.hextra-jupyter-error{border-left-style:var(--tw-border-style);border-left-width:2px;border-color:var(--hx-color-red-500);background-color:var(--hx-color-red-50)}@supports(color:color-mix(in lab,red,red)){.hextra-jupyter-error{background-color:color-mix(in oklab,var(--hx-color-red-50) 50%,transparent)}}.hextra-jupyter-error{padding-left:calc(var(--hx-spacing) * 3)}.hextra-jupyter-error:where(.dark,.dark *){background-color:var(--hx-color-red-950)}@supports(color:color-mix(in lab,red,red)){.hextra-jupyter-error:where(.dark,.dark *){background-color:color-mix(in oklab,var(--hx-color-red-950) 20%,transparent)}}.hextra-jupyter-html{max-width:100%;overflow-x:auto}.hextra-jupyter-html table{margin-block:calc(var(--hx-spacing) * 0);border-collapse:collapse;font-size:var(--hx-text-xs);line-height:var(--tw-leading,var(--hx-text-xs--line-height))}.hextra-jupyter-html table th,.hextra-jupyter-html table td{border-style:var(--tw-border-style);border-width:1px;border-color:var(--hx-color-gray-200);padding-inline:calc(var(--hx-spacing) * 3);padding-block:calc(var(--hx-spacing) * 1.5);text-align:left}:is(.hextra-jupyter-html table th,.hextra-jupyter-html table td):where(.dark,.dark *){border-color:var(--hx-color-neutral-700)}.hextra-jupyter-html table thead th{background-color:var(--hx-color-gray-50);--tw-font-weight:var(--hx-font-weight-semibold);font-weight:var(--hx-font-weight-semibold)}.hextra-jupyter-html table thead th:where(.dark,.dark *){background-color:var(--hx-color-neutral-800)}.hextra-jupyter-html table tbody tr:nth-child(2n){background-color:var(--hx-color-gray-50)}@supports(color:color-mix(in lab,red,red)){.hextra-jupyter-html table tbody tr:nth-child(2n){background-color:color-mix(in oklab,var(--hx-color-gray-50) 50%,transparent)}}.hextra-jupyter-html table tbody tr:nth-child(2n):where(.dark,.dark *){background-color:var(--hx-color-neutral-800)}@supports(color:color-mix(in lab,red,red)){.hextra-jupyter-html table tbody tr:nth-child(2n):where(.dark,.dark *){background-color:color-mix(in oklab,var(--hx-color-neutral-800) 50%,transparent)}}.hextra-jupyter-html table tbody tr:hover{background-color:var(--hx-color-primary-50)}.hextra-jupyter-html table tbody tr:hover:where(.dark,.dark *){background-color:var(--hx-color-primary-900)}@supports(color:color-mix(in lab,red,red)){.hextra-jupyter-html table tbody tr:hover:where(.dark,.dark *){background-color:color-mix(in oklab,var(--hx-color-primary-900) 20%,transparent)}}.hextra-jupyter-svg{max-width:100%;overflow-x:auto}.hextra-jupyter-svg svg{max-width:100%;height:auto}.hextra-jupyter-latex{margin-block:calc(var(--hx-spacing) * 2);overflow-x:auto}.hextra-jupyter-output-summary{margin-bottom:calc(var(--hx-spacing) * 2);cursor:pointer;font-size:var(--hx-text-xs);line-height:var(--tw-leading,var(--hx-text-xs--line-height));--tw-font-weight:var(--hx-font-weight-medium);font-weight:var(--hx-font-weight-medium);color:var(--hx-color-gray-500)}.hextra-jupyter-output-summary:where(.dark,.dark *){color:var(--hx-color-neutral-400)}.hextra-jupyter-raw-cell{margin-block:calc(var(--hx-spacing) * 4);border-radius:var(--hx-radius-md);background-color:var(--hx-color-gray-100);max-width:100%;padding-inline:calc(var(--hx-spacing) * 3);padding-block:calc(var(--hx-spacing) * 2);font-size:var(--hx-text-xs);line-height:var(--tw-leading,var(--hx-text-xs--line-height));overflow:auto}.hextra-jupyter-raw-cell:where(.dark,.dark *){background-color:var(--hx-color-neutral-800)}.hextra-jupyter-prompt-row{margin-top:calc(var(--hx-spacing) * 6);align-items:flex-start;display:flex}.hextra-jupyter-prompt-row:first-child{margin-top:calc(var(--hx-spacing) * 0)}.hextra-jupyter-prompt-row .hextra-jupyter-prompt{width:calc(var(--hx-spacing) * 20);padding-top:calc(var(--hx-spacing) * 4);padding-right:calc(var(--hx-spacing) * 2);text-align:right;font-family:var(--hx-font-mono);font-size:var(--hx-text-xs);line-height:var(--tw-leading,var(--hx-text-xs--line-height));--tw-leading:calc(var(--hx-spacing) * 5);line-height:calc(var(--hx-spacing) * 5);color:var(--hx-color-gray-400);-webkit-user-select:none;user-select:none;flex-shrink:0}.hextra-jupyter-prompt-row .hextra-jupyter-prompt:where(.dark,.dark *){color:var(--hx-color-neutral-500)}.hextra-jupyter-prompt-row .hextra-jupyter-prompt-in{--tw-font-weight:var(--hx-font-weight-bold);font-weight:var(--hx-font-weight-bold);color:var(--hx-color-blue-600)}.hextra-jupyter-prompt-row .hextra-jupyter-prompt-in:where(.dark,.dark *){color:var(--hx-color-blue-400)}.hextra-jupyter-prompt-row .hextra-jupyter-prompt-out{--tw-font-weight:var(--hx-font-weight-bold);font-weight:var(--hx-font-weight-bold);color:var(--hx-color-red-600)}.hextra-jupyter-prompt-row .hextra-jupyter-prompt-out:where(.dark,.dark *){color:var(--hx-color-red-400)}.hextra-jupyter-prompt-row .hextra-jupyter-prompt-content{min-width:calc(var(--hx-spacing) * 0);flex:1}.hextra-jupyter-prompt-row .hextra-jupyter-prompt-content>.hextra-code-block,.hextra-jupyter-prompt-row .hextra-jupyter-prompt-content>.hextra-jupyter-code-cell{margin-top:calc(var(--hx-spacing) * 0)}.hextra-badge{align-items:center;display:inline-flex}.hextra-toc a.hextra-toc-active{transition-property:all;transition-timing-function:var(--tw-ease,var(--hx-default-transition-timing-function));transition-duration:var(--tw-duration,var(--hx-default-transition-duration));--tw-duration:.2s;transition-duration:.2s;color:var(--hx-color-gray-900)!important}.hextra-toc a.hextra-toc-active:where(.dark,.dark *){color:var(--hx-color-gray-50)!important}.hextra-archive-timeline{border-left-style:var(--tw-border-style);border-left-width:2px;border-color:var(--hx-color-black)}@supports(color:color-mix(in lab,red,red)){.hextra-archive-timeline{border-color:color-mix(in oklab,var(--hx-color-black) 15%,transparent)}}.hextra-archive-timeline:where(.dark,.dark *){border-color:var(--hx-color-white)}@supports(color:color-mix(in lab,red,red)){.hextra-archive-timeline:where(.dark,.dark *){border-color:color-mix(in oklab,var(--hx-color-white) 15%,transparent)}}.hextra-gallery{--hextra-gallery-cols:3;--hextra-gallery-gap:.5rem;margin-block:calc(var(--hx-spacing) * 6)}.hextra-gallery__item{margin:calc(var(--hx-spacing) * 0);break-inside:avoid;border-radius:var(--hx-radius-md);background-color:var(--hx-color-gray-100);position:relative;overflow:hidden}.hextra-gallery__item:where(.dark,.dark *){background-color:var(--hx-color-neutral-800)}.hextra-gallery__link{cursor:zoom-in;--tw-outline-style:none;outline-style:none;width:100%;height:100%;display:block}.hextra-gallery__link--linked{cursor:pointer}.hextra-gallery__link:focus-visible{outline-style:var(--tw-outline-style);outline-offset:2px;outline-width:2px;outline-color:var(--hx-color-primary-500)}.hextra-gallery__item img{object-fit:cover;width:100%;height:100%;transition-property:transform,translate,scale,rotate;transition-timing-function:var(--tw-ease,var(--hx-default-transition-timing-function));transition-duration:var(--tw-duration,var(--hx-default-transition-duration));--tw-duration:.3s;transition-duration:.3s;display:block}.hextra-gallery__link:hover img{scale:1.03}.hextra-gallery__caption{pointer-events:none;inset-inline:calc(var(--hx-spacing) * 0);bottom:calc(var(--hx-spacing) * 0);margin:calc(var(--hx-spacing) * 0);padding-inline:calc(var(--hx-spacing) * 3);padding-block:calc(var(--hx-spacing) * 2);--tw-leading:1.3;color:var(--hx-color-white);--tw-gradient-position:to top;font-size:.8rem;line-height:1.3;position:absolute}@supports(background-image:linear-gradient(in lab,red,red)){.hextra-gallery__caption{--tw-gradient-position:to top in oklab}}.hextra-gallery__caption{background-image:linear-gradient(var(--tw-gradient-stops));--tw-gradient-from:color-mix(in oklab, var(--hx-color-black) 70%, transparent);--tw-gradient-to:transparent;--tw-gradient-stops:var(--tw-gradient-via-stops,var(--tw-gradient-position), var(--tw-gradient-from) var(--tw-gradient-from-position), var(--tw-gradient-to) var(--tw-gradient-to-position))}.hextra-gallery__caption :where(p){margin:calc(var(--hx-spacing) * 0)}.hextra-gallery--grid{grid-template-columns:repeat(var(--hextra-gallery-cols),minmax(0,1fr));gap:var(--hextra-gallery-gap);display:grid}.hextra-gallery--grid .hextra-gallery__item{aspect-ratio:1}@media(max-width:768px){.hextra-gallery--grid{grid-template-columns:repeat(2,minmax(0,1fr))}}@media(max-width:480px){.hextra-gallery--grid{grid-template-columns:1fr}}.hextra-gallery--mosaic{grid-template-columns:repeat(var(--hextra-gallery-cols),minmax(0,1fr));grid-auto-rows:10rem;grid-auto-flow:dense;gap:var(--hextra-gallery-gap);display:grid}.hextra-gallery--mosaic .hextra-gallery__item{height:100%}.hextra-gallery--mosaic .hextra-gallery__item--wide{grid-column:span 2}.hextra-gallery--mosaic .hextra-gallery__item--tall{grid-row:span 2}.hextra-gallery--mosaic .hextra-gallery__item--large{grid-area:span 2/span 2}@media(max-width:768px){.hextra-gallery--mosaic{grid-template-columns:repeat(2,minmax(0,1fr))}.hextra-gallery--mosaic .hextra-gallery__item--wide,.hextra-gallery--mosaic .hextra-gallery__item--large{grid-column:span 2}}@media(max-width:480px){.hextra-gallery--mosaic{grid-template-columns:1fr}.hextra-gallery--mosaic .hextra-gallery__item--wide,.hextra-gallery--mosaic .hextra-gallery__item--large{grid-column:span 1}.hextra-gallery--mosaic .hextra-gallery__item--tall,.hextra-gallery--mosaic .hextra-gallery__item--large{grid-row:span 1}}.hextra-gallery--masonry{column-count:var(--hextra-gallery-cols);column-gap:var(--hextra-gallery-gap)}.hextra-gallery--masonry .hextra-gallery__item{margin-bottom:var(--hextra-gallery-gap);display:block}.hextra-gallery--masonry .hextra-gallery__item img{object-fit:initial;height:auto}@media(max-width:768px){.hextra-gallery--masonry{column-count:2}}@media(max-width:480px){.hextra-gallery--masonry{column-count:1}}.hextra-gallery--carousel{position:relative}.hextra-gallery__track{gap:var(--hextra-gallery-gap);scroll-snap-type:x var(--tw-scroll-snap-strictness);--tw-scroll-snap-strictness:mandatory;scroll-behavior:smooth;padding-bottom:calc(var(--hx-spacing) * 1);-webkit-overflow-scrolling:touch;display:flex;overflow-x:auto}.hextra-gallery__track:focus-visible{border-radius:var(--hx-radius-md);outline-style:var(--tw-outline-style);outline-offset:2px;outline-width:2px;outline-color:var(--hx-color-primary-500)}.hextra-gallery--carousel .hextra-gallery__item{flex:0 0 calc((100% - var(--hextra-gallery-gap) * (var(--hextra-gallery-cols) - 1))/var(--hextra-gallery-cols));scroll-snap-align:start;aspect-ratio:4/3}@media(max-width:768px){.hextra-gallery--carousel .hextra-gallery__item{flex:0 0 calc((100% - var(--hextra-gallery-gap))/2)}}@media(max-width:480px){.hextra-gallery--carousel .hextra-gallery__item{flex:0 0 100%}}.hextra-gallery__nav{--tw-translate-y:calc(calc(1 / 2 * 100%) * -1);translate:var(--tw-translate-x)var(--tw-translate-y);z-index:10;height:calc(var(--hx-spacing) * 9);width:calc(var(--hx-spacing) * 9);cursor:pointer;--tw-shadow:0 1px 3px 0 var(--tw-shadow-color,#0000001a), 0 1px 2px -1px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow);border-style:var(--tw-border-style);border-width:1px;border-color:var(--hx-color-black);border-radius:340282e33px;justify-content:center;align-items:center;display:inline-flex;position:absolute;top:50%}@supports(color:color-mix(in lab,red,red)){.hextra-gallery__nav{border-color:color-mix(in oklab,var(--hx-color-black) 10%,transparent)}}.hextra-gallery__nav{background-color:var(--hx-color-white)}@supports(color:color-mix(in lab,red,red)){.hextra-gallery__nav{background-color:color-mix(in oklab,var(--hx-color-white) 90%,transparent)}}.hextra-gallery__nav{color:var(--hx-color-gray-800);transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to;transition-timing-function:var(--tw-ease,var(--hx-default-transition-timing-function));transition-duration:var(--tw-duration,var(--hx-default-transition-duration));--tw-duration:.2s;transition-duration:.2s}@media(hover:hover){.hextra-gallery__nav:hover{background-color:var(--hx-color-white)}}.hextra-gallery__nav:where(.dark,.dark *){border-color:var(--hx-color-white)}@supports(color:color-mix(in lab,red,red)){.hextra-gallery__nav:where(.dark,.dark *){border-color:color-mix(in oklab,var(--hx-color-white) 10%,transparent)}}.hextra-gallery__nav:where(.dark,.dark *){background-color:var(--hx-color-neutral-800)}@supports(color:color-mix(in lab,red,red)){.hextra-gallery__nav:where(.dark,.dark *){background-color:color-mix(in oklab,var(--hx-color-neutral-800) 90%,transparent)}}.hextra-gallery__nav:where(.dark,.dark *){color:var(--hx-color-gray-200)}@media(hover:hover){.hextra-gallery__nav:where(.dark,.dark *):hover{background-color:var(--hx-color-neutral-800)}}.hextra-gallery__nav:active{--tw-scale-x:95%;--tw-scale-y:95%;--tw-scale-z:95%;scale:var(--tw-scale-x)var(--tw-scale-y)}.hextra-gallery__nav:focus-visible{outline-style:var(--tw-outline-style);outline-offset:2px;outline-width:2px;outline-color:var(--hx-color-primary-500)}.hextra-gallery__nav--prev{inset-inline-start:-.5rem}.hextra-gallery__nav--next{inset-inline-end:-.5rem}[dir=rtl] .hextra-gallery__nav svg{transform:scaleX(-1)}.pswp__caption{pointer-events:none;inset-inline:calc(var(--hx-spacing) * 0);bottom:calc(var(--hx-spacing) * 0);padding-inline:calc(var(--hx-spacing) * 5);padding-block:calc(var(--hx-spacing) * 4);text-align:center;color:var(--hx-color-white);--tw-gradient-position:to top;font-size:.95rem;position:absolute}@supports(background-image:linear-gradient(in lab,red,red)){.pswp__caption{--tw-gradient-position:to top in oklab}}.pswp__caption{background-image:linear-gradient(var(--tw-gradient-stops));--tw-gradient-from:color-mix(in oklab, var(--hx-color-black) 70%, transparent);--tw-gradient-to:transparent;--tw-gradient-stops:var(--tw-gradient-via-stops,var(--tw-gradient-position), var(--tw-gradient-from) var(--tw-gradient-from-position), var(--tw-gradient-to) var(--tw-gradient-to-position))}.hextra-openapi{margin-block:calc(var(--hx-spacing) * 6)}.hextra-openapi .swagger-ui .wrapper{padding-inline:calc(var(--hx-spacing) * 0)}:root.dark-mode,html.dark-mode .hextra-openapi .swagger-ui{background:0 0}.hextra-openapi .swagger-ui select:focus-visible,.hextra-openapi .swagger-ui .opblock-summary-control:focus-visible,.hextra-openapi .swagger-ui .model-box-control:focus-visible,.hextra-openapi .swagger-ui .models-control:focus-visible{outline-offset:2px;outline:2px solid var(--hx-color-primary-500)!important}.hextra-openapi .swagger-ui .opblock.opblock-deprecated{opacity:1}.hextra-openapi .swagger-ui .opblock.opblock-deprecated .opblock-summary-method{background:#737373}html.dark-mode .hextra-openapi .swagger-ui .opblock.opblock-deprecated .opblock-summary-method{background:#d4d4d4}html.dark-mode .hextra-openapi .swagger-ui .opblock.opblock-put .opblock-section-header{background:#3b2a1d}@property --tw-translate-x{syntax:"*";inherits:false;initial-value:0}@property --tw-translate-y{syntax:"*";inherits:false;initial-value:0}@property --tw-translate-z{syntax:"*";inherits:false;initial-value:0}@property --tw-border-style{syntax:"*";inherits:false;initial-value:solid}@property --tw-gradient-position{syntax:"*";inherits:false}@property --tw-gradient-from{syntax:"";inherits:false;initial-value:#0000}@property --tw-gradient-via{syntax:"";inherits:false;initial-value:#0000}@property --tw-gradient-to{syntax:"";inherits:false;initial-value:#0000}@property --tw-gradient-stops{syntax:"*";inherits:false}@property --tw-gradient-via-stops{syntax:"*";inherits:false}@property --tw-gradient-from-position{syntax:"";inherits:false;initial-value:0%}@property --tw-gradient-via-position{syntax:"";inherits:false;initial-value:50%}@property --tw-gradient-to-position{syntax:"";inherits:false;initial-value:100%}@property --tw-leading{syntax:"*";inherits:false}@property --tw-font-weight{syntax:"*";inherits:false}@property --tw-tracking{syntax:"*";inherits:false}@property --tw-ordinal{syntax:"*";inherits:false}@property --tw-slashed-zero{syntax:"*";inherits:false}@property --tw-numeric-figure{syntax:"*";inherits:false}@property --tw-numeric-spacing{syntax:"*";inherits:false}@property --tw-numeric-fraction{syntax:"*";inherits:false}@property --tw-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-shadow-color{syntax:"*";inherits:false}@property --tw-shadow-alpha{syntax:"";inherits:false;initial-value:100%}@property --tw-inset-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-inset-shadow-color{syntax:"*";inherits:false}@property --tw-inset-shadow-alpha{syntax:"";inherits:false;initial-value:100%}@property --tw-ring-color{syntax:"*";inherits:false}@property --tw-ring-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-inset-ring-color{syntax:"*";inherits:false}@property --tw-inset-ring-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-ring-inset{syntax:"*";inherits:false}@property --tw-ring-offset-width{syntax:"";inherits:false;initial-value:0}@property --tw-ring-offset-color{syntax:"*";inherits:false;initial-value:#fff}@property --tw-ring-offset-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-duration{syntax:"*";inherits:false}@property --tw-ease{syntax:"*";inherits:false}@property --tw-content{syntax:"*";inherits:false;initial-value:""}@property --tw-blur{syntax:"*";inherits:false}@property --tw-brightness{syntax:"*";inherits:false}@property --tw-contrast{syntax:"*";inherits:false}@property --tw-grayscale{syntax:"*";inherits:false}@property --tw-hue-rotate{syntax:"*";inherits:false}@property --tw-invert{syntax:"*";inherits:false}@property --tw-opacity{syntax:"*";inherits:false}@property --tw-saturate{syntax:"*";inherits:false}@property --tw-sepia{syntax:"*";inherits:false}@property --tw-drop-shadow{syntax:"*";inherits:false}@property --tw-drop-shadow-color{syntax:"*";inherits:false}@property --tw-drop-shadow-alpha{syntax:"";inherits:false;initial-value:100%}@property --tw-drop-shadow-size{syntax:"*";inherits:false}@property --tw-backdrop-blur{syntax:"*";inherits:false}@property --tw-backdrop-brightness{syntax:"*";inherits:false}@property --tw-backdrop-contrast{syntax:"*";inherits:false}@property --tw-backdrop-grayscale{syntax:"*";inherits:false}@property --tw-backdrop-hue-rotate{syntax:"*";inherits:false}@property --tw-backdrop-invert{syntax:"*";inherits:false}@property --tw-backdrop-opacity{syntax:"*";inherits:false}@property --tw-backdrop-saturate{syntax:"*";inherits:false}@property --tw-backdrop-sepia{syntax:"*";inherits:false}@property --tw-outline-style{syntax:"*";inherits:false;initial-value:solid}@property --tw-scroll-snap-strictness{syntax:"*";inherits:false;initial-value:proximity}@property --tw-scale-x{syntax:"*";inherits:false;initial-value:1}@property --tw-scale-y{syntax:"*";inherits:false;initial-value:1}@property --tw-scale-z{syntax:"*";inherits:false;initial-value:1}:root{--meshcore-navy:#172B3A;--meshcore-light:#F4F6F8;--meshcore-mint:#65D6AD;--primary-hue:157;--primary-saturation:58%;--primary-lightness:48%}html.dark{--primary-hue:157;--primary-saturation:58%;--primary-lightness:58%}.content a{text-decoration-thickness:1px;text-underline-offset:3px}.content code:not(pre code){border-radius:4px} \ No newline at end of file diff --git a/css/custom.css b/css/custom.css new file mode 100644 index 0000000..370693c --- /dev/null +++ b/css/custom.css @@ -0,0 +1,29 @@ +/* Palette MeshCore Lab */ +:root { + --meshcore-navy: #172B3A; + --meshcore-light: #F4F6F8; + --meshcore-mint: #65D6AD; + + /* Vert menthe comme couleur d'accent */ + --primary-hue: 157; + --primary-saturation: 58%; + --primary-lightness: 48%; +} + +/* Couleur d'accent en mode sombre */ +html.dark { + --primary-hue: 157; + --primary-saturation: 58%; + --primary-lightness: 58%; +} + +/* Liens et éléments interactifs */ +.content a { + text-decoration-thickness: 1px; + text-underline-offset: 3px; +} + +/* Code technique */ +.content code:not(pre code) { + border-radius: 4px; +} diff --git a/css/variables.css b/css/variables.css new file mode 100644 index 0000000..f4f9ef7 --- /dev/null +++ b/css/variables.css @@ -0,0 +1,26 @@ +/* Hugo template to derive CSS variables from site and page parameters */ + +/* Do not remove the following comment. It is used by Hugo to render CSS variables.*/ + +:root { + --hextra-max-page-width: 80rem; + --hextra-max-content-width: 72rem; + --hextra-max-navbar-width: 80rem; + --hextra-max-footer-width: 80rem; +} + +.hextra-max-page-width { + max-width: var(--hextra-max-page-width); +} + +.hextra-max-content-width { + max-width: var(--hextra-max-content-width); +} + +.hextra-max-navbar-width { + max-width: var(--hextra-max-navbar-width); +} + +.hextra-max-footer-width { + max-width: var(--hextra-max-footer-width); +} diff --git a/documentation/companion/index.html b/documentation/companion/index.html new file mode 100644 index 0000000..6ddb394 --- /dev/null +++ b/documentation/companion/index.html @@ -0,0 +1,704 @@ + + + + + + + + + + +Companion – MeshEro + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Skip to content + +
+ + + + + +
+
+ +
+
Companion
+
+ +
+ +
+

Companion

+ +
+ + +

Le Companion est le rôle que tout le monde utilise en premier : c’est votre appareil personnel, celui que vous emportez avec vous. Il vous sert à émettre et à recevoir des messages, et il se pilote depuis un téléphone, un navigateur web ou encore en mode «standalone».

+

Ce qu’il fait (et ne fait pas) +

    +
  • Il envoie et reçoit vos messages, privés ou sur des canaux.
  • +
  • Il ne relaie pas le trafic des autres : seuls les répéteurs portent les messages sur le réseau.
  • +
  • Il ne s’annonce que lorsque vous le décidez (voir « Advert » plus bas).
  • +
+

Un companion tout seul ne fait donc pas un réseau : il a besoin d’autres companions à portée directe, ou d’au moins un répéteur à portée.

+

Les deux variantes de firmware/connexion +

+ + + + + + + + + + + + + + + + + + + +
VarianteConnexionUsage
BLE CompanionBluetoothLa plus courante : apparaiage avec l’application sur smartphone
USB CompanionCâble USBConnexion filaire à un ordinateur ou serveur
+

Ce qu’il vous faut +

    +
  1. Un appareil LoRa compatible avec le firmware Companion. Certains sont vendus préinstallés, comme le Wio Tracker L1 Pro que j’utilise.
  2. +
  3. Une application : + +
  4. +
+

Première mise en route +

+

Installer le firmware (si besoin) +

Avec le flasher officiel, choisissez votre modèle d’appareil et la variante Companion. Si votre appareil est livré avec MeshCore, il est fort possible de devoir mettre à jour le firmware qui est préinstallé.

+

Appairer l’appareil +

Activez le Bluetooth sur votre smartphone, ouvrez l’application meshcore et sélectionnez l’appareil.

+

Choisir un nom et régler la radio +

Donnez un nom à votre companion, puis appliquez le preset EU/UK (Narrow) (869,618 MHz, BW 62,5 kHz, SF8, CR8).

+

Envoyer un advert +

Utilisez l’icône de signal de l’application pour vous annoncer. Les nœuds à portée apparaissent dans votre liste de contacts, et vous apparaissez dans la leur.

+ +

Advert : comment on se découvre +

Un advert est un paquet par lequel un nœud annonce sa présence. Pour un companion, il part uniquement à votre demande. On distingue :

+
    +
  • l’advert local (zero-hop), entendu seulement par les nœuds directement à portée ;
  • +
  • l’advert diffusé (flood), relayé par les répéteurs sur tout le réseau.
  • +
+

Vous voyez les répéteurs et autres nœuds parce qu’eux s’annoncent régulièrement.

+
+

Tip +

+ +

Pour être vu des autres, pensez à envoyer un advert !

+
+

Contacts et canaux +

    +
  • Messages privés : ils vont d’un contact à un autre et sont chiffrés de votre appareil a celui de votre contact. Ils sont limités à 150 caractères.
  • +
  • Canaux : le canal Public et les canaux #hashtag (par exemple #test) sont ouverts à toute personne qui connaît leur nom. Évitez d’y écrire des informations sensibles.
  • +
  • Canaux privés : ils reposent sur une clé partagée entre les membres du groupe.
  • +
+

GPS et carte +

Si votre appareil a un GPS, vous pouvez partager votre position avec vos contacts.

+
+

Caution +

+ +

une position partagée est visible de ceux qui la reçoivent.

+
+

Administrer un répéteur ou un room server +

Depuis le companion, vous pouvez vous connecter à un répéteur ou à un room server à distance, par radio, avec son mot de passe, et en modifier les réglages.

+

Bon à savoir +

    +
  • Même appareil, un seul rôle à la fois : changer de rôle implique de reflasher.
  • +
  • Si ton companion est faible en portée, passe en revue l’antenne et ta position avant tout autre réglage.
  • +
  • Un companion reçoit surtout via les répéteurs : regardez la carte des répéteurs pour voir ce qui couvre votre zone.
  • +
  • Il est possible de mettre à jour votre companion via bluetooth directement
  • +
+ + +
+
+ +
+
+
+ +
+ + + + + + + + + diff --git a/documentation/index.html b/documentation/index.html new file mode 100644 index 0000000..f98ba9f --- /dev/null +++ b/documentation/index.html @@ -0,0 +1,560 @@ + + + + + + + + + + +Documentation – MeshEro + + + + + + + + + + + + + + + + + + + + + + + + + + + + Skip to content + +
+ + + + + +
+
+ +
Documentation
+
+ + +
+ +
+
+
+ +
+ + + + + + + + + diff --git a/documentation/index.xml b/documentation/index.xml new file mode 100644 index 0000000..e47f34d --- /dev/null +++ b/documentation/index.xml @@ -0,0 +1,19 @@ + + + MeshEro – Documentation + http://localhost:1313/documentation/ + Recent content in Documentation on MeshEro + Hugo -- gohugo.io + fr-fr + Sat, 24 Oct 2026 14:20:58 +0200 + + + + + + + + + + + diff --git a/documentation/meshcore/index.html b/documentation/meshcore/index.html new file mode 100644 index 0000000..b180774 --- /dev/null +++ b/documentation/meshcore/index.html @@ -0,0 +1,683 @@ + + + + + + + + + + +Introduction à MeshCore – MeshEro + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Skip to content + +
+ + + + + +
+
+ +
+
Introduction à MeshCore
+
+ +
+ +
+

Introduction à MeshCore

+ +
+ + +

C’est quoi MeshCore ? +

MeshCore permet d’échanger des messages texte sans internet ni réseau mobile, en s’appuyant sur un réseau maillé (mesh). +C’est un réseau communautaire ou chacun participe à sa construction. +À l’inverse du réseau mobile avec lequelle vous envoyez des SMS, les antennes sont ajouter et maintenu par les opérateurs télécom qui vous le facture. +Ici vous achetez votre matos, il est a vous et vous ne payez pas d’abonnement.

+

Cas d’utilisation +

    +
  • Événements de masse : Si vous etes deja aller à un «gros» festival par exemple, vous connaissez le probleme du «trop de monde, pas de réseau».
  • +
  • Activités extérieur : randonnée/trail en zone blanche.
  • +
  • Catastrophes naturelles : séisme, inondation, incendie. Les infrastructures télécom ne fonctionnent plus.
  • +
  • Expérimentation technique : juste s’amuser avec la technologie.
  • +
+

Pour l’utiliser, il faut :

+ +

Les trois rôles +

Contrairement à d’autres réseaux mesh où tous les nœuds se valent, MeshCore distingue des rôles précis, chacun avec son propre comportement. Cliquez sur une tuile pour voir la page détaillée.

+ + +

La conséquence pratique est importante : la couverture du réseau dépend surtout du placement des répéteurs, pas du nombre de companions.

+

Comment circule un message ? +

MeshCore utilise un routage hybride :

+
    +
  1. Le premier message vers un destinataire est diffusé (flood) via les répéteurs pour découvrir un chemin.
  2. +
  3. Le chemin emprunté est mémorisé.
  4. +
  5. Les messages suivants sont envoyés le long de ce chemin connu, sans être rediffusés partout.
  6. +
  7. Si le chemin ne fonctionne plus, le réseau retombe sur la diffusion.
  8. +
+

Résultat : moins d’occupation du canal radio, ce qui compte beaucoup sur une bande partagée et limitée en temps d’émission.

+
+

Note +

+ +

Le chemin peut etre définit manuellement

+
+

Réglages radio en France +

La communauté française utilise le preset EU/UK (Narrow) :

+ + + + + + + + + + + + + + + + + + + + + + + + + +
ParamètreValeur
Fréquence869,618 MHz
Bande passante62,5 kHz
Spreading FactorSF8
Coding RateCR8
+

La bande 868 MHz est partagée et soumise à des règles (puissance, temps d’émission). Le réseau est commun : un mauvais réglage gêne les autres utilisateurs.

+

Outils utiles +

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
BesoinAdresse
Installer un firmwareflasher.meshcore.io
Configurer un répéteur par USBconfig.meshcore.io
Documentation techniquedocs.meshcore.io
Carte des nœudsmap.meshcore.io
Informations Francemeshcore.fr
+

Pour aller plus loin +

+ + +
+
+ +
+
+
+ +
+ + + + + + + + + diff --git a/documentation/ota_update/index.html b/documentation/ota_update/index.html new file mode 100644 index 0000000..f746ea6 --- /dev/null +++ b/documentation/ota_update/index.html @@ -0,0 +1,712 @@ + + + + + + + + + + +OTA Update – MeshEro + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Skip to content + +
+ + + + + +
+
+ +
+
OTA Update
+
+ +
+ +
+

OTA Update

+ +
+ + +

Comment mettre à jour mon équipement à distance ?

Une fois qu’on a flasher le firmware de notre companion / repeteur ou room serveur vous allez vous posé la question : +Mais comment on met à jour à distance ?

+

Cela va se passer en 2 étapes:

+
    +
  1. Installer un bootloader alternatif pour faciliter l’installation des futurs mise à jour.
  2. +
  3. Installer la mise à jour lors de sa sortie via bluetooth.
  4. +
+
+

Note +

+ +

Forcément si vous venez de flasher votre equipement avec la derniere version de meshcore. vous n’avez pas de mise à jour à appliquer. +Cela vous aidera lorsque les prochaines version sortiront

+
+

Prérequis

    +
  • Avoir un appareil meshcore
  • +
  • Un cable USB pour connecter votre équipement à votre ordinateur
  • +
+

C’est partie !

    +
  1. Mettre votre équipement en mode UF2 DFU
  2. +
+
+

Pour la plupart des équipements il suffit de +

+ +
    +
  • +
      +
    1. Brancher votre appareil à votre ordinateur
    2. +
    +
  • +
  • +
      +
    1. Rapidement, appuyez sur le bouton reset 2 fois en 0,5sec
    2. +
    +
  • +
  • +
      +
    1. Un montage USB va apparaitre sur votre PC
    2. +
    +
  • +
+
+
+

Tip +

+ +

Certain équipement rentre dans ce mode d’une façon différentes. +Par exemple le T1000E, il faut débrancher et rebrancher le cable USB rapidement +landscape

+
+
+

Important +

+ +

Si vous avez un pc sur windows, n’oubliez pas d’installer les pilotes

+
+
    +
  1. Vérifiez la version actuellement installé (Optionnel)
  2. +
+
    +
  • Entrez en UF2 DFU mode (voir precedemment)
  • +
  • Ouvrez le fichier INFO_UF2.TXT avec votre editeur de texte
  • +
+
+

Note +

+ +

Celui-ci contient des informations par rapport à votre firmware actuel.

+
+
    +
  1. Télécharger le OTAFix bootloader +
      +
    • Aller sur le flasher meshcore
    • +
    • Selectionner votre appareil
    • +
    • Selectionner votre role (companion ou repeteur)
    • +
    • Un lien de téléchargement du bootloader va apparaitre en violet +Vous pouvez le télécharger directement, le fichier aura pour nom “update-xxxx.uf2”
    • +
    +
  2. +
+
+

Tip +

+ +

Alternativement vous pouvez récupérer la releaser sur le github

+
+
    +
  1. +

    Installation du Bootloader +Faites un glisser - déposer du fichier “update-xxxx.uf2” dans le partage UF2 DFU de votre équipement. Celui-ci va s’installer directement et reboot

    +
  2. +
  3. +

    Attendez le reboot et c’est bon

    +
  4. +
+
+

Tip +

+ +

Vous pouvez vérifiez en retournant en UF2 DFU. +Si vous voyez OTAFIX, la mise à jour s’est bien faite. +landscape

+
+

source

+

Prochaine étape

Maintenant que le fix est installé, il est possible de mettre à jour vos equipements par bluetooth.

+
    +
  1. +

    Télécharger le nouveau firmware +Depuis le webflasher, selectionner votre équipement. +Choisissez le role répéteur ou room serveur. Enfin télécharger la dernière version disponible au format .zip.

    +
  2. +
  3. +

    Connectez vous à votre équipement et aller dans le CLI. +Tapez la commande

    +
  4. +
+
+ +
start ota
+ +
+
+

À partir de ce moment, le bluetooth va s’activer sur l’equipement

+
    +
  1. +

    Lancer l’application nRF DFU android / nRF DFU iOS

    +
  2. +
  3. +

    Dans l’application, allez dans «settings». +Appliquez les parametre suivant:

    +
  4. +
+
    +
  • Packet receipts notification - ON
  • +
  • Number of packets - 8
  • +
  • Request high MTU (Android only) - OFF
  • +
  • Disable resume - ON
  • +
  • Prepare object delay - 0 ms
  • +
  • Force scanning - ON
  • +
+
    +
  1. Lancer la mise à jour
  2. +
+
    +
  • Selectionner le .zip télécharger à l’étape 1
  • +
  • Selectionnez votre appareil (visible en bluetooth dans la liste)
  • +
  • Appuyez sur «Start» pour demarrer (comptez une dizaine de minutes)
  • +
+

À la fin votre équipement redémarre. +C’tout ! +Vous pouvez vérifier que vous etes bien sur la derniere version depuis le CLI avec la commande :

+
+ +
ver
+ +
+
+

source

+ + +
+
+ +
+
+
+ +
+ + + + + + + + + diff --git a/documentation/repeater/index.html b/documentation/repeater/index.html new file mode 100644 index 0000000..7d7edc5 --- /dev/null +++ b/documentation/repeater/index.html @@ -0,0 +1,760 @@ + + + + + + + + + + +Repeater – MeshEro + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Skip to content + +
+ + + + + +
+
+ +
+
Repeater
+
+ +
+ +
+

Repeater

+ +
+ + +

Le répéteur (repeater) est l’infrastructure du réseau. C’est un nœud fixe, généralement placé en hauteur, dont le seul travail est de retransmettre les messages pour étendre la portée.

+
+
+ +
+
Dans MeshCore, ce sont les répéteurs qui portent le trafic, pas les companions. La qualité d’un réseau dépend donc surtout de où ils sont placés.
+
+
+ +

Comment il se comporte +

    +
  • Il ne retransmet pas tout ce qu’il entend : il transmet ce qui doit l’être, notamment les messages sur un chemin connu qui passe par lui.
  • +
  • Il s’annonce automatiquement à intervalles réguliers, ce qui permet aux companions de le découvrir.
  • +
  • Il se gère à distance, par radio, depuis un companion, ou par USB.
  • +
+

Bien le placer +

Le placement compte plus que la puissance ou le matériel.

+
    +
  • Hauteur et dégagement : toit, mât, point haut avec vue dégagée dans la direction à couvrir.
  • +
  • Antenne : une bonne antenne, bien orientée et bien raccordée, apporte plus qu’un réglage de puissance.
  • +
  • Obstacles : bâtiments, relief et végétation dense sont des freins au signal.
  • +
  • Alimentation : prise secteur, ou panneau solaire et batterie pour les sites isolés.
  • +
+

Mise en service +

+

Flasher le firmware Repeater +

Avec le flasher officiel, choisissez votre modèle et le firmware Repeater. +N’oubliez pas de formaté le device la 1ere fois.

+

Configurer par USB +

Utilisez config.meshcore.io (ou la console série du flasher) pour régler la radio sur le preset EU/UK (Narrow) et donner un nom a votre répéteur.

+

Changer les mots de passe +

    +
  • Configurez un mot de passe robuste d’administration.
  • +
  • Laissez le mot de passe invité vide. (Cela permet aux utilisateurs de récuperer la télémétrie de l’appareil).
  • +
+

Synchroniser l’horloge +

Règlez l’heure du répéteur depuis l’application ou la console.

+

Envoyer un advert et tester +

Envoyez un advert depuis le répéteur, puis vérifie qu’il apparaît dans la liste d’un de vos companion.

+ +
+
+ +
+
Avant de monter le répéteur sur un mât, testez l’administration à distance depuis un companion. Une fois installé en hauteur, il sera plus compliqué d’y revenir par câble USB.
+
+
+ +
+

Tip +

+ +

Pensez à suivre cette procédure, afin d’activer la mise à jour à distance.

+
+

Réglages courants +

Les commandes se tapent dans la console du répéteur (série) ou depuis l’administration à distance. Quelques-unes parmi les plus utiles :

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
CommandeRôle
advertEnvoie un advert diffusé (flood)
advert.zerohopEnvoie un advert local
set advert.interval <minutes>Intervalle des adverts locaux (60 à 240 min)
set flood.advert.interval <heures>Intervalle des adverts diffusés (3 à 168 h)
set dutycycle 10Configure un duty cycle de 10%
password <nouveau>Change le mot de passe admin
set guest.password <mot de passe>Définit le mot de passe invité
rebootRedémarre le nœud
+

La liste complète est dans la documentation officielle des commandes.

+

Exemple de réglages communautaires +

La communauté française recommande les réglages suivant :

+
+ +
set advert.interval 240
+set flood.advert.interval 24
+set agc.reset.interval 4
+set multi.acks 1
+set dutycycle 10
+set path.hash.mode 1
+set loop.detect minimal
+set flood.max.advert 8
+set flood.max.unscoped 5
+region def eu europe fr
+region default fr
+region home fr
+region save
+set repeat on
+set guest.password ''
+clock sync
+reboot
+ +
+
+

Ces valeurs sont un exemple

+
+

Important +

+ +

Les adverts diffusés consomment du temps d’antenne pour tout le monde ; plus l’intervalle est court, plus le réseau est chargé.

+
+

Identifiant et chemins +

Dans l’historique du trajet d’un message, chaque répéteur est repéré par les premiers caractères de sa clé publique. Deux répéteurs avec le même préfixe créent de la confusion.

+

Régions +

Les répéteurs peuvent être rattachés à des régions (par exemple France, puis région, puis département) pour limiter la propagation des messages à une zone utile. Les noms et la structure sont définis par chaque communauté locale.

+

Règles du jeu +

Le réseau est partagé et la bande 868 MHz est réglementée (puissance, temps d’émission). Respecte le preset communautaire et le duty cycle, et ne multiplie pas les répéteurs au même endroit sans concertation.

+

Et le room server ? +

Un room server n’est pas fait pour faire repeteur ! C’est un appareil qui sert à poster des messages dans un salon public.

+ + +
+
+ +
+
+
+ +
+ + + + + + + + + diff --git a/documentation/room-server/index.html b/documentation/room-server/index.html new file mode 100644 index 0000000..17b6adf --- /dev/null +++ b/documentation/room-server/index.html @@ -0,0 +1,681 @@ + + + + + + + + + + +Room Server – MeshEro + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Skip to content + +
+ + + + + +
+
+ +
+
Room Server
+
+ +
+ +
+

Room Server

+ +
+ + +

Le Room Server est le rôle le plus particulier de MeshCore. C’est un petit serveur de messages de type forum : les gens s’y connectent depuis leur companion, déposent des messages dans un espace partagé et lisent ceux des autres, même s’ils n’étaient pas connectés au moment de leur publication.

+

À quoi ça sert +

Un canal classique ne garde rien : si tu n’es pas à l’écoute, tu rates le message. Un room server conserve les messages, ce qui le rend utile pour :

+
    +
  • un tableau d’affichage local (infos pratiques, météo, annonces) ;
  • +
  • un groupe ou une association qui veut un fil de discussion persistant ;
  • +
  • un événement (randonnée, rassemblement) où tout le monde n’est pas toujours à portée.
  • +
+

Comment ça marche +

    +
  • Le room server est un nœud fixe, installé comme un répéteur, que l’on contacte par radio.
  • +
  • Le client s’y connecte avec un mot de passe, puis peut lire et poster.
  • +
  • À la connexion, le client reçoit les 32 derniers messages qu’il n’avait pas encore vus.
  • +
  • Les messages d’un room server sont limités à 150 caractères.
  • +
+

Accès et mots de passe +

+ + + + + + + + + + + + + + + + + + + +
Mot de passeDroitsRestriction de connexion
AdminAdministrer le room server (réglages, accès)Y appliquer un mot de passe fort
InvitéSe connecter à la room et y posterNE PAS appliquer de mot de passe
+
+

Note +

+ +

Le room server peut aussi être réglé en lecture seule, ce qui autorise une connexion sans mot de passe sans pouvoir poster.

+
+

Mise en service +

+

Flasher le firmware Room Server +

Pour flasher votre équipement, choisissez votre modèle d’appareil et le firmware Room Server. +Deux possibilités :

+
    +
  • Le flasher officiel : Rien de spécial
  • +
  • Le flasher communautaire gessman : Flasher interressant si vous souhaitez envoyer des données sur internet. Cela permet de monitorer le réseau afin de voir se qui passe et ou par exemple. L’avantage de ce flasher, c’est que des preset sont pré-installer. +Un preset est une pré-configuration qui permet à notre room serveur d’etre aussi un Observer et d’envoyé des données sur internet. Necessite un equipement connecté à internet (par exemple un Heltec v4 connecté au wifi) +Il vous suffit de suivre la documentation officiel pour les activé en cli. +Vous avez plusierus emplacement de preset
  • +
+

Pour configurer meshmapper sur le slot 3 :

+
+ +
set mqtt3.preset meshmapper
+ +
+
+

Configurer la radio et les mots de passe +

Comme pour un répéteur : preset EU/UK (Narrow), nom du nœud, mot de passe admin, mot de passe invité vide.

+

Envoyer un advert +

Envoyez un advert pour que les companions voient la room dans leur liste de contacts.

+

Se connecter depuis un companion +

Ajoutez le room server comme contact, ouvrez-le et saisissez le mot de passe. Les messages en attente arrivent ensuite.

+ +

Peut-il aussi faire répéteur ? +

Techniquement oui, avec la commande set repeat on. Ce n’est ni recommandé ni encouragé : un room server qui répète n’a pas toutes les fonctions du firmware Repeater, notamment en administration à distance. Le plus simple et le plus fiable est de dédier un appareil au répéteur et un autre au room server.

+

Administration à distance +

Comme pour un répéteur, on peut administrer un room server à distance depuis un companion, ou par USB avec la console série. Les commandes sont en grande partie les mêmes que celles du répéteur : voir la documentation officielle.

+

Bon à savoir +

    +
  • Un room server ne sert à rien tout seul : il faut des gens à portée, directement ou via des répéteurs.
  • +
  • Il stocke des messages
  • +
  • Placez-le comme un répéteur, en hauteur et bien dégagé, si vous voulez qu’il soit joignable de loin.
  • +
+ + +
+
+ +
+
+
+ +
+ + + + + + + + + diff --git a/en.search-data.json b/en.search-data.json new file mode 100644 index 0000000..a2dd230 --- /dev/null +++ b/en.search-data.json @@ -0,0 +1 @@ +{"/a-propos/":{"data":{"contactez-moi#Contactez moi":"email : hello [@] meshero.fr xmpp : à venir","cookies#Cookies":"Qu’est-ce que les cookies ? Les cookies sont des petits fichiers texte qui sont déposés ou lus sur votre terminal (ordinateur, tablette, smartphone, etc…) lorsque vous naviguez sur un site internet.\nQuels Cookies sont utilisés par meshero.fr ? Le site meshero.fr utilise 1 cookie technique. Ce cookies est lié à mon hebergeur pour la répartition de charge (son petit nom : SERVERID17573). Il s’agit d’un cookies edité par OVH (voir les mentions légales). Ce cookie n’est pas désactivable. Ce cookie s’auto-detruit lorsque vous fermez votre navigateur.\nLorsque vous visitez le site meshero.fr, sont enregistré par OVH dans les log apache votre adresse IP, des informations relatives à votre navigateur internet, le type de connexion (ADSL, fibre …), les ressources demandés ainsi que l’heure.","mentions-légales#Mentions Légales":"Ce site web est hebergé chez OVH. SAS au capital de 10 069 020 € - RCS Lille Métropole 424 761 419 00045 Siège social : 2 rue Kellermann - 59100 Roubaix - France Code APE 2620Z N° TVA : FR 22 424 761 419 Président : Henryk KLABA Directeur général : Miroslaw KLABA Directeur de la publication : Octave KLABA Directeur général délégué : Octave KLABA Directeur général délégué : Halina KLABA Pour contacter OVH : https://www.ovh.com/fr/support/"},"title":"À Propos"},"/documentation/":{"data":{"":"Retrouvez dans cette section les divers documentations autour de MeshCore.","gestion-des-mise-à-jour#Gestion des mise à jour":"Over The Air updater Mettez a jour vos équipements à distance via le bluetooth","les-trois-rôles#Les trois rôles":"Companion Votre appareil personnel pour envoyer et recevoir des messages. Repeater Le nœud fixe qui étend la couverture du réseau. Room Server Un espace de messages partagé, façon forum.","pour-commencer#Pour commencer":"Introduction à MeshCore Les bases : principe, rôles, routage et réglages radio en France."},"title":"Documentation"},"/documentation/companion/":{"data":{"":"Le Companion est le rôle que tout le monde utilise en premier : c’est votre appareil personnel, celui que vous emportez avec vous. Il vous sert à émettre et à recevoir des messages, et il se pilote depuis un téléphone, un navigateur web ou encore en mode «standalone».","administrer-un-répéteur-ou-un-room-server#Administrer un répéteur ou un room server":"Depuis le companion, vous pouvez vous connecter à un répéteur ou à un room server à distance, par radio, avec son mot de passe, et en modifier les réglages.","advert--comment-on-se-découvre#Advert : comment on se découvre":"Un advert est un paquet par lequel un nœud annonce sa présence. Pour un companion, il part uniquement à votre demande. On distingue :\nl’advert local (zero-hop), entendu seulement par les nœuds directement à portée ; l’advert diffusé (flood), relayé par les répéteurs sur tout le réseau. Vous voyez les répéteurs et autres nœuds parce qu’eux s’annoncent régulièrement.\nTip Pour être vu des autres, pensez à envoyer un advert !","appairer-lappareil#Appairer l’appareil":"Activez le Bluetooth sur votre smartphone, ouvrez l’application meshcore et sélectionnez l’appareil.","bon-à-savoir#Bon à savoir":"Même appareil, un seul rôle à la fois : changer de rôle implique de reflasher. Si ton companion est faible en portée, passe en revue l’antenne et ta position avant tout autre réglage. Un companion reçoit surtout via les répéteurs : regardez la carte des répéteurs pour voir ce qui couvre votre zone. Il est possible de mettre à jour votre companion via bluetooth directement","ce-quil-fait-et-ne-fait-pas#Ce qu’il fait (et ne fait pas)":"Il envoie et reçoit vos messages, privés ou sur des canaux. Il ne relaie pas le trafic des autres : seuls les répéteurs portent les messages sur le réseau. Il ne s’annonce que lorsque vous le décidez (voir « Advert » plus bas). Un companion tout seul ne fait donc pas un réseau : il a besoin d’autres companions à portée directe, ou d’au moins un répéteur à portée.","ce-quil-vous-faut#Ce qu’il vous faut":"Un appareil LoRa compatible avec le firmware Companion. Certains sont vendus préinstallés, comme le Wio Tracker L1 Pro que j’utilise. Une application : l’application MeshCore (android meshcore open / android meshcore ou meshcore iOS) ; le client web app.meshcore.nz ; des clients tiers existent également. (Par exemple mishmesh c’est un firmware qui vous permet de l’utiliser en mode «standalone».)","choisir-un-nom-et-régler-la-radio#Choisir un nom et régler la radio":"Donnez un nom à votre companion, puis appliquez le preset EU/UK (Narrow) (869,618 MHz, BW 62,5 kHz, SF8, CR8).","contacts-et-canaux#Contacts et canaux":"Messages privés : ils vont d’un contact à un autre et sont chiffrés de votre appareil a celui de votre contact. Ils sont limités à 150 caractères. Canaux : le canal Public et les canaux #hashtag (par exemple #test) sont ouverts à toute personne qui connaît leur nom. Évitez d’y écrire des informations sensibles. Canaux privés : ils reposent sur une clé partagée entre les membres du groupe.","envoyer-un-advert#Envoyer un advert":"Utilisez l’icône de signal de l’application pour vous annoncer. Les nœuds à portée apparaissent dans votre liste de contacts, et vous apparaissez dans la leur.","gps-et-carte#GPS et carte":"Si votre appareil a un GPS, vous pouvez partager votre position avec vos contacts.\nCaution une position partagée est visible de ceux qui la reçoivent.","installer-le-firmware-si-besoin#Installer le firmware (si besoin)":"Avec le flasher officiel, choisissez votre modèle d’appareil et la variante Companion. Si votre appareil est livré avec MeshCore, il est fort possible de devoir mettre à jour le firmware qui est préinstallé.","les-deux-variantes-de-firmwareconnexion#Les deux variantes de firmware/connexion":"Variante Connexion Usage BLE Companion Bluetooth La plus courante : apparaiage avec l’application sur smartphone USB Companion Câble USB Connexion filaire à un ordinateur ou serveur","première-mise-en-route#Première mise en route":""},"title":"Companion"},"/documentation/meshcore/":{"data":{"cas-dutilisation#Cas d’utilisation":"Événements de masse : Si vous etes deja aller à un «gros» festival par exemple, vous connaissez le probleme du «trop de monde, pas de réseau». Activités extérieur : randonnée/trail en zone blanche. Catastrophes naturelles : séisme, inondation, incendie. Les infrastructures télécom ne fonctionnent plus. Expérimentation technique : juste s’amuser avec la technologie. Pour l’utiliser, il faut :\nun appareil compatible (Heltec, RAK, LilyGo, Seeed…) sur lequel on installe MeshCore une application sur smartphone pour écrire et lire les messages. Par exemple meshcore google playstore ou meshcore-open github ou encore meshcore iOS ou le client web","cest-quoi-meshcore-#C’est quoi MeshCore ?":"MeshCore permet d’échanger des messages texte sans internet ni réseau mobile, en s’appuyant sur un réseau maillé (mesh). C’est un réseau communautaire ou chacun participe à sa construction. À l’inverse du réseau mobile avec lequelle vous envoyez des SMS, les antennes sont ajouter et maintenu par les opérateurs télécom qui vous le facture. Ici vous achetez votre matos, il est a vous et vous ne payez pas d’abonnement.","comment-circule-un-message-#Comment circule un message ?":"MeshCore utilise un routage hybride :\nLe premier message vers un destinataire est diffusé (flood) via les répéteurs pour découvrir un chemin. Le chemin emprunté est mémorisé. Les messages suivants sont envoyés le long de ce chemin connu, sans être rediffusés partout. Si le chemin ne fonctionne plus, le réseau retombe sur la diffusion. Résultat : moins d’occupation du canal radio, ce qui compte beaucoup sur une bande partagée et limitée en temps d’émission.\nNote Le chemin peut etre définit manuellement","les-trois-rôles#Les trois rôles":"Contrairement à d’autres réseaux mesh où tous les nœuds se valent, MeshCore distingue des rôles précis, chacun avec son propre comportement. Cliquez sur une tuile pour voir la page détaillée.\nCompanion Votre appareil personnel. Il se connecte à l’application (Bluetooth ou USB) pour envoyer et recevoir des messages. Il ne relaie pas le trafic des autres. Repeater Un nœud fixe, placé idéalement en hauteur, qui retransmet les messages pour étendre la couverture. C’est l’infrastructure du réseau. Room Server Une sorte de place publique : les clients s’y connectent pour déposer et relire des messages partagés sur le salon. La conséquence pratique est importante : la couverture du réseau dépend surtout du placement des répéteurs, pas du nombre de companions.","outils-utiles#Outils utiles":"Besoin Adresse Installer un firmware flasher.meshcore.io Configurer un répéteur par USB config.meshcore.io Documentation technique docs.meshcore.io Carte des nœuds map.meshcore.io Informations France meshcore.fr","pour-aller-plus-loin#Pour aller plus loin":"Voir les répéteurs sur la carte. Lire mes tests de matériel.","réglages-radio-en-france#Réglages radio en France":"La communauté française utilise le preset EU/UK (Narrow) :\nParamètre Valeur Fréquence 869,618 MHz Bande passante 62,5 kHz Spreading Factor SF8 Coding Rate CR8 La bande 868 MHz est partagée et soumise à des règles (puissance, temps d’émission). Le réseau est commun : un mauvais réglage gêne les autres utilisateurs."},"title":"Introduction à MeshCore"},"/documentation/ota_update/":{"data":{"cest-partie-#C’est partie !":"Mettre votre équipement en mode UF2 DFU Pour la plupart des équipements il suffit de Brancher votre appareil à votre ordinateur Rapidement, appuyez sur le bouton reset 2 fois en 0,5sec Un montage USB va apparaitre sur votre PC Tip Certain équipement rentre dans ce mode d’une façon différentes. Par exemple le T1000E, il faut débrancher et rebrancher le cable USB rapidement Important Si vous avez un pc sur windows, n’oubliez pas d’installer les pilotes\nVérifiez la version actuellement installé (Optionnel) Entrez en UF2 DFU mode (voir precedemment) Ouvrez le fichier INFO_UF2.TXT avec votre editeur de texte Note Celui-ci contient des informations par rapport à votre firmware actuel.\nTélécharger le OTAFix bootloader Aller sur le flasher meshcore Selectionner votre appareil Selectionner votre role (companion ou repeteur) Un lien de téléchargement du bootloader va apparaitre en violet Vous pouvez le télécharger directement, le fichier aura pour nom “update-xxxx.uf2” Tip Alternativement vous pouvez récupérer la releaser sur le github\nInstallation du Bootloader Faites un glisser - déposer du fichier “update-xxxx.uf2” dans le partage UF2 DFU de votre équipement. Celui-ci va s’installer directement et reboot\nAttendez le reboot et c’est bon\nTip Vous pouvez vérifiez en retournant en UF2 DFU. Si vous voyez OTAFIX, la mise à jour s’est bien faite. source","comment-mettre-à-jour-mon-équipement-à-distance-#Comment mettre à jour mon équipement à distance ?":"Une fois qu’on a flasher le firmware de notre companion / repeteur ou room serveur vous allez vous posé la question : Mais comment on met à jour à distance ?\nCela va se passer en 2 étapes:\nInstaller un bootloader alternatif pour faciliter l’installation des futurs mise à jour. Installer la mise à jour lors de sa sortie via bluetooth. Note Forcément si vous venez de flasher votre equipement avec la derniere version de meshcore. vous n’avez pas de mise à jour à appliquer. Cela vous aidera lorsque les prochaines version sortiront","prochaine-étape#Prochaine étape":"Maintenant que le fix est installé, il est possible de mettre à jour vos equipements par bluetooth.\nTélécharger le nouveau firmware Depuis le webflasher, selectionner votre équipement. Choisissez le role répéteur ou room serveur. Enfin télécharger la dernière version disponible au format .zip.\nConnectez vous à votre équipement et aller dans le CLI. Tapez la commande\nstart ota À partir de ce moment, le bluetooth va s’activer sur l’equipement\nLancer l’application nRF DFU android / nRF DFU iOS\nDans l’application, allez dans «settings». Appliquez les parametre suivant:\nPacket receipts notification - ON Number of packets - 8 Request high MTU (Android only) - OFF Disable resume - ON Prepare object delay - 0 ms Force scanning - ON Lancer la mise à jour Selectionner le .zip télécharger à l’étape 1 Selectionnez votre appareil (visible en bluetooth dans la liste) Appuyez sur «Start» pour demarrer (comptez une dizaine de minutes) À la fin votre équipement redémarre. C’tout ! Vous pouvez vérifier que vous etes bien sur la derniere version depuis le CLI avec la commande :\nver source","prérequis#Prérequis":"Avoir un appareil meshcore Un cable USB pour connecter votre équipement à votre ordinateur"},"title":"OTA Update"},"/documentation/repeater/":{"data":{"":"Le répéteur (repeater) est l’infrastructure du réseau. C’est un nœud fixe, généralement placé en hauteur, dont le seul travail est de retransmettre les messages pour étendre la portée.\nDans MeshCore, ce sont les répéteurs qui portent le trafic, pas les companions. La qualité d’un réseau dépend donc surtout de où ils sont placés.","bien-le-placer#Bien le placer":"Le placement compte plus que la puissance ou le matériel.\nHauteur et dégagement : toit, mât, point haut avec vue dégagée dans la direction à couvrir. Antenne : une bonne antenne, bien orientée et bien raccordée, apporte plus qu’un réglage de puissance. Obstacles : bâtiments, relief et végétation dense sont des freins au signal. Alimentation : prise secteur, ou panneau solaire et batterie pour les sites isolés.","changer-les-mots-de-passe#Changer les mots de passe":"Configurez un mot de passe robuste d’administration. Laissez le mot de passe invité vide. (Cela permet aux utilisateurs de récuperer la télémétrie de l’appareil).","comment-il-se-comporte#Comment il se comporte":"Il ne retransmet pas tout ce qu’il entend : il transmet ce qui doit l’être, notamment les messages sur un chemin connu qui passe par lui. Il s’annonce automatiquement à intervalles réguliers, ce qui permet aux companions de le découvrir. Il se gère à distance, par radio, depuis un companion, ou par USB.","configurer-par-usb#Configurer par USB":"Utilisez config.meshcore.io (ou la console série du flasher) pour régler la radio sur le preset EU/UK (Narrow) et donner un nom a votre répéteur.","envoyer-un-advert-et-tester#Envoyer un advert et tester":"Envoyez un advert depuis le répéteur, puis vérifie qu’il apparaît dans la liste d’un de vos companion.\nAvant de monter le répéteur sur un mât, testez l’administration à distance depuis un companion. Une fois installé en hauteur, il sera plus compliqué d’y revenir par câble USB. Tip Pensez à suivre cette procédure, afin d’activer la mise à jour à distance.","et-le-room-server-#Et le room server ?":"Un room server n’est pas fait pour faire repeteur ! C’est un appareil qui sert à poster des messages dans un salon public.","exemple-de-réglages-communautaires#Exemple de réglages communautaires":"La communauté française recommande les réglages suivant :\nset advert.interval 240 set flood.advert.interval 24 set agc.reset.interval 4 set multi.acks 1 set dutycycle 10 set path.hash.mode 1 set loop.detect minimal set flood.max.advert 8 set flood.max.unscoped 5 region def eu europe fr region default fr region home fr region save set repeat on set guest.password '' clock sync reboot Ces valeurs sont un exemple\nImportant Les adverts diffusés consomment du temps d’antenne pour tout le monde ; plus l’intervalle est court, plus le réseau est chargé.","flasher-le-firmware-repeater#Flasher le firmware Repeater":"Avec le flasher officiel, choisissez votre modèle et le firmware Repeater. N’oubliez pas de formaté le device la 1ere fois.","identifiant-et-chemins#Identifiant et chemins":"Dans l’historique du trajet d’un message, chaque répéteur est repéré par les premiers caractères de sa clé publique. Deux répéteurs avec le même préfixe créent de la confusion.","mise-en-service#Mise en service":"","règles-du-jeu#Règles du jeu":"Le réseau est partagé et la bande 868 MHz est réglementée (puissance, temps d’émission). Respecte le preset communautaire et le duty cycle, et ne multiplie pas les répéteurs au même endroit sans concertation.","régions#Régions":"Les répéteurs peuvent être rattachés à des régions (par exemple France, puis région, puis département) pour limiter la propagation des messages à une zone utile. Les noms et la structure sont définis par chaque communauté locale.","réglages-courants#Réglages courants":"Les commandes se tapent dans la console du répéteur (série) ou depuis l’administration à distance. Quelques-unes parmi les plus utiles :\nCommande Rôle advert Envoie un advert diffusé (flood) advert.zerohop Envoie un advert local set advert.interval Intervalle des adverts locaux (60 à 240 min) set flood.advert.interval Intervalle des adverts diffusés (3 à 168 h) set dutycycle 10 Configure un duty cycle de 10% password Change le mot de passe admin set guest.password Définit le mot de passe invité reboot Redémarre le nœud La liste complète est dans la documentation officielle des commandes.","synchroniser-lhorloge#Synchroniser l’horloge":"Règlez l’heure du répéteur depuis l’application ou la console."},"title":"Repeater"},"/documentation/room-server/":{"data":{"":"Le Room Server est le rôle le plus particulier de MeshCore. C’est un petit serveur de messages de type forum : les gens s’y connectent depuis leur companion, déposent des messages dans un espace partagé et lisent ceux des autres, même s’ils n’étaient pas connectés au moment de leur publication.","accès-et-mots-de-passe#Accès et mots de passe":"Mot de passe Droits Restriction de connexion Admin Administrer le room server (réglages, accès) Y appliquer un mot de passe fort Invité Se connecter à la room et y poster NE PAS appliquer de mot de passe Note Le room server peut aussi être réglé en lecture seule, ce qui autorise une connexion sans mot de passe sans pouvoir poster.","administration-à-distance#Administration à distance":"Comme pour un répéteur, on peut administrer un room server à distance depuis un companion, ou par USB avec la console série. Les commandes sont en grande partie les mêmes que celles du répéteur : voir la documentation officielle.","bon-à-savoir#Bon à savoir":"Un room server ne sert à rien tout seul : il faut des gens à portée, directement ou via des répéteurs. Il stocke des messages Placez-le comme un répéteur, en hauteur et bien dégagé, si vous voulez qu’il soit joignable de loin.","comment-ça-marche#Comment ça marche":"Le room server est un nœud fixe, installé comme un répéteur, que l’on contacte par radio. Le client s’y connecte avec un mot de passe, puis peut lire et poster. À la connexion, le client reçoit les 32 derniers messages qu’il n’avait pas encore vus. Les messages d’un room server sont limités à 150 caractères.","configurer-la-radio-et-les-mots-de-passe#Configurer la radio et les mots de passe":"Comme pour un répéteur : preset EU/UK (Narrow), nom du nœud, mot de passe admin, mot de passe invité vide.","envoyer-un-advert#Envoyer un advert":"Envoyez un advert pour que les companions voient la room dans leur liste de contacts.","flasher-le-firmware-room-server#Flasher le firmware Room Server":"Pour flasher votre équipement, choisissez votre modèle d’appareil et le firmware Room Server. Deux possibilités :\nLe flasher officiel : Rien de spécial Le flasher communautaire gessman : Flasher interressant si vous souhaitez envoyer des données sur internet. Cela permet de monitorer le réseau afin de voir se qui passe et ou par exemple. L’avantage de ce flasher, c’est que des preset sont pré-installer. Un preset est une pré-configuration qui permet à notre room serveur d’etre aussi un Observer et d’envoyé des données sur internet. Necessite un equipement connecté à internet (par exemple un Heltec v4 connecté au wifi) Il vous suffit de suivre la documentation officiel pour les activé en cli. Vous avez plusierus emplacement de preset Pour configurer meshmapper sur le slot 3 :\nset mqtt3.preset meshmapper","mise-en-service#Mise en service":"","peut-il-aussi-faire-répéteur-#Peut-il aussi faire répéteur ?":"Techniquement oui, avec la commande set repeat on. Ce n’est ni recommandé ni encouragé : un room server qui répète n’a pas toutes les fonctions du firmware Repeater, notamment en administration à distance. Le plus simple et le plus fiable est de dédier un appareil au répéteur et un autre au room server.","se-connecter-depuis-un-companion#Se connecter depuis un companion":"Ajoutez le room server comme contact, ouvrez-le et saisissez le mot de passe. Les messages en attente arrivent ensuite.","à-quoi-ça-sert#À quoi ça sert":"Un canal classique ne garde rien : si tu n’es pas à l’écoute, tu rates le message. Un room server conserve les messages, ce qui le rend utile pour :\nun tableau d’affichage local (infos pratiques, météo, annonces) ; un groupe ou une association qui veut un fil de discussion persistant ; un événement (randonnée, rassemblement) où tout le monde n’est pas toujours à portée."},"title":"Room Server"},"/materiel/":{"data":{"":"Mes differents équipements testé et utilisé actuellement.","antennes#Antennes":"McGill 9dBi Antenne puissante McGill Sensecap 3dBi Antenne générique","companions#Companions":"Seeed Wio Tracker L1 Pro Companion prêt à l’emploi avec boîtier et GPS. Seeed Wio Tracker L2 Pro Companion avec un écran tactile et GPS. Sensecap T1000E Companion d’une taille de carte de crédit avec un tas de feature ! Sensecap X1 Companion au format compacte avec un tas de feature !","retrouvez-mes-équipements#Retrouvez mes équipements":"","room-serveur#Room Serveur":"Heltec V4 DIY Room Serveur","répéteurs#Répéteurs":"Sensecap P1 Pro Répéteur solaire"},"title":"Matériel"},"/materiel/heltec-v4/":{"data":{"appairer#Appairer":"Quelques probleme d’apparaige à l’application meshcore (obliger de rallumer le bluetooth à chaque déconnexion). Corriger depuis via une maj.","configurer#Configurer":"Preset radio EU/UK (Narrow), nom du nœud, etc.","contenu-et-première-impression#Contenu et première impression":"Je l’ai commandé sur un marketplace chinois avec la coque en 3D La carte est ok mais la coque 3D m’inspire pas confiance … La batterie n’etait pas fournis avec. On assemble le tout, y a du jeu dans la coque je suis mitigé de mon montage.","fiche-rapide#Fiche rapide":"Fabricant / modèle Heltec WiFi LoRa 32 V4 Puce radio Semtech SX1262 (LoRa) Microcontrôleur ESP32-S3R2 Écran / GPS / Bluetooth Écran OLED 0,96″ (128 × 64) / GPS non intégré, connecteur GNSS disponible / Bluetooth BLE 5.0 Batterie / USB Batterie Li-ion externe 3,3–4,2 V, connecteur JST SH1.25 / USB-C Prix payé / lieu d’achat 34€ sur un market place chinois Date d’achat 24/10/2026 Firmware testé MeshCore 1.17 Documentation : https://wiki.heltec.org/docs/devices/open-source-hardware/esp32-series/lora-32/wifi-lora-32-v4_r8_board/","flasher#Flasher":"Companion les premieres semaines (utiliser sur les cotes bretonnes) Puis un Observer à coté de mon répéteur.","installation-du-firmware#Installation du firmware":"","tests-réalisés#Tests réalisés":"Portée : Plutot correct pour la taille Autonomie : trop variable mais de 1 a 3 jours. Le heltec v4 est gourmand en energie. Stabilité : Probleme connexion bluetooth","verdict#Verdict":"Points forts\nPuissant pour sa taille Polyvalence et evolutif (utilisation en tant que companion dans un boitier 3D, répéteur ou room serveur dans un boitier étanche) Peu chère (à l’époque ou je l’ai acheté) Points faibles\nLivrer sans batterie Boitier 3D qui laisse à désirer la navigation à 1 bouton pour un companion (l’autre sert à reboot) Durée de la batterie trop aléatoire Pour qui ? Novice ou confirmé. Je recommande pour un room server ou repéteur dans un boitier etanche mais pas forcement en tant que companion, preferez un L1 Pro"},"title":"Heltec v4"},"/materiel/mcgill9dbi/":{"data":{"branchement#Branchement":"J’ai commandé aussi un cable RP-SMA Male to N-Female Bulkhead RF Cable 300mm pour la brancher sur mon P1 Pro","contenu-et-première-impression#Contenu et première impression":"Une GROSSE antenne d'1m60 en deux morceau. C’est épais sa pese 2kg3!","fiche-rapide#Fiche rapide":"Fabricant / modèle McGill Microwave Prix payé et lieu d’achat 99€ sur Hexaspot Date de d’achat 07/11/2026 Installation Installer sur un P1 Pro Spécification produit Source","installation-de-lantenne#Installation de l’antenne":"","montage#Montage":"Visser les deux partie entre elle.","pose#Pose":"En cours (Prevoir un mat ou quelque chose, ne se fixe pas directement sur le P1 Pro)","test-en-cours#TEST EN COURS":"","tests-réalisés#Tests réalisés":"Portée : Si bien placer en hauteur dégagé plusieurs Km Solidité : Indiqué pour resister à des vents de 210km/h","verdict#Verdict":"Points forts\nPoints faibles\nPour qui ? Companion, répéteur, les deux ?"},"title":"McGill 9dBi"},"/materiel/sensecap-p1pro/":{"data":{"appairer#Appairer":"La 1ere configuration se fait via la connexion USB lors du flashage de l’appareil. Ensuite on se débrouillera via notre companion.","configurer#Configurer":"Preset radio EU/UK (Narrow), nom du nœud, etc.","contenu-et-première-impression#Contenu et première impression":"Le P1 Pro (la version pro dispose de batterie intégré) / le systeme de montage / une antenne. Semble costaud et est bien fini.","fiche-rapide#Fiche rapide":"Fabricant / modèle SenseCAP Solar Node P1-Pro Puce radio Semtech SX1262 (LoRa, 868 MHz en Europe) Microcontrôleur XIAO nRF52840 Plus, ARM Cortex-M4, 64 MHz Écran / GPS / Bluetooth Pas d’écran / GPS intégré L76K (GPS, GLONASS, Galileo) / Bluetooth 5.0 BLE Batterie / USB 4 batteries Li-ion 18650 de 3 350 mAh chacune (13 400 mAh au total) / USB-C / panneau solaire 5 W Prix payé / lieu d’achat $110 sur Seeed Studio Date d’achat 12/08/2026 Firmware testé MeshCore 1.17 et 1.18 Documentation : https://wiki.seeedstudio.com/get_started_with_meshcore_solar_node/","flasher#Flasher":"Rôle installé répéteur","installation-du-firmware#Installation du firmware":"","tests-réalisés#Tests réalisés":"Portée : Tres bonne si degagé (Le fabriquant annonce 9km, je ne les ai pas atteinds car je n’ai pas suffisament de degagement malgres le fait que le repeteur soit sur mon toit) Autonomie : Très bonne grace au panneau solaire et les batteries intégrés. Stabilité : RAS sa tourne comme une horloge.","verdict#Verdict":"Points forts\nQualité de fabrication Prix (100€) Rechargement solaire Systeme d’attache Points faibles\nAntenne de base (c’est vraiment pour chipoter) Pour qui ? Bon premier repeteur, à destination d’utilisateur novice ou confirmé. Un bonne investissement dans le réseau."},"title":"SenseCAP P1Pro"},"/materiel/sensecap-t1000e/":{"data":{"appairer#Appairer":"Apparaillage via les parametre bluetooth android et ensuite depuis l’application android meshcore open / android meshcore ou meshcore iOS","configurer#Configurer":"Preset radio EU/UK (Narrow), nom du nœud, etc.","contenu-et-première-impression#Contenu et première impression":"Livré dans une petite boite. Fournis avec un cable de rechargement (USB-C / fiche propriétaire) Le produit semble solide avec un beau boitier translucide. La petit sangle est vendu séparement.","fiche-rapide#Fiche rapide":"Fabricant / modèle Seeed Studio, T1000-E Puce radio Semtech LR1110 (LoRa, 863–928 MHz) Microcontrôleur Nordic Semiconductor nRF52840 (ARM Cortex-M4) Écran / GPS / Bluetooth Pas d’écran ; GPS/GNSS MediaTek AG3335 ; Bluetooth Low Energy (BLE) 5.1 Batterie / USB Batterie lithium rechargeable de 700 mAh ; recharge via câble USB-A magnétique à 4 broches (proprietaire) Prix payé / lieu d’achat $46 sur Seeed Studio Date d’achat 12/08/2026 Firmware testé MeshCore 1.17 et 1.18 Documentation : https://wiki.seeedstudio.com/sensecap_t1000_e_meshcore/","flasher#Flasher":"On l’utilisera en mode companion","installation-du-firmware#Installation du firmware":"","tests-réalisés#Tests réalisés":"Portée : courte Autonomie : entre 2 et 3 jours suivant l’utilisation Stabilité : RAS","verdict#Verdict":"Points forts\nDesign / Compact et discret Télémetrie (température, luminosité, GPS) Points faibles\nPort propriétaire Sangle d’attache vendu séparement Pour qui ? Companion compact pour tout les jours pour tout le monde. (Vous pouvez meme l’utiliser en tant que traceur GPS pour votre animal favoris)"},"title":"SenseCAP T1000E"},"/materiel/sensecap-x1/":{"data":{"appairer#Appairer":"Connexion à l’application, premiers messages.","configurer#Configurer":"Preset radio EU/UK (Narrow), nom du nœud, etc.","contenu-et-première-impression#Contenu et première impression":"Ce qu’il y a dans la boîte, qualité de fabrication, antenne fournie.","fiche-rapide#Fiche rapide":"Fabricant / modèle Puce radio Microcontrôleur Écran / GPS / Bluetooth Batterie / USB Prix payé et lieu d’achat Date de d’achat 29/10/2026 Firmware testé MeshCore (version : )","flasher#Flasher":"Rôle installé (Companion, Repeater ou Room Server) et outil utilisé.","installation-du-firmware#Installation du firmware":"","prochainement#Prochainement":"","tests-réalisés#Tests réalisés":"Portée : lieu, distance, obstacles, résultat. Autonomie : durée mesurée, conditions. Stabilité : plantages, redémarrages, comportement après plusieurs jours.","verdict#Verdict":"Points forts\nPoints faibles\nPour qui ? Companion, répéteur, les deux ?"},"title":"SenseCAP X1"},"/materiel/sensecap3dbi/":{"data":{"branchement#Branchement":"le cable RP-SMA est fournis avec.","contenu-et-première-impression#Contenu et première impression":"Petite antenne de 360mm.","fiche-rapide#Fiche rapide":"Fabricant / modèle Sensecap Prix payé et lieu d’achat $35 sur seeedstudio Date de d’achat 15/11/2026 Installation sur un P1 Pro Spécification produit source","installation-de-lantenne#Installation de l’antenne":"","montage#Montage":"Rôle installé (Companion, Repeater ou Room Server) et outil utilisé.","pose#Pose":"Peut se fixer sur le P1 Pro directement.","prochainement#Prochainement":"","tests-réalisés#Tests réalisés":"Portée : lieu, distance, obstacles, résultat. Solidité : durée mesurée, conditions.","verdict#Verdict":"Points forts\nPoints faibles\nPour qui ? Companion, répéteur, les deux ?"},"title":"Sensecap 3dBi"},"/materiel/wio-tracker-l1-pro/":{"data":{"appairer#Appairer":"","configurer#Configurer":"Preset radio EU/UK (Narrow), nom du nœud, etc.","contenu-et-première-impression#Contenu et première impression":"une boite simple et petite, on sort l’antenne, on la vis avant de faire quoi que se soit. Le boitier semble de qualité et les boutons repondent bien notamment le petit joystick.","fiche-rapide#Fiche rapide":"Fabricant / modèle Seeed Studio, Wio Tracker L1 Pro (version MeshCore) Puce radio Semtech SX1262 (module Wio-SX1262, 862-930 MHz) Microcontrôleur Nordic nRF52840 (Cortex-M4, 64 MHz, 1 Mo de flash, 256 ko de RAM) Écran / GPS / Bluetooth OLED 1,3\" (128 × 64) / L76K (GPS, BeiDou, GLONASS, QZSS) / BLE 5.0 Batterie / USB Batterie Li-ion 3,7 V / USB-C 5 V Prix payé / lieu d’achat $49 sur Seeed Studio Date d’achat 19/08/2026 Version du firmware testé 1.17 et 1.18 Documentation : https://wiki.seeedstudio.com/get_started_with_other_mesh_firmware/","flasher#Flasher":"Companion","installation-du-firmware#Installation du firmware":"Avant de le démarrer on va flasher mishmesh. C’est un firmware qui permet de l’utiliser sans téléphone, en mode “standalone” comme on dit dans le jargon.\nTip Il reste possible de le connecter via bluetooth meme avec un firmware standalone","tests-réalisés#Tests réalisés":"Portée : Rien de particulier jusqu’a 1km en zone urbaine Autonomie : 3 jours Stabilité : RAS","verdict#Verdict":"Points forts\nQualité de fabrication Facile d’utilisation Mode standalone (pas besoin de téléphone) avec mishmesh Points faibles\nAntenne de base peut etre un peu faiblarde Pour qui ? Débutant et Utilisateur confirmé\nAmélioration possible Ajout d’une antenne plus performante"},"title":"Wio Tracker L1 Pro"},"/materiel/wio-tracker-l2-pro/":{"data":{"appairer#Appairer":"Connexion à l’application, premiers messages.","configurer#Configurer":"Preset radio EU/UK (Narrow), nom du nœud, etc.","contenu-et-première-impression#Contenu et première impression":"Ce qu’il y a dans la boîte, qualité de fabrication, antenne fournie.","fiche-rapide#Fiche rapide":"Fabricant / modèle Puce radio Microcontrôleur Écran / GPS / Bluetooth Batterie / USB Prix payé et lieu d’achat $73 sur seeedstudio Date de d’achat 08/11/2026 Firmware testé MeshCore (version : )","flasher#Flasher":"Rôle installé (Companion, Repeater ou Room Server) et outil utilisé.","installation-du-firmware#Installation du firmware":"","prochainement#Prochainement":"","tests-réalisés#Tests réalisés":"Portée : lieu, distance, obstacles, résultat. Autonomie : durée mesurée, conditions. Stabilité : plantages, redémarrages, comportement après plusieurs jours.","verdict#Verdict":"Points forts\nPoints faibles\nPour qui ? Companion, répéteur, les deux ?"},"title":"Wio Tracker L2 Pro"},"/repeteurs/":{"data":{"":"Retrouvé la carte du réseau meshcore\nLa carte ne s'affiche pas ? Ouvrir dans un nouvel onglet → Note Cette carte ne représente pas nécessairement tous les équipements réellement actifs (seuls les nœuds qui ont été ajoutés ou qui se signalent apparaissent)."},"title":"Carte des nœuds"}} \ No newline at end of file diff --git a/en.search-data.min.7c084e10d80d8432dcd879abe2a210ab0538068d9abdf0762cec3b1655109268.json b/en.search-data.min.7c084e10d80d8432dcd879abe2a210ab0538068d9abdf0762cec3b1655109268.json new file mode 100644 index 0000000..51acfe8 --- /dev/null +++ b/en.search-data.min.7c084e10d80d8432dcd879abe2a210ab0538068d9abdf0762cec3b1655109268.json @@ -0,0 +1 @@ +{"/documentation/":{"data":{"":"Retrouvez dans cette section les divers documentations autour de MeshCore.","gestion-des-mise-à-jour#Gestion des mise à jour":"Over The Air updater Mettez a jour vos équipements à distance via le bluetooth","les-trois-rôles#Les trois rôles":"Companion Votre appareil personnel pour envoyer et recevoir des messages. Repeater Le nœud fixe qui étend la couverture du réseau. Room Server Un espace de messages partagé, façon forum.","pour-commencer#Pour commencer":"Introduction à MeshCore Les bases : principe, rôles, routage et réglages radio en France."},"title":"Documentation"},"/documentation/companion/":{"data":{"":"Le Companion est le rôle que tout le monde utilise en premier : c’est votre appareil personnel, celui que vous emportez avec vous. Il vous sert à émettre et à recevoir des messages, et il se pilote depuis un téléphone, un navigateur web ou encore en mode «standalone».","administrer-un-répéteur-ou-un-room-server#Administrer un répéteur ou un room server":"Depuis le companion, vous pouvez vous connecter à un répéteur ou à un room server à distance, par radio, avec son mot de passe, et en modifier les réglages.","advert--comment-on-se-découvre#Advert : comment on se découvre":"Un advert est un paquet par lequel un nœud annonce sa présence. Pour un companion, il part uniquement à votre demande. On distingue :\nl’advert local (zero-hop), entendu seulement par les nœuds directement à portée ; l’advert diffusé (flood), relayé par les répéteurs sur tout le réseau. Vous voyez les répéteurs et autres nœuds parce qu’eux s’annoncent régulièrement.\nTip Pour être vu des autres, pensez à envoyer un advert !","appairer-lappareil#Appairer l’appareil":"Activez le Bluetooth sur votre smartphone, ouvrez l’application meshcore et sélectionnez l’appareil.","bon-à-savoir#Bon à savoir":"Même appareil, un seul rôle à la fois : changer de rôle implique de reflasher. Si ton companion est faible en portée, passe en revue l’antenne et ta position avant tout autre réglage. Un companion reçoit surtout via les répéteurs : regardez la carte des répéteurs pour voir ce qui couvre votre zone. Il est possible de mettre à jour votre companion via bluetooth directement","ce-quil-fait-et-ne-fait-pas#Ce qu’il fait (et ne fait pas)":"Il envoie et reçoit vos messages, privés ou sur des canaux. Il ne relaie pas le trafic des autres : seuls les répéteurs portent les messages sur le réseau. Il ne s’annonce que lorsque vous le décidez (voir « Advert » plus bas). Un companion tout seul ne fait donc pas un réseau : il a besoin d’autres companions à portée directe, ou d’au moins un répéteur à portée.","ce-quil-vous-faut#Ce qu’il vous faut":"Un appareil LoRa compatible avec le firmware Companion. Certains sont vendus préinstallés, comme le Wio Tracker L1 Pro que j’utilise. Une application : l’application MeshCore (android meshcore open / android meshcore ou meshcore iOS) ; le client web app.meshcore.nz ; des clients tiers existent également. (Par exemple mishmesh c’est un firmware qui vous permet de l’utiliser en mode «standalone».)","choisir-un-nom-et-régler-la-radio#Choisir un nom et régler la radio":"Donnez un nom à votre companion, puis appliquez le preset EU/UK (Narrow) (869,618 MHz, BW 62,5 kHz, SF8, CR8).","contacts-et-canaux#Contacts et canaux":"Messages privés : ils vont d’un contact à un autre et sont chiffrés de votre appareil a celui de votre contact. Ils sont limités à 150 caractères. Canaux : le canal Public et les canaux #hashtag (par exemple #test) sont ouverts à toute personne qui connaît leur nom. Évitez d’y écrire des informations sensibles. Canaux privés : ils reposent sur une clé partagée entre les membres du groupe.","envoyer-un-advert#Envoyer un advert":"Utilisez l’icône de signal de l’application pour vous annoncer. Les nœuds à portée apparaissent dans votre liste de contacts, et vous apparaissez dans la leur.","gps-et-carte#GPS et carte":"Si votre appareil a un GPS, vous pouvez partager votre position avec vos contacts.\nCaution une position partagée est visible de ceux qui la reçoivent.","installer-le-firmware-si-besoin#Installer le firmware (si besoin)":"Avec le flasher officiel, choisissez votre modèle d’appareil et la variante Companion. Si votre appareil est livré avec MeshCore, il est fort possible de devoir mettre à jour le firmware qui est préinstallé.","les-deux-variantes-de-firmwareconnexion#Les deux variantes de firmware/connexion":"Variante Connexion Usage BLE Companion Bluetooth La plus courante : apparaiage avec l’application sur smartphone USB Companion Câble USB Connexion filaire à un ordinateur ou serveur","première-mise-en-route#Première mise en route":""},"title":"Companion"},"/documentation/meshcore/":{"data":{"cas-dutilisation#Cas d’utilisation":"Événements de masse : Si vous etes deja aller à un «gros» festival par exemple, vous connaissez le probleme du «trop de monde, pas de réseau». Activités extérieur : randonnée/trail en zone blanche. Catastrophes naturelles : séisme, inondation, incendie. Les infrastructures télécom ne fonctionnent plus. Expérimentation technique : juste s’amuser avec la technologie. Pour l’utiliser, il faut :\nun appareil compatible (Heltec, RAK, LilyGo, Seeed…) sur lequel on installe MeshCore une application sur smartphone pour écrire et lire les messages. Par exemple meshcore google playstore ou meshcore-open github ou encore meshcore iOS ou le client web","cest-quoi-meshcore-#C’est quoi MeshCore ?":"MeshCore permet d’échanger des messages texte sans internet ni réseau mobile, en s’appuyant sur un réseau maillé (mesh). C’est un réseau communautaire ou chacun participe à sa construction. À l’inverse du réseau mobile avec lequelle vous envoyez des SMS, les antennes sont ajouter et maintenu par les opérateurs télécom qui vous le facture. Ici vous achetez votre matos, il est a vous et vous ne payez pas d’abonnement.","comment-circule-un-message-#Comment circule un message ?":"MeshCore utilise un routage hybride :\nLe premier message vers un destinataire est diffusé (flood) via les répéteurs pour découvrir un chemin. Le chemin emprunté est mémorisé. Les messages suivants sont envoyés le long de ce chemin connu, sans être rediffusés partout. Si le chemin ne fonctionne plus, le réseau retombe sur la diffusion. Résultat : moins d’occupation du canal radio, ce qui compte beaucoup sur une bande partagée et limitée en temps d’émission.\nNote Le chemin peut etre définit manuellement","les-trois-rôles#Les trois rôles":"Contrairement à d’autres réseaux mesh où tous les nœuds se valent, MeshCore distingue des rôles précis, chacun avec son propre comportement. Cliquez sur une tuile pour voir la page détaillée.\nCompanion Votre appareil personnel. Il se connecte à l’application (Bluetooth ou USB) pour envoyer et recevoir des messages. Il ne relaie pas le trafic des autres. Repeater Un nœud fixe, placé idéalement en hauteur, qui retransmet les messages pour étendre la couverture. C’est l’infrastructure du réseau. Room Server Une sorte de place publique : les clients s’y connectent pour déposer et relire des messages partagés sur le salon. La conséquence pratique est importante : la couverture du réseau dépend surtout du placement des répéteurs, pas du nombre de companions.","outils-utiles#Outils utiles":"Besoin Adresse Installer un firmware flasher.meshcore.io Configurer un répéteur par USB config.meshcore.io Documentation technique docs.meshcore.io Carte des nœuds map.meshcore.io Informations France meshcore.fr","pour-aller-plus-loin#Pour aller plus loin":"Voir les répéteurs sur la carte. Lire mes tests de matériel.","réglages-radio-en-france#Réglages radio en France":"La communauté française utilise le preset EU/UK (Narrow) :\nParamètre Valeur Fréquence 869,618 MHz Bande passante 62,5 kHz Spreading Factor SF8 Coding Rate CR8 La bande 868 MHz est partagée et soumise à des règles (puissance, temps d’émission). Le réseau est commun : un mauvais réglage gêne les autres utilisateurs."},"title":"Introduction à MeshCore"},"/documentation/ota_update/":{"data":{"cest-partie-#C’est partie !":"Mettre votre équipement en mode UF2 DFU Pour la plupart des équipements il suffit de Brancher votre appareil à votre ordinateur Rapidement, appuyez sur le bouton reset 2 fois en 0,5sec Un montage USB va apparaitre sur votre PC Tip Certain équipement rentre dans ce mode d’une façon différentes. Par exemple le T1000E, il faut débrancher et rebrancher le cable USB rapidement Important Si vous avez un pc sur windows, n’oubliez pas d’installer les pilotes\nVérifiez la version actuellement installé (Optionnel) Entrez en UF2 DFU mode (voir precedemment) Ouvrez le fichier INFO_UF2.TXT avec votre editeur de texte Note Celui-ci contient des informations par rapport à votre firmware actuel.\nTélécharger le OTAFix bootloader Aller sur le flasher meshcore Selectionner votre appareil Selectionner votre role (companion ou repeteur) Un lien de téléchargement du bootloader va apparaitre en violet Vous pouvez le télécharger directement, le fichier aura pour nom “update-xxxx.uf2” Tip Alternativement vous pouvez récupérer la releaser sur le github\nInstallation du Bootloader Faites un glisser - déposer du fichier “update-xxxx.uf2” dans le partage UF2 DFU de votre équipement. Celui-ci va s’installer directement et reboot\nAttendez le reboot et c’est bon\nTip Vous pouvez vérifiez en retournant en UF2 DFU. Si vous voyez OTAFIX, la mise à jour s’est bien faite. source","comment-mettre-à-jour-mon-équipement-à-distance-#Comment mettre à jour mon équipement à distance ?":"Une fois qu’on a flasher le firmware de notre companion / repeteur ou room serveur vous allez vous posé la question : Mais comment on met à jour à distance ?\nCela va se passer en 2 étapes:\nInstaller un bootloader alternatif pour faciliter l’installation des futurs mise à jour. Installer la mise à jour lors de sa sortie via bluetooth. Note Forcément si vous venez de flasher votre equipement avec la derniere version de meshcore. vous n’avez pas de mise à jour à appliquer. Cela vous aidera lorsque les prochaines version sortiront","prochaine-étape#Prochaine étape":"Maintenant que le fix est installé, il est possible de mettre à jour vos equipements par bluetooth.\nTélécharger le nouveau firmware Depuis le webflasher, selectionner votre équipement. Choisissez le role répéteur ou room serveur. Enfin télécharger la dernière version disponible au format .zip.\nConnectez vous à votre équipement et aller dans le CLI. Tapez la commande\nstart ota À partir de ce moment, le bluetooth va s’activer sur l’equipement\nLancer l’application nRF DFU android / nRF DFU iOS\nDans l’application, allez dans «settings». Appliquez les parametre suivant:\nPacket receipts notification - ON Number of packets - 8 Request high MTU (Android only) - OFF Disable resume - ON Prepare object delay - 0 ms Force scanning - ON Lancer la mise à jour Selectionner le .zip télécharger à l’étape 1 Selectionnez votre appareil (visible en bluetooth dans la liste) Appuyez sur «Start» pour demarrer (comptez une dizaine de minutes) À la fin votre équipement redémarre. C’tout ! Vous pouvez vérifier que vous etes bien sur la derniere version depuis le CLI avec la commande :\nver source","prérequis#Prérequis":"Avoir un appareil meshcore Un cable USB pour connecter votre équipement à votre ordinateur"},"title":"OTA Update"},"/documentation/repeater/":{"data":{"":"Le répéteur (repeater) est l’infrastructure du réseau. C’est un nœud fixe, généralement placé en hauteur, dont le seul travail est de retransmettre les messages pour étendre la portée.\nDans MeshCore, ce sont les répéteurs qui portent le trafic, pas les companions. La qualité d’un réseau dépend donc surtout de où ils sont placés.","bien-le-placer#Bien le placer":"Le placement compte plus que la puissance ou le matériel.\nHauteur et dégagement : toit, mât, point haut avec vue dégagée dans la direction à couvrir. Antenne : une bonne antenne, bien orientée et bien raccordée, apporte plus qu’un réglage de puissance. Obstacles : bâtiments, relief et végétation dense sont des freins au signal. Alimentation : prise secteur, ou panneau solaire et batterie pour les sites isolés.","changer-les-mots-de-passe#Changer les mots de passe":"Configurez un mot de passe robuste d’administration. Laissez le mot de passe invité vide. (Cela permet aux utilisateurs de récuperer la télémétrie de l’appareil).","comment-il-se-comporte#Comment il se comporte":"Il ne retransmet pas tout ce qu’il entend : il transmet ce qui doit l’être, notamment les messages sur un chemin connu qui passe par lui. Il s’annonce automatiquement à intervalles réguliers, ce qui permet aux companions de le découvrir. Il se gère à distance, par radio, depuis un companion, ou par USB.","configurer-par-usb#Configurer par USB":"Utilisez config.meshcore.io (ou la console série du flasher) pour régler la radio sur le preset EU/UK (Narrow) et donner un nom a votre répéteur.","envoyer-un-advert-et-tester#Envoyer un advert et tester":"Envoyez un advert depuis le répéteur, puis vérifie qu’il apparaît dans la liste d’un de vos companion.\nAvant de monter le répéteur sur un mât, testez l’administration à distance depuis un companion. Une fois installé en hauteur, il sera plus compliqué d’y revenir par câble USB. Tip Pensez à suivre cette procédure, afin d’activer la mise à jour à distance.","et-le-room-server-#Et le room server ?":"Un room server n’est pas fait pour faire repeteur ! C’est un appareil qui sert à poster des messages dans un salon public.","exemple-de-réglages-communautaires#Exemple de réglages communautaires":"La communauté française recommande les réglages suivant :\nset advert.interval 240 set flood.advert.interval 24 set agc.reset.interval 4 set multi.acks 1 set dutycycle 10 set path.hash.mode 1 set loop.detect minimal set flood.max.advert 8 set flood.max.unscoped 5 region def eu europe fr region default fr region home fr region save set repeat on set guest.password '' clock sync reboot Ces valeurs sont un exemple\nImportant Les adverts diffusés consomment du temps d’antenne pour tout le monde ; plus l’intervalle est court, plus le réseau est chargé.","flasher-le-firmware-repeater#Flasher le firmware Repeater":"Avec le flasher officiel, choisissez votre modèle et le firmware Repeater. N’oubliez pas de formaté le device la 1ere fois.","identifiant-et-chemins#Identifiant et chemins":"Dans l’historique du trajet d’un message, chaque répéteur est repéré par les premiers caractères de sa clé publique. Deux répéteurs avec le même préfixe créent de la confusion.","mise-en-service#Mise en service":"","règles-du-jeu#Règles du jeu":"Le réseau est partagé et la bande 868 MHz est réglementée (puissance, temps d’émission). Respecte le preset communautaire et le duty cycle, et ne multiplie pas les répéteurs au même endroit sans concertation.","régions#Régions":"Les répéteurs peuvent être rattachés à des régions (par exemple France, puis région, puis département) pour limiter la propagation des messages à une zone utile. Les noms et la structure sont définis par chaque communauté locale.","réglages-courants#Réglages courants":"Les commandes se tapent dans la console du répéteur (série) ou depuis l’administration à distance. Quelques-unes parmi les plus utiles :\nCommande Rôle advert Envoie un advert diffusé (flood) advert.zerohop Envoie un advert local set advert.interval Intervalle des adverts locaux (60 à 240 min) set flood.advert.interval Intervalle des adverts diffusés (3 à 168 h) set dutycycle 10 Configure un duty cycle de 10% password Change le mot de passe admin set guest.password Définit le mot de passe invité reboot Redémarre le nœud La liste complète est dans la documentation officielle des commandes.","synchroniser-lhorloge#Synchroniser l’horloge":"Règlez l’heure du répéteur depuis l’application ou la console."},"title":"Repeater"},"/documentation/room-server/":{"data":{"":"Le Room Server est le rôle le plus particulier de MeshCore. C’est un petit serveur de messages de type forum : les gens s’y connectent depuis leur companion, déposent des messages dans un espace partagé et lisent ceux des autres, même s’ils n’étaient pas connectés au moment de leur publication.","accès-et-mots-de-passe#Accès et mots de passe":"Mot de passe Droits Restriction de connexion Admin Administrer le room server (réglages, accès) Y appliquer un mot de passe fort Invité Se connecter à la room et y poster NE PAS appliquer de mot de passe Note Le room server peut aussi être réglé en lecture seule, ce qui autorise une connexion sans mot de passe sans pouvoir poster.","administration-à-distance#Administration à distance":"Comme pour un répéteur, on peut administrer un room server à distance depuis un companion, ou par USB avec la console série. Les commandes sont en grande partie les mêmes que celles du répéteur : voir la documentation officielle.","bon-à-savoir#Bon à savoir":"Un room server ne sert à rien tout seul : il faut des gens à portée, directement ou via des répéteurs. Il stocke des messages Placez-le comme un répéteur, en hauteur et bien dégagé, si vous voulez qu’il soit joignable de loin.","comment-ça-marche#Comment ça marche":"Le room server est un nœud fixe, installé comme un répéteur, que l’on contacte par radio. Le client s’y connecte avec un mot de passe, puis peut lire et poster. À la connexion, le client reçoit les 32 derniers messages qu’il n’avait pas encore vus. Les messages d’un room server sont limités à 150 caractères.","configurer-la-radio-et-les-mots-de-passe#Configurer la radio et les mots de passe":"Comme pour un répéteur : preset EU/UK (Narrow), nom du nœud, mot de passe admin, mot de passe invité vide.","envoyer-un-advert#Envoyer un advert":"Envoyez un advert pour que les companions voient la room dans leur liste de contacts.","flasher-le-firmware-room-server#Flasher le firmware Room Server":"Pour flasher votre équipement, choisissez votre modèle d’appareil et le firmware Room Server. Deux possibilités :\nLe flasher officiel : Rien de spécial Le flasher communautaire gessman : Flasher interressant si vous souhaitez envoyer des données sur internet. Cela permet de monitorer le réseau afin de voir se qui passe et ou par exemple. L’avantage de ce flasher, c’est que des preset sont pré-installer. Un preset est une pré-configuration qui permet à notre room serveur d’etre aussi un Observer et d’envoyé des données sur internet. Necessite un equipement connecté à internet (par exemple un Heltec v4 connecté au wifi) Il vous suffit de suivre la documentation officiel pour les activé en cli. Vous avez plusierus emplacement de preset Pour configurer meshmapper sur le slot 3 :\nset mqtt3.preset meshmapper","mise-en-service#Mise en service":"","peut-il-aussi-faire-répéteur-#Peut-il aussi faire répéteur ?":"Techniquement oui, avec la commande set repeat on. Ce n’est ni recommandé ni encouragé : un room server qui répète n’a pas toutes les fonctions du firmware Repeater, notamment en administration à distance. Le plus simple et le plus fiable est de dédier un appareil au répéteur et un autre au room server.","se-connecter-depuis-un-companion#Se connecter depuis un companion":"Ajoutez le room server comme contact, ouvrez-le et saisissez le mot de passe. Les messages en attente arrivent ensuite.","à-quoi-ça-sert#À quoi ça sert":"Un canal classique ne garde rien : si tu n’es pas à l’écoute, tu rates le message. Un room server conserve les messages, ce qui le rend utile pour :\nun tableau d’affichage local (infos pratiques, météo, annonces) ; un groupe ou une association qui veut un fil de discussion persistant ; un événement (randonnée, rassemblement) où tout le monde n’est pas toujours à portée."},"title":"Room Server"},"/materiel/":{"data":{"":"Mes differents équipements testé et utilisé actuellement.","antennes#Antennes":"McGill 9dBi Antenne puissante McGill Sensecap 3dBi Antenne générique","companions#Companions":"Seeed Wio Tracker L1 Pro Companion prêt à l’emploi avec boîtier et GPS. Seeed Wio Tracker L2 Pro Companion avec un écran tactile et GPS. Sensecap T1000E Companion d’une taille de carte de crédit avec un tas de feature ! Sensecap X1 Companion au format compacte avec un tas de feature !","retrouvez-mes-équipements#Retrouvez mes équipements":"","room-serveur#Room Serveur":"Heltec V4 DIY Room Serveur","répéteurs#Répéteurs":"Sensecap P1 Pro Répéteur solaire"},"title":"Matériel"},"/materiel/heltec-v4/":{"data":{"appairer#Appairer":"Quelques probleme d’apparaige à l’application meshcore (obliger de rallumer le bluetooth à chaque déconnexion). Corriger depuis via une maj.","configurer#Configurer":"Preset radio EU/UK (Narrow), nom du nœud, etc.","contenu-et-première-impression#Contenu et première impression":"Je l’ai commandé sur un marketplace chinois avec la coque en 3D La carte est ok mais la coque 3D m’inspire pas confiance … La batterie n’etait pas fournis avec. On assemble le tout, y a du jeu dans la coque je suis mitigé de mon montage.","fiche-rapide#Fiche rapide":"Fabricant / modèle Heltec WiFi LoRa 32 V4 Puce radio Semtech SX1262 (LoRa) Microcontrôleur ESP32-S3R2 Écran / GPS / Bluetooth Écran OLED 0,96″ (128 × 64) / GPS non intégré, connecteur GNSS disponible / Bluetooth BLE 5.0 Batterie / USB Batterie Li-ion externe 3,3–4,2 V, connecteur JST SH1.25 / USB-C Prix payé / lieu d’achat 34€ sur un market place chinois Date d’achat 24/10/2026 Firmware testé MeshCore 1.17 Documentation : https://wiki.heltec.org/docs/devices/open-source-hardware/esp32-series/lora-32/wifi-lora-32-v4_r8_board/","flasher#Flasher":"Companion les premieres semaines (utiliser sur les cotes bretonnes) Puis un Observer à coté de mon répéteur.","installation-du-firmware#Installation du firmware":"","tests-réalisés#Tests réalisés":"Portée : Plutot correct pour la taille Autonomie : trop variable mais de 1 a 3 jours. Le heltec v4 est gourmand en energie. Stabilité : Probleme connexion bluetooth","verdict#Verdict":"Points forts\nPuissant pour sa taille Polyvalence et evolutif (utilisation en tant que companion dans un boitier 3D, répéteur ou room serveur dans un boitier étanche) Peu chère (à l’époque ou je l’ai acheté) Points faibles\nLivrer sans batterie Boitier 3D qui laisse à désirer la navigation à 1 bouton pour un companion (l’autre sert à reboot) Durée de la batterie trop aléatoire Pour qui ? Novice ou confirmé. Je recommande pour un room server ou repéteur dans un boitier etanche mais pas forcement en tant que companion, preferez un L1 Pro"},"title":"Heltec v4"},"/materiel/mcgill9dbi/":{"data":{"branchement#Branchement":"J’ai commandé aussi un cable RP-SMA Male to N-Female Bulkhead RF Cable 300mm pour la brancher sur mon P1 Pro","contenu-et-première-impression#Contenu et première impression":"Une GROSSE antenne d'1m60 en deux morceau. C’est épais sa pese 2kg3!","fiche-rapide#Fiche rapide":"Fabricant / modèle McGill Microwave Prix payé et lieu d’achat 99€ sur Hexaspot Date de d’achat 07/11/2026 Installation Installer sur un P1 Pro Spécification produit Source","installation-de-lantenne#Installation de l’antenne":"","montage#Montage":"Visser les deux partie entre elle.","pose#Pose":"En cours (Prevoir un mat ou quelque chose, ne se fixe pas directement sur le P1 Pro)","test-en-cours#TEST EN COURS":"","tests-réalisés#Tests réalisés":"Portée : Si bien placer en hauteur dégagé plusieurs Km Solidité : Indiqué pour resister à des vents de 210km/h","verdict#Verdict":"Points forts\nPoints faibles\nPour qui ? Companion, répéteur, les deux ?"},"title":"McGill 9dBi"},"/materiel/sensecap-p1pro/":{"data":{"appairer#Appairer":"La 1ere configuration se fait via la connexion USB lors du flashage de l’appareil. Ensuite on se débrouillera via notre companion.","configurer#Configurer":"Preset radio EU/UK (Narrow), nom du nœud, etc.","contenu-et-première-impression#Contenu et première impression":"Le P1 Pro (la version pro dispose de batterie intégré) / le systeme de montage / une antenne. Semble costaud et est bien fini.","fiche-rapide#Fiche rapide":"Fabricant / modèle SenseCAP Solar Node P1-Pro Puce radio Semtech SX1262 (LoRa, 868 MHz en Europe) Microcontrôleur XIAO nRF52840 Plus, ARM Cortex-M4, 64 MHz Écran / GPS / Bluetooth Pas d’écran / GPS intégré L76K (GPS, GLONASS, Galileo) / Bluetooth 5.0 BLE Batterie / USB 4 batteries Li-ion 18650 de 3 350 mAh chacune (13 400 mAh au total) / USB-C / panneau solaire 5 W Prix payé / lieu d’achat $110 sur Seeed Studio Date d’achat 12/08/2026 Firmware testé MeshCore 1.17 et 1.18 Documentation : https://wiki.seeedstudio.com/get_started_with_meshcore_solar_node/","flasher#Flasher":"Rôle installé répéteur","installation-du-firmware#Installation du firmware":"","tests-réalisés#Tests réalisés":"Portée : Tres bonne si degagé (Le fabriquant annonce 9km, je ne les ai pas atteinds car je n’ai pas suffisament de degagement malgres le fait que le repeteur soit sur mon toit) Autonomie : Très bonne grace au panneau solaire et les batteries intégrés. Stabilité : RAS sa tourne comme une horloge.","verdict#Verdict":"Points forts\nQualité de fabrication Prix (100€) Rechargement solaire Systeme d’attache Points faibles\nAntenne de base (c’est vraiment pour chipoter) Pour qui ? Bon premier repeteur, à destination d’utilisateur novice ou confirmé. Un bonne investissement dans le réseau."},"title":"SenseCAP P1Pro"},"/materiel/sensecap-t1000e/":{"data":{"appairer#Appairer":"Apparaillage via les parametre bluetooth android et ensuite depuis l’application android meshcore open / android meshcore ou meshcore iOS","configurer#Configurer":"Preset radio EU/UK (Narrow), nom du nœud, etc.","contenu-et-première-impression#Contenu et première impression":"Livré dans une petite boite. Fournis avec un cable de rechargement (USB-C / fiche propriétaire) Le produit semble solide avec un beau boitier translucide. La petit sangle est vendu séparement.","fiche-rapide#Fiche rapide":"Fabricant / modèle Seeed Studio, T1000-E Puce radio Semtech LR1110 (LoRa, 863–928 MHz) Microcontrôleur Nordic Semiconductor nRF52840 (ARM Cortex-M4) Écran / GPS / Bluetooth Pas d’écran ; GPS/GNSS MediaTek AG3335 ; Bluetooth Low Energy (BLE) 5.1 Batterie / USB Batterie lithium rechargeable de 700 mAh ; recharge via câble USB-A magnétique à 4 broches (proprietaire) Prix payé / lieu d’achat $46 sur Seeed Studio Date d’achat 12/08/2026 Firmware testé MeshCore 1.17 et 1.18 Documentation : https://wiki.seeedstudio.com/sensecap_t1000_e_meshcore/","flasher#Flasher":"On l’utilisera en mode companion","installation-du-firmware#Installation du firmware":"","tests-réalisés#Tests réalisés":"Portée : courte Autonomie : entre 2 et 3 jours suivant l’utilisation Stabilité : RAS","verdict#Verdict":"Points forts\nDesign / Compact et discret Télémetrie (température, luminosité, GPS) Points faibles\nPort propriétaire Sangle d’attache vendu séparement Pour qui ? Companion compact pour tout les jours pour tout le monde. (Vous pouvez meme l’utiliser en tant que traceur GPS pour votre animal favoris)"},"title":"SenseCAP T1000E"},"/materiel/sensecap-x1/":{"data":{"appairer#Appairer":"Connexion à l’application, premiers messages.","configurer#Configurer":"Preset radio EU/UK (Narrow), nom du nœud, etc.","contenu-et-première-impression#Contenu et première impression":"Ce qu’il y a dans la boîte, qualité de fabrication, antenne fournie.","fiche-rapide#Fiche rapide":"Fabricant / modèle Puce radio Microcontrôleur Écran / GPS / Bluetooth Batterie / USB Prix payé et lieu d’achat Date de d’achat 29/10/2026 Firmware testé MeshCore (version : )","flasher#Flasher":"Rôle installé (Companion, Repeater ou Room Server) et outil utilisé.","installation-du-firmware#Installation du firmware":"","prochainement#Prochainement":"","tests-réalisés#Tests réalisés":"Portée : lieu, distance, obstacles, résultat. Autonomie : durée mesurée, conditions. Stabilité : plantages, redémarrages, comportement après plusieurs jours.","verdict#Verdict":"Points forts\nPoints faibles\nPour qui ? Companion, répéteur, les deux ?"},"title":"SenseCAP X1"},"/materiel/sensecap3dbi/":{"data":{"branchement#Branchement":"le cable RP-SMA est fournis avec.","contenu-et-première-impression#Contenu et première impression":"Petite antenne de 360mm.","fiche-rapide#Fiche rapide":"Fabricant / modèle Sensecap Prix payé et lieu d’achat $35 sur seeedstudio Date de d’achat 15/11/2026 Installation sur un P1 Pro Spécification produit source","installation-de-lantenne#Installation de l’antenne":"","montage#Montage":"Rôle installé (Companion, Repeater ou Room Server) et outil utilisé.","pose#Pose":"Peut se fixer sur le P1 Pro directement.","prochainement#Prochainement":"","tests-réalisés#Tests réalisés":"Portée : lieu, distance, obstacles, résultat. Solidité : durée mesurée, conditions.","verdict#Verdict":"Points forts\nPoints faibles\nPour qui ? Companion, répéteur, les deux ?"},"title":"Sensecap 3dBi"},"/materiel/wio-tracker-l1-pro/":{"data":{"appairer#Appairer":"","configurer#Configurer":"Preset radio EU/UK (Narrow), nom du nœud, etc.","contenu-et-première-impression#Contenu et première impression":"une boite simple et petite, on sort l’antenne, on la vis avant de faire quoi que se soit. Le boitier semble de qualité et les boutons repondent bien notamment le petit joystick.","fiche-rapide#Fiche rapide":"Fabricant / modèle Seeed Studio, Wio Tracker L1 Pro (version MeshCore) Puce radio Semtech SX1262 (module Wio-SX1262, 862-930 MHz) Microcontrôleur Nordic nRF52840 (Cortex-M4, 64 MHz, 1 Mo de flash, 256 ko de RAM) Écran / GPS / Bluetooth OLED 1,3\" (128 × 64) / L76K (GPS, BeiDou, GLONASS, QZSS) / BLE 5.0 Batterie / USB Batterie Li-ion 3,7 V / USB-C 5 V Prix payé / lieu d’achat $49 sur Seeed Studio Date d’achat 19/08/2026 Version du firmware testé 1.17 et 1.18 Documentation : https://wiki.seeedstudio.com/get_started_with_other_mesh_firmware/","flasher#Flasher":"Companion","installation-du-firmware#Installation du firmware":"Avant de le démarrer on va flasher mishmesh. C’est un firmware qui permet de l’utiliser sans téléphone, en mode “standalone” comme on dit dans le jargon.\nTip Il reste possible de le connecter via bluetooth meme avec un firmware standalone","tests-réalisés#Tests réalisés":"Portée : Rien de particulier jusqu’a 1km en zone urbaine Autonomie : 3 jours Stabilité : RAS","verdict#Verdict":"Points forts\nQualité de fabrication Facile d’utilisation Mode standalone (pas besoin de téléphone) avec mishmesh Points faibles\nAntenne de base peut etre un peu faiblarde Pour qui ? Débutant et Utilisateur confirmé\nAmélioration possible Ajout d’une antenne plus performante"},"title":"Wio Tracker L1 Pro"},"/materiel/wio-tracker-l2-pro/":{"data":{"appairer#Appairer":"Connexion à l’application, premiers messages.","configurer#Configurer":"Preset radio EU/UK (Narrow), nom du nœud, etc.","contenu-et-première-impression#Contenu et première impression":"Ce qu’il y a dans la boîte, qualité de fabrication, antenne fournie.","fiche-rapide#Fiche rapide":"Fabricant / modèle Puce radio Microcontrôleur Écran / GPS / Bluetooth Batterie / USB Prix payé et lieu d’achat $73 sur seeedstudio Date de d’achat 08/11/2026 Firmware testé MeshCore (version : )","flasher#Flasher":"Rôle installé (Companion, Repeater ou Room Server) et outil utilisé.","installation-du-firmware#Installation du firmware":"","prochainement#Prochainement":"","tests-réalisés#Tests réalisés":"Portée : lieu, distance, obstacles, résultat. Autonomie : durée mesurée, conditions. Stabilité : plantages, redémarrages, comportement après plusieurs jours.","verdict#Verdict":"Points forts\nPoints faibles\nPour qui ? Companion, répéteur, les deux ?"},"title":"Wio Tracker L2 Pro"},"/repeteurs/":{"data":{"":"Retrouvé la carte du réseau meshcore\nLa carte ne s'affiche pas ? Ouvrir dans un nouvel onglet → Note Cette carte ne représente pas nécessairement tous les équipements réellement actifs (seuls les nœuds qui ont été ajoutés ou qui se signalent apparaissent)."},"title":"Carte des nœuds"}} \ No newline at end of file diff --git a/en.search-dialog.js b/en.search-dialog.js new file mode 100644 index 0000000..ded3d42 --- /dev/null +++ b/en.search-dialog.js @@ -0,0 +1,505 @@ +// Search command palette UI. Owns the , keyboard shortcuts, result +// rendering, and animations. Reads data from `window.hextraSearch` (defined +// in flexsearch.js). + +// + +(function () { + const resultsFoundTemplate = '%d results found'; + const noResultsText = 'No results found.'; + + const EDITABLE_TAGS = ['INPUT', 'SELECT', 'BUTTON', 'TEXTAREA']; + const isMac = /iPad|iPhone|Macintosh/.test(navigator.userAgent); + + let dialog; + let input; + let resultsEl; + let emptyEl; + let statusEl; + let viewportEl; + let innerEl; + let closeAnimationListener = null; + let closeTimer = null; + let collapseTimer = null; + + document.addEventListener('DOMContentLoaded', init); + + function init() { + dialog = document.getElementById('hextra-search-dialog'); + if (!dialog) return; + + input = dialog.querySelector('.hextra-search-input'); + resultsEl = dialog.querySelector('.hextra-search-results'); + emptyEl = dialog.querySelector('[data-search-empty]'); + statusEl = dialog.querySelector('.hextra-search-status'); + viewportEl = dialog.querySelector('[data-search-viewport]'); + innerEl = dialog.querySelector('[data-search-inner]'); + + if (isMac) { + document.querySelectorAll('.hextra-search-trigger-kbd').forEach(el => { + while (el.firstChild) el.removeChild(el.firstChild); + const cmd = document.createElement('span'); + cmd.style.fontSize = '0.75rem'; + cmd.textContent = '⌘'; + el.appendChild(cmd); + el.appendChild(document.createTextNode('K')); + }); + } + + document.querySelectorAll('[data-search-open]').forEach(btn => { + btn.addEventListener('click', () => openDialog()); + }); + + const closeBtn = dialog.querySelector('[data-search-close]'); + if (closeBtn) closeBtn.addEventListener('click', () => closeDialog()); + + document.addEventListener('keydown', handleGlobalKeyDown); + + input.addEventListener('input', runSearch); + dialog.addEventListener('keydown', handleDialogKeyDown); + + // Click on backdrop closes the dialog. + dialog.addEventListener('click', (e) => { + if (e.target === dialog) closeDialog(); + }); + + // Keep the previous query and results when reopening — only flip aria state. + dialog.addEventListener('close', () => { + input.setAttribute('aria-expanded', 'false'); + }); + + // Intercept the native Escape "cancel" so we can play the close animation. + dialog.addEventListener('cancel', (e) => { + e.preventDefault(); + closeDialog(); + }); + + // Delegate result clicks so we can close the dialog on navigation. + resultsEl.addEventListener('click', (e) => { + const anchor = e.target.closest('a[role="option"]'); + if (anchor) closeDialog(); + }); + + // Hover updates selection like a standard command palette. + resultsEl.addEventListener('mousemove', (e) => { + const anchor = e.target.closest('a[role="option"]'); + if (anchor) setActiveOption(anchor, { scroll: false }); + }); + + // Result anchors are in the Tab sequence; keep aria-selected in sync with + // the focused option so the highlighted row matches keyboard focus. + resultsEl.addEventListener('focusin', (e) => { + const anchor = e.target.closest('a[role="option"]'); + if (anchor) setActiveOption(anchor, { scroll: false }); + }); + + // Dialog-level keyboard handling keeps input and result navigation in sync. + // Enter on focused result anchors falls through to native anchor activation. + } + + function isEditableElement(element) { + const tag = element && element.tagName; + return !!element && (EDITABLE_TAGS.includes(tag) || element.isContentEditable); + } + + function setActiveDescendant(id) { + if (id) input.setAttribute('aria-activedescendant', id); + else input.removeAttribute('aria-activedescendant'); + } + + function handleGlobalKeyDown(e) { + const inEditable = isEditableElement(document.activeElement); + + if (e.key === 'k' && (e.metaKey || e.ctrlKey)) { + if (inEditable) return; + e.preventDefault(); + // A dialog mid-dismiss is logically "closed" for toggle purposes — without + // this, a rapid second Cmd+K is eaten by closeDialog's early-return. + const isClosing = dialog.dataset.state === 'closing'; + if (dialog.open && !isClosing) closeDialog(); + else openDialog(); + return; + } + + if (dialog.open) return; + + if (e.key === '/') { + if (inEditable) return; + e.preventDefault(); + openDialog(); + } + } + + function openDialog() { + // Mid-dismiss? Cancel the close animation and stay open — the in animation + // re-plays so the dialog visibly snaps back instead of completing the fade. + if (dialog.open && dialog.dataset.state === 'closing') { + cancelClose(); + input.focus(); + input.select(); + return; + } + if (dialog.open) return; + dialog.showModal(); + input.setAttribute('aria-expanded', 'true'); + // showModal autofocuses the first focusable element, but be explicit. + // Select existing query so typing immediately replaces it. + requestAnimationFrame(() => { + input.focus(); + input.select(); + }); + if (window.hextraSearch) window.hextraSearch.preload().catch(() => {}); + } + + function cancelClose() { + if (closeAnimationListener) { + dialog.removeEventListener('animationend', closeAnimationListener); + closeAnimationListener = null; + } + if (closeTimer !== null) { + clearTimeout(closeTimer); + closeTimer = null; + } + delete dialog.dataset.state; + } + + function closeDialog() { + if (!dialog.open || dialog.dataset.state === 'closing') return; + cancelCollapse(); + + const reducedMotion = window.matchMedia('(prefers-reduced-motion: reduce)').matches; + if (reducedMotion) { + dialog.close(); + return; + } + + dialog.dataset.state = 'closing'; + const finalize = () => { + if (closeTimer !== null) { + clearTimeout(closeTimer); + closeTimer = null; + } + if (closeAnimationListener) { + dialog.removeEventListener('animationend', closeAnimationListener); + closeAnimationListener = null; + } + if (dialog.dataset.state === 'closing') { + delete dialog.dataset.state; + dialog.close(); + } + }; + // The backdrop animation is the longest — wait for it so neither layer + // gets cut off when the dialog is removed from the top layer. + closeAnimationListener = (e) => { + if (e.animationName !== 'hextra-search-backdrop-out') return; + finalize(); + }; + dialog.addEventListener('animationend', closeAnimationListener); + // animationend on ::backdrop doesn't bubble reliably across browsers + // (Firefox in particular); force-close shortly after the 300ms animation + // so the dialog can't get stranded. + closeTimer = setTimeout(finalize, 400); + } + + function setViewportExpanded(expanded) { + if (!viewportEl) return; + viewportEl.dataset.expanded = expanded ? 'true' : 'false'; + } + + function cancelCollapse() { + if (collapseTimer !== null) { + clearTimeout(collapseTimer); + collapseTimer = null; + } + } + + function clearResults() { + while (resultsEl.firstChild) resultsEl.removeChild(resultsEl.firstChild); + } + + function handleDialogKeyDown(e) { + const anchor = e.target.closest('a[role="option"]'); + const fromInput = e.target === input; + if (!fromInput && !anchor) return; + + // During IME composition the user is still selecting a candidate; Enter + // commits the candidate (not the result), arrow keys cycle candidates. + if (fromInput && (e.isComposing || e.keyCode === 229)) return; + + const focusResults = !!anchor; + switch (e.key) { + case 'ArrowDown': + e.preventDefault(); + moveSelection(1, { current: anchor, focus: focusResults }); + break; + case 'ArrowUp': + e.preventDefault(); + moveSelection(-1, { current: anchor, focus: focusResults }); + break; + case 'Home': { + const all = getOptions(); + if (!all.length) return; + e.preventDefault(); + selectOption(all[0], { focus: focusResults }); + break; + } + case 'End': { + const all = getOptions(); + if (!all.length) return; + e.preventDefault(); + selectOption(all[all.length - 1], { focus: focusResults }); + break; + } + case 'Enter': { + if (!fromInput) return; + const opt = getActiveOption(); + if (!opt) return; + e.preventDefault(); + opt.click(); + break; + } + case 'Escape': + // input[type=search] clears its value on Escape and swallows the event, + // so close the dialog explicitly here. + e.preventDefault(); + closeDialog(); + break; + } + } + + function getOptions() { + return Array.from(resultsEl.querySelectorAll('a[role="option"]')); + } + + function getActiveOption() { + return resultsEl.querySelector('a[aria-selected="true"]'); + } + + function setActiveOption(el, opts) { + const scroll = !opts || opts.scroll !== false; + getOptions().forEach((o) => { + o.setAttribute('aria-selected', o === el ? 'true' : 'false'); + }); + if (el) { + setActiveDescendant(el.id); + if (scroll) el.scrollIntoView({ block: 'nearest' }); + } else { + setActiveDescendant(); + } + } + + function focusOption(el) { + setActiveOption(el, { scroll: false }); + el.focus({ preventScroll: true }); + el.scrollIntoView({ block: 'nearest' }); + } + + function selectOption(el, opts) { + if (opts && opts.focus) focusOption(el); + else setActiveOption(el); + } + + function moveSelection(delta, opts) { + const options = getOptions(); + if (!options.length) return; + const current = (opts && opts.current) || getActiveOption(); + let i = options.indexOf(current); + if (i === -1) { + i = delta > 0 ? 0 : options.length - 1; + } else { + i = (i + delta + options.length) % options.length; + } + selectOption(options[i], opts); + } + + async function runSearch(e) { + if (e && e.isComposing) return; + + const query = input.value.trim(); + if (!query) { + setActiveDescendant(); + if (statusEl) statusEl.textContent = ''; + setViewportExpanded(false); + // Defer DOM clear until the viewport finishes collapsing — otherwise the + // results vanish first and the viewport snaps to the inner padding before + // animating the last few pixels to 0. + cancelCollapse(); + collapseTimer = setTimeout(() => { + collapseTimer = null; + clearResults(); + if (emptyEl) emptyEl.hidden = true; + }, 250); + return; + } + if (!window.hextraSearch) return; + let results; + try { + results = await window.hextraSearch.search(query); + } catch (err) { + // Stale failure for an old query — ignore. Otherwise log and fall + // through to an empty render so the user sees feedback instead of stale + // results. + if (input.value.trim() !== query) return; + console.warn('[hextra-search]', err); + results = []; + } + // Drop stale results if the input changed during the await. + if (input.value.trim() !== query) return; + renderResults(results, query); + } + + function appendHighlightedText(container, text, query) { + if (!text) return; + if (!query) { + container.textContent = text; + return; + } + const escapedQuery = query.replace(/[-\\^$*+?.()|[\]{}]/g, '\\$&'); + if (!escapedQuery) { + container.textContent = text; + return; + } + const regex = new RegExp(escapedQuery, 'gi'); + let lastIndex = 0; + let match; + while ((match = regex.exec(text)) !== null) { + if (match.index > lastIndex) { + container.appendChild(document.createTextNode(text.slice(lastIndex, match.index))); + } + const span = document.createElement('span'); + span.className = 'hextra-search-match'; + span.textContent = match[0]; + container.appendChild(span); + lastIndex = match.index + match[0].length; + } + if (lastIndex < text.length) { + container.appendChild(document.createTextNode(text.slice(lastIndex))); + } + } + + function createBreadcrumbSeparator() { + const svg = document.createElementNS('http://www.w3.org/2000/svg', 'svg'); + svg.classList.add('hextra-search-crumb-separator'); + svg.setAttribute('viewBox', '0 0 24 24'); + svg.setAttribute('fill', 'none'); + svg.setAttribute('stroke', 'currentColor'); + svg.setAttribute('stroke-width', '2'); + svg.setAttribute('stroke-linecap', 'round'); + svg.setAttribute('stroke-linejoin', 'round'); + svg.setAttribute('aria-hidden', 'true'); + svg.setAttribute('focusable', 'false'); + + const path = document.createElementNS('http://www.w3.org/2000/svg', 'path'); + path.setAttribute('d', 'm9 18 6-6-6-6'); + svg.appendChild(path); + return svg; + } + + function appendBreadcrumb(container, parts) { + for (let i = 0; i < parts.length; i++) { + if (i > 0) container.appendChild(createBreadcrumbSeparator()); + + const part = document.createElement('span'); + part.textContent = parts[i]; + container.appendChild(part); + } + } + + function renderResults(results, query) { + cancelCollapse(); + clearResults(); + if (innerEl) innerEl.scrollTop = 0; + + if (!results.length) { + if (emptyEl) emptyEl.hidden = false; + if (statusEl) statusEl.textContent = noResultsText; + setActiveDescendant(); + setViewportExpanded(true); + return; + } + + if (emptyEl) emptyEl.hidden = true; + + const fragment = document.createDocumentFragment(); + let isFirstOption = true; + let optionCount = 0; + for (let i = 0; i < results.length; i++) { + const result = results[i]; + + const li = document.createElement('li'); + li.setAttribute('role', 'presentation'); + + const link = document.createElement('a'); + link.id = result.id; + link.href = result.route; + link.setAttribute('role', 'option'); + link.setAttribute('aria-selected', isFirstOption ? 'true' : 'false'); + isFirstOption = false; + optionCount++; + + if (result.breadcrumbs && result.breadcrumbs.length) { + const crumb = document.createElement('div'); + crumb.className = 'hextra-search-crumb'; + crumb.setAttribute('aria-label', result.breadcrumbs.join(' > ')); + appendBreadcrumb(crumb, result.breadcrumbs); + link.appendChild(crumb); + } + + const title = document.createElement('div'); + title.className = 'hextra-search-title'; + appendHighlightedText(title, result.title, query); + link.appendChild(title); + + li.appendChild(link); + fragment.appendChild(li); + + for (let j = 0; j < result.matches.length; j++) { + const match = result.matches[j]; + const hasExcerpt = match.content && match.content !== match.title; + if (match.title === result.title && !hasExcerpt) continue; + + const excerptLi = document.createElement('li'); + excerptLi.setAttribute('role', 'presentation'); + excerptLi.classList.add('hextra-search-child'); + + const excerptLink = document.createElement('a'); + excerptLink.id = match.id; + excerptLink.href = match.route; + excerptLink.setAttribute('role', 'option'); + excerptLink.setAttribute('aria-selected', isFirstOption ? 'true' : 'false'); + isFirstOption = false; + optionCount++; + + const label = hasExcerpt ? `${match.title} - ${match.content}` : match.title; + if (label) excerptLink.setAttribute('aria-label', label); + + if (match.title && match.title !== result.title) { + const title = document.createElement('div'); + title.className = 'hextra-search-title'; + appendHighlightedText(title, match.title, query); + excerptLink.appendChild(title); + } + + if (hasExcerpt) { + const excerpt = document.createElement('div'); + excerpt.className = 'hextra-search-excerpt'; + appendHighlightedText(excerpt, match.content, query); + excerptLink.appendChild(excerpt); + } + + excerptLi.appendChild(excerptLink); + fragment.appendChild(excerptLi); + } + } + resultsEl.appendChild(fragment); + + const firstOption = resultsEl.querySelector('a[role="option"]'); + setActiveDescendant(firstOption && firstOption.id); + + if (statusEl) { + statusEl.textContent = resultsFoundTemplate.replace('%d', optionCount.toString()); + } + + setViewportExpanded(true); + } +})(); diff --git a/en.search-dialog.min.fda123910557b5b3a328696105af51f85abc3cfc6784387c49b11b5b857b256f.js b/en.search-dialog.min.fda123910557b5b3a328696105af51f85abc3cfc6784387c49b11b5b857b256f.js new file mode 100644 index 0000000..96ed92c --- /dev/null +++ b/en.search-dialog.min.fda123910557b5b3a328696105af51f85abc3cfc6784387c49b11b5b857b256f.js @@ -0,0 +1 @@ +(function(){const S="%d results found",k="No results found.",C=["INPUT","SELECT","BUTTON","TEXTAREA"],A=/iPad|iPhone|Macintosh/.test(navigator.userAgent);let e,t,n,i,a,h,g,s=null,o=null,l=null;document.addEventListener("DOMContentLoaded",T);function T(){if(e=document.getElementById("hextra-search-dialog"),!e)return;t=e.querySelector(".hextra-search-input"),n=e.querySelector(".hextra-search-results"),i=e.querySelector("[data-search-empty]"),a=e.querySelector(".hextra-search-status"),h=e.querySelector("[data-search-viewport]"),g=e.querySelector("[data-search-inner]"),A&&document.querySelectorAll(".hextra-search-trigger-kbd").forEach(e=>{for(;e.firstChild;)e.removeChild(e.firstChild);const t=document.createElement("span");t.style.fontSize="0.75rem",t.textContent="⌘",e.appendChild(t),e.appendChild(document.createTextNode("K"))}),document.querySelectorAll("[data-search-open]").forEach(e=>{e.addEventListener("click",()=>b())});const s=e.querySelector("[data-search-close]");s&&s.addEventListener("click",()=>r()),document.addEventListener("keydown",E),t.addEventListener("input",F),e.addEventListener("keydown",x),e.addEventListener("click",t=>{t.target===e&&r()}),e.addEventListener("close",()=>{t.setAttribute("aria-expanded","false")}),e.addEventListener("cancel",e=>{e.preventDefault(),r()}),n.addEventListener("click",e=>{const t=e.target.closest('a[role="option"]');t&&r()}),n.addEventListener("mousemove",e=>{const t=e.target.closest('a[role="option"]');t&&d(t,{scroll:!1})}),n.addEventListener("focusin",e=>{const t=e.target.closest('a[role="option"]');t&&d(t,{scroll:!1})})}function O(e){const t=e&&e.tagName;return!!e&&(C.includes(t)||e.isContentEditable)}function c(e){e?t.setAttribute("aria-activedescendant",e):t.removeAttribute("aria-activedescendant")}function E(t){const n=O(document.activeElement);if(t.key==="k"&&(t.metaKey||t.ctrlKey)){if(n)return;t.preventDefault();const s=e.dataset.state==="closing";e.open&&!s?r():b();return}if(e.open)return;if(t.key==="/"){if(n)return;t.preventDefault(),b()}}function b(){if(e.open&&e.dataset.state==="closing"){M(),t.focus(),t.select();return}if(e.open)return;e.showModal(),t.setAttribute("aria-expanded","true"),requestAnimationFrame(()=>{t.focus(),t.select()}),window.hextraSearch&&window.hextraSearch.preload().catch(()=>{})}function M(){s&&(e.removeEventListener("animationend",s),s=null),o!==null&&(clearTimeout(o),o=null),delete e.dataset.state}function r(){if(!e.open||e.dataset.state==="closing")return;v();const n=window.matchMedia("(prefers-reduced-motion: reduce)").matches;if(n){e.close();return}e.dataset.state="closing";const t=()=>{o!==null&&(clearTimeout(o),o=null),s&&(e.removeEventListener("animationend",s),s=null),e.dataset.state==="closing"&&(delete e.dataset.state,e.close())};s=e=>{if(e.animationName!=="hextra-search-backdrop-out")return;t()},e.addEventListener("animationend",s),o=setTimeout(t,400)}function m(e){if(!h)return;h.dataset.expanded=e?"true":"false"}function v(){l!==null&&(clearTimeout(l),l=null)}function j(){for(;n.firstChild;)n.removeChild(n.firstChild)}function x(e){const n=e.target.closest('a[role="option"]'),o=e.target===t;if(!o&&!n)return;if(o&&(e.isComposing||e.keyCode===229))return;const s=!!n;switch(e.key){case"ArrowDown":e.preventDefault(),_(1,{current:n,focus:s});break;case"ArrowUp":e.preventDefault(),_(-1,{current:n,focus:s});break;case"Home":{const t=u();if(!t.length)return;e.preventDefault(),p(t[0],{focus:s});break}case"End":{const t=u();if(!t.length)return;e.preventDefault(),p(t[t.length-1],{focus:s});break}case"Enter":{if(!o)return;const t=y();if(!t)return;e.preventDefault(),t.click();break}case"Escape":e.preventDefault(),r();break}}function u(){return Array.from(n.querySelectorAll('a[role="option"]'))}function y(){return n.querySelector('a[aria-selected="true"]')}function d(e,t){const n=!t||t.scroll!==!1;u().forEach(t=>{t.setAttribute("aria-selected",t===e?"true":"false")}),e?(c(e.id),n&&e.scrollIntoView({block:"nearest"})):c()}function w(e){d(e,{scroll:!1}),e.focus({preventScroll:!0}),e.scrollIntoView({block:"nearest"})}function p(e,t){t&&t.focus?w(e):d(e)}function _(e,t){const n=u();if(!n.length)return;const o=t&&t.current||y();let s=n.indexOf(o);s===-1?s=e>0?0:n.length-1:s=(s+e+n.length)%n.length,p(n[s],t)}async function F(e){if(e&&e.isComposing)return;const n=t.value.trim();if(!n){c(),a&&(a.textContent=""),m(!1),v(),l=setTimeout(()=>{l=null,j(),i&&(i.hidden=!0)},250);return}if(!window.hextraSearch)return;let s;try{s=await window.hextraSearch.search(n)}catch(e){if(t.value.trim()!==n)return;console.warn("[hextra-search]",e),s=[]}if(t.value.trim()!==n)return;N(s,n)}function f(e,t,n){if(!t)return;if(!n){e.textContent=t;return}const i=n.replace(/[-\\^$*+?.()|[\]{}]/g,"\\$&");if(!i){e.textContent=t;return}const a=new RegExp(i,"gi");let o=0,s;for(;(s=a.exec(t))!==null;){s.index>o&&e.appendChild(document.createTextNode(t.slice(o,s.index)));const n=document.createElement("span");n.className="hextra-search-match",n.textContent=s[0],e.appendChild(n),o=s.index+s[0].length}o0&&e.appendChild(z());const s=document.createElement("span");s.textContent=t[n],e.appendChild(s)}}function N(e,t){if(v(),j(),g&&(g.scrollTop=0),!e.length){i&&(i.hidden=!1),a&&(a.textContent=k),c(),m(!0);return}i&&(i.hidden=!0);const o=document.createDocumentFragment();let s=!0,r=0;for(let a=0;a ")),D(e,n.breadcrumbs),i.appendChild(e)}const l=document.createElement("div");l.className="hextra-search-title",f(l,n.title,t),i.appendChild(l),c.appendChild(i),o.appendChild(c);for(let c=0;c} A promise that resolves when the index is preloaded. + */ + function preloadIndex() { + if (indexPromise) return indexPromise; + const attempt = (async () => { + const tokenize = 'forward'; + + // https://github.com/TryGhost/Ghost/pull/21148 + const regex = new RegExp( + `[\u{4E00}-\u{9FFF}\u{3040}-\u{309F}\u{30A0}-\u{30FF}\u{AC00}-\u{D7A3}\u{3400}-\u{4DBF}\u{20000}-\u{2A6DF}\u{2A700}-\u{2B73F}\u{2B740}-\u{2B81F}\u{2B820}-\u{2CEAF}\u{2CEB0}-\u{2EBEF}\u{30000}-\u{3134F}\u{31350}-\u{323AF}\u{2EBF0}-\u{2EE5F}\u{F900}-\u{FAFF}\u{2F800}-\u{2FA1F}]|[0-9A-Za-zа-яÀ-ſЀ-ӿ؀-ۿঀ-৿Ḁ-ỿ֐-׿]+`, + 'mug' + ); + const encode = (str) => { return ('' + str).toLowerCase().match(regex) ?? []; } + + pageIndex = new FlexSearch.Document({ + tokenize, + encode, + cache: 100, + document: { + id: 'id', + store: ['title', 'breadcrumbs'], + index: "content" + } + }); + + sectionIndex = new FlexSearch.Document({ + tokenize, + encode, + cache: 100, + document: { + id: 'id', + store: ['title', 'content', 'url', 'display', 'crumb'], + index: "content", + tag: [{ + field: "pageId" + }] + } + }); + + const resp = await fetch(searchDataURL); + const data = await resp.json(); + let pageId = 0; + for (const route in data) { + let pageContent = ''; + ++pageId; + const urlParts = route.split('/').filter(x => x !== "" && !x.startsWith('#')); + + let crumb = ''; + const crumbParts = []; + let searchUrl = '/'; + for (let i = 0; i < urlParts.length; i++) { + const urlPart = urlParts[i]; + searchUrl += urlPart + '/' + + const crumbData = data[searchUrl]; + if (!crumbData) { + console.debug('Excluded page', searchUrl, '- will not be included for search result breadcrumb for', route); + continue; + } + + let title = data[searchUrl].title; + if (title === "_index") { + title = urlPart.split("-").map(x => x).join(" "); + } + crumbParts.push(title); + crumb += title; + + if (i < urlParts.length - 1) { + crumb += ' > '; + } + } + + for (const heading in data[route].data) { + const separator = heading.indexOf('#'); + const hash = separator === -1 ? heading : heading.slice(0, separator); + const text = separator === -1 ? '' : heading.slice(separator + 1); + const url = hash ? `${route}#${hash}` : route; + const title = text || data[route].title; + + const content = data[route].data[heading] || ''; + const paragraphs = content.split('\n').filter(Boolean); + + sectionIndex.add({ + id: url, + url, + title, + crumb, + pageId: `page_${pageId}`, + content: title, + ...(paragraphs[0] && { display: paragraphs[0] }) + }); + + for (let i = 0; i < paragraphs.length; i++) { + sectionIndex.add({ + id: `${url}_${i}`, + url, + title, + crumb, + pageId: `page_${pageId}`, + content: paragraphs[i] + }); + } + + pageContent += ` ${title} ${content}`; + } + + pageIndex.add({ + id: pageId, + title: data[route].title, + breadcrumbs: crumbParts.slice(0, -1), + content: pageContent + }); + } + })(); + // Clear the cached promise on failure so the next call retries instead of + // returning the rejection forever. + const wrapped = attempt.catch((err) => { + if (indexPromise === wrapped) indexPromise = null; + pageIndex = undefined; + sectionIndex = undefined; + throw err; + }); + indexPromise = wrapped; + return indexPromise; + } + + /** + * Run the actual FlexSearch query and return sorted, deduped page groups. + * @param {string} query + * @returns {Array<{id: string, route: string, title: string, breadcrumbs: string[], matches: Array<{id: string, route: string, title: string, content: string}>}>} + */ + function performSearch(query) { + const maxPageResults = parseInt('20', 10); + const maxSectionResults = parseInt('10', 10); + const pageResults = pageIndex.search(query, maxPageResults, { enrich: true, suggest: true })[0]?.result || []; + + const groups = []; + const pageTitleMatches = {}; + + for (let i = 0; i < pageResults.length; i++) { + const result = pageResults[i]; + pageTitleMatches[i] = 0; + + const sectionResults = sectionIndex.search(query, + { enrich: true, suggest: true, tag: { 'pageId': `page_${result.id}` } })[0]?.result || []; + const occurred = {}; + const group = { + _page_rk: i, + route: '', + title: result.doc.title, + breadcrumbs: result.doc.breadcrumbs || [], + matches: [] + }; + + const nResults = Math.min(sectionResults.length, maxSectionResults); + for (let j = 0; j < nResults; j++) { + const { doc } = sectionResults[j]; + const isMatchingTitle = doc.display !== undefined; + if (isMatchingTitle) { + pageTitleMatches[i]++; + } + const { url, title } = doc; + const content = doc.display || doc.content; + + if (occurred[url + '@' + content]) continue; + occurred[url + '@' + content] = true; + if (!group.route) group.route = url.split('#')[0]; + group.matches.push({ + route: url, + title, + content + }); + } + + if (group.matches.length) groups.push(group); + } + + let optionId = 0; + return groups + .sort((a, b) => { + if (pageTitleMatches[a._page_rk] !== pageTitleMatches[b._page_rk]) { + return pageTitleMatches[b._page_rk] - pageTitleMatches[a._page_rk]; + } + return a._page_rk - b._page_rk; + }) + .map((res) => ({ + id: `hextra-search-opt-${optionId++}`, + route: res.route, + title: res.title, + breadcrumbs: res.breadcrumbs, + matches: res.matches.map((match) => ({ + id: `hextra-search-opt-${optionId++}`, + route: match.route, + title: match.title, + content: match.content + })) + })); + } + + window.hextraSearch = { + preload: preloadIndex, + async search(query) { + await preloadIndex(); + return performSearch(query); + }, + }; +})(); diff --git a/en.search.min.6d39eea7d5f460265013dcf9314a599356de1552b08716d5c057206ea51e87e2.js b/en.search.min.6d39eea7d5f460265013dcf9314a599356de1552b08716d5c057206ea51e87e2.js new file mode 100644 index 0000000..1605bb1 --- /dev/null +++ b/en.search.min.6d39eea7d5f460265013dcf9314a599356de1552b08716d5c057206ea51e87e2.js @@ -0,0 +1,2 @@ +(function(){const o="/en.search-data.min.7c084e10d80d8432dcd879abe2a210ab0538068d9abdf0762cec3b1655109268.json";let n,t,e=null;function s(){if(e)return e;const i=(async()=>{const i="forward",r=new RegExp(`[一-鿿぀-ゟ゠-ヿ가-힣㐀-䶿𠀀-𪛟𪜀-𫜿𫝀-𫠟𫠠-𬺯𬺰-𮯯𰀀-𱍏𱍐-𲎯𮯰-𮹟豈-﫿丽-𯨟]|[0-9A-Za-zа-яÀ-ſЀ-ӿ؀-ۿঀ-৿Ḁ-ỿ֐-׿]+`,"mug"),a=e=>(""+e).toLowerCase().match(r)??[];n=new FlexSearch.Document({tokenize:i,encode:a,cache:100,document:{id:"id",store:["title","breadcrumbs"],index:"content"}}),t=new FlexSearch.Document({tokenize:i,encode:a,cache:100,document:{id:"id",store:["title","content","url","display","crumb"],index:"content",tag:[{field:"pageId"}]}});const c=await fetch(o),e=await c.json();let s=0;for(const o in e){let c="";++s;const r=o.split("/").filter(e=>e!==""&&!e.startsWith("#"));let i="";const l=[];let a="/";for(let t=0;te).join(" ")),l.push(n),i+=n,t ")}for(const n in e[o].data){const a=n.indexOf("#"),u=a===-1?n:n.slice(0,a),m=a===-1?"":n.slice(a+1),r=u?`${o}#${u}`:o,l=m||e[o].title,h=e[o].data[n]||"",d=h.split(` +`).filter(Boolean);t.add({id:r,url:r,title:l,crumb:i,pageId:`page_${s}`,content:l,...d[0]&&{display:d[0]}});for(let e=0;e{throw e===s&&(e=null),n=0[0],t=0[0],o});return e=s,e}function i(e){const r=parseInt("20",10),c=parseInt("10",10),o=n.search(e,r,{enrich:!0,suggest:!0})[0]?.result||[],i=[],s={};for(let n=0;ns[e._page_rk]!==s[t._page_rk]?s[t._page_rk]-s[e._page_rk]:e._page_rk-t._page_rk).map(e=>({id:`hextra-search-opt-${a++}`,route:e.route,title:e.title,breadcrumbs:e.breadcrumbs,matches:e.matches.map(e=>({id:`hextra-search-opt-${a++}`,route:e.route,title:e.title,content:e.content}))}))}window.hextraSearch={preload:s,async search(e){return await s(),i(e)}}})() \ No newline at end of file diff --git a/favicon-16x16.png b/favicon-16x16.png new file mode 100644 index 0000000..0f2dd2b Binary files /dev/null and b/favicon-16x16.png differ diff --git a/favicon-32x32.png b/favicon-32x32.png new file mode 100644 index 0000000..5c1aea5 Binary files /dev/null and b/favicon-32x32.png differ diff --git a/favicon-dark.svg b/favicon-dark.svg new file mode 100644 index 0000000..0fb5e92 Binary files /dev/null and b/favicon-dark.svg differ diff --git a/favicon.ico b/favicon.ico new file mode 100644 index 0000000..0fb5e92 Binary files /dev/null and b/favicon.ico differ diff --git a/favicon.svg b/favicon.svg new file mode 100644 index 0000000..0fb5e92 Binary files /dev/null and b/favicon.svg differ diff --git a/images/dfu-mode2.gif b/images/dfu-mode2.gif new file mode 100644 index 0000000..1519b76 Binary files /dev/null and b/images/dfu-mode2.gif differ diff --git a/images/logo-dark.svg b/images/logo-dark.svg new file mode 100644 index 0000000..2857264 --- /dev/null +++ b/images/logo-dark.svg @@ -0,0 +1,3 @@ + + + diff --git a/images/logo.svg b/images/logo.svg new file mode 100644 index 0000000..0fb5e92 Binary files /dev/null and b/images/logo.svg differ diff --git a/images/mcgill9dbi.png b/images/mcgill9dbi.png new file mode 100644 index 0000000..af126cf Binary files /dev/null and b/images/mcgill9dbi.png differ diff --git a/images/otafix_installed.webp b/images/otafix_installed.webp new file mode 100644 index 0000000..58a6e94 Binary files /dev/null and b/images/otafix_installed.webp differ diff --git a/images/sensecap3dbi.png b/images/sensecap3dbi.png new file mode 100644 index 0000000..ebe4a35 Binary files /dev/null and b/images/sensecap3dbi.png differ diff --git a/index.html b/index.html new file mode 100644 index 0000000..2992677 --- /dev/null +++ b/index.html @@ -0,0 +1,511 @@ + + + + + + + + + + +MeshEro + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Skip to content + +
+ + + + + +
+
+ +

Bienvenue sur MeshEro

+
+ +

Bienvenue sur mon site dédié à MeshCore, aux communications maillées LoRa et aux expérimentations autour de ce réseau.

+

Pourquoi ? Quand on m’a parlé «mesh», j’ai commencé mes recherches et je me suis vite rendu compte qu’il existait très peu de ressource en Français. Meme si on en trouve de plus en plus.

+

L’objectif : Partager des guides pratiques, des essais de matériel et des retours d’expérience pour mieux comprendre MeshCore.

+

Lancez-vous en lisant l’introduction à meshcore pour en savoir plus !

+

Explorer le site +

+

Dernières expérimentations +

Retrouvez les tests dans la section matériel

+ + +
+ +
+
+
+ +

+ + + + + + + + + diff --git a/index.xml b/index.xml new file mode 100644 index 0000000..0fefcfe --- /dev/null +++ b/index.xml @@ -0,0 +1,18 @@ + + + MeshEro – Bienvenue sur MeshEro + http://localhost:1313/ + Recent content in Bienvenue sur MeshEro on MeshEro + Hugo -- gohugo.io + fr-fr + Sat, 07 Nov 2026 17:32:10 +0100 + + + + + + + + + + diff --git a/js/flexsearch.433e941a8a573ebb9931fc16fc75266ab6b93f569ac2fb4f3dc66882e0416f4c.js b/js/flexsearch.433e941a8a573ebb9931fc16fc75266ab6b93f569ac2fb4f3dc66882e0416f4c.js new file mode 100644 index 0000000..970b757 --- /dev/null +++ b/js/flexsearch.433e941a8a573ebb9931fc16fc75266ab6b93f569ac2fb4f3dc66882e0416f4c.js @@ -0,0 +1,96 @@ +/**! + * FlexSearch.js v0.8.143 (Bundle) + * Author and Copyright: Thomas Wilkerling + * Licence: Apache-2.0 + * Hosted by Nextapps GmbH + * https://github.com/nextapps-de/flexsearch + */ +(function _f(self){'use strict';if(typeof module!=='undefined')self=module;else if(typeof process !== 'undefined')self=process;self._factory=_f;var t;function z(a,c,b){const e=typeof b,d=typeof a;if("undefined"!==e){if("undefined"!==d){if(b){if("function"===d&&e===d)return function(h){return a(b(h))};c=a.constructor;if(c===b.constructor){if(c===Array)return b.concat(a);if(c===Map){var f=new Map(b);for(var g of a)f.set(g[0],g[1]);return f}if(c===Set){g=new Set(b);for(f of a.values())g.add(f);return g}}}return a}return b}return"undefined"===d?c:a}function B(){return Object.create(null)}function E(a){return"string"===typeof a} +function I(a){return"object"===typeof a}function aa(a){const c=[];for(const b of a.keys())c.push(b);return c}function ba(a,c){if(E(c))a=a[c];else for(let b=0;a&&b"a1a".split(b).length; +this.numeric=z(a.numeric,e)}else{try{this.split=z(this.split,da)}catch(d){this.split=/\s+/}this.numeric=z(a.numeric,z(this.numeric,!0))}this.prepare=z(a.prepare,null,this.prepare);this.finalize=z(a.finalize,null,this.finalize);b=a.filter;this.filter="function"===typeof b?b:z(b&&new Set(b),null,this.filter);this.dedupe=z(a.dedupe,!1,this.dedupe);this.matcher=z((b=a.matcher)&&new Map(b),null,this.matcher);this.mapper=z((b=a.mapper)&&new Map(b),null,this.mapper);this.stemmer=z((b=a.stemmer)&&new Map(b), +null,this.stemmer);this.replacer=z(a.replacer,null,this.replacer);this.minlength=z(a.minlength,1,this.minlength);this.maxlength=z(a.maxlength,0,this.maxlength);this.rtl=z(a.rtl,!1,this.rtl);if(this.cache=b=z(a.cache,!0,this.cache))this.H=null,this.S="number"===typeof b?b:2E5,this.B=new Map,this.G=new Map,this.L=this.K=128;this.h="";this.M=null;this.A="";this.N=null;if(this.matcher)for(const d of this.matcher.keys())this.h+=(this.h?"|":"")+d;if(this.stemmer)for(const d of this.stemmer.keys())this.A+= +(this.A?"|":"")+d;return this};t.addStemmer=function(a,c){this.stemmer||(this.stemmer=new Map);this.stemmer.set(a,c);this.A+=(this.A?"|":"")+a;this.N=null;this.cache&&K(this);return this};t.addFilter=function(a){"function"===typeof a?this.filter=a:(this.filter||(this.filter=new Set),this.filter.add(a));this.cache&&K(this);return this}; +t.addMapper=function(a,c){if("object"===typeof a)return this.addReplacer(a,c);if(1a.length&&(this.dedupe||this.mapper))return this.addMapper(a,c);this.matcher||(this.matcher=new Map);this.matcher.set(a,c);this.h+=(this.h?"|":"")+a;this.M=null;this.cache&&K(this);return this}; +t.addReplacer=function(a,c){if("string"===typeof a)return this.addMatcher(a,c);this.replacer||(this.replacer=[]);this.replacer.push(a,c);this.cache&&K(this);return this}; +t.encode=function(a){if(this.cache&&a.length<=this.K)if(this.H){if(this.B.has(a))return this.B.get(a)}else this.H=setTimeout(K,50,this);this.normalize&&("function"===typeof this.normalize?a=this.normalize(a):a=ia?a.normalize("NFKD").replace(ia,"").toLowerCase():a.toLowerCase());this.prepare&&(a=this.prepare(a));this.numeric&&3this.stemmer.get(k)),d!==g&&this.filter&& +g.length>=this.minlength&&("function"===typeof this.filter?!this.filter(g):this.filter.has(g))&&(g=""));if(g&&(this.mapper||this.dedupe&&1this.matcher.get(k)));if(g&&this.replacer)for(d=0;g&&dthis.S&&(this.G.clear(),this.L=this.L/1.1|0));g&&b.push(g)}this.finalize&&(b=this.finalize(b)||b);this.cache&&a.length<=this.K&&(this.B.set(a,b),this.B.size>this.S&&(this.B.clear(),this.K=this.K/1.1|0));return b};function K(a){a.H=null;a.B.clear();a.G.clear()};let M,ja;async function ka(a){a=a.data;var c=a.task;const b=a.id;let e=a.args;switch(c){case "init":ja=a.options||{};(c=a.factory)?(Function("return "+c)()(self),M=new self.FlexSearch.Index(ja),delete self.FlexSearch):M=new N(ja);postMessage({id:b});break;default:let d;"export"===c&&(e[1]?(e[0]=ja.export,e[2]=0,e[3]=1):e=null);"import"===c?e[0]&&(a=await ja.import.call(M,e[0]),M.import(e[0],a)):(d=e&&M[c].apply(M,e))&&d.then&&(d=await d);postMessage("search"===c?{id:b,msg:d}:{id:b})}};function la(a){ma.call(a,"add");ma.call(a,"append");ma.call(a,"search");ma.call(a,"update");ma.call(a,"remove")}let na,oa,pa;function qa(){na=pa=0} +function ma(a){this[a+"Async"]=function(){const c=arguments;var b=c[c.length-1];let e;"function"===typeof b&&(e=b,delete c[c.length-1]);na?pa||(pa=Date.now()-oa>=this.priority*this.priority*3):(na=setTimeout(qa,0),oa=Date.now());if(pa){const f=this;return new Promise(g=>{setTimeout(function(){g(f[a+"Async"].apply(f,c))},0)})}const d=this[a].apply(this,c);b=d.then?d:new Promise(f=>f(d));e&&b.then(e);return b}};let O=0; +function P(a={}){function c(g){function h(k){k=k.data||k;const l=k.id,n=l&&d.h[l];n&&(n(k.msg),delete d.h[l])}this.worker=g;this.h=B();if(this.worker){e?this.worker.on("message",h):this.worker.onmessage=h;if(a.config)return new Promise(function(k){d.h[++O]=function(){k(d);1E9=g.length)c-=g.length;else{c=g[e?"splice":"slice"](c,b);const h=c.length;if(h&&(d=d.length?d.concat(c):c,b-=h,e&&(a.length-=h),!b))break;c=0}return d} +function R(a){if(!this||this.constructor!==R)return new R(a);this.index=a?[a]:[];this.length=a?a.length:0;const c=this;return new Proxy([],{get(b,e){if("length"===e)return c.length;if("push"===e)return function(d){c.index[c.index.length-1].push(d);c.length++};if("pop"===e)return function(){if(c.length)return c.length--,c.index[c.index.length-1].pop()};if("indexOf"===e)return function(d){let f=0;for(let g=0,h,k;gb||e?k.slice(e,b+e):k;else{if(ab||e)k=k.slice(e,b+e)}else{d=[];for(let m= +0,q;me)e-=q.length;else{if(q.length>b||e)q=q.slice(e,b+e),b-=q.length,e&&(e-=q.length);d.push(q);if(!b)break}k=1c?c?a.slice(b,b+c):a.slice(b):a,e?V.call(this,a):a;let d=[];for(let f=0,g,h;f=h){b-=h;continue}bc&&(g=g.slice(0,c),h=c);if(!d.length&&h>=c)return e?V.call(this,g):g;d.push(g);c-=h;if(!c)break}d=1a.length?this.result=a[0]:(this.result=Ga(a,b,e,!1,this.h),e=0));return f?this.resolve(b,e,d):this};W.prototype.and=function(){let a=this.result.length,c,b,e,d;if(!a){const f=arguments[0];f&&(a=!!f.suggest,d=f.resolve,c=f.limit,b=f.offset,e=f.enrich&&d)}if(a){const {O:f,P:g,limit:h,offset:k,enrich:l,resolve:n,suggest:m}=Ja(this,"and",arguments);return La.call(this,f,g,h,k,l,n,m)}return d?this.resolve(c,b,e):this}; +function La(a,c,b,e,d,f,g){if(c.length){const h=this;return Promise.all(c).then(function(k){a=[];for(let l=0,n;la.length)this.result=a[0];else{if(c=ca(a))return this.result=Fa(a,c,b,e,g,this.h,f),f?d?V.call(this.index,this.result):this.result:this;this.result=[]}else g||(this.result=a);return f?this.resolve(b,e,d):this};W.prototype.xor=function(){const {O:a,P:c,limit:b,offset:e,enrich:d,resolve:f,suggest:g}=Ja(this,"xor",arguments);return Ma.call(this,a,c,b,e,d,f,g)}; +function Ma(a,c,b,e,d,f,g){if(c.length){const h=this;return Promise.all(c).then(function(k){a=[];for(let l=0,n;la.length)this.result=a[0];else return this.result=Na.call(this,a,b,e,f,this.h),f?d?V.call(this.index,this.result):this.result:this;else g||(this.result=a);return f?this.resolve(b,e,d):this} +function Na(a,c,b,e,d){const f=[],g=B();let h=0;for(let k=0,l;kb||e)a=a.slice(e,e+b);d&&(a=V.call(this,a));return a}}function V(a){if(!this||!this.store)return a;const c=Array(a.length);for(let b=0,e;bthis.limit&&this.cache.delete(this.cache.keys().next().value)}; +X.prototype.get=function(a){const c=this.cache.get(a);c&&this.h!==a&&(this.cache.delete(a),this.cache.set(this.h=a,c));return c};X.prototype.remove=function(a){for(const c of this.cache){const b=c[0];c[1].includes(a)&&this.cache.delete(b)}};X.prototype.clear=function(){this.cache.clear();this.h=""};const Wa={normalize:!1,numeric:!1,split:/\s+/};const Xa={normalize:!0};const Ya={normalize:!0,dedupe:!0};const Za=new Map([["b","p"],["v","f"],["w","f"],["z","s"],["x","s"],["d","t"],["n","m"],["c","k"],["g","k"],["j","k"],["q","k"],["i","e"],["y","e"],["u","o"]]);const $a=new Map([["ae","a"],["oe","o"],["sh","s"],["kh","k"],["th","t"],["ph","f"],["pf","f"]]),ab=[/([^aeo])h(.)/g,"$1$2",/([aeo])h([^aeo]|$)/g,"$1$2",/(.)\1+/g,"$1"];const bb={a:"",e:"",i:"",o:"",u:"",y:"",b:1,f:1,p:1,v:1,c:2,g:2,j:2,k:2,q:2,s:2,x:2,z:2,"\u00df":2,d:3,t:3,l:4,m:5,n:5,r:6};var cb={X:Wa,W:Xa,Y:Ya,LatinBalance:{normalize:!0,dedupe:!0,mapper:Za},LatinAdvanced:{normalize:!0,dedupe:!0,mapper:Za,matcher:$a,replacer:ab},LatinExtra:{normalize:!0,dedupe:!0,mapper:Za,replacer:ab.concat([/(?!^)[aeo]/g,""]),matcher:$a},LatinSoundex:{normalize:!0,dedupe:!1,include:{letter:!0},finalize:function(a){for(let b=0;bu;f--){g=r.substring(u,f);v=this.rtl?d-1-u:u;var h=this.score?this.score(c,r,p,g,v):eb(q,e,p,d,v); +fb(this,n,g,h,a,b)}break}case "bidirectional":case "reverse":if(1g?0:1), +e,p,h-1,k-1),v=this.bidirectional&&r>f;fb(this,l,v?f:r,u,a,b,v?r:f)}}}}this.fastupdate||this.reg.add(a)}else c=""}this.db&&(c||this.commit_task.push({del:a}),this.T&&gb(this));return this}; +function fb(a,c,b,e,d,f,g){let h=g?a.ctx:a.map,k;if(!c[b]||g&&!(k=c[b])[g])if(g?(c=k||(c[b]=B()),c[g]=1,(k=h.get(g))?h=k:h.set(g,h=new Map)):c[b]=1,(k=h.get(b))?h=k:h.set(b,h=k=[]),h=h[e]||(h[e]=[]),!f||!h.includes(d)){if(h.length===2**31-1){c=new R(h);if(a.fastupdate)for(let l of a.reg.values())l.includes(h)&&(l[l.indexOf(h)]=c);k[e]=h=c}h.push(d);a.fastupdate&&((e=a.reg.get(d))?e.push(h):a.reg.set(d,[h]))}} +function eb(a,c,b,e,d){return b&&1b)&&(k=b,b=c,c=k);if(a.db)return a.db.get(c,b,e,d,f,g,h);a=b?(a=a.ctx.get(b))&&a.get(c):a.map.get(c);return a};N.prototype.remove=function(a,c){const b=this.reg.size&&(this.fastupdate?this.reg.get(a):this.reg.has(a));if(b){if(this.fastupdate)for(let e=0,d;ed.length)d.pop();else{const f=d.indexOf(a);f===b.length-1?d.pop():d.splice(f,1)}}else lb(this.map,a),this.depth&&lb(this.ctx,a);c||this.reg.delete(a)}this.db&&(this.commit_task.push({del:a}),this.T&&gb(this));this.cache&&this.cache.remove(a);return this}; +function lb(a,c){let b=0;if(a.constructor===Array)for(let e=0,d,f;eb.add(a,c)):this.add(a,c)}; +function mb(a){let c=0;if(a.constructor===Array)for(let b=0,e;b=n.length){e-=n.length;continue}const m=b?e+Math.min(n.length-e,b):n.length;for(let q=e;q=f.length)return[];if(!c&&!b)return f;f=f.slice(b,b+c);return e?d.enrich(f):f})}; +t.enrich=function(a){"object"!==typeof a&&(a=[a]);const c=this.db.transaction("reg","readonly").objectStore("reg"),b=[];for(let e=0;e{a.onsuccess=a.oncomplete=function(){c&&c(this.result);c=null;b(this.result)};a.onerror=a.onblocked=e;a=null})};const rb={Index:N,Charset:cb,Encoder:J,Document:U,Worker:P,Resolver:W,IndexedDB:pb,Language:{}},tb="undefined"!==typeof self?self:"undefined"!==typeof global?global:self;let ub;(ub=tb.define)&&ub.amd?ub([],function(){return rb}):"object"===typeof tb.exports?tb.exports=rb:tb.FlexSearch=rb;}(this||self)); diff --git a/js/flexsearch.9f5b5908f93ae86f1ecd4b043b799f580c2d1654e703dd9357d568ac41b2547a.js b/js/flexsearch.9f5b5908f93ae86f1ecd4b043b799f580c2d1654e703dd9357d568ac41b2547a.js new file mode 100644 index 0000000..82ae0dd --- /dev/null +++ b/js/flexsearch.9f5b5908f93ae86f1ecd4b043b799f580c2d1654e703dd9357d568ac41b2547a.js @@ -0,0 +1,2525 @@ +/**! + * FlexSearch.js v0.8.143 (Bundle/Debug) + * Author and Copyright: Thomas Wilkerling + * Licence: Apache-2.0 + * Hosted by Nextapps GmbH + * https://github.com/nextapps-de/flexsearch + */ +(function _f(self){'use strict';if(typeof module!=='undefined')self=module;else if(typeof process !== 'undefined')self=process;self._factory=_f; +var t; +function z(a, c, b) { + const e = typeof b, d = typeof a; + if ("undefined" !== e) { + if ("undefined" !== d) { + if (b) { + if ("function" === d && e === d) { + return function(k) { + return a(b(k)); + }; + } + c = a.constructor; + if (c === b.constructor) { + if (c === Array) { + return b.concat(a); + } + if (c === Map) { + var f = new Map(b); + for (var g of a) { + f.set(g[0], g[1]); + } + return f; + } + if (c === Set) { + g = new Set(b); + for (f of a.values()) { + g.add(f); + } + return g; + } + } + } + return a; + } + return b; + } + return "undefined" === d ? c : a; +} +function B() { + return Object.create(null); +} +function E(a) { + return "string" === typeof a; +} +function I(a) { + return "object" === typeof a; +} +function aa(a) { + const c = []; + for (const b of a.keys()) { + c.push(b); + } + return c; +} +function ba(a, c) { + if (E(c)) { + a = a[c]; + } else { + for (let b = 0; a && b < c.length; b++) { + a = a[c[b]]; + } + } + return a; +} +function ca(a) { + let c = 0; + for (let b = 0, e; b < a.length; b++) { + (e = a[b]) && c < e.length && (c = e.length); + } + return c; +} +;const da = /[^\p{L}\p{N}]+/u, ea = /(\d{3})/g, fa = /(\D)(\d{3})/g, ha = /(\d{3})(\D)/g, ia = /[\u0300-\u036f]/g; +function ja(a = {}) { + if (!this || this.constructor !== ja) { + return new ja(...arguments); + } + if (arguments.length) { + for (a = 0; a < arguments.length; a++) { + this.assign(arguments[a]); + } + } else { + this.assign(a); + } +} +t = ja.prototype; +t.assign = function(a) { + this.normalize = z(a.normalize, !0, this.normalize); + let c = a.include, b = c || a.exclude || a.split, e; + if (b || "" === b) { + if ("object" === typeof b && b.constructor !== RegExp) { + let d = ""; + e = !c; + c || (d += "\\p{Z}"); + b.letter && (d += "\\p{L}"); + b.number && (d += "\\p{N}", e = !!c); + b.symbol && (d += "\\p{S}"); + b.punctuation && (d += "\\p{P}"); + b.control && (d += "\\p{C}"); + if (b = b.char) { + d += "object" === typeof b ? b.join("") : b; + } + try { + this.split = new RegExp("[" + (c ? "^" : "") + d + "]+", "u"); + } catch (f) { + console.error("Your split configuration:", b, "is not supported on this platform. It falls back to using simple whitespace splitter instead: /s+/."), this.split = /\s+/; + } + } else { + this.split = b, e = !1 === b || 2 > "a1a".split(b).length; + } + this.numeric = z(a.numeric, e); + } else { + try { + this.split = z(this.split, da); + } catch (d) { + console.warn("This platform does not support unicode regex. It falls back to using simple whitespace splitter instead: /s+/."), this.split = /\s+/; + } + this.numeric = z(a.numeric, z(this.numeric, !0)); + } + this.prepare = z(a.prepare, null, this.prepare); + this.finalize = z(a.finalize, null, this.finalize); + b = a.filter; + this.filter = "function" === typeof b ? b : z(b && new Set(b), null, this.filter); + this.dedupe = z(a.dedupe, !1, this.dedupe); + this.matcher = z((b = a.matcher) && new Map(b), null, this.matcher); + this.mapper = z((b = a.mapper) && new Map(b), null, this.mapper); + this.stemmer = z((b = a.stemmer) && new Map(b), null, this.stemmer); + this.replacer = z(a.replacer, null, this.replacer); + this.minlength = z(a.minlength, 1, this.minlength); + this.maxlength = z(a.maxlength, 0, this.maxlength); + this.rtl = z(a.rtl, !1, this.rtl); + if (this.cache = b = z(a.cache, !0, this.cache)) { + this.H = null, this.S = "number" === typeof b ? b : 2e5, this.B = new Map(), this.G = new Map(), this.L = this.K = 128; + } + this.h = ""; + this.M = null; + this.A = ""; + this.N = null; + if (this.matcher) { + for (const d of this.matcher.keys()) { + this.h += (this.h ? "|" : "") + d; + } + } + if (this.stemmer) { + for (const d of this.stemmer.keys()) { + this.A += (this.A ? "|" : "") + d; + } + } + return this; +}; +t.addStemmer = function(a, c) { + this.stemmer || (this.stemmer = new Map()); + this.stemmer.set(a, c); + this.A += (this.A ? "|" : "") + a; + this.N = null; + this.cache && J(this); + return this; +}; +t.addFilter = function(a) { + "function" === typeof a ? this.filter = a : (this.filter || (this.filter = new Set()), this.filter.add(a)); + this.cache && J(this); + return this; +}; +t.addMapper = function(a, c) { + if ("object" === typeof a) { + return this.addReplacer(a, c); + } + if (1 < a.length) { + return this.addMatcher(a, c); + } + this.mapper || (this.mapper = new Map()); + this.mapper.set(a, c); + this.cache && J(this); + return this; +}; +t.addMatcher = function(a, c) { + if ("object" === typeof a) { + return this.addReplacer(a, c); + } + if (2 > a.length && (this.dedupe || this.mapper)) { + return this.addMapper(a, c); + } + this.matcher || (this.matcher = new Map()); + this.matcher.set(a, c); + this.h += (this.h ? "|" : "") + a; + this.M = null; + this.cache && J(this); + return this; +}; +t.addReplacer = function(a, c) { + if ("string" === typeof a) { + return this.addMatcher(a, c); + } + this.replacer || (this.replacer = []); + this.replacer.push(a, c); + this.cache && J(this); + return this; +}; +t.encode = function(a) { + if (this.cache && a.length <= this.K) { + if (this.H) { + if (this.B.has(a)) { + return this.B.get(a); + } + } else { + this.H = setTimeout(J, 50, this); + } + } + this.normalize && ("function" === typeof this.normalize ? a = this.normalize(a) : a = ia ? a.normalize("NFKD").replace(ia, "").toLowerCase() : a.toLowerCase()); + this.prepare && (a = this.prepare(a)); + this.numeric && 3 < a.length && (a = a.replace(fa, "$1 $2").replace(ha, "$1 $2").replace(ea, "$1 ")); + const c = !(this.dedupe || this.mapper || this.filter || this.matcher || this.stemmer || this.replacer); + let b = [], e = this.split || "" === this.split ? a.split(this.split) : a; + for (let f = 0, g, k; f < e.length; f++) { + if ((g = k = e[f]) && !(g.length < this.minlength)) { + if (c) { + b.push(g); + } else { + if (!this.filter || ("function" === typeof this.filter ? this.filter(g) : !this.filter.has(g))) { + if (this.cache && g.length <= this.L) { + if (this.H) { + var d = this.G.get(g); + if (d || "" === d) { + d && b.push(d); + continue; + } + } else { + this.H = setTimeout(J, 50, this); + } + } + this.stemmer && 2 < g.length && (this.N || (this.N = new RegExp("(?!^)(" + this.A + ")$")), d = g, g = g.replace(this.N, h => this.stemmer.get(h)), d !== g && this.filter && g.length >= this.minlength && ("function" === typeof this.filter ? !this.filter(g) : this.filter.has(g)) && (g = "")); + if (g && (this.mapper || this.dedupe && 1 < g.length)) { + d = ""; + for (let h = 0, l = "", n, m; h < g.length; h++) { + n = g.charAt(h), n === l && this.dedupe || ((m = this.mapper && this.mapper.get(n)) || "" === m ? m === l && this.dedupe || !(l = m) || (d += m) : d += l = n); + } + g = d; + } + this.matcher && 1 < g.length && (this.M || (this.M = new RegExp("(" + this.h + ")", "g")), g = g.replace(this.M, h => this.matcher.get(h))); + if (g && this.replacer) { + for (d = 0; g && d < this.replacer.length; d += 2) { + g = g.replace(this.replacer[d], this.replacer[d + 1]); + } + } + this.cache && k.length <= this.L && (this.G.set(k, g), this.G.size > this.S && (this.G.clear(), this.L = this.L / 1.1 | 0)); + g && b.push(g); + } + } + } + } + this.finalize && (b = this.finalize(b) || b); + this.cache && a.length <= this.K && (this.B.set(a, b), this.B.size > this.S && (this.B.clear(), this.K = this.K / 1.1 | 0)); + return b; +}; +function J(a) { + a.H = null; + a.B.clear(); + a.G.clear(); +} +;let K, M; +async function ka(a) { + a = a.data; + var c = a.task; + const b = a.id; + let e = a.args; + switch(c) { + case "init": + M = a.options || {}; + (c = a.factory) ? (Function("return " + c)()(self), K = new self.FlexSearch.Index(M), delete self.FlexSearch) : K = new N(M); + postMessage({id:b}); + break; + default: + let d; + if ("export" === c) { + if (!M.export || "function" !== typeof M.export) { + throw Error('Either no extern configuration provided for the Worker-Index or no method was defined on the config property "export".'); + } + e[1] ? (e[0] = M.export, e[2] = 0, e[3] = 1) : e = null; + } + if ("import" === c) { + if (!M.import || "function" !== typeof M.import) { + throw Error('Either no extern configuration provided for the Worker-Index or no method was defined on the config property "import".'); + } + e[0] && (a = await M.import.call(K, e[0]), K.import(e[0], a)); + } else { + (d = e && K[c].apply(K, e)) && d.then && (d = await d); + } + postMessage("search" === c ? {id:b, msg:d} : {id:b}); + } +} +;function la(a) { + ma.call(a, "add"); + ma.call(a, "append"); + ma.call(a, "search"); + ma.call(a, "update"); + ma.call(a, "remove"); +} +let na, oa, pa; +function qa() { + na = pa = 0; +} +function ma(a) { + this[a + "Async"] = function() { + const c = arguments; + var b = c[c.length - 1]; + let e; + "function" === typeof b && (e = b, delete c[c.length - 1]); + na ? pa || (pa = Date.now() - oa >= this.priority * this.priority * 3) : (na = setTimeout(qa, 0), oa = Date.now()); + if (pa) { + const f = this; + return new Promise(g => { + setTimeout(function() { + g(f[a + "Async"].apply(f, c)); + }, 0); + }); + } + const d = this[a].apply(this, c); + b = d.then ? d : new Promise(f => f(d)); + e && b.then(e); + return b; + }; +} +;let O = 0; +function P(a = {}) { + function c(g) { + function k(h) { + h = h.data || h; + const l = h.id, n = l && d.h[l]; + n && (n(h.msg), delete d.h[l]); + } + this.worker = g; + this.h = B(); + if (this.worker) { + e ? this.worker.on("message", k) : this.worker.onmessage = k; + if (a.config) { + return new Promise(function(h) { + d.h[++O] = function() { + h(d); + 1e9 < O && (O = 0); + }; + d.worker.postMessage({id:O, task:"init", factory:b, options:a}); + }); + } + this.worker.postMessage({task:"init", factory:b, options:a}); + this.priority = a.priority || 4; + return this; + } + } + if (!this || this.constructor !== P) { + return new P(a); + } + let b = "undefined" !== typeof self ? self._factory : "undefined" !== typeof window ? window._factory : null; + b && (b = b.toString()); + const e = "undefined" === typeof window, d = this, f = ra(b, e, a.worker); + return f.then ? f.then(function(g) { + return c.call(d, g); + }) : c.call(this, f); +} +Q("add"); +Q("append"); +Q("search"); +Q("update"); +Q("remove"); +Q("clear"); +Q("export"); +Q("import"); +la(P.prototype); +function Q(a) { + P.prototype[a] = function() { + const c = this, b = [].slice.call(arguments); + var e = b[b.length - 1]; + let d; + "function" === typeof e && (d = e, b.pop()); + e = new Promise(function(f) { + "export" === a && "function" === typeof b[0] && (b[0] = null); + c.h[++O] = f; + c.worker.postMessage({task:a, id:O, args:b}); + }); + return d ? (e.then(d), this) : e; + }; +} +function ra(a, c, b) { + return c ? "undefined" !== typeof module ? new(require("worker_threads")["Worker"])(__dirname+"/node/node.js") : import("worker_threads").then(function(worker){return new worker["Worker"]((1,eval)("import.meta.dirname")+"/node/node.mjs")}) : a ? new window.Worker(URL.createObjectURL(new Blob(["onmessage=" + ka.toString()], {type:"text/javascript"}))) : new window.Worker("string" === typeof b ? b : (0,eval)("import.meta.url").replace("/worker.js", "/worker/worker.js").replace("flexsearch.bundle.module.min.js", + "module/worker/worker.js"), {type:"module"}); +} +;function sa(a, c = 0) { + let b = [], e = []; + c && (c = 250000 / c * 5000 | 0); + for (const d of a.entries()) { + e.push(d), e.length === c && (b.push(e), e = []); + } + e.length && b.push(e); + return b; +} +function ta(a, c) { + c || (c = new Map()); + for (let b = 0, e; b < a.length; b++) { + e = a[b], c.set(e[0], e[1]); + } + return c; +} +function ua(a, c = 0) { + let b = [], e = []; + c && (c = 250000 / c * 1000 | 0); + for (const d of a.entries()) { + e.push([d[0], sa(d[1])[0]]), e.length === c && (b.push(e), e = []); + } + e.length && b.push(e); + return b; +} +function va(a, c) { + c || (c = new Map()); + for (let b = 0, e, d; b < a.length; b++) { + e = a[b], d = c.get(e[0]), c.set(e[0], ta(e[1], d)); + } + return c; +} +function wa(a) { + let c = [], b = []; + for (const e of a.keys()) { + b.push(e), 250000 === b.length && (c.push(b), b = []); + } + b.length && c.push(b); + return c; +} +function xa(a, c) { + c || (c = new Set()); + for (let b = 0; b < a.length; b++) { + c.add(a[b]); + } + return c; +} +function ya(a, c, b, e, d, f, g = 0) { + const k = e && e.constructor === Array; + var h = k ? e.shift() : e; + if (!h) { + return this.export(a, c, d, f + 1); + } + if ((h = a((c ? c + "." : "") + (g + 1) + "." + b, JSON.stringify(h))) && h.then) { + const l = this; + return h.then(function() { + return ya.call(l, a, c, b, k ? e : null, d, f, g + 1); + }); + } + return ya.call(this, a, c, b, k ? e : null, d, f, g + 1); +} +function za(a, c) { + let b = ""; + for (const e of a.entries()) { + a = e[0]; + const d = e[1]; + let f = ""; + for (let g = 0, k; g < d.length; g++) { + k = d[g] || [""]; + let h = ""; + for (let l = 0; l < k.length; l++) { + h += (h ? "," : "") + ("string" === c ? '"' + k[l] + '"' : k[l]); + } + h = "[" + h + "]"; + f += (f ? "," : "") + h; + } + f = '["' + a + '",[' + f + "]]"; + b += (b ? "," : "") + f; + } + return b; +} +;function Aa(a, c, b, e) { + let d = []; + for (let f = 0, g; f < a.index.length; f++) { + if (g = a.index[f], c >= g.length) { + c -= g.length; + } else { + c = g[e ? "splice" : "slice"](c, b); + const k = c.length; + if (k && (d = d.length ? d.concat(c) : c, b -= k, e && (a.length -= k), !b)) { + break; + } + c = 0; + } + } + return d; +} +function R(a) { + if (!this || this.constructor !== R) { + return new R(a); + } + this.index = a ? [a] : []; + this.length = a ? a.length : 0; + const c = this; + return new Proxy([], {get(b, e) { + if ("length" === e) { + return c.length; + } + if ("push" === e) { + return function(d) { + c.index[c.index.length - 1].push(d); + c.length++; + }; + } + if ("pop" === e) { + return function() { + if (c.length) { + return c.length--, c.index[c.index.length - 1].pop(); + } + }; + } + if ("indexOf" === e) { + return function(d) { + let f = 0; + for (let g = 0, k, h; g < c.index.length; g++) { + k = c.index[g]; + h = k.indexOf(d); + if (0 <= h) { + return f + h; + } + f += k.length; + } + return -1; + }; + } + if ("includes" === e) { + return function(d) { + for (let f = 0; f < c.index.length; f++) { + if (c.index[f].includes(d)) { + return !0; + } + } + return !1; + }; + } + if ("slice" === e) { + return function(d, f) { + return Aa(c, d || 0, f || c.length, !1); + }; + } + if ("splice" === e) { + return function(d, f) { + return Aa(c, d || 0, f || c.length, !0); + }; + } + if ("constructor" === e) { + return Array; + } + if ("symbol" !== typeof e) { + return (b = c.index[e / 2 ** 31 | 0]) && b[e]; + } + }, set(b, e, d) { + b = e / 2 ** 31 | 0; + (c.index[b] || (c.index[b] = []))[e] = d; + c.length++; + return !0; + }}); +} +R.prototype.clear = function() { + this.index.length = 0; +}; +R.prototype.destroy = function() { + this.proxy = this.index = null; +}; +R.prototype.push = function() { +}; +function S(a = 8) { + if (!this || this.constructor !== S) { + return new S(a); + } + this.index = B(); + this.h = []; + this.size = 0; + 32 < a ? (this.B = Ba, this.A = BigInt(a)) : (this.B = Ca, this.A = a); +} +S.prototype.get = function(a) { + const c = this.index[this.B(a)]; + return c && c.get(a); +}; +S.prototype.set = function(a, c) { + var b = this.B(a); + let e = this.index[b]; + e ? (b = e.size, e.set(a, c), (b -= e.size) && this.size++) : (this.index[b] = e = new Map([[a, c]]), this.h.push(e), this.size++); +}; +function T(a = 8) { + if (!this || this.constructor !== T) { + return new T(a); + } + this.index = B(); + this.h = []; + this.size = 0; + 32 < a ? (this.B = Ba, this.A = BigInt(a)) : (this.B = Ca, this.A = a); +} +T.prototype.add = function(a) { + var c = this.B(a); + let b = this.index[c]; + b ? (c = b.size, b.add(a), (c -= b.size) && this.size++) : (this.index[c] = b = new Set([a]), this.h.push(b), this.size++); +}; +t = S.prototype; +t.has = T.prototype.has = function(a) { + const c = this.index[this.B(a)]; + return c && c.has(a); +}; +t.delete = T.prototype.delete = function(a) { + const c = this.index[this.B(a)]; + c && c.delete(a) && this.size--; +}; +t.clear = T.prototype.clear = function() { + this.index = B(); + this.h = []; + this.size = 0; +}; +t.values = T.prototype.values = function*() { + for (let a = 0; a < this.h.length; a++) { + for (let c of this.h[a].values()) { + yield c; + } + } +}; +t.keys = T.prototype.keys = function*() { + for (let a = 0; a < this.h.length; a++) { + for (let c of this.h[a].keys()) { + yield c; + } + } +}; +t.entries = T.prototype.entries = function*() { + for (let a = 0; a < this.h.length; a++) { + for (let c of this.h[a].entries()) { + yield c; + } + } +}; +function Ca(a) { + let c = 2 ** this.A - 1; + if ("number" == typeof a) { + return a & c; + } + let b = 0, e = this.A + 1; + for (let d = 0; d < a.length; d++) { + b = (b * e ^ a.charCodeAt(d)) & c; + } + return 32 === this.A ? b + 2 ** 31 : b; +} +function Ba(a) { + let c = BigInt(2) ** this.A - BigInt(1); + var b = typeof a; + if ("bigint" === b) { + return a & c; + } + if ("number" === b) { + return BigInt(a) & c; + } + b = BigInt(0); + let e = this.A + BigInt(1); + for (let d = 0; d < a.length; d++) { + b = (b * e ^ BigInt(a.charCodeAt(d))) & c; + } + return b; +} +;U.prototype.add = function(a, c, b) { + I(a) && (c = a, a = ba(c, this.key)); + if (c && (a || 0 === a)) { + if (!b && this.reg.has(a)) { + return this.update(a, c); + } + for (let k = 0, h; k < this.field.length; k++) { + h = this.D[k]; + var e = this.index.get(this.field[k]); + if ("function" === typeof h) { + var d = h(c); + d && e.add(a, d, !1, !0); + } else { + if (d = h.I, !d || d(c)) { + h.constructor === String ? h = ["" + h] : E(h) && (h = [h]), Da(c, h, this.J, 0, e, a, h[0], b); + } + } + } + if (this.tag) { + for (e = 0; e < this.F.length; e++) { + var f = this.F[e], g = this.R[e]; + d = this.tag.get(g); + let k = B(); + if ("function" === typeof f) { + if (f = f(c), !f) { + continue; + } + } else { + const h = f.I; + if (h && !h(c)) { + continue; + } + f.constructor === String && (f = "" + f); + f = ba(c, f); + } + if (d && f) { + E(f) && (f = [f]); + for (let h = 0, l, n; h < f.length; h++) { + if (l = f[h], !k[l] && (k[l] = 1, (g = d.get(l)) ? n = g : d.set(l, n = []), !b || !n.includes(a))) { + if (n.length === 2 ** 31 - 1) { + g = new R(n); + if (this.fastupdate) { + for (let m of this.reg.values()) { + m.includes(n) && (m[m.indexOf(n)] = g); + } + } + d.set(l, n = g); + } + n.push(a); + this.fastupdate && ((g = this.reg.get(a)) ? g.push(n) : this.reg.set(a, [n])); + } + } + } else { + d || console.warn("Tag '" + g + "' was not found"); + } + } + } + if (this.store && (!b || !this.store.has(a))) { + let k; + if (this.C) { + k = B(); + for (let h = 0, l; h < this.C.length; h++) { + l = this.C[h]; + if ((b = l.I) && !b(c)) { + continue; + } + let n; + if ("function" === typeof l) { + n = l(c); + if (!n) { + continue; + } + l = [l.V]; + } else if (E(l) || l.constructor === String) { + k[l] = c[l]; + continue; + } + Ea(c, k, l, 0, l[0], n); + } + } + this.store.set(a, k || c); + } + this.worker && (this.fastupdate || this.reg.add(a)); + } + return this; +}; +function Ea(a, c, b, e, d, f) { + a = a[d]; + if (e === b.length - 1) { + c[d] = f || a; + } else if (a) { + if (a.constructor === Array) { + for (c = c[d] = Array(a.length), d = 0; d < a.length; d++) { + Ea(a, c, b, e, d); + } + } else { + c = c[d] || (c[d] = B()), d = b[++e], Ea(a, c, b, e, d); + } + } +} +function Da(a, c, b, e, d, f, g, k) { + if (a = a[g]) { + if (e === c.length - 1) { + if (a.constructor === Array) { + if (b[e]) { + for (c = 0; c < a.length; c++) { + d.add(f, a[c], !0, !0); + } + return; + } + a = a.join(" "); + } + d.add(f, a, k, !0); + } else { + if (a.constructor === Array) { + for (g = 0; g < a.length; g++) { + Da(a, c, b, e, d, f, g, k); + } + } else { + g = c[++e], Da(a, c, b, e, d, f, g, k); + } + } + } else { + d.db && d.remove(f); + } +} +;function Fa(a, c, b, e, d, f, g) { + const k = a.length; + let h = [], l, n; + l = B(); + for (let m = 0, q, p, r, u; m < c; m++) { + for (let v = 0; v < k; v++) { + if (r = a[v], m < r.length && (q = r[m])) { + for (let w = 0; w < q.length; w++) { + p = q[w]; + (n = l[p]) ? l[p]++ : (n = 0, l[p] = 1); + u = h[n] || (h[n] = []); + if (!g) { + let y = m + (v || !d ? 0 : f || 0); + u = u[y] || (u[y] = []); + } + u.push(p); + if (g && b && n === k - 1 && u.length - e === b) { + return u; + } + } + } + } + } + if (a = h.length) { + if (d) { + h = 1 < h.length ? Ga(h, b, e, g, f) : (h = h[0]).length > b || e ? h.slice(e, b + e) : h; + } else { + if (a < k) { + return []; + } + h = h[a - 1]; + if (b || e) { + if (g) { + if (h.length > b || e) { + h = h.slice(e, b + e); + } + } else { + d = []; + for (let m = 0, q; m < h.length; m++) { + if (q = h[m], q.length > e) { + e -= q.length; + } else { + if (q.length > b || e) { + q = q.slice(e, b + e), b -= q.length, e && (e -= q.length); + } + d.push(q); + if (!b) { + break; + } + } + } + h = 1 < d.length ? [].concat.apply([], d) : d[0]; + } + } + } + } + return h; +} +function Ga(a, c, b, e, d) { + const f = [], g = B(); + let k; + var h = a.length; + let l; + if (e) { + for (d = h - 1; 0 <= d; d--) { + if (l = (e = a[d]) && e.length) { + for (h = 0; h < l; h++) { + if (k = e[h], !g[k]) { + if (g[k] = 1, b) { + b--; + } else { + if (f.push(k), f.length === c) { + return f; + } + } + } + } + } + } + } else { + for (let n = h - 1, m, q = 0; 0 <= n; n--) { + m = a[n]; + for (let p = 0; p < m.length; p++) { + if (l = (e = m[p]) && e.length) { + for (let r = 0; r < l; r++) { + if (k = e[r], !g[k]) { + if (g[k] = 1, b) { + b--; + } else { + let u = (p + (n < h - 1 ? d || 0 : 0)) / (n + 1) | 0; + (f[u] || (f[u] = [])).push(k); + if (++q === c) { + return f; + } + } + } + } + } + } + } + } + return f; +} +function Ha(a, c, b) { + const e = B(), d = []; + for (let f = 0, g; f < c.length; f++) { + g = c[f]; + for (let k = 0; k < g.length; k++) { + e[g[k]] = 1; + } + } + if (b) { + for (let f = 0, g; f < a.length; f++) { + g = a[f], e[g] && (d.push(g), e[g] = 0); + } + } else { + for (let f = 0, g, k; f < a.result.length; f++) { + for (g = a.result[f], c = 0; c < g.length; c++) { + k = g[c], e[k] && ((d[f] || (d[f] = [])).push(k), e[k] = 0); + } + } + } + return d; +} +;function Ia(a, c, b, e) { + if (!a.length) { + return a; + } + if (1 === a.length) { + return a = a[0], a = b || a.length > c ? c ? a.slice(b, b + c) : a.slice(b) : a, e ? V.call(this, a) : a; + } + let d = []; + for (let f = 0, g, k; f < a.length; f++) { + if ((g = a[f]) && (k = g.length)) { + if (b) { + if (b >= k) { + b -= k; + continue; + } + b < k && (g = c ? g.slice(b, b + c) : g.slice(b), k = g.length, b = 0); + } + k > c && (g = g.slice(0, c), k = c); + if (!d.length && k >= c) { + return e ? V.call(this, g) : g; + } + d.push(g); + c -= k; + if (!c) { + break; + } + } + } + d = 1 < d.length ? [].concat.apply([], d) : d[0]; + return e ? V.call(this, d) : d; +} +;function Ja(a, c, b) { + var e = b[0]; + if (e.then) { + return Promise.all(b).then(function(n) { + return a[c].apply(a, n); + }); + } + if (e[0] && e[0].index) { + return a[c].apply(a, e); + } + e = []; + let d = [], f = 0, g = 0, k, h, l; + for (let n = 0, m; n < b.length; n++) { + if (m = b[n]) { + let q; + if (m.constructor === W) { + q = m.result; + } else if (m.constructor === Array) { + q = m; + } else { + if (f = m.limit || 0, g = m.offset || 0, l = m.suggest, h = m.resolve, k = m.enrich && h, m.index) { + m.resolve = !1, m.enrich = !1, q = m.index.search(m).result, m.resolve = h, m.enrich = k; + } else if (m.and) { + q = a.and(m.and); + } else if (m.or) { + q = a.or(m.or); + } else if (m.xor) { + q = a.xor(m.xor); + } else if (m.not) { + q = a.not(m.not); + } else { + continue; + } + } + if (q.then) { + d.push(q); + } else if (q.length) { + e[n] = q; + } else if (!l && ("and" === c || "xor" === c)) { + e = []; + break; + } + } + } + return {O:e, P:d, limit:f, offset:g, enrich:k, resolve:h, suggest:l}; +} +;W.prototype.or = function() { + const {O:a, P:c, limit:b, offset:e, enrich:d, resolve:f} = Ja(this, "or", arguments); + return Ka.call(this, a, c, b, e, d, f); +}; +function Ka(a, c, b, e, d, f) { + if (c.length) { + const g = this; + return Promise.all(c).then(function(k) { + a = []; + for (let h = 0, l; h < k.length; h++) { + (l = k[h]).length && (a[h] = l); + } + return Ka.call(g, a, [], b, e, d, f); + }); + } + a.length && (this.result.length && a.push(this.result), 2 > a.length ? this.result = a[0] : (this.result = Ga(a, b, e, !1, this.h), e = 0)); + return f ? this.resolve(b, e, d) : this; +} +;W.prototype.and = function() { + let a = this.result.length, c, b, e, d; + if (!a) { + const f = arguments[0]; + f && (a = !!f.suggest, d = f.resolve, c = f.limit, b = f.offset, e = f.enrich && d); + } + if (a) { + const {O:f, P:g, limit:k, offset:h, enrich:l, resolve:n, suggest:m} = Ja(this, "and", arguments); + return La.call(this, f, g, k, h, l, n, m); + } + return d ? this.resolve(c, b, e) : this; +}; +function La(a, c, b, e, d, f, g) { + if (c.length) { + const k = this; + return Promise.all(c).then(function(h) { + a = []; + for (let l = 0, n; l < h.length; l++) { + (n = h[l]).length && (a[l] = n); + } + return La.call(k, a, [], b, e, d, f, g); + }); + } + if (a.length) { + if (this.result.length && a.unshift(this.result), 2 > a.length) { + this.result = a[0]; + } else { + if (c = ca(a)) { + return this.result = Fa(a, c, b, e, g, this.h, f), f ? d ? V.call(this.index, this.result) : this.result : this; + } + this.result = []; + } + } else { + g || (this.result = a); + } + return f ? this.resolve(b, e, d) : this; +} +;W.prototype.xor = function() { + const {O:a, P:c, limit:b, offset:e, enrich:d, resolve:f, suggest:g} = Ja(this, "xor", arguments); + return Ma.call(this, a, c, b, e, d, f, g); +}; +function Ma(a, c, b, e, d, f, g) { + if (c.length) { + const k = this; + return Promise.all(c).then(function(h) { + a = []; + for (let l = 0, n; l < h.length; l++) { + (n = h[l]).length && (a[l] = n); + } + return Ma.call(k, a, [], b, e, d, f, g); + }); + } + if (a.length) { + if (this.result.length && a.unshift(this.result), 2 > a.length) { + this.result = a[0]; + } else { + return this.result = Na.call(this, a, b, e, f, this.h), f ? d ? V.call(this.index, this.result) : this.result : this; + } + } else { + g || (this.result = a); + } + return f ? this.resolve(b, e, d) : this; +} +function Na(a, c, b, e, d) { + const f = [], g = B(); + let k = 0; + for (let h = 0, l; h < a.length; h++) { + if (l = a[h]) { + k < l.length && (k = l.length); + for (let n = 0, m; n < l.length; n++) { + if (m = l[n]) { + for (let q = 0, p; q < m.length; q++) { + p = m[q], g[p] = g[p] ? 2 : 1; + } + } + } + } + } + for (let h = 0, l, n = 0; h < k; h++) { + for (let m = 0, q; m < a.length; m++) { + if (q = a[m]) { + if (l = q[h]) { + for (let p = 0, r; p < l.length; p++) { + if (r = l[p], 1 === g[r]) { + if (b) { + b--; + } else { + if (e) { + if (f.push(r), f.length === c) { + return f; + } + } else { + const u = h + (m ? d : 0); + f[u] || (f[u] = []); + f[u].push(r); + if (++n === c) { + return f; + } + } + } + } + } + } + } + } + } + return f; +} +;W.prototype.not = function() { + const {O:a, P:c, limit:b, offset:e, enrich:d, resolve:f, suggest:g} = Ja(this, "not", arguments); + return Oa.call(this, a, c, b, e, d, f, g); +}; +function Oa(a, c, b, e, d, f, g) { + if (c.length) { + const k = this; + return Promise.all(c).then(function(h) { + a = []; + for (let l = 0, n; l < h.length; l++) { + (n = h[l]).length && (a[l] = n); + } + return Oa.call(k, a, [], b, e, d, f, g); + }); + } + if (a.length && this.result.length) { + this.result = Pa.call(this, a, b, e, f); + } else if (f) { + return this.resolve(b, e, d); + } + return f ? d ? V.call(this.index, this.result) : this.result : this; +} +function Pa(a, c, b, e) { + const d = []; + a = new Set(a.flat().flat()); + for (let f = 0, g, k = 0; f < this.result.length; f++) { + if (g = this.result[f]) { + for (let h = 0, l; h < g.length; h++) { + if (l = g[h], !a.has(l)) { + if (b) { + b--; + } else { + if (e) { + if (d.push(l), d.length === c) { + return d; + } + } else { + if (d[f] || (d[f] = []), d[f].push(l), ++k === c) { + return d; + } + } + } + } + } + } + } + return d; +} +;function W(a) { + if (!this || this.constructor !== W) { + return new W(a); + } + if (a && a.index) { + return a.resolve = !1, this.index = a.index, this.h = a.boost || 0, this.result = a.index.search(a).result, this; + } + this.index = null; + this.result = a || []; + this.h = 0; +} +W.prototype.limit = function(a) { + if (this.result.length) { + const c = []; + for (let b = 0, e; b < this.result.length; b++) { + if (e = this.result[b]) { + if (e.length <= a) { + if (c[b] = e, a -= e.length, !a) { + break; + } + } else { + c[b] = e.slice(0, a); + break; + } + } + } + this.result = c; + } + return this; +}; +W.prototype.offset = function(a) { + if (this.result.length) { + const c = []; + for (let b = 0, e; b < this.result.length; b++) { + if (e = this.result[b]) { + e.length <= a ? a -= e.length : (c[b] = e.slice(a), a = 0); + } + } + this.result = c; + } + return this; +}; +W.prototype.boost = function(a) { + this.h += a; + return this; +}; +W.prototype.resolve = function(a, c, b) { + const e = this.result, d = this.index; + this.result = this.index = null; + return e.length ? ("object" === typeof a && (b = a.enrich, c = a.offset, a = a.limit), Ia.call(d, e, a || 100, c, b)) : e; +}; +B(); +U.prototype.search = function(a, c, b, e) { + b || (!c && I(a) ? (b = a, a = "") : I(c) && (b = c, c = 0)); + let d = []; + var f = [], g; + let k; + let h, l; + let n = 0; + var m = !0; + let q; + if (b) { + b.constructor === Array && (b = {index:b}); + a = b.query || a; + var p = b.pluck; + k = b.merge; + h = p || b.field || (h = b.index) && (h.index ? null : h); + l = this.tag && b.tag; + var r = b.suggest; + m = !1 !== b.resolve; + if (!m && !p) { + if (h = h || this.field) { + E(h) ? p = h : (h.constructor === Array && 1 === h.length && (h = h[0]), p = h.field || h.index); + } + if (!p) { + throw Error("Apply resolver on document search requires either the option 'pluck' to be set or just select a single field name in your query."); + } + } + this.store && b.enrich && !m && console.warn("Enrich results can only be done on a final resolver task or when calling .resolve({ enrich: true })"); + q = (g = this.store && b.enrich && m) && b.highlight; + c = b.limit || c; + var u = b.offset || 0; + c || (c = 100); + if (l && (!this.db || !e)) { + l.constructor !== Array && (l = [l]); + var v = []; + for (let A = 0, x; A < l.length; A++) { + x = l[A]; + if (E(x)) { + throw Error("A tag option can't be a string, instead it needs a { field: tag } format."); + } + if (x.field && x.tag) { + var w = x.tag; + if (w.constructor === Array) { + for (var y = 0; y < w.length; y++) { + v.push(x.field, w[y]); + } + } else { + v.push(x.field, w); + } + } else { + w = Object.keys(x); + for (let D = 0, H, C; D < w.length; D++) { + if (H = w[D], C = x[H], C.constructor === Array) { + for (y = 0; y < C.length; y++) { + v.push(H, C[y]); + } + } else { + v.push(H, C); + } + } + } + } + if (!v.length) { + throw Error("Your tag definition within the search options is probably wrong. No valid tags found."); + } + l = v; + if (!a) { + m = []; + if (v.length) { + for (f = 0; f < v.length; f += 2) { + if (this.db) { + p = this.index.get(v[f]); + if (!p) { + console.warn("Tag '" + v[f] + ":" + v[f + 1] + "' will be skipped because there is no field '" + v[f] + "'."); + continue; + } + m.push(p = p.db.tag(v[f + 1], c, u, g)); + } else { + p = Qa.call(this, v[f], v[f + 1], c, u, g); + } + d.push({field:v[f], tag:v[f + 1], result:p}); + } + } + return m.length ? Promise.all(m).then(function(A) { + for (let x = 0; x < A.length; x++) { + d[x].result = A[x]; + } + return d; + }) : d; + } + } + h && h.constructor !== Array && (h = [h]); + } + h || (h = this.field); + v = !e && (this.worker || this.db) && []; + let F; + for (let A = 0, x, D, H; A < h.length; A++) { + D = h[A]; + if (this.db && this.tag && !this.D[A]) { + continue; + } + let C; + E(D) || (C = D, D = C.field, a = C.query || a, c = C.limit || c, u = C.offset || u, r = C.suggest || r, g = this.store && (C.enrich || g)); + if (e) { + x = e[A]; + } else { + if (w = C || b, y = this.index.get(D), l && (this.db && (w.tag = l, F = y.db.support_tag_search, w.field = h), F || (w.enrich = !1)), v) { + v[A] = y.search(a, c, w); + w && g && (w.enrich = g); + continue; + } else { + x = y.search(a, c, w), w && g && (w.enrich = g); + } + } + H = x && (m ? x.length : x.result.length); + if (l && H) { + w = []; + y = 0; + if (this.db && e) { + if (!F) { + for (let G = h.length; G < e.length; G++) { + let L = e[G]; + if (L && L.length) { + y++, w.push(L); + } else if (!r) { + return m ? d : new W(d); + } + } + } + } else { + for (let G = 0, L, tb; G < l.length; G += 2) { + L = this.tag.get(l[G]); + if (!L) { + if (console.warn("Tag '" + l[G] + ":" + l[G + 1] + "' will be skipped because there is no field '" + l[G] + "'."), r) { + continue; + } else { + return m ? d : new W(d); + } + } + if (tb = (L = L && L.get(l[G + 1])) && L.length) { + y++, w.push(L); + } else if (!r) { + return m ? d : new W(d); + } + } + } + if (y) { + x = Ha(x, w, m); + H = x.length; + if (!H && !r) { + return m ? x : new W(x); + } + y--; + } + } + if (H) { + f[n] = D, d.push(x), n++; + } else if (1 === h.length) { + return m ? d : new W(d); + } + } + if (v) { + if (this.db && l && l.length && !F) { + for (g = 0; g < l.length; g += 2) { + f = this.index.get(l[g]); + if (!f) { + if (console.warn("Tag '" + l[g] + ":" + l[g + 1] + "' was not found because there is no field '" + l[g] + "'."), r) { + continue; + } else { + return m ? d : new W(d); + } + } + v.push(f.db.tag(l[g + 1], c, u, !1)); + } + } + const A = this; + return Promise.all(v).then(function(x) { + return x.length ? A.search(a, c, b, x) : x; + }); + } + if (!n) { + return m ? d : new W(d); + } + if (p && (!g || !this.store)) { + return d[0]; + } + v = []; + for (u = 0; u < f.length; u++) { + r = d[u]; + g && r.length && "undefined" === typeof r[0].doc && (this.db ? v.push(r = this.index.get(this.field[0]).db.enrich(r)) : r = V.call(this, r)); + if (p) { + return m ? r : new W(r); + } + d[u] = {field:f[u], result:r}; + } + if (g && this.db && v.length) { + const A = this; + return Promise.all(v).then(function(x) { + for (let D = 0; D < x.length; D++) { + d[D].result = x[D]; + } + return k ? Ra(d, c) : q ? Sa(d, a, A.index, A.field, A.D, q) : d; + }); + } + return k ? Ra(d, c) : q ? Sa(d, a, this.index, this.field, this.D, q) : d; +}; +function Sa(a, c, b, e, d, f) { + let g, k, h; + for (let n = 0, m, q, p, r; n < a.length; n++) { + let u = a[n].result; + m = a[n].field; + p = b.get(m); + q = p.encoder; + h = p.tokenize; + r = d[e.indexOf(m)]; + q !== g && (g = q, k = g.encode(c)); + for (let v = 0; v < u.length; v++) { + let w = ""; + var l = ba(u[v].doc, r); + let y = g.encode(l); + l = l.split(g.split); + for (let F = 0, A, x; F < y.length; F++) { + A = y[F]; + x = l[F]; + if (!A || !x) { + continue; + } + let D; + for (let H = 0, C; H < k.length; H++) { + if (C = k[H], "strict" === h) { + if (A === C) { + w += (w ? " " : "") + f.replace("$1", x); + D = !0; + break; + } + } else { + const G = A.indexOf(C); + if (-1 < G) { + w += (w ? " " : "") + x.substring(0, G) + f.replace("$1", x.substring(G, C.length)) + x.substring(G + C.length); + D = !0; + break; + } + } + } + D || (w += (w ? " " : "") + l[F]); + } + u[v].highlight = w; + } + } + return a; +} +function Ra(a, c) { + const b = [], e = B(); + for (let d = 0, f, g; d < a.length; d++) { + f = a[d]; + g = f.result; + for (let k = 0, h, l, n; k < g.length; k++) { + if (l = g[k], "object" !== typeof l && (l = {id:l}), h = l.id, n = e[h]) { + n.push(f.field); + } else { + if (b.length === c) { + return b; + } + l.field = e[h] = [f.field]; + b.push(l); + } + } + } + return b; +} +function Qa(a, c, b, e, d) { + let f = this.tag.get(a); + if (!f) { + return console.warn("Tag '" + a + "' was not found"), []; + } + if ((a = (f = f && f.get(c)) && f.length - e) && 0 < a) { + if (a > b || e) { + f = f.slice(e, e + b); + } + d && (f = V.call(this, f)); + return f; + } +} +function V(a) { + if (!this || !this.store) { + return a; + } + const c = Array(a.length); + for (let b = 0, e; b < a.length; b++) { + e = a[b], c[b] = {id:e, doc:this.store.get(e)}; + } + return c; +} +;function U(a) { + if (!this || this.constructor !== U) { + return new U(a); + } + const c = a.document || a.doc || a; + let b, e; + this.D = []; + this.field = []; + this.J = []; + this.key = (b = c.key || c.id) && Ta(b, this.J) || "id"; + (e = a.keystore || 0) && (this.keystore = e); + this.fastupdate = !!a.fastupdate; + this.reg = !this.fastupdate || a.worker || a.db ? e ? new T(e) : new Set() : e ? new S(e) : new Map(); + this.C = (b = c.store || null) && b && !0 !== b && []; + this.store = b && (e ? new S(e) : new Map()); + this.cache = (b = a.cache || null) && new X(b); + a.cache = !1; + this.worker = a.worker; + this.priority = a.priority || 4; + this.index = Ua.call(this, a, c); + this.tag = null; + if (b = c.tag) { + if ("string" === typeof b && (b = [b]), b.length) { + this.tag = new Map(); + this.F = []; + this.R = []; + for (let d = 0, f, g; d < b.length; d++) { + f = b[d]; + g = f.field || f; + if (!g) { + throw Error("The tag field from the document descriptor is undefined."); + } + f.custom ? this.F[d] = f.custom : (this.F[d] = Ta(g, this.J), f.filter && ("string" === typeof this.F[d] && (this.F[d] = new String(this.F[d])), this.F[d].I = f.filter)); + this.R[d] = g; + this.tag.set(g, new Map()); + } + } + } + if (this.worker) { + this.fastupdate = !1; + a = []; + for (const d of this.index.values()) { + d.then && a.push(d); + } + if (a.length) { + const d = this; + return Promise.all(a).then(function(f) { + let g = 0; + for (const k of d.index.entries()) { + const h = k[0]; + k[1].then && d.index.set(h, f[g++]); + } + return d; + }); + } + } else { + a.db && (this.fastupdate = !1, this.mount(a.db)); + } +} +t = U.prototype; +t.mount = function(a) { + if (this.worker) { + throw Error("You can't use Worker-Indexes on a persistent model. That would be useless, since each of the persistent model acts like Worker-Index by default (Master/Slave)."); + } + let c = this.field; + if (this.tag) { + for (let d = 0, f; d < this.R.length; d++) { + f = this.R[d]; + var b = void 0; + this.index.set(f, b = new N({}, this.reg)); + c === this.field && (c = c.slice(0)); + c.push(f); + b.tag = this.tag.get(f); + } + } + b = []; + const e = {db:a.db, type:a.type, fastupdate:a.fastupdate}; + for (let d = 0, f, g; d < c.length; d++) { + e.field = g = c[d]; + f = this.index.get(g); + const k = new a.constructor(a.id, e); + k.id = a.id; + b[d] = k.mount(f); + f.document = !0; + d ? f.bypass = !0 : f.store = this.store; + } + this.db = !0; + return Promise.all(b); +}; +t.commit = async function(a, c) { + const b = []; + for (const e of this.index.values()) { + b.push(e.commit(a, c)); + } + await Promise.all(b); + this.reg.clear(); +}; +t.destroy = function() { + const a = []; + for (const c of this.index.values()) { + a.push(c.destroy()); + } + return Promise.all(a); +}; +function Ua(a, c) { + const b = new Map(); + let e = c.index || c.field || c; + E(e) && (e = [e]); + for (let d = 0, f, g; d < e.length; d++) { + f = e[d]; + E(f) || (g = f, f = f.field); + g = I(g) ? Object.assign({}, a, g) : a; + if (this.worker) { + const k = new P(g); + b.set(f, k); + } + this.worker || b.set(f, new N(g, this.reg)); + g.custom ? this.D[d] = g.custom : (this.D[d] = Ta(f, this.J), g.filter && ("string" === typeof this.D[d] && (this.D[d] = new String(this.D[d])), this.D[d].I = g.filter)); + this.field[d] = f; + } + if (this.C) { + a = c.store; + E(a) && (a = [a]); + for (let d = 0, f, g; d < a.length; d++) { + f = a[d], g = f.field || f, f.custom ? (this.C[d] = f.custom, f.custom.V = g) : (this.C[d] = Ta(g, this.J), f.filter && ("string" === typeof this.C[d] && (this.C[d] = new String(this.C[d])), this.C[d].I = f.filter)); + } + } + return b; +} +function Ta(a, c) { + const b = a.split(":"); + let e = 0; + for (let d = 0; d < b.length; d++) { + a = b[d], "]" === a[a.length - 1] && (a = a.substring(0, a.length - 2)) && (c[e] = !0), a && (b[e++] = a); + } + e < b.length && (b.length = e); + return 1 < e ? b : b[0]; +} +t.append = function(a, c) { + return this.add(a, c, !0); +}; +t.update = function(a, c) { + return this.remove(a).add(a, c); +}; +t.remove = function(a) { + I(a) && (a = ba(a, this.key)); + for (var c of this.index.values()) { + c.remove(a, !0); + } + if (this.reg.has(a)) { + if (this.tag && !this.fastupdate) { + for (let b of this.tag.values()) { + for (let e of b) { + c = e[0]; + const d = e[1], f = d.indexOf(a); + -1 < f && (1 < d.length ? d.splice(f, 1) : b.delete(c)); + } + } + } + this.store && this.store.delete(a); + this.reg.delete(a); + } + this.cache && this.cache.remove(a); + return this; +}; +t.clear = function() { + const a = []; + for (const c of this.index.values()) { + const b = c.clear(); + b.then && a.push(b); + } + if (this.tag) { + for (const c of this.tag.values()) { + c.clear(); + } + } + this.store && this.store.clear(); + this.cache && this.cache.clear(); + return a.length ? Promise.all(a) : this; +}; +t.contain = function(a) { + return this.db ? this.index.get(this.field[0]).db.has(a) : this.reg.has(a); +}; +t.cleanup = function() { + for (const a of this.index.values()) { + a.cleanup(); + } + return this; +}; +t.get = function(a) { + return this.db ? this.index.get(this.field[0]).db.enrich(a).then(function(c) { + return c[0] && c[0].doc; + }) : this.store.get(a); +}; +t.set = function(a, c) { + this.store.set(a, c); + return this; +}; +t.searchCache = Va; +t.export = function(a, c, b = 0, e = 0) { + if (b < this.field.length) { + const g = this.field[b]; + if ((c = this.index.get(g).export(a, g, b, e = 1)) && c.then) { + const k = this; + return c.then(function() { + return k.export(a, g, b + 1); + }); + } + return this.export(a, g, b + 1); + } + let d, f; + switch(e) { + case 0: + d = "reg"; + f = wa(this.reg); + c = null; + break; + case 1: + d = "tag"; + f = this.tag && ua(this.tag, this.reg.size); + c = null; + break; + case 2: + d = "doc"; + f = this.store && sa(this.store); + c = null; + break; + default: + return; + } + return ya.call(this, a, c, d, f, b, e); +}; +t.import = function(a, c) { + var b = a.split("."); + "json" === b[b.length - 1] && b.pop(); + const e = 2 < b.length ? b[0] : ""; + b = 2 < b.length ? b[2] : b[1]; + if (this.worker && e) { + return this.index.get(e).import(a); + } + if (c) { + "string" === typeof c && (c = JSON.parse(c)); + if (e) { + return this.index.get(e).import(b, c); + } + switch(b) { + case "reg": + this.fastupdate = !1; + this.reg = xa(c, this.reg); + for (let d = 0, f; d < this.field.length; d++) { + f = this.index.get(this.field[d]), f.fastupdate = !1, f.reg = this.reg; + } + if (this.worker) { + c = []; + for (const d of this.index.values()) { + c.push(d.import(a)); + } + return Promise.all(c); + } + break; + case "tag": + this.tag = va(c, this.tag); + break; + case "doc": + this.store = ta(c, this.store); + } + } +}; +la(U.prototype); +function Va(a, c, b) { + a = ("object" === typeof a ? "" + a.query : a).toLowerCase(); + this.cache || (this.cache = new X()); + let e = this.cache.get(a); + if (!e) { + e = this.search(a, c, b); + if (e.then) { + const d = this; + e.then(function(f) { + d.cache.set(a, f); + return f; + }); + } + this.cache.set(a, e); + } + return e; +} +function X(a) { + this.limit = a && !0 !== a ? a : 1000; + this.cache = new Map(); + this.h = ""; +} +X.prototype.set = function(a, c) { + this.cache.set(this.h = a, c); + this.cache.size > this.limit && this.cache.delete(this.cache.keys().next().value); +}; +X.prototype.get = function(a) { + const c = this.cache.get(a); + c && this.h !== a && (this.cache.delete(a), this.cache.set(this.h = a, c)); + return c; +}; +X.prototype.remove = function(a) { + for (const c of this.cache) { + const b = c[0]; + c[1].includes(a) && this.cache.delete(b); + } +}; +X.prototype.clear = function() { + this.cache.clear(); + this.h = ""; +}; +const Wa = {normalize:!1, numeric:!1, split:/\s+/}; +const Xa = {normalize:!0}; +const Ya = {normalize:!0, dedupe:!0}; +const Za = new Map([["b", "p"], ["v", "f"], ["w", "f"], ["z", "s"], ["x", "s"], ["d", "t"], ["n", "m"], ["c", "k"], ["g", "k"], ["j", "k"], ["q", "k"], ["i", "e"], ["y", "e"], ["u", "o"]]); +const $a = new Map([["ae", "a"], ["oe", "o"], ["sh", "s"], ["kh", "k"], ["th", "t"], ["ph", "f"], ["pf", "f"]]), ab = [/([^aeo])h(.)/g, "$1$2", /([aeo])h([^aeo]|$)/g, "$1$2", /(.)\1+/g, "$1"]; +const bb = {a:"", e:"", i:"", o:"", u:"", y:"", b:1, f:1, p:1, v:1, c:2, g:2, j:2, k:2, q:2, s:2, x:2, z:2, "\u00df":2, d:3, t:3, l:4, m:5, n:5, r:6}; +var cb = {X:Wa, W:Xa, Y:Ya, LatinBalance:{normalize:!0, dedupe:!0, mapper:Za}, LatinAdvanced:{normalize:!0, dedupe:!0, mapper:Za, matcher:$a, replacer:ab}, LatinExtra:{normalize:!0, dedupe:!0, mapper:Za, replacer:ab.concat([/(?!^)[aeo]/g, ""]), matcher:$a}, LatinSoundex:{normalize:!0, dedupe:!1, include:{letter:!0}, finalize:function(a) { + for (let b = 0; b < a.length; b++) { + var c = a[b]; + let e = c.charAt(0), d = bb[e]; + for (let f = 1, g; f < c.length && (g = c.charAt(f), "h" === g || "w" === g || !(g = bb[g]) || g === d || (e += g, d = g, 4 !== e.length)); f++) { + } + a[b] = e; + } +}}, LatinExact:Wa, LatinDefault:Xa, LatinSimple:Ya}; +const db = {memory:{resolution:1}, performance:{resolution:3, fastupdate:!0, context:{depth:1, resolution:1}}, match:{tokenize:"forward"}, score:{resolution:9, context:{depth:2, resolution:3}}}; +N.prototype.add = function(a, c, b, e) { + if (c && (a || 0 === a)) { + if (!e && !b && this.reg.has(a)) { + return this.update(a, c); + } + c = this.encoder.encode(c); + if (e = c.length) { + const l = B(), n = B(), m = this.depth, q = this.resolution; + for (let p = 0; p < e; p++) { + let r = c[this.rtl ? e - 1 - p : p]; + var d = r.length; + if (d && (m || !n[r])) { + var f = this.score ? this.score(c, r, p, null, 0) : eb(q, e, p), g = ""; + switch(this.tokenize) { + case "full": + if (2 < d) { + for (let u = 0, v; u < d; u++) { + for (f = d; f > u; f--) { + g = r.substring(u, f); + v = this.rtl ? d - 1 - u : u; + var k = this.score ? this.score(c, r, p, g, v) : eb(q, e, p, d, v); + fb(this, n, g, k, a, b); + } + } + break; + } + case "bidirectional": + case "reverse": + if (1 < d) { + for (k = d - 1; 0 < k; k--) { + g = r[this.rtl ? d - 1 - k : k] + g; + var h = this.score ? this.score(c, r, p, g, k) : eb(q, e, p, d, k); + fb(this, n, g, h, a, b); + } + g = ""; + } + case "forward": + if (1 < d) { + for (k = 0; k < d; k++) { + g += r[this.rtl ? d - 1 - k : k], fb(this, n, g, f, a, b); + } + break; + } + default: + if (fb(this, n, r, f, a, b), m && 1 < e && p < e - 1) { + for (d = B(), g = this.U, f = r, k = Math.min(m + 1, this.rtl ? p + 1 : e - p), d[f] = 1, h = 1; h < k; h++) { + if ((r = c[this.rtl ? e - 1 - p - h : p + h]) && !d[r]) { + d[r] = 1; + const u = this.score ? this.score(c, f, p, r, h - 1) : eb(g + (e / 2 > g ? 0 : 1), e, p, k - 1, h - 1), v = this.bidirectional && r > f; + fb(this, l, v ? f : r, u, a, b, v ? r : f); + } + } + } + } + } + } + this.fastupdate || this.reg.add(a); + } else { + c = ""; + } + } + this.db && (c || this.commit_task.push({del:a}), this.T && gb(this)); + return this; +}; +function fb(a, c, b, e, d, f, g) { + let k = g ? a.ctx : a.map, h; + if (!c[b] || g && !(h = c[b])[g]) { + if (g ? (c = h || (c[b] = B()), c[g] = 1, (h = k.get(g)) ? k = h : k.set(g, k = new Map())) : c[b] = 1, (h = k.get(b)) ? k = h : k.set(b, k = h = []), k = k[e] || (k[e] = []), !f || !k.includes(d)) { + if (k.length === 2 ** 31 - 1) { + c = new R(k); + if (a.fastupdate) { + for (let l of a.reg.values()) { + l.includes(k) && (l[l.indexOf(k)] = c); + } + } + h[e] = k = c; + } + k.push(d); + a.fastupdate && ((e = a.reg.get(d)) ? e.push(k) : a.reg.set(d, [k])); + } + } +} +function eb(a, c, b, e, d) { + return b && 1 < a ? c + (e || 0) <= a ? b + (d || 0) : (a - 1) / (c + (e || 0)) * (b + (d || 0)) + 1 | 0 : 0; +} +;N.prototype.search = function(a, c, b) { + b || (!c && I(a) ? (b = a, a = "") : I(c) && (b = c, c = 0)); + let e = [], d, f, g, k = 0, h, l, n, m, q; + b ? (a = b.query || a, c = b.limit || c, k = b.offset || 0, f = b.context, g = b.suggest, q = (h = !1 !== b.resolve) && b.enrich, n = b.boost, m = b.resolution, l = this.db && b.tag) : h = this.resolve; + let p = this.encoder.encode(a); + d = p.length; + c = c || (h ? 100 : 0); + if (1 === d) { + return hb.call(this, p[0], "", c, k, h, q, l); + } + f = this.depth && !1 !== f; + if (2 === d && f && !g) { + return hb.call(this, p[0], p[1], c, k, h, q, l); + } + let r = B(), u = 0, v; + 1 < d && f && (v = p[0], u = 1); + m || 0 === m || (m = v ? this.U : this.resolution); + if (this.db) { + if (this.db.search && (a = this.db.search(this, p, c, k, g, h, q, l), !1 !== a)) { + return a; + } + const w = this; + return async function() { + for (let y, F; u < d; u++) { + if ((F = p[u]) && !r[F]) { + r[F] = 1; + y = await ib(w, F, v, 0, 0, !1, !1); + if (y = jb(y, e, g, m)) { + e = y; + break; + } + v && (g && y && e.length || (v = F)); + } + g && v && u === d - 1 && !e.length && (m = w.resolution, v = "", u = -1, r = B()); + } + return kb(e, m, c, k, g, n, h); + }(); + } + for (let w, y; u < d; u++) { + if ((y = p[u]) && !r[y]) { + r[y] = 1; + w = ib(this, y, v, 0, 0, !1, !1); + if (w = jb(w, e, g, m)) { + e = w; + break; + } + v && (g && w && e.length || (v = y)); + } + g && v && u === d - 1 && !e.length && (m = this.resolution, v = "", u = -1, r = B()); + } + return kb(e, m, c, k, g, n, h); +}; +function kb(a, c, b, e, d, f, g) { + let k = a.length, h = a; + if (1 < k) { + h = Fa(a, c, b, e, d, f, g); + } else if (1 === k) { + return g ? Ia.call(null, a[0], b, e) : new W(a[0]); + } + return g ? h : new W(h); +} +function hb(a, c, b, e, d, f, g) { + a = ib(this, a, c, b, e, d, f, g); + return this.db ? a.then(function(k) { + return d ? k || [] : new W(k); + }) : a && a.length ? d ? Ia.call(this, a, b, e) : new W(a) : d ? [] : new W(); +} +function jb(a, c, b, e) { + let d = []; + if (a && a.length) { + if (a.length <= e) { + c.push(a); + return; + } + for (let f = 0, g; f < e; f++) { + if (g = a[f]) { + d[f] = g; + } + } + if (d.length) { + c.push(d); + return; + } + } + if (!b) { + return d; + } +} +function ib(a, c, b, e, d, f, g, k) { + let h; + b && (h = a.bidirectional && c > b) && (h = b, b = c, c = h); + if (a.db) { + return a.db.get(c, b, e, d, f, g, k); + } + a = b ? (a = a.ctx.get(b)) && a.get(c) : a.map.get(c); + return a; +} +;N.prototype.remove = function(a, c) { + const b = this.reg.size && (this.fastupdate ? this.reg.get(a) : this.reg.has(a)); + if (b) { + if (this.fastupdate) { + for (let e = 0, d; e < b.length; e++) { + if (d = b[e]) { + if (2 > d.length) { + d.pop(); + } else { + const f = d.indexOf(a); + f === b.length - 1 ? d.pop() : d.splice(f, 1); + } + } + } + } else { + lb(this.map, a), this.depth && lb(this.ctx, a); + } + c || this.reg.delete(a); + } + this.db && (this.commit_task.push({del:a}), this.T && gb(this)); + this.cache && this.cache.remove(a); + return this; +}; +function lb(a, c) { + let b = 0; + if (a.constructor === Array) { + for (let e = 0, d, f; e < a.length; e++) { + if ((d = a[e]) && d.length) { + if (f = d.indexOf(c), 0 <= f) { + 1 < d.length ? (d.splice(f, 1), b++) : delete a[e]; + break; + } else { + b++; + } + } + } + } else { + for (let e of a.entries()) { + const d = e[0], f = lb(e[1], c); + f ? b += f : a.delete(d); + } + } + return b; +} +;function N(a, c) { + if (!this || this.constructor !== N) { + return new N(a); + } + if (a) { + var b = E(a) ? a : a.preset; + b && (db[b] || console.warn("Preset not found: " + b), a = Object.assign({}, db[b], a)); + } else { + a = {}; + } + b = a.context; + const e = !0 === b ? {depth:1} : b || {}, d = E(a.encoder) ? cb[a.encoder] : a.encode || a.encoder || Xa; + this.encoder = d.encode ? d : "object" === typeof d ? new ja(d) : {encode:d}; + this.resolution = a.resolution || 9; + this.tokenize = b = (b = a.tokenize) && "default" !== b && "exact" !== b && b || "strict"; + this.depth = "strict" === b && e.depth || 0; + this.bidirectional = !1 !== e.bidirectional; + this.fastupdate = !!a.fastupdate; + this.score = a.score || null; + e && "strict" !== this.tokenize && console.warn('Context-Search could not applied, because it is just supported when using the tokenizer "strict".'); + (b = a.keystore || 0) && (this.keystore = b); + this.map = b ? new S(b) : new Map(); + this.ctx = b ? new S(b) : new Map(); + this.reg = c || (this.fastupdate ? b ? new S(b) : new Map() : b ? new T(b) : new Set()); + this.U = e.resolution || 3; + this.rtl = d.rtl || a.rtl || !1; + this.cache = (b = a.cache || null) && new X(b); + this.resolve = !1 !== a.resolve; + if (b = a.db) { + this.db = this.mount(b); + } + this.T = !1 !== a.commit; + this.commit_task = []; + this.commit_timer = null; + this.priority = a.priority || 4; +} +t = N.prototype; +t.mount = function(a) { + this.commit_timer && (clearTimeout(this.commit_timer), this.commit_timer = null); + return a.mount(this); +}; +t.commit = function(a, c) { + this.commit_timer && (clearTimeout(this.commit_timer), this.commit_timer = null); + return this.db.commit(this, a, c); +}; +t.destroy = function() { + this.commit_timer && (clearTimeout(this.commit_timer), this.commit_timer = null); + return this.db.destroy(); +}; +function gb(a) { + a.commit_timer || (a.commit_timer = setTimeout(function() { + a.commit_timer = null; + a.db.commit(a, void 0, void 0); + }, 1)); +} +t.clear = function() { + this.map.clear(); + this.ctx.clear(); + this.reg.clear(); + this.cache && this.cache.clear(); + this.db && (this.commit_timer && clearTimeout(this.commit_timer), this.commit_timer = null, this.commit_task = [{clear:!0}]); + return this; +}; +t.append = function(a, c) { + return this.add(a, c, !0); +}; +t.contain = function(a) { + return this.db ? this.db.has(a) : this.reg.has(a); +}; +t.update = function(a, c) { + const b = this, e = this.remove(a); + return e && e.then ? e.then(() => b.add(a, c)) : this.add(a, c); +}; +function mb(a) { + let c = 0; + if (a.constructor === Array) { + for (let b = 0, e; b < a.length; b++) { + (e = a[b]) && (c += e.length); + } + } else { + for (const b of a.entries()) { + const e = b[0], d = mb(b[1]); + d ? c += d : a.delete(e); + } + } + return c; +} +t.cleanup = function() { + if (!this.fastupdate) { + return console.info('Cleanup the index isn\'t required when not using "fastupdate".'), this; + } + mb(this.map); + this.depth && mb(this.ctx); + return this; +}; +t.searchCache = Va; +t.export = function(a, c, b = 0, e = 0) { + let d, f; + switch(e) { + case 0: + d = "reg"; + f = wa(this.reg); + break; + case 1: + d = "cfg"; + f = null; + break; + case 2: + d = "map"; + f = sa(this.map, this.reg.size); + break; + case 3: + d = "ctx"; + f = ua(this.ctx, this.reg.size); + break; + default: + return; + } + return ya.call(this, a, c, d, f, b, e); +}; +t.import = function(a, c) { + if (c) { + switch("string" === typeof c && (c = JSON.parse(c)), a = a.split("."), "json" === a[a.length - 1] && a.pop(), 3 === a.length && a.shift(), a = 1 < a.length ? a[1] : a[0], a) { + case "reg": + this.fastupdate = !1; + this.reg = xa(c, this.reg); + break; + case "map": + this.map = ta(c, this.map); + break; + case "ctx": + this.ctx = va(c, this.ctx); + } + } +}; +t.serialize = function(a = !0) { + let c = "", b = "", e = ""; + if (this.reg.size) { + let f; + for (var d of this.reg.keys()) { + f || (f = typeof d), c += (c ? "," : "") + ("string" === f ? '"' + d + '"' : d); + } + c = "index.reg=new Set([" + c + "]);"; + b = za(this.map, f); + b = "index.map=new Map([" + b + "]);"; + for (const g of this.ctx.entries()) { + d = g[0]; + let k = za(g[1], f); + k = "new Map([" + k + "])"; + k = '["' + d + '",' + k + "]"; + e += (e ? "," : "") + k; + } + e = "index.ctx=new Map([" + e + "]);"; + } + return a ? "function inject(index){" + c + b + e + "}" : c + b + e; +}; +la(N.prototype); +const nb = "undefined" !== typeof window && (window.indexedDB || window.mozIndexedDB || window.webkitIndexedDB || window.msIndexedDB), ob = ["map", "ctx", "tag", "reg", "cfg"], Y = B(); +function pb(a, c = {}) { + if (!this) { + return new pb(a, c); + } + "object" === typeof a && (c = a, a = a.name); + a || console.info("Default storage space was used, because a name was not passed."); + this.id = "flexsearch" + (a ? ":" + a.toLowerCase().replace(/[^a-z0-9_\-]/g, "") : ""); + this.field = c.field ? c.field.toLowerCase().replace(/[^a-z0-9_\-]/g, "") : ""; + this.type = c.type; + this.fastupdate = this.support_tag_search = !1; + this.db = null; + this.h = {}; +} +t = pb.prototype; +t.mount = function(a) { + if (!a.encoder) { + return a.mount(this); + } + a.db = this; + return this.open(); +}; +t.open = function() { + if (this.db) { + return this.db; + } + let a = this; + navigator.storage && navigator.storage.persist(); + Y[a.id] || (Y[a.id] = []); + Y[a.id].push(a.field); + const c = nb.open(a.id, 1); + c.onupgradeneeded = function() { + const b = a.db = this.result; + for (let e = 0, d; e < ob.length; e++) { + d = ob[e]; + for (let f = 0, g; f < Y[a.id].length; f++) { + g = Y[a.id][f], b.objectStoreNames.contains(d + ("reg" !== d ? g ? ":" + g : "" : "")) || b.createObjectStore(d + ("reg" !== d ? g ? ":" + g : "" : "")); + } + } + }; + return a.db = Z(c, function(b) { + a.db = b; + a.db.onversionchange = function() { + a.close(); + }; + }); +}; +t.close = function() { + this.db && this.db.close(); + this.db = null; +}; +t.destroy = function() { + const a = nb.deleteDatabase(this.id); + return Z(a); +}; +t.clear = function() { + const a = []; + for (let b = 0, e; b < ob.length; b++) { + e = ob[b]; + for (let d = 0, f; d < Y[this.id].length; d++) { + f = Y[this.id][d], a.push(e + ("reg" !== e ? f ? ":" + f : "" : "")); + } + } + const c = this.db.transaction(a, "readwrite"); + for (let b = 0; b < a.length; b++) { + c.objectStore(a[b]).clear(); + } + return Z(c); +}; +t.get = function(a, c, b = 0, e = 0, d = !0, f = !1) { + a = this.db.transaction((c ? "ctx" : "map") + (this.field ? ":" + this.field : ""), "readonly").objectStore((c ? "ctx" : "map") + (this.field ? ":" + this.field : "")).get(c ? c + ":" + a : a); + const g = this; + return Z(a).then(function(k) { + let h = []; + if (!k || !k.length) { + return h; + } + if (d) { + if (!b && !e && 1 === k.length) { + return k[0]; + } + for (let l = 0, n; l < k.length; l++) { + if ((n = k[l]) && n.length) { + if (e >= n.length) { + e -= n.length; + continue; + } + const m = b ? e + Math.min(n.length - e, b) : n.length; + for (let q = e; q < m; q++) { + h.push(n[q]); + } + e = 0; + if (h.length === b) { + break; + } + } + } + return f ? g.enrich(h) : h; + } + return k; + }); +}; +t.tag = function(a, c = 0, b = 0, e = !1) { + a = this.db.transaction("tag" + (this.field ? ":" + this.field : ""), "readonly").objectStore("tag" + (this.field ? ":" + this.field : "")).get(a); + const d = this; + return Z(a).then(function(f) { + if (!f || !f.length || b >= f.length) { + return []; + } + if (!c && !b) { + return f; + } + f = f.slice(b, b + c); + return e ? d.enrich(f) : f; + }); +}; +t.enrich = function(a) { + "object" !== typeof a && (a = [a]); + const c = this.db.transaction("reg", "readonly").objectStore("reg"), b = []; + for (let e = 0; e < a.length; e++) { + b[e] = Z(c.get(a[e])); + } + return Promise.all(b).then(function(e) { + for (let d = 0; d < e.length; d++) { + e[d] = {id:a[d], doc:e[d] ? JSON.parse(e[d]) : null}; + } + return e; + }); +}; +t.has = function(a) { + a = this.db.transaction("reg", "readonly").objectStore("reg").getKey(a); + return Z(a).then(function(c) { + return !!c; + }); +}; +t.search = null; +t.info = function() { +}; +t.transaction = function(a, c, b) { + a += "reg" !== a ? this.field ? ":" + this.field : "" : ""; + let e = this.h[a + ":" + c]; + if (e) { + return b.call(this, e); + } + let d = this.db.transaction(a, c); + this.h[a + ":" + c] = e = d.objectStore(a); + const f = b.call(this, e); + this.h[a + ":" + c] = null; + return Z(d).finally(function() { + d = e = null; + return f; + }); +}; +t.commit = async function(a, c, b) { + if (c) { + await this.clear(), a.commit_task = []; + } else { + let e = a.commit_task; + a.commit_task = []; + for (let d = 0, f; d < e.length; d++) { + if (f = e[d], f.clear) { + await this.clear(); + c = !0; + break; + } else { + e[d] = f.del; + } + } + c || (b || (e = e.concat(aa(a.reg))), e.length && await this.remove(e)); + } + a.reg.size && (await this.transaction("map", "readwrite", function(e) { + for (const d of a.map) { + const f = d[0], g = d[1]; + g.length && (c ? e.put(g, f) : e.get(f).onsuccess = function() { + let k = this.result; + var h; + if (k && k.length) { + const l = Math.max(k.length, g.length); + for (let n = 0, m, q; n < l; n++) { + if ((q = g[n]) && q.length) { + if ((m = k[n]) && m.length) { + for (h = 0; h < q.length; h++) { + m.push(q[h]); + } + } else { + k[n] = q; + } + h = 1; + } + } + } else { + k = g, h = 1; + } + h && e.put(k, f); + }); + } + }), await this.transaction("ctx", "readwrite", function(e) { + for (const d of a.ctx) { + const f = d[0], g = d[1]; + for (const k of g) { + const h = k[0], l = k[1]; + l.length && (c ? e.put(l, f + ":" + h) : e.get(f + ":" + h).onsuccess = function() { + let n = this.result; + var m; + if (n && n.length) { + const q = Math.max(n.length, l.length); + for (let p = 0, r, u; p < q; p++) { + if ((u = l[p]) && u.length) { + if ((r = n[p]) && r.length) { + for (m = 0; m < u.length; m++) { + r.push(u[m]); + } + } else { + n[p] = u; + } + m = 1; + } + } + } else { + n = l, m = 1; + } + m && e.put(n, f + ":" + h); + }); + } + } + }), a.store ? await this.transaction("reg", "readwrite", function(e) { + for (const d of a.store) { + const f = d[0], g = d[1]; + e.put("object" === typeof g ? JSON.stringify(g) : 1, f); + } + }) : a.bypass || await this.transaction("reg", "readwrite", function(e) { + for (const d of a.reg.keys()) { + e.put(1, d); + } + }), a.tag && await this.transaction("tag", "readwrite", function(e) { + for (const d of a.tag) { + const f = d[0], g = d[1]; + g.length && (e.get(f).onsuccess = function() { + let k = this.result; + k = k && k.length ? k.concat(g) : g; + e.put(k, f); + }); + } + }), a.map.clear(), a.ctx.clear(), a.tag && a.tag.clear(), a.store && a.store.clear(), a.document || a.reg.clear()); +}; +function qb(a, c, b) { + const e = a.value; + let d, f = 0; + for (let g = 0, k; g < e.length; g++) { + if (k = b ? e : e[g]) { + for (let h = 0, l, n; h < c.length; h++) { + if (n = c[h], l = k.indexOf(n), 0 <= l) { + if (d = 1, 1 < k.length) { + k.splice(l, 1); + } else { + e[g] = []; + break; + } + } + } + f += k.length; + } + if (b) { + break; + } + } + f ? d && a.update(e) : a.delete(); + a.continue(); +} +t.remove = function(a) { + "object" !== typeof a && (a = [a]); + return Promise.all([this.transaction("map", "readwrite", function(c) { + c.openCursor().onsuccess = function() { + const b = this.result; + b && qb(b, a); + }; + }), this.transaction("ctx", "readwrite", function(c) { + c.openCursor().onsuccess = function() { + const b = this.result; + b && qb(b, a); + }; + }), this.transaction("tag", "readwrite", function(c) { + c.openCursor().onsuccess = function() { + const b = this.result; + b && qb(b, a, !0); + }; + }), this.transaction("reg", "readwrite", function(c) { + for (let b = 0; b < a.length; b++) { + c.delete(a[b]); + } + })]); +}; +function Z(a, c) { + return new Promise((b, e) => { + a.onsuccess = a.oncomplete = function() { + c && c(this.result); + c = null; + b(this.result); + }; + a.onerror = a.onblocked = e; + a = null; + }); +} +;const rb = {Index:N, Charset:cb, Encoder:ja, Document:U, Worker:P, Resolver:W, IndexedDB:pb, Language:{}}, sb = "undefined" !== typeof self ? self : "undefined" !== typeof global ? global : self; +let ub; +(ub = sb.define) && ub.amd ? ub([], function() { + return rb; +}) : "object" === typeof sb.exports ? sb.exports = rb : sb.FlexSearch = rb; +}(this||self)); diff --git a/js/main-head.js b/js/main-head.js new file mode 100644 index 0000000..5b6ce07 --- /dev/null +++ b/js/main-head.js @@ -0,0 +1,19 @@ +// The section must not be in the banner.js (body) file because it can create a quick flash. + +// + +; +// The section must not be in the theme.js (body) file because it can create a quick flash (switch between light and dark). + +function setTheme(theme) { + document.documentElement.classList.remove("light", "dark"); + + if (theme !== "light" && theme !== "dark") { + theme = window.matchMedia("(prefers-color-scheme: dark)").matches ? "dark" : "light"; + } + + document.documentElement.classList.add(theme); + document.documentElement.style.colorScheme = theme; +} + +setTheme("color-theme" in localStorage ? localStorage.getItem("color-theme") : 'dark') diff --git a/js/main-head.min.0a536a3d6032591f79f3f92493af62ab967517fe66e55361030bb4fc101b0dee.js b/js/main-head.min.0a536a3d6032591f79f3f92493af62ab967517fe66e55361030bb4fc101b0dee.js new file mode 100644 index 0000000..7884f08 --- /dev/null +++ b/js/main-head.min.0a536a3d6032591f79f3f92493af62ab967517fe66e55361030bb4fc101b0dee.js @@ -0,0 +1 @@ +function setTheme(e){document.documentElement.classList.remove("light","dark"),e!=="light"&&e!=="dark"&&(e=window.matchMedia("(prefers-color-scheme: dark)").matches?"dark":"light"),document.documentElement.classList.add(e),document.documentElement.style.colorScheme=e}setTheme("color-theme"in localStorage?localStorage.getItem("color-theme"):"dark") \ No newline at end of file diff --git a/js/main.js b/js/main.js new file mode 100644 index 0000000..3d0ecae --- /dev/null +++ b/js/main.js @@ -0,0 +1,1108 @@ +document.addEventListener("DOMContentLoaded", function () { + document.querySelectorAll(".hextra-alert[data-alert-fold]").forEach(function (alert) { + const button = alert.querySelector(".hextra-alert-toggle"); + const content = alert.querySelector(".hextra-alert-content"); + if (!button || !content) { + return; + } + + const sync = function (open) { + alert.dataset.alertFold = open ? "+" : "-"; + button.setAttribute("aria-expanded", open ? "true" : "false"); + content.setAttribute("aria-hidden", open ? "false" : "true"); + content.toggleAttribute("inert", !open); + }; + + sync(alert.dataset.alertFold === "+"); + + button.addEventListener("click", function () { + sync(alert.dataset.alertFold !== "+"); + }); + }); +}); + +; +// Back to top button + +document.addEventListener("DOMContentLoaded", function () { + const backToTop = document.querySelector("#backToTop"); + if (backToTop) { + backToTop.addEventListener("click", scrollUp); + document.addEventListener("scroll", (e) => { + if (window.scrollY > 300) { + backToTop.classList.remove("hx:opacity-0"); + backToTop.removeAttribute("tabindex"); + } else { + backToTop.classList.add("hx:opacity-0"); + backToTop.setAttribute("tabindex", "-1"); + } + }); + } +}); + +function scrollUp() { + const prefersReducedMotion = window.matchMedia('(prefers-reduced-motion: reduce)').matches; + window.scroll({ + top: 0, + left: 0, + behavior: prefersReducedMotion ? 'auto' : 'smooth', + }); +} + +; +// +; +// Copy button for code blocks + +document.addEventListener('DOMContentLoaded', function () { + const getCopyIcon = () => { + const svg = document.createElementNS('http://www.w3.org/2000/svg', 'svg'); + svg.innerHTML = ` + + `; + svg.setAttribute('fill', 'none'); + svg.setAttribute('viewBox', '0 0 24 24'); + svg.setAttribute('stroke', 'currentColor'); + svg.setAttribute('stroke-width', '2'); + return svg; + } + + const getSuccessIcon = () => { + const svg = document.createElementNS('http://www.w3.org/2000/svg', 'svg'); + svg.innerHTML = ` + + `; + svg.setAttribute('fill', 'none'); + svg.setAttribute('viewBox', '0 0 24 24'); + svg.setAttribute('stroke', 'currentColor'); + svg.setAttribute('stroke-width', '2'); + return svg; + } + + // Make scrollable code blocks focusable for keyboard users. + const updateScrollableCodeBlocks = () => { + document.querySelectorAll('.hextra-code-block pre, .highlight pre').forEach(function (pre) { + if (pre.scrollWidth > pre.clientWidth) { + pre.setAttribute('tabindex', '0'); + } else { + pre.removeAttribute('tabindex'); + } + }); + }; + + updateScrollableCodeBlocks(); + + let resizeRaf; + window.addEventListener('resize', () => { + if (resizeRaf) { + cancelAnimationFrame(resizeRaf); + } + resizeRaf = requestAnimationFrame(updateScrollableCodeBlocks); + }); + + document.querySelectorAll('.hextra-code-copy-btn').forEach(function (button) { + // Add copy and success icons + button.querySelector('.hextra-copy-icon')?.appendChild(getCopyIcon()); + button.querySelector('.hextra-success-icon')?.appendChild(getSuccessIcon()); + + // Add click event listener for copy button + button.addEventListener('click', function (e) { + e.preventDefault(); + // Get the code target + const target = button.parentElement.previousElementSibling; + let codeElement; + if (target.tagName === 'CODE') { + codeElement = target; + } else { + // Select the last code element in case line numbers are present + const codeElements = target.querySelectorAll('code'); + codeElement = codeElements[codeElements.length - 1]; + } + if (codeElement) { + let code = codeElement.innerText; + // Replace double newlines with single newlines in the innerText + // as each line inside has trailing newline '\n' + if ("lang" in codeElement.dataset) { + code = code.replace(/\n\n/g, '\n'); + } + navigator.clipboard.writeText(code).then(function () { + button.classList.add('copied'); + var originalLabel = button.getAttribute('aria-label'); + var copiedLabel = button.dataset.copiedLabel || 'Copied!'; + button.setAttribute('aria-label', copiedLabel); + setTimeout(function () { + button.classList.remove('copied'); + button.setAttribute('aria-label', originalLabel); + }, 1000); + }).catch(function (err) { + console.error('Failed to copy text: ', err); + }); + } else { + console.error('Target element not found'); + } + }); + }); +}); + +; +// +(function () { + const faviconEl = document.getElementById("favicon-svg"); + const faviconDarkExists = "true" === "true"; + + if (faviconEl && faviconDarkExists) { + const lightFavicon = '/favicon.svg'; + const darkFavicon = '/favicon-dark.svg'; + + const darkModeQuery = window.matchMedia("(prefers-color-scheme: dark)"); + + function updateFavicon(e) { + faviconEl.href = e.matches ? darkFavicon : lightFavicon; + } + + // Set favicon on load + updateFavicon(darkModeQuery); + + // Listen for system preference changes + darkModeQuery.addEventListener("change", updateFavicon); + } +})(); + +; +// Script for filetree shortcode collapsing/expanding folders used in the theme +// ====================================================================== +document.addEventListener("DOMContentLoaded", function () { + const folders = document.querySelectorAll(".hextra-filetree-folder"); + folders.forEach(function (folder) { + folder.addEventListener("click", function () { + Array.from(folder.children).forEach(function (el) { + el.dataset.state = el.dataset.state === "open" ? "closed" : "open"; + }); + var newState = folder.nextElementSibling.dataset.state === "open" ? "closed" : "open"; + folder.nextElementSibling.dataset.state = newState; + folder.setAttribute('aria-expanded', newState === 'open' ? 'true' : 'false'); + }); + }); +}); + +; +(function () { + const languageSwitchers = document.querySelectorAll('.hextra-language-switcher'); + const closeSwitcher = (switcher, focusSwitcher = false) => { + switcher.dataset.state = 'closed'; + switcher.setAttribute('aria-expanded', 'false'); + const optionsElement = switcher.nextElementSibling; + optionsElement.classList.add('hx:hidden'); + if (focusSwitcher) { + switcher.focus(); + } + }; + + const openSwitcher = (switcher, focusTarget = "none") => { + switcher.dataset.state = 'open'; + switcher.setAttribute('aria-expanded', 'true'); + const optionsElement = switcher.nextElementSibling; + if (optionsElement.classList.contains('hx:hidden')) { + toggleMenu(switcher); + } else { + resizeMenu(switcher); + } + + if (focusTarget !== "none") { + const items = Array.from(optionsElement.querySelectorAll('[role="menuitem"]')); + if (items.length > 0) { + const target = focusTarget === "last" ? items[items.length - 1] : items[0]; + target.focus(); + } + } + }; + + languageSwitchers.forEach((switcher) => { + switcher.addEventListener('click', (e) => { + e.preventDefault(); + + if (switcher.dataset.state === 'open') { + closeSwitcher(switcher); + } else { + openSwitcher(switcher); + } + }); + + switcher.addEventListener('keydown', (e) => { + if (e.key === 'ArrowDown') { + e.preventDefault(); + openSwitcher(switcher, 'first'); + } else if (e.key === 'ArrowUp') { + e.preventDefault(); + openSwitcher(switcher, 'last'); + } + }); + }); + + document.querySelectorAll('.hextra-language-options[role=menu]').forEach((menu) => { + menu.addEventListener('keydown', (e) => { + const items = Array.from(menu.querySelectorAll('[role="menuitem"]')); + if (items.length === 0) return; + + const currentIndex = items.indexOf(document.activeElement); + let newIndex; + + switch (e.key) { + case 'ArrowDown': + e.preventDefault(); + newIndex = (currentIndex + 1) % items.length; + items[newIndex].focus(); + break; + case 'ArrowUp': + e.preventDefault(); + newIndex = (currentIndex - 1 + items.length) % items.length; + items[newIndex].focus(); + break; + case 'Home': + e.preventDefault(); + items[0].focus(); + break; + case 'End': + e.preventDefault(); + items[items.length - 1].focus(); + break; + case 'Escape': { + e.preventDefault(); + const switcher = menu.previousElementSibling; + if (switcher) { + closeSwitcher(switcher, true); + } + break; + } + } + }); + }); + + window.addEventListener("resize", () => languageSwitchers.forEach(resizeMenu)); + + // Dismiss language switcher when clicking outside. + document.addEventListener('click', (e) => { + if (!e.target.closest('.hextra-language-switcher') && !e.target.closest('.hextra-language-options')) { + languageSwitchers.forEach((switcher) => { + closeSwitcher(switcher); + }); + } + }); +})(); + +; +// Hamburger menu for mobile navigation + +document.addEventListener('DOMContentLoaded', function () { + const menu = document.querySelector('.hextra-hamburger-menu'); + const sidebarContainer = document.querySelector('.hextra-sidebar-container'); + const mobileQuery = window.matchMedia('(max-width: 767px)'); + + function isMenuOpen() { + return menu.querySelector('svg').classList.contains('open'); + } + + // On mobile, the sidebar is off-screen so hide it from assistive tech + function syncAriaHidden() { + if (mobileQuery.matches) { + sidebarContainer.setAttribute('aria-hidden', isMenuOpen() ? 'false' : 'true'); + } else { + sidebarContainer.removeAttribute('aria-hidden'); + } + } + + // Set initial state + syncAriaHidden(); + mobileQuery.addEventListener('change', syncAriaHidden); + + function toggleMenu(options = {}) { + const { focusOnOpen = true } = options; + + // Toggle the hamburger menu + menu.querySelector('svg').classList.toggle('open'); + + // When the menu is open, we want to show the navigation sidebar + sidebarContainer.classList.toggle('hx:max-md:[transform:translate3d(0,-100%,0)]'); + sidebarContainer.classList.toggle('hx:max-md:[transform:translate3d(0,0,0)]'); + + // When the menu is open, we want to prevent the body from scrolling + document.body.classList.toggle('hx:overflow-hidden'); + document.body.classList.toggle('hx:md:overflow-auto'); + + // Sync aria-expanded and aria-hidden + const isOpen = isMenuOpen(); + menu.setAttribute('aria-expanded', isOpen ? 'true' : 'false'); + syncAriaHidden(); + + // Move focus into sidebar when opening, restore when closing + if (isOpen) { + if (focusOnOpen) { + const firstFocusable = sidebarContainer.querySelector('a, button, input, [tabindex="0"]'); + if (firstFocusable) firstFocusable.focus(); + } + } else { + menu.focus(); + } + } + + menu.addEventListener('click', (e) => { + e.preventDefault(); + // Pointer-initiated clicks on mobile should not force focus into the search input, + // which opens the software keyboard immediately. + toggleMenu({ focusOnOpen: e.detail === 0 }); + }); + + // Close menu on Escape key (mobile only) + document.addEventListener('keydown', (e) => { + if (e.key !== 'Escape') return; + if (document.getElementById('hextra-search-dialog')?.open) return; + if (mobileQuery.matches && isMenuOpen()) { + toggleMenu(); + } + }); + + // Select all anchor tags in the sidebar container + const sidebarLinks = sidebarContainer.querySelectorAll('a'); + + // Add click event listener to each anchor tag + sidebarLinks.forEach(link => { + link.addEventListener('click', (e) => { + // Check if the href attribute contains a hash symbol (links to a heading) + if (link.getAttribute('href') && link.getAttribute('href').startsWith('#')) { + // Only dismiss overlay on mobile view + if (window.innerWidth < 768) { + toggleMenu(); + } + } + }); + }); +}); + +; +(function () { + const hiddenClass = "hx:hidden"; + const dropdownToggles = document.querySelectorAll(".hextra-nav-menu-toggle"); + const closeDropdown = (toggle, focusToggle = false) => { + toggle.dataset.state = "closed"; + toggle.setAttribute("aria-expanded", "false"); + const menuItemsElement = toggle.nextElementSibling; + menuItemsElement.classList.add(hiddenClass); + if (focusToggle) { + toggle.focus(); + } + }; + + const openDropdown = (toggle, focusTarget = "none") => { + // Close all other dropdowns first. + dropdownToggles.forEach((otherToggle) => { + if (otherToggle !== toggle) { + closeDropdown(otherToggle); + } + }); + + toggle.dataset.state = "open"; + toggle.setAttribute("aria-expanded", "true"); + const menuItemsElement = toggle.nextElementSibling; + + // Position dropdown centered with toggle. + menuItemsElement.style.position = "absolute"; + menuItemsElement.style.top = "100%"; + menuItemsElement.style.left = "50%"; + menuItemsElement.style.transform = "translateX(-50%)"; + menuItemsElement.style.zIndex = "1000"; + menuItemsElement.classList.remove(hiddenClass); + + if (focusTarget !== "none") { + const items = Array.from(menuItemsElement.querySelectorAll('[role="menuitem"]')); + if (items.length > 0) { + const target = focusTarget === "last" ? items[items.length - 1] : items[0]; + target.focus(); + } + } + }; + + dropdownToggles.forEach((toggle) => { + toggle.addEventListener("click", (e) => { + e.preventDefault(); + e.stopPropagation(); + + // Toggle current dropdown. + const isOpen = toggle.dataset.state === "open"; + if (isOpen) { + closeDropdown(toggle); + } else { + openDropdown(toggle); + } + }); + + toggle.addEventListener("keydown", (e) => { + if (e.key === "ArrowDown") { + e.preventDefault(); + openDropdown(toggle, "first"); + } else if (e.key === "ArrowUp") { + e.preventDefault(); + openDropdown(toggle, "last"); + } + }); + }); + + document.querySelectorAll(".hextra-nav-menu-items[role=menu]").forEach((menu) => { + menu.addEventListener("keydown", (e) => { + const items = Array.from(menu.querySelectorAll('[role="menuitem"]')); + if (items.length === 0) return; + + const currentIndex = items.indexOf(document.activeElement); + let newIndex; + + switch (e.key) { + case "ArrowDown": + e.preventDefault(); + newIndex = (currentIndex + 1) % items.length; + items[newIndex].focus(); + break; + case "ArrowUp": + e.preventDefault(); + newIndex = (currentIndex - 1 + items.length) % items.length; + items[newIndex].focus(); + break; + case "Home": + e.preventDefault(); + items[0].focus(); + break; + case "End": + e.preventDefault(); + items[items.length - 1].focus(); + break; + case "Escape": { + e.preventDefault(); + const toggle = menu.previousElementSibling; + if (toggle) { + closeDropdown(toggle, true); + } + break; + } + } + }); + }); + + // Dismiss dropdown when clicking outside. + document.addEventListener("click", (e) => { + if (!e.target.closest(".hextra-nav-menu-toggle") && !e.target.closest(".hextra-nav-menu-items")) { + dropdownToggles.forEach((toggle) => { + closeDropdown(toggle); + }); + } + }); + + // Close dropdowns on escape key. + document.addEventListener("keydown", (e) => { + if (e.key === "Escape") { + dropdownToggles.forEach((toggle) => { + if (toggle.dataset.state === "open") { + closeDropdown(toggle, true); + } + }); + } + }); +})(); + +; +document.addEventListener('DOMContentLoaded', () => { + // Pre-fetch markdown content for all copy buttons to avoid Safari NotAllowedError + // Safari requires clipboard writes to happen synchronously within user gesture + const copyButtons = document.querySelectorAll('.hextra-page-context-menu-copy'); + const contentCache = new Map(); + + // Pre-fetch content for each button on page load + copyButtons.forEach(button => { + const url = button.dataset.url; + if (url) { + fetch(url) + .then(response => { + if (response.ok) return response.text(); + throw new Error('Failed to fetch'); + }) + .then(markdown => contentCache.set(url, markdown)) + .catch(error => console.error('Failed to pre-fetch markdown:', error)); + } + }); + + // Initialize copy buttons with synchronous clipboard access + copyButtons.forEach(button => { + button.addEventListener('click', () => { + const url = button.dataset.url; + const markdown = contentCache.get(url); + + if (markdown) { + // Synchronous clipboard write initiation - works in Safari + navigator.clipboard.writeText(markdown) + .then(() => { + button.classList.add('copied'); + setTimeout(() => button.classList.remove('copied'), 1000); + }) + .catch(error => console.error('Failed to copy markdown:', error)); + } else { + // Fallback: fetch and copy (may fail in Safari if content not pre-fetched) + fetch(url) + .then(response => { + if (!response.ok) throw new Error('Failed to fetch'); + return response.text(); + }) + .then(text => { + contentCache.set(url, text); + return navigator.clipboard.writeText(text); + }) + .then(() => { + button.classList.add('copied'); + setTimeout(() => button.classList.remove('copied'), 1000); + }) + .catch(error => console.error('Failed to copy markdown:', error)); + } + }); + }); + + // Initialize dropdown toggles + const dropdownToggles = document.querySelectorAll('.hextra-page-context-menu-toggle'); + dropdownToggles.forEach(toggle => { + const container = toggle.closest('.hextra-page-context-menu'); + const menu = container.querySelector('.hextra-page-context-menu-dropdown'); + const chevron = toggle.querySelector('[data-chevron]'); + + toggle.addEventListener('click', (e) => { + e.stopPropagation(); + const isOpen = toggle.dataset.state === 'open'; + + // Close all other dropdowns first + dropdownToggles.forEach(t => { + if (t !== toggle) { + t.dataset.state = 'closed'; + t.setAttribute('aria-expanded', 'false'); + const otherContainer = t.closest('.hextra-page-context-menu'); + const otherMenu = otherContainer.querySelector('.hextra-page-context-menu-dropdown'); + const otherChevron = t.querySelector('[data-chevron]'); + otherMenu.classList.add('hx:hidden'); + if (otherChevron) { + otherChevron.style.transform = ''; + } + } + }); + + // Toggle current + toggle.dataset.state = isOpen ? 'closed' : 'open'; + toggle.setAttribute('aria-expanded', isOpen ? 'false' : 'true'); + menu.classList.toggle('hx:hidden', isOpen); + + // Rotate chevron icon + if (chevron) { + chevron.style.transform = isOpen ? '' : 'rotate(180deg)'; + } + }); + }); + + // Close dropdown when clicking outside + document.addEventListener('click', (e) => { + // Check if click is outside any dropdown container + const isOutside = !e.target.closest('.hextra-page-context-menu'); + if (isOutside) { + dropdownToggles.forEach(toggle => { + toggle.dataset.state = 'closed'; + toggle.setAttribute('aria-expanded', 'false'); + const container = toggle.closest('.hextra-page-context-menu'); + const menu = container.querySelector('.hextra-page-context-menu-dropdown'); + const chevron = toggle.querySelector('[data-chevron]'); + menu.classList.add('hx:hidden'); + if (chevron) { + chevron.style.transform = ''; + } + }); + } + }); + + // Close dropdown on Escape key and return focus to toggle + document.addEventListener('keydown', (e) => { + if (e.key === 'Escape') { + dropdownToggles.forEach(toggle => { + if (toggle.dataset.state === 'open') { + const container = toggle.closest('.hextra-page-context-menu'); + closeDropdown(container); + toggle.focus(); + } + }); + } + }); + + // Helper to close dropdown + const closeDropdown = (container) => { + if (!container) return; + + const toggle = container.querySelector('.hextra-page-context-menu-toggle'); + const menu = container.querySelector('.hextra-page-context-menu-dropdown'); + + if (!toggle || !menu) return; + + const chevron = toggle.querySelector('[data-chevron]'); + toggle.dataset.state = 'closed'; + toggle.setAttribute('aria-expanded', 'false'); + menu.classList.add('hx:hidden'); + if (chevron) { + chevron.style.transform = ''; + } + }; + + // Handle dropdown menu copy action + document.querySelectorAll('.hextra-page-context-menu-dropdown button[data-action="copy"]').forEach(btn => { + btn.addEventListener('click', async (e) => { + e.stopPropagation(); + const container = btn.closest('.hextra-page-context-menu'); + if (!container) return; + + const copyBtn = container.querySelector('.hextra-page-context-menu-copy'); + if (!copyBtn) return; + + closeDropdown(container); + copyBtn.click(); + }); + }); + + // Handle dropdown menu view action + document.querySelectorAll('.hextra-page-context-menu-dropdown button[data-action="view"]').forEach(btn => { + btn.addEventListener('click', (e) => { + e.stopPropagation(); + const container = btn.closest('.hextra-page-context-menu'); + if (!container) return; + + const url = btn.dataset.url; + if (!url) return; + + closeDropdown(container); + window.open(url, '_blank', 'noopener,noreferrer'); + }); + }); +}); + +; +document.addEventListener("DOMContentLoaded", function () { + scrollToActiveItem(); + enableCollapsibles(); +}); + +function enableCollapsibles() { + const buttons = document.querySelectorAll(".hextra-sidebar-collapsible-button"); + buttons.forEach(function (button) { + button.addEventListener("click", function (e) { + e.preventDefault(); + const list = button.closest('li'); + if (list) { + list.classList.toggle("open"); + button.setAttribute('aria-expanded', list.classList.contains('open') ? 'true' : 'false'); + } + }); + }); +} + +function scrollToActiveItem() { + const sidebarScrollbar = document.querySelector("aside.hextra-sidebar-container > .hextra-scrollbar"); + const activeItems = document.querySelectorAll(".hextra-sidebar-active-item"); + const visibleActiveItem = Array.from(activeItems).find(function (activeItem) { + return activeItem.getBoundingClientRect().height > 0; + }); + + if (!visibleActiveItem) { + return; + } + + const yOffset = visibleActiveItem.clientHeight; + const yDistance = visibleActiveItem.getBoundingClientRect().top - sidebarScrollbar.getBoundingClientRect().top; + sidebarScrollbar.scrollTo({ + behavior: "instant", + top: yDistance - yOffset + }); +} + +; +function computeMenuTranslation(switcher, optionsElement) { + // Calculate the position of a language options element. + const switcherRect = switcher.getBoundingClientRect(); + + // Must be called before optionsElement.clientWidth. + optionsElement.style.minWidth = `${Math.max(switcherRect.width, 50)}px`; + + const isOnTop = switcher.dataset.location === 'top'; + const isOnBottom = switcher.dataset.location === 'bottom'; + const isOnBottomRight = switcher.dataset.location === 'bottom-right'; + const isRTL = document.documentElement.dir === 'rtl' + + // Stuck on the left side of the switcher. + let x = switcherRect.left; + + if (isOnTop && !isRTL || isOnBottom && isRTL || isOnBottomRight && !isRTL) { + // Stuck on the right side of the switcher. + x = switcherRect.right - optionsElement.clientWidth; + } + + // Stuck on the top of the switcher. + let y = switcherRect.top - window.innerHeight - 10; + + if (isOnTop) { + // Stuck on the bottom of the switcher. + y = switcherRect.top - window.innerHeight + optionsElement.clientHeight + switcher.clientHeight + 4; + } + + return { x: x, y: y }; +} + +function toggleMenu(switcher) { + const optionsElement = switcher.nextElementSibling; + + optionsElement.classList.toggle('hx:hidden'); + + // Calculate the position of a language options element. + const translate = computeMenuTranslation(switcher, optionsElement); + + optionsElement.style.transform = `translate3d(${translate.x}px, ${translate.y}px, 0)`; +} + +function resizeMenu(switcher) { + const optionsElement = switcher.nextElementSibling; + + if (optionsElement.classList.contains('hx:hidden')) return; + + // Calculate the position of a language options element. + const translate = computeMenuTranslation(switcher, optionsElement); + + optionsElement.style.transform = `translate3d(${translate.x}px, ${translate.y}px, 0)`; +} + +; +(function () { + function updateGroup(container, index) { + const tabs = Array.from(container.querySelectorAll('.hextra-tabs-toggle')); + tabs.forEach((tab, i) => { + tab.dataset.state = i === index ? 'selected' : ''; + if (i === index) { + tab.setAttribute('aria-selected', 'true'); + tab.tabIndex = 0; + } else { + tab.setAttribute('aria-selected', 'false'); + tab.tabIndex = -1; + } + }); + const panelsContainer = container.parentElement.nextElementSibling; + if (!panelsContainer) return; + Array.from(panelsContainer.children).forEach((panel, i) => { + panel.dataset.state = i === index ? 'selected' : ''; + panel.setAttribute('aria-hidden', i === index ? 'false' : 'true'); + if (i === index) { + panel.tabIndex = 0; + } else { + panel.removeAttribute('tabindex'); + } + }); + } + + const syncGroups = document.querySelectorAll('[data-tab-group]'); + + syncGroups.forEach((group) => { + const key = encodeURIComponent(group.dataset.tabGroup); + const saved = localStorage.getItem('hextra-tab-' + key); + if (saved !== null) { + updateGroup(group, parseInt(saved, 10)); + } + }); + + document.querySelectorAll('.hextra-tabs-toggle').forEach((button) => { + button.addEventListener('click', function (e) { + const targetButton = e.currentTarget; + const container = targetButton.parentElement; + const index = Array.from(container.querySelectorAll('.hextra-tabs-toggle')).indexOf( + targetButton + ); + + if (container.dataset.tabGroup) { + // Sync behavior: update all tab groups with the same name + const tabGroupValue = container.dataset.tabGroup; + const key = encodeURIComponent(tabGroupValue); + document + .querySelectorAll('[data-tab-group="' + tabGroupValue + '"]') + .forEach((grp) => updateGroup(grp, index)); + localStorage.setItem('hextra-tab-' + key, index.toString()); + } else { + // Non-sync behavior: update only this specific tab group + updateGroup(container, index); + } + }); + + // Keyboard navigation for tabs + button.addEventListener('keydown', function (e) { + const container = button.parentElement; + const tabs = Array.from(container.querySelectorAll('.hextra-tabs-toggle')); + const currentIndex = tabs.indexOf(button); + let newIndex; + + switch (e.key) { + case 'ArrowRight': + case 'ArrowDown': + e.preventDefault(); + newIndex = (currentIndex + 1) % tabs.length; + break; + case 'ArrowLeft': + case 'ArrowUp': + e.preventDefault(); + newIndex = (currentIndex - 1 + tabs.length) % tabs.length; + break; + case 'Home': + e.preventDefault(); + newIndex = 0; + break; + case 'End': + e.preventDefault(); + newIndex = tabs.length - 1; + break; + default: + return; + } + + if (container.dataset.tabGroup) { + const tabGroupValue = container.dataset.tabGroup; + const key = encodeURIComponent(tabGroupValue); + document + .querySelectorAll('[data-tab-group="' + tabGroupValue + '"]') + .forEach((grp) => updateGroup(grp, newIndex)); + localStorage.setItem('hextra-tab-' + key, newIndex.toString()); + } else { + updateGroup(container, newIndex); + } + tabs[newIndex].focus(); + }); + }); +})(); + +; +document.addEventListener("DOMContentLoaded", function () { + // Hugo task lists render bare checkboxes; provide an accessible name. + document.querySelectorAll("main#content li > input[type='checkbox']").forEach(function (checkbox) { + if (checkbox.hasAttribute("aria-label") || checkbox.hasAttribute("aria-labelledby")) { + return; + } + var listItem = checkbox.closest("li"); + if (!listItem) return; + + var labelText = listItem.textContent.replace(/\s+/g, " ").trim(); + if (labelText) { + checkbox.setAttribute("aria-label", labelText); + } + }); +}); + +; +// Light / Dark theme toggle +(function () { + const defaultTheme = 'dark' + const themes = ["light", "dark"]; + + const themeToggleButtons = document.querySelectorAll(".hextra-theme-toggle"); + const themeToggleOptions = document.querySelectorAll(".hextra-theme-toggle-options button[role=menuitemradio]"); + + function applyTheme(theme) { + theme = themes.includes(theme) ? theme : "system"; + + themeToggleButtons.forEach((btn) => btn.parentElement.dataset.theme = theme ); + themeToggleOptions.forEach((option) => { + option.setAttribute('aria-checked', option.dataset.item === theme ? 'true' : 'false'); + }); + + localStorage.setItem("color-theme", theme); + } + + function switchTheme(theme) { + setTheme(theme); + applyTheme(theme); + } + + const colorTheme = "color-theme" in localStorage ? localStorage.getItem("color-theme") : defaultTheme; + switchTheme(colorTheme); + + // Add click event handler to the menu items. + themeToggleOptions.forEach((option) => { + option.addEventListener("click", function (e) { + e.preventDefault(); + + switchTheme(option.dataset.item); + }) + }) + + // Add click event handler to the buttons + themeToggleButtons.forEach((toggler) => { + toggler.addEventListener("click", function (e) { + e.preventDefault(); + + toggler.dataset.state = toggler.dataset.state === 'open' ? 'closed' : 'open'; + toggleMenu(toggler); + const isOpen = toggler.dataset.state === 'open'; + toggler.setAttribute('aria-expanded', isOpen ? 'true' : 'false'); + + // Focus first menuitem when opening + if (isOpen) { + const firstItem = toggler.nextElementSibling.querySelector('button[role=menuitemradio]'); + if (firstItem) firstItem.focus(); + } + }); + }); + + window.addEventListener("resize", () => themeToggleButtons.forEach(resizeMenu)) + + // Dismiss the menu when clicking outside + document.addEventListener('click', (e) => { + if (e.target.closest('.hextra-theme-toggle') === null) { + themeToggleButtons.forEach((toggler) => { + toggler.dataset.state = 'closed'; + toggler.setAttribute('aria-expanded', 'false'); + toggler.nextElementSibling.classList.add('hx:hidden'); + }); + } + }); + + // Keyboard navigation for the theme menu + document.querySelectorAll('.hextra-theme-toggle-options[role=menu]').forEach(function (menu) { + menu.addEventListener('keydown', function (e) { + const items = Array.from(menu.querySelectorAll('button[role=menuitemradio]')); + const currentIndex = items.indexOf(document.activeElement); + let newIndex; + + switch (e.key) { + case 'ArrowDown': + e.preventDefault(); + newIndex = (currentIndex + 1) % items.length; + items[newIndex].focus(); + break; + case 'ArrowUp': + e.preventDefault(); + newIndex = (currentIndex - 1 + items.length) % items.length; + items[newIndex].focus(); + break; + case 'Home': + e.preventDefault(); + items[0].focus(); + break; + case 'End': + e.preventDefault(); + items[items.length - 1].focus(); + break; + case 'Escape': + e.preventDefault(); + var toggler = menu.previousElementSibling; + toggler.dataset.state = 'closed'; + toggler.setAttribute('aria-expanded', 'false'); + menu.classList.add('hx:hidden'); + toggler.focus(); + break; + } + }); + }); + + // Listen for system theme changes + window.matchMedia("(prefers-color-scheme: dark)").addEventListener("change", () => { + if (localStorage.getItem("color-theme") === "system") { + setTheme("system"); + } + }); +})(); + +; +/** + * TOC Scroll - Highlights active TOC links based on visible headings + * + * Uses Intersection Observer to track heading visibility and applies + * 'hextra-toc-active' class to corresponding TOC links. Selects the + * topmost heading when multiple are visible. + * + * Requires: .hextra-toc element, matching heading IDs, toc.css styles + */ +document.addEventListener("DOMContentLoaded", function () { + const toc = document.querySelector(".hextra-toc"); + if (!toc) return; + + const tocLinks = toc.querySelectorAll('a[href^="#"]'); + if (tocLinks.length === 0) return; + + const headingIds = Array.from(tocLinks).map((link) => link.getAttribute("href").substring(1)); + + const headings = headingIds.map((id) => document.getElementById(decodeURIComponent(id))).filter(Boolean); + if (headings.length === 0) return; + + let currentActiveLink = null; + let isHashNavigation = false; + + // Create intersection observer + const observer = new IntersectionObserver( + (entries) => { + // Skip observer updates during hash navigation + if (isHashNavigation) return; + + const visibleHeadings = entries.filter((entry) => entry.isIntersecting).map((entry) => entry.target); + + if (visibleHeadings.length === 0) return; + + // Find the heading closest to the top of the viewport + const topMostHeading = visibleHeadings.reduce((closest, heading) => { + const headingTop = heading.getBoundingClientRect().top; + const closestTop = closest.getBoundingClientRect().top; + return Math.abs(headingTop) < Math.abs(closestTop) ? heading : closest; + }); + + // Encode the id and make it lowercase to match the TOC link + const targetId = encodeURIComponent(topMostHeading.id).toLowerCase(); + const targetLink = toc.querySelector(`a[href="#${targetId}"]`); + + if (targetLink && targetLink !== currentActiveLink) { + // Remove active class from previous link + if (currentActiveLink) { + currentActiveLink.classList.remove("hextra-toc-active"); + currentActiveLink.removeAttribute("aria-current"); + } + + // Add active class to current link + targetLink.classList.add("hextra-toc-active"); + targetLink.setAttribute("aria-current", "location"); + currentActiveLink = targetLink; + } + }, + { + rootMargin: "-20px 0px -60% 0px", // Adjust sensitivity + threshold: [0, 0.1, 0.5, 1], + } + ); + + // Observe all headings + headings.forEach((heading) => observer.observe(heading)); + + // Handle direct navigation to page with hash + function handleHashNavigation() { + const hash = window.location.hash; // already url encoded + if (hash) { + const targetLink = toc.querySelector(`a[href="${hash}"]`); + if (targetLink) { + // Disable observer temporarily during hash navigation + isHashNavigation = true; + + if (currentActiveLink) { + currentActiveLink.classList.remove("hextra-toc-active"); + currentActiveLink.removeAttribute("aria-current"); + } + targetLink.classList.add("hextra-toc-active"); + targetLink.setAttribute("aria-current", "location"); + currentActiveLink = targetLink; + + // Re-enable observer after scroll settles + setTimeout(() => { isHashNavigation = false; }, 500); + return; + } + } + } + + // Handle hash changes navigation + window.addEventListener("hashchange", handleHashNavigation); + + // Handle initial load + setTimeout(handleHashNavigation, 100); +}); diff --git a/js/main.min.5a33e67419f50c564bfb1a76c021e37fea076ca4e73ffeba1c2df2d11f6aa3f6.js b/js/main.min.5a33e67419f50c564bfb1a76c021e37fea076ca4e73ffeba1c2df2d11f6aa3f6.js new file mode 100644 index 0000000..720e7d7 --- /dev/null +++ b/js/main.min.5a33e67419f50c564bfb1a76c021e37fea076ca4e73ffeba1c2df2d11f6aa3f6.js @@ -0,0 +1,6 @@ +document.addEventListener("DOMContentLoaded",function(){document.querySelectorAll(".hextra-alert[data-alert-fold]").forEach(function(e){const t=e.querySelector(".hextra-alert-toggle"),n=e.querySelector(".hextra-alert-content");if(!t||!n)return;const s=function(s){e.dataset.alertFold=s?"+":"-",t.setAttribute("aria-expanded",s?"true":"false"),n.setAttribute("aria-hidden",s?"false":"true"),n.toggleAttribute("inert",!s)};s(e.dataset.alertFold==="+"),t.addEventListener("click",function(){s(e.dataset.alertFold!=="+")})})}),document.addEventListener("DOMContentLoaded",function(){const e=document.querySelector("#backToTop");e&&(e.addEventListener("click",scrollUp),document.addEventListener("scroll",t=>{window.scrollY>300?(e.classList.remove("hx:opacity-0"),e.removeAttribute("tabindex")):(e.classList.add("hx:opacity-0"),e.setAttribute("tabindex","-1"))}))});function scrollUp(){const e=window.matchMedia("(prefers-reduced-motion: reduce)").matches;window.scroll({top:0,left:0,behavior:e?"auto":"smooth"})}document.addEventListener("DOMContentLoaded",function(){const n=()=>{const e=document.createElementNS("http://www.w3.org/2000/svg","svg");return e.innerHTML=` + + `,e.setAttribute("fill","none"),e.setAttribute("viewBox","0 0 24 24"),e.setAttribute("stroke","currentColor"),e.setAttribute("stroke-width","2"),e},s=()=>{const e=document.createElementNS("http://www.w3.org/2000/svg","svg");return e.innerHTML=` + + `,e.setAttribute("fill","none"),e.setAttribute("viewBox","0 0 24 24"),e.setAttribute("stroke","currentColor"),e.setAttribute("stroke-width","2"),e},t=()=>{document.querySelectorAll(".hextra-code-block pre, .highlight pre").forEach(function(e){e.scrollWidth>e.clientWidth?e.setAttribute("tabindex","0"):e.removeAttribute("tabindex")})};t();let e;window.addEventListener("resize",()=>{e&&cancelAnimationFrame(e),e=requestAnimationFrame(t)}),document.querySelectorAll(".hextra-code-copy-btn").forEach(function(e){e.querySelector(".hextra-copy-icon")?.appendChild(n()),e.querySelector(".hextra-success-icon")?.appendChild(s()),e.addEventListener("click",function(t){t.preventDefault();const s=e.parentElement.previousElementSibling;let n;if(s.tagName==="CODE")n=s;else{const e=s.querySelectorAll("code");n=e[e.length-1]}if(n){let t=n.innerText;"lang"in n.dataset&&(t=t.replace(/\n\n/g,` +`)),navigator.clipboard.writeText(t).then(function(){e.classList.add("copied");var t=e.getAttribute("aria-label"),n=e.dataset.copiedLabel||"Copied!";e.setAttribute("aria-label",n),setTimeout(function(){e.classList.remove("copied"),e.setAttribute("aria-label",t)},1e3)}).catch(function(e){console.error("Failed to copy text: ",e)})}else console.error("Target element not found")})})}),function(){const e=document.getElementById("favicon-svg"),n="true"==="true";if(e&&n){const s="/favicon.svg",o="/favicon-dark.svg",n=window.matchMedia("(prefers-color-scheme: dark)");function t(t){e.href=t.matches?o:s}t(n),n.addEventListener("change",t)}}(),document.addEventListener("DOMContentLoaded",function(){const e=document.querySelectorAll(".hextra-filetree-folder");e.forEach(function(e){e.addEventListener("click",function(){Array.from(e.children).forEach(function(e){e.dataset.state=e.dataset.state==="open"?"closed":"open"});var t=e.nextElementSibling.dataset.state==="open"?"closed":"open";e.nextElementSibling.dataset.state=t,e.setAttribute("aria-expanded",t==="open"?"true":"false")})})}),function(){const e=document.querySelectorAll(".hextra-language-switcher"),t=(e,t=!1)=>{e.dataset.state="closed",e.setAttribute("aria-expanded","false");const n=e.nextElementSibling;n.classList.add("hx:hidden"),t&&e.focus()},n=(e,t="none")=>{e.dataset.state="open",e.setAttribute("aria-expanded","true");const n=e.nextElementSibling;if(n.classList.contains("hx:hidden")?toggleMenu(e):resizeMenu(e),t!=="none"){const e=Array.from(n.querySelectorAll('[role="menuitem"]'));if(e.length>0){const n=t==="last"?e[e.length-1]:e[0];n.focus()}}};e.forEach(e=>{e.addEventListener("click",s=>{s.preventDefault(),e.dataset.state==="open"?t(e):n(e)}),e.addEventListener("keydown",t=>{t.key==="ArrowDown"?(t.preventDefault(),n(e,"first")):t.key==="ArrowUp"&&(t.preventDefault(),n(e,"last"))})}),document.querySelectorAll(".hextra-language-options[role=menu]").forEach(e=>{e.addEventListener("keydown",n=>{const s=Array.from(e.querySelectorAll('[role="menuitem"]'));if(s.length===0)return;const i=s.indexOf(document.activeElement);let o;switch(n.key){case"ArrowDown":n.preventDefault(),o=(i+1)%s.length,s[o].focus();break;case"ArrowUp":n.preventDefault(),o=(i-1+s.length)%s.length,s[o].focus();break;case"Home":n.preventDefault(),s[0].focus();break;case"End":n.preventDefault(),s[s.length-1].focus();break;case"Escape":{n.preventDefault();const s=e.previousElementSibling;s&&t(s,!0);break}}})}),window.addEventListener("resize",()=>e.forEach(resizeMenu)),document.addEventListener("click",n=>{!n.target.closest(".hextra-language-switcher")&&!n.target.closest(".hextra-language-options")&&e.forEach(e=>{t(e)})})}(),document.addEventListener("DOMContentLoaded",function(){const t=document.querySelector(".hextra-hamburger-menu"),e=document.querySelector(".hextra-sidebar-container"),n=window.matchMedia("(max-width: 767px)");function s(){return t.querySelector("svg").classList.contains("open")}function o(){n.matches?e.setAttribute("aria-hidden",s()?"false":"true"):e.removeAttribute("aria-hidden")}o(),n.addEventListener("change",o);function i(n={}){const{focusOnOpen:a=!0}=n;t.querySelector("svg").classList.toggle("open"),e.classList.toggle("hx:max-md:[transform:translate3d(0,-100%,0)]"),e.classList.toggle("hx:max-md:[transform:translate3d(0,0,0)]"),document.body.classList.toggle("hx:overflow-hidden"),document.body.classList.toggle("hx:md:overflow-auto");const i=s();if(t.setAttribute("aria-expanded",i?"true":"false"),o(),i){if(a){const t=e.querySelector('a, button, input, [tabindex="0"]');t&&t.focus()}}else t.focus()}t.addEventListener("click",e=>{e.preventDefault(),i({focusOnOpen:e.detail===0})}),document.addEventListener("keydown",e=>{if(e.key!=="Escape")return;if(document.getElementById("hextra-search-dialog")?.open)return;n.matches&&s()&&i()});const a=e.querySelectorAll("a");a.forEach(e=>{e.addEventListener("click",t=>{e.getAttribute("href")&&e.getAttribute("href").startsWith("#")&&window.innerWidth<768&&i()})})}),function(){const s="hx:hidden",t=document.querySelectorAll(".hextra-nav-menu-toggle"),e=(e,t=!1)=>{e.dataset.state="closed",e.setAttribute("aria-expanded","false");const n=e.nextElementSibling;n.classList.add(s),t&&e.focus()},n=(n,o="none")=>{t.forEach(t=>{t!==n&&e(t)}),n.dataset.state="open",n.setAttribute("aria-expanded","true");const i=n.nextElementSibling;if(i.style.position="absolute",i.style.top="100%",i.style.left="50%",i.style.transform="translateX(-50%)",i.style.zIndex="1000",i.classList.remove(s),o!=="none"){const e=Array.from(i.querySelectorAll('[role="menuitem"]'));if(e.length>0){const t=o==="last"?e[e.length-1]:e[0];t.focus()}}};t.forEach(t=>{t.addEventListener("click",s=>{s.preventDefault(),s.stopPropagation();const o=t.dataset.state==="open";o?e(t):n(t)}),t.addEventListener("keydown",e=>{e.key==="ArrowDown"?(e.preventDefault(),n(t,"first")):e.key==="ArrowUp"&&(e.preventDefault(),n(t,"last"))})}),document.querySelectorAll(".hextra-nav-menu-items[role=menu]").forEach(t=>{t.addEventListener("keydown",n=>{const s=Array.from(t.querySelectorAll('[role="menuitem"]'));if(s.length===0)return;const i=s.indexOf(document.activeElement);let o;switch(n.key){case"ArrowDown":n.preventDefault(),o=(i+1)%s.length,s[o].focus();break;case"ArrowUp":n.preventDefault(),o=(i-1+s.length)%s.length,s[o].focus();break;case"Home":n.preventDefault(),s[0].focus();break;case"End":n.preventDefault(),s[s.length-1].focus();break;case"Escape":{n.preventDefault();const s=t.previousElementSibling;s&&e(s,!0);break}}})}),document.addEventListener("click",n=>{!n.target.closest(".hextra-nav-menu-toggle")&&!n.target.closest(".hextra-nav-menu-items")&&t.forEach(t=>{e(t)})}),document.addEventListener("keydown",n=>{n.key==="Escape"&&t.forEach(t=>{t.dataset.state==="open"&&e(t,!0)})})}(),document.addEventListener("DOMContentLoaded",()=>{const s=document.querySelectorAll(".hextra-page-context-menu-copy"),t=new Map;s.forEach(e=>{const n=e.dataset.url;n&&fetch(n).then(e=>{if(e.ok)return e.text();throw new Error("Failed to fetch")}).then(e=>t.set(n,e)).catch(e=>console.error("Failed to pre-fetch markdown:",e))}),s.forEach(e=>{e.addEventListener("click",()=>{const n=e.dataset.url,s=t.get(n);s?navigator.clipboard.writeText(s).then(()=>{e.classList.add("copied"),setTimeout(()=>e.classList.remove("copied"),1e3)}).catch(e=>console.error("Failed to copy markdown:",e)):fetch(n).then(e=>{if(!e.ok)throw new Error("Failed to fetch");return e.text()}).then(e=>(t.set(n,e),navigator.clipboard.writeText(e))).then(()=>{e.classList.add("copied"),setTimeout(()=>e.classList.remove("copied"),1e3)}).catch(e=>console.error("Failed to copy markdown:",e))})});const e=document.querySelectorAll(".hextra-page-context-menu-toggle");e.forEach(t=>{const s=t.closest(".hextra-page-context-menu"),o=s.querySelector(".hextra-page-context-menu-dropdown"),n=t.querySelector("[data-chevron]");t.addEventListener("click",s=>{s.stopPropagation();const i=t.dataset.state==="open";e.forEach(e=>{if(e!==t){e.dataset.state="closed",e.setAttribute("aria-expanded","false");const n=e.closest(".hextra-page-context-menu"),s=n.querySelector(".hextra-page-context-menu-dropdown"),t=e.querySelector("[data-chevron]");s.classList.add("hx:hidden"),t&&(t.style.transform="")}}),t.dataset.state=i?"closed":"open",t.setAttribute("aria-expanded",i?"false":"true"),o.classList.toggle("hx:hidden",i),n&&(n.style.transform=i?"":"rotate(180deg)")})}),document.addEventListener("click",t=>{const n=!t.target.closest(".hextra-page-context-menu");n&&e.forEach(e=>{e.dataset.state="closed",e.setAttribute("aria-expanded","false");const n=e.closest(".hextra-page-context-menu"),s=n.querySelector(".hextra-page-context-menu-dropdown"),t=e.querySelector("[data-chevron]");s.classList.add("hx:hidden"),t&&(t.style.transform="")})}),document.addEventListener("keydown",t=>{t.key==="Escape"&&e.forEach(e=>{if(e.dataset.state==="open"){const t=e.closest(".hextra-page-context-menu");n(t),e.focus()}})});const n=e=>{if(!e)return;const t=e.querySelector(".hextra-page-context-menu-toggle"),n=e.querySelector(".hextra-page-context-menu-dropdown");if(!t||!n)return;const s=t.querySelector("[data-chevron]");t.dataset.state="closed",t.setAttribute("aria-expanded","false"),n.classList.add("hx:hidden"),s&&(s.style.transform="")};document.querySelectorAll('.hextra-page-context-menu-dropdown button[data-action="copy"]').forEach(e=>{e.addEventListener("click",async t=>{t.stopPropagation();const s=e.closest(".hextra-page-context-menu");if(!s)return;const o=s.querySelector(".hextra-page-context-menu-copy");if(!o)return;n(s),o.click()})}),document.querySelectorAll('.hextra-page-context-menu-dropdown button[data-action="view"]').forEach(e=>{e.addEventListener("click",t=>{t.stopPropagation();const s=e.closest(".hextra-page-context-menu");if(!s)return;const o=e.dataset.url;if(!o)return;n(s),window.open(o,"_blank","noopener,noreferrer")})})}),document.addEventListener("DOMContentLoaded",function(){scrollToActiveItem(),enableCollapsibles()});function enableCollapsibles(){const e=document.querySelectorAll(".hextra-sidebar-collapsible-button");e.forEach(function(e){e.addEventListener("click",function(t){t.preventDefault();const n=e.closest("li");n&&(n.classList.toggle("open"),e.setAttribute("aria-expanded",n.classList.contains("open")?"true":"false"))})})}function scrollToActiveItem(){const t=document.querySelector("aside.hextra-sidebar-container > .hextra-scrollbar"),n=document.querySelectorAll(".hextra-sidebar-active-item"),e=Array.from(n).find(function(e){return e.getBoundingClientRect().height>0});if(!e)return;const s=e.clientHeight,o=e.getBoundingClientRect().top-t.getBoundingClientRect().top;t.scrollTo({behavior:"instant",top:o-s})}function computeMenuTranslation(e,t){const n=e.getBoundingClientRect();t.style.minWidth=`${Math.max(n.width,50)}px`;const o=e.dataset.location==="top",r=e.dataset.location==="bottom",c=e.dataset.location==="bottom-right",s=document.documentElement.dir==="rtl";let i=n.left;(o&&!s||r&&s||c&&!s)&&(i=n.right-t.clientWidth);let a=n.top-window.innerHeight-10;return o&&(a=n.top-window.innerHeight+t.clientHeight+e.clientHeight+4),{x:i,y:a}}function toggleMenu(e){const t=e.nextElementSibling;t.classList.toggle("hx:hidden");const n=computeMenuTranslation(e,t);t.style.transform=`translate3d(${n.x}px, ${n.y}px, 0)`}function resizeMenu(e){const t=e.nextElementSibling;if(t.classList.contains("hx:hidden"))return;const n=computeMenuTranslation(e,t);t.style.transform=`translate3d(${n.x}px, ${n.y}px, 0)`}(function(){function e(e,t){const s=Array.from(e.querySelectorAll(".hextra-tabs-toggle"));s.forEach((e,n)=>{e.dataset.state=n===t?"selected":"",n===t?(e.setAttribute("aria-selected","true"),e.tabIndex=0):(e.setAttribute("aria-selected","false"),e.tabIndex=-1)});const n=e.parentElement.nextElementSibling;if(!n)return;Array.from(n.children).forEach((e,n)=>{e.dataset.state=n===t?"selected":"",e.setAttribute("aria-hidden",n===t?"false":"true"),n===t?e.tabIndex=0:e.removeAttribute("tabindex")})}const t=document.querySelectorAll("[data-tab-group]");t.forEach(t=>{const s=encodeURIComponent(t.dataset.tabGroup),n=localStorage.getItem("hextra-tab-"+s);n!==null&&e(t,parseInt(n,10))}),document.querySelectorAll(".hextra-tabs-toggle").forEach(t=>{t.addEventListener("click",function(t){const o=t.currentTarget,n=o.parentElement,s=Array.from(n.querySelectorAll(".hextra-tabs-toggle")).indexOf(o);if(n.dataset.tabGroup){const t=n.dataset.tabGroup,o=encodeURIComponent(t);document.querySelectorAll('[data-tab-group="'+t+'"]').forEach(t=>e(t,s)),localStorage.setItem("hextra-tab-"+o,s.toString())}else e(n,s)}),t.addEventListener("keydown",function(n){const i=t.parentElement,o=Array.from(i.querySelectorAll(".hextra-tabs-toggle")),a=o.indexOf(t);let s;switch(n.key){case"ArrowRight":case"ArrowDown":n.preventDefault(),s=(a+1)%o.length;break;case"ArrowLeft":case"ArrowUp":n.preventDefault(),s=(a-1+o.length)%o.length;break;case"Home":n.preventDefault(),s=0;break;case"End":n.preventDefault(),s=o.length-1;break;default:return}if(i.dataset.tabGroup){const t=i.dataset.tabGroup,n=encodeURIComponent(t);document.querySelectorAll('[data-tab-group="'+t+'"]').forEach(t=>e(t,s)),localStorage.setItem("hextra-tab-"+n,s.toString())}else e(i,s);o[s].focus()})})})(),document.addEventListener("DOMContentLoaded",function(){document.querySelectorAll("main#content li > input[type='checkbox']").forEach(function(e){if(e.hasAttribute("aria-label")||e.hasAttribute("aria-labelledby"))return;var t,n=e.closest("li");if(!n)return;t=n.textContent.replace(/\s+/g," ").trim(),t&&e.setAttribute("aria-label",t)})}),function(){const s="dark",o=["light","dark"],e=document.querySelectorAll(".hextra-theme-toggle"),t=document.querySelectorAll(".hextra-theme-toggle-options button[role=menuitemradio]");function i(n){n=o.includes(n)?n:"system",e.forEach(e=>e.parentElement.dataset.theme=n),t.forEach(e=>{e.setAttribute("aria-checked",e.dataset.item===n?"true":"false")}),localStorage.setItem("color-theme",n)}function n(e){setTheme(e),i(e)}const a="color-theme"in localStorage?localStorage.getItem("color-theme"):s;n(a),t.forEach(e=>{e.addEventListener("click",function(t){t.preventDefault(),n(e.dataset.item)})}),e.forEach(e=>{e.addEventListener("click",function(t){t.preventDefault(),e.dataset.state=e.dataset.state==="open"?"closed":"open",toggleMenu(e);const n=e.dataset.state==="open";if(e.setAttribute("aria-expanded",n?"true":"false"),n){const t=e.nextElementSibling.querySelector("button[role=menuitemradio]");t&&t.focus()}})}),window.addEventListener("resize",()=>e.forEach(resizeMenu)),document.addEventListener("click",t=>{t.target.closest(".hextra-theme-toggle")===null&&e.forEach(e=>{e.dataset.state="closed",e.setAttribute("aria-expanded","false"),e.nextElementSibling.classList.add("hx:hidden")})}),document.querySelectorAll(".hextra-theme-toggle-options[role=menu]").forEach(function(e){e.addEventListener("keydown",function(t){const n=Array.from(e.querySelectorAll("button[role=menuitemradio]")),i=n.indexOf(document.activeElement);let s;switch(t.key){case"ArrowDown":t.preventDefault(),s=(i+1)%n.length,n[s].focus();break;case"ArrowUp":t.preventDefault(),s=(i-1+n.length)%n.length,n[s].focus();break;case"Home":t.preventDefault(),n[0].focus();break;case"End":t.preventDefault(),n[n.length-1].focus();break;case"Escape":t.preventDefault();var o=e.previousElementSibling;o.dataset.state="closed",o.setAttribute("aria-expanded","false"),e.classList.add("hx:hidden"),o.focus();break}})}),window.matchMedia("(prefers-color-scheme: dark)").addEventListener("change",()=>{localStorage.getItem("color-theme")==="system"&&setTheme("system")})}(),document.addEventListener("DOMContentLoaded",function(){const t=document.querySelector(".hextra-toc");if(!t)return;const s=t.querySelectorAll('a[href^="#"]');if(s.length===0)return;const a=Array.from(s).map(e=>e.getAttribute("href").substring(1)),o=a.map(e=>document.getElementById(decodeURIComponent(e))).filter(Boolean);if(o.length===0)return;let e=null,n=!1;const r=new IntersectionObserver(s=>{if(n)return;const i=s.filter(e=>e.isIntersecting).map(e=>e.target);if(i.length===0)return;const a=i.reduce((e,t)=>{const n=t.getBoundingClientRect().top,s=e.getBoundingClientRect().top;return(n<0?-n:n)<(s<0?-s:s)?t:e}),r=encodeURIComponent(a.id).toLowerCase(),o=t.querySelector(`a[href="#${r}"]`);o&&o!==e&&(e&&(e.classList.remove("hextra-toc-active"),e.removeAttribute("aria-current")),o.classList.add("hextra-toc-active"),o.setAttribute("aria-current","location"),e=o)},{rootMargin:"-20px 0px -60% 0px",threshold:[0,.1,.5,1]});o.forEach(e=>r.observe(e));function i(){const s=window.location.hash;if(s){const o=t.querySelector(`a[href="${s}"]`);if(o){n=!0,e&&(e.classList.remove("hextra-toc-active"),e.removeAttribute("aria-current")),o.classList.add("hextra-toc-active"),o.setAttribute("aria-current","location"),e=o,setTimeout(()=>{n=!1},500);return}}}window.addEventListener("hashchange",i),setTimeout(i,100)}) \ No newline at end of file diff --git a/materiel/heltec-v4/index.html b/materiel/heltec-v4/index.html new file mode 100644 index 0000000..d585f15 --- /dev/null +++ b/materiel/heltec-v4/index.html @@ -0,0 +1,675 @@ + + + + + + + + + + +Heltec v4 – MeshEro + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Skip to content + +
+ + + + + +
+
+ +
+
+ Matériel +
Heltec v4
+
+ +
+ +
+

Heltec v4

+ +
+ + +

Fiche rapide +

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Fabricant / modèleHeltec WiFi LoRa 32 V4
Puce radioSemtech SX1262 (LoRa)
MicrocontrôleurESP32-S3R2
Écran / GPS / BluetoothÉcran OLED 0,96″ (128 × 64) / GPS non intégré, connecteur GNSS disponible / Bluetooth BLE 5.0
Batterie / USBBatterie Li-ion externe 3,3–4,2 V, connecteur JST SH1.25 / USB-C
Prix payé / lieu d’achat34€ sur un market place chinois
Date d’achat24/10/2026
Firmware testéMeshCore 1.17
+

Documentation : https://wiki.heltec.org/docs/devices/open-source-hardware/esp32-series/lora-32/wifi-lora-32-v4_r8_board/

+

Contenu et première impression +

Je l’ai commandé sur un marketplace chinois avec la coque en 3D +La carte est ok mais la coque 3D m’inspire pas confiance … +La batterie n’etait pas fournis avec. +On assemble le tout, y a du jeu dans la coque je suis mitigé de mon montage.

+

Installation du firmware +

+

Flasher +

Companion les premieres semaines (utiliser sur les cotes bretonnes) +Puis un Observer à coté de mon répéteur.

+

Configurer +

Preset radio EU/UK (Narrow), nom du nœud, etc.

+

Appairer +

Quelques probleme d’apparaige à l’application meshcore (obliger de rallumer le bluetooth à chaque déconnexion). Corriger depuis via une maj.

+ +

Tests réalisés +

    +
  • Portée : Plutot correct pour la taille
  • +
  • Autonomie : trop variable mais de 1 a 3 jours. Le heltec v4 est gourmand en energie.
  • +
  • Stabilité : Probleme connexion bluetooth
  • +
+

Verdict +

Points forts

+
    +
  • Puissant pour sa taille
  • +
  • Polyvalence et evolutif (utilisation en tant que companion dans un boitier 3D, répéteur ou room serveur dans un boitier étanche)
  • +
  • Peu chère (à l’époque ou je l’ai acheté)
  • +
+

Points faibles

+
    +
  • Livrer sans batterie
  • +
  • Boitier 3D qui laisse à désirer
  • +
  • la navigation à 1 bouton pour un companion (l’autre sert à reboot)
  • +
  • Durée de la batterie trop aléatoire
  • +
+

Pour qui ? Novice ou confirmé. Je recommande pour un room server ou repéteur dans un boitier etanche mais pas forcement en tant que companion, preferez un L1 Pro

+ + +
+
+ +
+
+
+ +
+ + + + + + + + + diff --git a/materiel/index.html b/materiel/index.html new file mode 100644 index 0000000..6da7d8d --- /dev/null +++ b/materiel/index.html @@ -0,0 +1,610 @@ + + + + + + + + + + +Matériel – MeshEro + + + + + + + + + + + + + + + + + + + + + + + + + + + + Skip to content + +
+ + + + + +
+
+ +
Matériel
+
+ + +
+ +
+
+
+ +
+ + + + + + + + + diff --git a/materiel/index.xml b/materiel/index.xml new file mode 100644 index 0000000..63d4f77 --- /dev/null +++ b/materiel/index.xml @@ -0,0 +1,19 @@ + + + MeshEro – Matériel + http://localhost:1313/materiel/ + Recent content in Matériel on MeshEro + Hugo -- gohugo.io + fr-fr + Sat, 07 Nov 2026 17:32:10 +0100 + + + + + + + + + + + diff --git a/materiel/mcgill9dbi/index.html b/materiel/mcgill9dbi/index.html new file mode 100644 index 0000000..6bbd806 --- /dev/null +++ b/materiel/mcgill9dbi/index.html @@ -0,0 +1,649 @@ + + + + + + + + + + +McGill 9dBi – MeshEro + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Skip to content + +
+ + + + + +
+
+ +
+
+ Matériel +
McGill 9dBi
+
+ +
+ +
+

McGill 9dBi

+ +
+ + +

TEST EN COURS

Fiche rapide +

+ + + + + + + + + + + + + + + + + + + + + + + + +
Fabricant / modèleMcGill Microwave
Prix payé et lieu d’achat99€ sur Hexaspot
Date de d’achat07/11/2026
InstallationInstaller sur un P1 Pro
+

+ landscape +
Spécification produit
+
+Source

+

Contenu et première impression +

Une GROSSE antenne d'1m60 en deux morceau. C’est épais sa pese 2kg3!

+

Installation de l’antenne +

+

Montage +

Visser les deux partie entre elle.

+

Branchement +

J’ai commandé aussi un cable RP-SMA Male to N-Female Bulkhead RF Cable 300mm pour la brancher sur mon P1 Pro

+

Pose +

En cours (Prevoir un mat ou quelque chose, ne se fixe pas directement sur le P1 Pro)

+ +

Tests réalisés +

    +
  • Portée : Si bien placer en hauteur dégagé plusieurs Km
  • +
  • Solidité : Indiqué pour resister à des vents de 210km/h
  • +
+

Verdict +

Points forts

+
    +
  • +
+

Points faibles

+
    +
  • +
+

Pour qui ? Companion, répéteur, les deux ?

+ + +
+
+ +
+
+
+ +
+ + + + + + + + + diff --git a/materiel/sensecap-p1pro/index.html b/materiel/sensecap-p1pro/index.html new file mode 100644 index 0000000..3e713aa --- /dev/null +++ b/materiel/sensecap-p1pro/index.html @@ -0,0 +1,669 @@ + + + + + + + + + + +SenseCAP P1Pro – MeshEro + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Skip to content + +
+ + + + + +
+
+ +
+
+ Matériel +
SenseCAP P1Pro
+
+ +
+ +
+

SenseCAP P1Pro

+ +
+ + +

Fiche rapide +

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Fabricant / modèleSenseCAP Solar Node P1-Pro
Puce radioSemtech SX1262 (LoRa, 868 MHz en Europe)
MicrocontrôleurXIAO nRF52840 Plus, ARM Cortex-M4, 64 MHz
Écran / GPS / BluetoothPas d’écran / GPS intégré L76K (GPS, GLONASS, Galileo) / Bluetooth 5.0 BLE
Batterie / USB4 batteries Li-ion 18650 de 3 350 mAh chacune (13 400 mAh au total) / USB-C / panneau solaire 5 W
Prix payé / lieu d’achat$110 sur Seeed Studio
Date d’achat12/08/2026
Firmware testéMeshCore 1.17 et 1.18
+

Documentation : https://wiki.seeedstudio.com/get_started_with_meshcore_solar_node/

+

Contenu et première impression +

Le P1 Pro (la version pro dispose de batterie intégré) / le systeme de montage / une antenne. Semble costaud et est bien fini.

+

Installation du firmware +

+

Flasher +

Rôle installé répéteur

+

Configurer +

Preset radio EU/UK (Narrow), nom du nœud, etc.

+

Appairer +

La 1ere configuration se fait via la connexion USB lors du flashage de l’appareil. Ensuite on se débrouillera via notre companion.

+ +

Tests réalisés +

    +
  • Portée : Tres bonne si degagé (Le fabriquant annonce 9km, je ne les ai pas atteinds car je n’ai pas suffisament de degagement malgres le fait que le repeteur soit sur mon toit)
  • +
  • Autonomie : Très bonne grace au panneau solaire et les batteries intégrés.
  • +
  • Stabilité : RAS sa tourne comme une horloge.
  • +
+

Verdict +

Points forts

+
    +
  • Qualité de fabrication
  • +
  • Prix (100€)
  • +
  • Rechargement solaire
  • +
  • Systeme d’attache
  • +
+

Points faibles

+
    +
  • Antenne de base (c’est vraiment pour chipoter)
  • +
+

Pour qui ? Bon premier repeteur, à destination d’utilisateur novice ou confirmé. Un bonne investissement dans le réseau.

+ + +
+
+ +
+
+
+ +
+ + + + + + + + + diff --git a/materiel/sensecap-t1000e/index.html b/materiel/sensecap-t1000e/index.html new file mode 100644 index 0000000..8935d31 --- /dev/null +++ b/materiel/sensecap-t1000e/index.html @@ -0,0 +1,670 @@ + + + + + + + + + + +SenseCAP T1000E – MeshEro + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Skip to content + +
+ + + + + +
+
+ +
+
+ Matériel +
SenseCAP T1000E
+
+ +
+ +
+

SenseCAP T1000E

+ +
+ + +

Fiche rapide +

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Fabricant / modèleSeeed Studio, T1000-E
Puce radioSemtech LR1110 (LoRa, 863–928 MHz)
MicrocontrôleurNordic Semiconductor nRF52840 (ARM Cortex-M4)
Écran / GPS / BluetoothPas d’écran ; GPS/GNSS MediaTek AG3335 ; Bluetooth Low Energy (BLE) 5.1
Batterie / USBBatterie lithium rechargeable de 700 mAh ; recharge via câble USB-A magnétique à 4 broches (proprietaire)
Prix payé / lieu d’achat$46 sur Seeed Studio
Date d’achat12/08/2026
Firmware testéMeshCore 1.17 et 1.18
+

Documentation : https://wiki.seeedstudio.com/sensecap_t1000_e_meshcore/

+

Contenu et première impression +

Livré dans une petite boite. Fournis avec un cable de rechargement (USB-C / fiche propriétaire) +Le produit semble solide avec un beau boitier translucide. +La petit sangle est vendu séparement.

+

Installation du firmware +

+

Flasher +

On l’utilisera en mode companion

+

Configurer +

Preset radio EU/UK (Narrow), nom du nœud, etc.

+

Appairer +

Apparaillage via les parametre bluetooth android et ensuite depuis l’application android meshcore open / android meshcore ou meshcore iOS

+ +

Tests réalisés +

    +
  • Portée : courte
  • +
  • Autonomie : entre 2 et 3 jours suivant l’utilisation
  • +
  • Stabilité : RAS
  • +
+

Verdict +

Points forts

+
    +
  • Design / Compact et discret
  • +
  • Télémetrie (température, luminosité, GPS)
  • +
+

Points faibles

+
    +
  • Port propriétaire
  • +
  • Sangle d’attache vendu séparement
  • +
+

Pour qui ? Companion compact pour tout les jours pour tout le monde. (Vous pouvez meme l’utiliser en tant que traceur GPS pour votre animal favoris)

+ + +
+
+ +
+
+
+ +
+ + + + + + + + + diff --git a/materiel/sensecap-x1/index.html b/materiel/sensecap-x1/index.html new file mode 100644 index 0000000..2605463 --- /dev/null +++ b/materiel/sensecap-x1/index.html @@ -0,0 +1,665 @@ + + + + + + + + + + +SenseCAP X1 – MeshEro + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Skip to content + +
+ + + + + +
+
+ +
+
+ Matériel +
SenseCAP X1
+
+ +
+ +
+

SenseCAP X1

+ +
+ + +

Prochainement

Fiche rapide +

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Fabricant / modèle
Puce radio
Microcontrôleur
Écran / GPS / Bluetooth
Batterie / USB
Prix payé et lieu d’achat
Date de d’achat29/10/2026
Firmware testéMeshCore (version : )
+

Contenu et première impression +

Ce qu’il y a dans la boîte, qualité de fabrication, antenne fournie.

+

Installation du firmware +

+

Flasher +

Rôle installé (Companion, Repeater ou Room Server) et outil utilisé.

+

Configurer +

Preset radio EU/UK (Narrow), nom du nœud, etc.

+

Appairer +

Connexion à l’application, premiers messages.

+ +

Tests réalisés +

    +
  • Portée : lieu, distance, obstacles, résultat.
  • +
  • Autonomie : durée mesurée, conditions.
  • +
  • Stabilité : plantages, redémarrages, comportement après plusieurs jours.
  • +
+

Verdict +

Points forts

+
    +
  • +
+

Points faibles

+
    +
  • +
+

Pour qui ? Companion, répéteur, les deux ?

+ + +
+
+ +
+
+
+ +
+ + + + + + + + + diff --git a/materiel/sensecap3dbi/index.html b/materiel/sensecap3dbi/index.html new file mode 100644 index 0000000..2635143 --- /dev/null +++ b/materiel/sensecap3dbi/index.html @@ -0,0 +1,653 @@ + + + + + + + + + + +Sensecap 3dBi – MeshEro + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Skip to content + +
+ + + + + +
+
+ +
+
+ Matériel +
Sensecap 3dBi
+
+ +
+ +
+

Sensecap 3dBi

+ +
+ + +

Prochainement

Fiche rapide +

+ + + + + + + + + + + + + + + + + + + + + + + + +
Fabricant / modèleSensecap
Prix payé et lieu d’achat$35 sur seeedstudio
Date de d’achat15/11/2026
Installationsur un P1 Pro
+

+ landscape +
Spécification produit
+
+source

+

Contenu et première impression +

Petite antenne de 360mm.

+

Installation de l’antenne +

+

Montage +

Rôle installé (Companion, Repeater ou Room Server) et outil utilisé.

+

Branchement +

le cable RP-SMA est fournis avec.

+

Pose +

Peut se fixer sur le P1 Pro directement.

+ +

Tests réalisés +

    +
  • Portée : lieu, distance, obstacles, résultat.
  • +
  • Solidité : durée mesurée, conditions.
  • +
+

Verdict +

Points forts

+
    +
  • +
+

Points faibles

+
    +
  • +
+

Pour qui ? Companion, répéteur, les deux ?

+ + +
+
+ +
+
+
+ +
+ + + + + + + + + diff --git a/materiel/wio-tracker-l1-pro/index.html b/materiel/wio-tracker-l1-pro/index.html new file mode 100644 index 0000000..6848a98 --- /dev/null +++ b/materiel/wio-tracker-l1-pro/index.html @@ -0,0 +1,674 @@ + + + + + + + + + + +Wio Tracker L1 Pro – MeshEro + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Skip to content + +
+ + + + + +
+
+ +
+
+ Matériel +
Wio Tracker L1 Pro
+
+ +
+ +
+

Wio Tracker L1 Pro

+ +
+ + +

Fiche rapide +

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Fabricant / modèleSeeed Studio, Wio Tracker L1 Pro (version MeshCore)
Puce radioSemtech SX1262 (module Wio-SX1262, 862-930 MHz)
MicrocontrôleurNordic nRF52840 (Cortex-M4, 64 MHz, 1 Mo de flash, 256 ko de RAM)
Écran / GPS / BluetoothOLED 1,3" (128 × 64) / L76K (GPS, BeiDou, GLONASS, QZSS) / BLE 5.0
Batterie / USBBatterie Li-ion 3,7 V / USB-C 5 V
Prix payé / lieu d’achat$49 sur Seeed Studio
Date d’achat19/08/2026
Version du firmware testé1.17 et 1.18
+

Documentation : https://wiki.seeedstudio.com/get_started_with_other_mesh_firmware/

+

Contenu et première impression +

une boite simple et petite, on sort l’antenne, on la vis avant de faire quoi que se soit. +Le boitier semble de qualité et les boutons repondent bien notamment le petit joystick.

+

Installation du firmware +

Avant de le démarrer on va flasher mishmesh. C’est un firmware qui permet de l’utiliser sans téléphone, en mode “standalone” comme on dit dans le jargon.

+
+

Tip +

+ +

Il reste possible de le connecter via bluetooth meme avec un firmware standalone

+
+ +

Flasher +

Companion

+

Configurer +

Preset radio EU/UK (Narrow), nom du nœud, etc.

+

Appairer +

+

Tests réalisés +

    +
  • Portée : Rien de particulier jusqu’a 1km en zone urbaine
  • +
  • Autonomie : 3 jours
  • +
  • Stabilité : RAS
  • +
+

Verdict +

Points forts

+
    +
  • Qualité de fabrication
  • +
  • Facile d’utilisation
  • +
  • Mode standalone (pas besoin de téléphone) avec mishmesh
  • +
+

Points faibles

+
    +
  • Antenne de base peut etre un peu faiblarde
  • +
+

Pour qui ? Débutant et Utilisateur confirmé

+

Amélioration possible Ajout d’une antenne plus performante

+ + +
+
+ +
+
+
+ +
+ + + + + + + + + diff --git a/materiel/wio-tracker-l2-pro/index.html b/materiel/wio-tracker-l2-pro/index.html new file mode 100644 index 0000000..13f1289 --- /dev/null +++ b/materiel/wio-tracker-l2-pro/index.html @@ -0,0 +1,665 @@ + + + + + + + + + + +Wio Tracker L2 Pro – MeshEro + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Skip to content + +
+ + + + + +
+
+ +
+
+ Matériel +
Wio Tracker L2 Pro
+
+ +
+ +
+

Wio Tracker L2 Pro

+ +
+ + +

Prochainement

Fiche rapide +

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Fabricant / modèle
Puce radio
Microcontrôleur
Écran / GPS / Bluetooth
Batterie / USB
Prix payé et lieu d’achat$73 sur seeedstudio
Date de d’achat08/11/2026
Firmware testéMeshCore (version : )
+

Contenu et première impression +

Ce qu’il y a dans la boîte, qualité de fabrication, antenne fournie.

+

Installation du firmware +

+

Flasher +

Rôle installé (Companion, Repeater ou Room Server) et outil utilisé.

+

Configurer +

Preset radio EU/UK (Narrow), nom du nœud, etc.

+

Appairer +

Connexion à l’application, premiers messages.

+ +

Tests réalisés +

    +
  • Portée : lieu, distance, obstacles, résultat.
  • +
  • Autonomie : durée mesurée, conditions.
  • +
  • Stabilité : plantages, redémarrages, comportement après plusieurs jours.
  • +
+

Verdict +

Points forts

+
    +
  • +
+

Points faibles

+
    +
  • +
+

Pour qui ? Companion, répéteur, les deux ?

+ + +
+
+ +
+
+
+ +
+ + + + + + + + + diff --git a/repeteurs/index.html b/repeteurs/index.html new file mode 100644 index 0000000..0165ee7 --- /dev/null +++ b/repeteurs/index.html @@ -0,0 +1,455 @@ + + + + + + + + + + +Carte des nœuds – MeshEro + + + + + + + + + + + + + + + + + + + + + + + + + + Skip to content + +
+ + + + + +
+
+ + +
+

Carte des nœuds

+ +

Retrouvé la carte du réseau meshcore

+
+ +

+ La carte ne s'affiche pas ? + + Ouvrir dans un nouvel onglet → + +

+
+ +
+

Note +

+ +

Cette carte ne représente pas nécessairement tous les équipements réellement actifs (seuls les nœuds qui ont été ajoutés ou qui se signalent apparaissent).

+
+ + +
+
+
+ + +
+
+
+ +
+ + + + + + + + + diff --git a/repeteurs/index.xml b/repeteurs/index.xml new file mode 100644 index 0000000..93ce68f --- /dev/null +++ b/repeteurs/index.xml @@ -0,0 +1,18 @@ + + + MeshEro – Carte des nœuds + http://localhost:1313/repeteurs/ + Recent content in Carte des nœuds on MeshEro + Hugo -- gohugo.io + fr-fr + + + + + + + + + + + diff --git a/robots.txt b/robots.txt new file mode 100644 index 0000000..7d329b1 --- /dev/null +++ b/robots.txt @@ -0,0 +1 @@ +User-agent: * diff --git a/site.webmanifest b/site.webmanifest new file mode 100644 index 0000000..c36f3b3 --- /dev/null +++ b/site.webmanifest @@ -0,0 +1,20 @@ +{ + "name": "Hextra", + "short_name": "Hextra", + "start_url": "index.html", + "icons": [ + { + "src": "android-chrome-192x192.png", + "sizes": "192x192", + "type": "image/png" + }, + { + "src": "android-chrome-512x512.png", + "sizes": "512x512", + "type": "image/png" + } + ], + "theme_color": "#000000", + "background_color": "#000000", + "display": "standalone" +} diff --git a/sitemap.xml b/sitemap.xml new file mode 100644 index 0000000..c6967fb --- /dev/null +++ b/sitemap.xml @@ -0,0 +1,62 @@ + + + + http://localhost:1313/materiel/wio-tracker-l1-pro/ + 2026-10-25T16:09:49+01:00 + + http://localhost:1313/documentation/meshcore/ + 2026-10-23T14:22:43+02:00 + + http://localhost:1313/materiel/wio-tracker-l2-pro/ + 2026-11-05T12:40:52+01:00 + + http://localhost:1313/documentation/companion/ + 2026-10-23T16:00:00+02:00 + + http://localhost:1313/materiel/sensecap-t1000e/ + 2026-10-23T22:09:49+02:00 + + http://localhost:1313/documentation/repeater/ + 2026-10-23T16:10:00+02:00 + + http://localhost:1313/materiel/sensecap-x1/ + 2026-10-29T13:22:47+01:00 + + http://localhost:1313/documentation/room-server/ + 2026-10-23T16:20:00+02:00 + + http://localhost:1313/documentation/ota_update/ + 2026-10-24T14:20:58+02:00 + + http://localhost:1313/materiel/sensecap-p1pro/ + 2026-10-24T12:33:41+02:00 + + http://localhost:1313/materiel/heltec-v4/ + 2026-10-24T12:40:27+02:00 + + http://localhost:1313/ + 2026-11-07T17:32:10+01:00 + + http://localhost:1313/materiel/ + 2026-11-07T17:32:10+01:00 + + http://localhost:1313/materiel/sensecap3dbi/ + 2026-11-07T17:32:10+01:00 + + http://localhost:1313/materiel/mcgill9dbi/ + 2026-11-07T17:31:57+01:00 + + http://localhost:1313/documentation/ + 2026-10-24T14:20:58+02:00 + + http://localhost:1313/a-propos/ + 2026-10-22T18:43:41+02:00 + + http://localhost:1313/repeteurs/ + + http://localhost:1313/categories/ + + http://localhost:1313/tags/ + + diff --git a/tags/index.html b/tags/index.html new file mode 100644 index 0000000..6c1e0d6 --- /dev/null +++ b/tags/index.html @@ -0,0 +1,476 @@ + + + + + + + + + + +Tags – MeshEro + + + + + + + + + + + + + + + + + + + + + + + + + Skip to content + +
+ + + + + +
+
+ +
+

Tags

+
+
+ + + +
+
+ +
+ +
+
+
+ +

+ + + + + + + + + diff --git a/tags/index.xml b/tags/index.xml new file mode 100644 index 0000000..9d637f9 --- /dev/null +++ b/tags/index.xml @@ -0,0 +1,18 @@ + + + MeshEro – Tags + http://localhost:1313/tags/ + Recent content in Tags on MeshEro + Hugo -- gohugo.io + fr-fr + + + + + + + + + + +