From d7b880126509a020377b6609d36e3a9ca1a10e46 Mon Sep 17 00:00:00 2001 From: Master-Bw3 Date: Tue, 21 May 2024 23:30:33 +0000 Subject: [PATCH] =?UTF-8?q?Deploying=20to=20gh-pages=20from=20@=20Master-B?= =?UTF-8?q?w3/Hexagon@acedce9a281e2baece5e6a0ffdb6e7919fa981d5=20?= =?UTF-8?q?=F0=9F=9A=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- artifacts.js | 245 +++++++++ artifacts.json | 1 + artifacts/index.html | 254 ++++++++++ changelog.rss | 6 + changelog/0.0.2/index.html | 108 ++++ changelog/index.html | 218 ++++++++ changelog/v0.0.1/index.html | 108 ++++ changelog/v0.2.0/index.html | 113 +++++ favicon.ico | Bin 0 -> 15406 bytes hexagon-installer.ps1.txt | 375 ++++++++++++++ hexagon-installer.sh.txt | 963 ++++++++++++++++++++++++++++++++++++ index.html | 625 +++++++++++++++++++++++ oranda-v0.6.1.css | 3 + 13 files changed, 3019 insertions(+) create mode 100644 artifacts.js create mode 100644 artifacts.json create mode 100644 artifacts/index.html create mode 100644 changelog.rss create mode 100644 changelog/0.0.2/index.html create mode 100644 changelog/index.html create mode 100644 changelog/v0.0.1/index.html create mode 100644 changelog/v0.2.0/index.html create mode 100644 favicon.ico create mode 100644 hexagon-installer.ps1.txt create mode 100644 hexagon-installer.sh.txt create mode 100644 index.html create mode 100644 oranda-v0.6.1.css diff --git a/artifacts.js b/artifacts.js new file mode 100644 index 0000000..2dbfc70 --- /dev/null +++ b/artifacts.js @@ -0,0 +1,245 @@ +/* Code modified from the blender website + * https://www.blender.org/wp-content/themes/bthree/assets/js/get_os.js?x82196 + */ + +let options = { + windows64: "x86_64-pc-windows", + windows32: "i686-pc-windows", + windowsArm: "aarch64-pc-windows", + + mac64: "x86_64-apple", + mac32: "i686-apple", + macSilicon: "aarch64-apple", + + linux64: "x86_64-unknown-linux", + linux32: "i686-unknown-linux", + linuxArm: "aarch64-unknown-linux", + + // ios: "ios", + // android: "linux-android", + // freebsd: "freebsd", +}; + +function isAppleSilicon() { + try { + var glcontext = document.createElement("canvas").getContext("webgl"); + var debugrenderer = glcontext + ? glcontext.getExtension("WEBGL_debug_renderer_info") + : null; + var renderername = + (debugrenderer && + glcontext.getParameter(debugrenderer.UNMASKED_RENDERER_WEBGL)) || + ""; + if (renderername.match(/Apple M/) || renderername.match(/Apple GPU/)) { + return true; + } + + return false; + } catch (e) {} +} + +function getOS() { + var OS = options.windows64.default; + var userAgent = navigator.userAgent; + var platform = navigator.platform; + + if (navigator.appVersion.includes("Win")) { + if ( + !userAgent.includes("Windows NT 5.0") && + !userAgent.includes("Windows NT 5.1") && + (userAgent.indexOf("Win64") > -1 || + platform == "Win64" || + userAgent.indexOf("x86_64") > -1 || + userAgent.indexOf("x86_64") > -1 || + userAgent.indexOf("amd64") > -1 || + userAgent.indexOf("AMD64") > -1 || + userAgent.indexOf("WOW64") > -1) + ) { + OS = options.windows64; + } else { + if ( + window.external && + window.external.getHostEnvironmentValue && + window.external + .getHostEnvironmentValue("os-architecture") + .includes("ARM64") + ) { + OS = options.windowsArm; + } else { + try { + var canvas = document.createElement("canvas"); + var gl = canvas.getContext("webgl"); + + var debugInfo = gl.getExtension("WEBGL_debug_renderer_info"); + var renderer = gl.getParameter(debugInfo.UNMASKED_RENDERER_WEBGL); + if (renderer.includes("Qualcomm")) OS = options.windowsArm; + } catch (e) {} + } + } + } + + //MacOS, MacOS X, macOS + if (navigator.appVersion.includes("Mac")) { + if ( + navigator.userAgent.includes("OS X 10.5") || + navigator.userAgent.includes("OS X 10.6") + ) { + OS = options.mac32; + } else { + OS = options.mac64; + + const isSilicon = isAppleSilicon(); + if (isSilicon) { + OS = options.macSilicon; + } + } + } + + // linux + if (platform.includes("Linux")) { + OS = options.linux64; + // FIXME: Can we find out whether linux 32-bit or ARM are used? + } + + // if ( + // userAgent.includes("iPad") || + // userAgent.includes("iPhone") || + // userAgent.includes("iPod") + // ) { + // OS = options.ios; + // } + // if (platform.toLocaleLowerCase().includes("freebsd")) { + // OS = options.freebsd; + // } + + return OS; +} + +let os = getOS(); +window.os = os; + +// Unhide and hydrate selector with events +const archSelect = document.querySelector(".arch-select"); +if (archSelect) { + archSelect.classList.remove("hidden"); + const selector = document.querySelector("#install-arch-select"); + if (selector) { + selector.addEventListener("change", onArchChange); + } +} + +// Hydrate tab buttons with events +Array.from(document.querySelectorAll(".install-tab[data-id]")).forEach((tab) => { + tab.addEventListener("click", onTabClick); +}); + +function onArchChange(evt) { + // Get target + const target = evt.currentTarget.value; + // Find corresponding installer lists + const newContentEl = document.querySelector(`.arch[data-arch=${target}]`); + const oldContentEl = document.querySelector(`.arch[data-arch]:not(.hidden)`); + // Hide old content element (if applicable) + if (oldContentEl) { + oldContentEl.classList.add("hidden"); + } + // Show new content element + newContentEl.classList.remove("hidden"); + // Show the first tab's content if nothing was selected before + if (newContentEl.querySelectorAll(".install-tab.selected").length === 0) { + const firstContentChild = newContentEl.querySelector(".install-content:first-of-type"); + const firstTabChild = newContentEl.querySelector(".install-tab:first-of-type"); + firstContentChild.classList.remove("hidden"); + if (firstTabChild) { + firstTabChild.classList.add("selected"); + } + } + // Hide "no OS detected" message + const noDetectEl = document.querySelector(".no-autodetect"); + noDetectEl.classList.add("hidden"); + // Hide Mac hint + document.querySelector(".mac-switch").classList.add("hidden"); +} + +function onTabClick(evt) { + // Get target and ID + const {triple, id} = evt.currentTarget.dataset; + if (triple) { + // Find corresponding content elements + const newContentEl = document.querySelector(`.install-content[data-id="${String(id)}"][data-triple=${triple}]`); + const oldContentEl = document.querySelector(`.install-content[data-triple=${triple}][data-id]:not(.hidden)`); + // Find old tab to unselect + const oldTabEl = document.querySelector(`.install-tab[data-triple=${triple}].selected`); + // Hide old content element + if (oldContentEl && oldTabEl) { + oldContentEl.classList.add("hidden"); + oldTabEl.classList.remove("selected"); + } + + // Unhide new content element + newContentEl.classList.remove("hidden"); + // Select new tab element + evt.currentTarget.classList.add("selected"); + } +} + +const allPlatforms = Array.from(document.querySelectorAll(`.arch[data-arch]`)); +let hit = allPlatforms.find( + (a) => { + // Show Intel Mac downloads if no M1 Mac downloads are available + if ( + a.attributes["data-arch"].value.includes(options.mac64) && + os.includes(options.macSilicon) && + !allPlatforms.find(p => p.attributes["data-arch"].value.includes(options.macSilicon))) { + // Unhide hint + document.querySelector(".mac-switch").classList.remove("hidden"); + return true; + } + return a.attributes["data-arch"].value.includes(os); + } +); + +if (hit) { + hit.classList.remove("hidden"); + const selectEl = document.querySelector("#install-arch-select"); + selectEl.value = hit.dataset.arch; + const firstContentChild = hit.querySelector(".install-content:first-of-type"); + const firstTabChild = hit.querySelector(".install-tab:first-of-type"); + firstContentChild.classList.remove("hidden"); + if (firstTabChild) { + firstTabChild.classList.add("selected"); + } +} else { + const noDetectEl = document.querySelector(".no-autodetect"); + if (noDetectEl) { + const noDetectElDetails = document.querySelector(".no-autodetect-details"); + if (noDetectElDetails) { + noDetectElDetails.innerHTML = `We detected you're on ${os} but there don't seem to be installers for that. ` + } + noDetectEl.classList.remove("hidden"); + } +} + +let copyButtons = Array.from(document.querySelectorAll("[data-copy]")); +if (copyButtons.length) { + copyButtons.forEach(function (element) { + element.addEventListener("click", () => { + navigator.clipboard.writeText(element.attributes["data-copy"].value); + }); + }); +} + +// Toggle for pre releases +const checkbox = document.getElementById("show-prereleases"); + +if (checkbox) { + checkbox.addEventListener("click", () => { + const all = document.getElementsByClassName("pre-release"); + + if (all) { + for (var item of all) { + item.classList.toggle("hidden"); + } + } + }); +} \ No newline at end of file diff --git a/artifacts.json b/artifacts.json new file mode 100644 index 0000000..02b159a --- /dev/null +++ b/artifacts.json @@ -0,0 +1 @@ +{"format_version":"0.6.3","tag":"v0.2.0","formatted_date":"May 21 2024 at 22:42 UTC","platforms_with_downloads":[{"target":["aarch64-apple-darwin"],"display_name":"macOS Apple Silicon","installers":[6,0]},{"target":["x86_64-apple-darwin"],"display_name":"macOS Intel","installers":[6,1]},{"target":["x86_64-pc-windows-msvc"],"display_name":"Windows x64","installers":[5,3,2]},{"target":["x86_64-unknown-linux-gnu"],"display_name":"Linux x64","installers":[6,4]}],"downloadable_files":[[2,{"name":"hexagon-aarch64-apple-darwin.tar.xz","download_url":"https://github.com/Master-Bw3/Hexagon/releases/download/v0.2.0/hexagon-aarch64-apple-darwin.tar.xz","view_path":null,"checksum_file":3},["macOS Apple Silicon"]],[7,{"name":"hexagon-x86_64-apple-darwin.tar.xz","download_url":"https://github.com/Master-Bw3/Hexagon/releases/download/v0.2.0/hexagon-x86_64-apple-darwin.tar.xz","view_path":null,"checksum_file":8},["macOS Intel"]],[10,{"name":"hexagon-x86_64-pc-windows-msvc.msi","download_url":"https://github.com/Master-Bw3/Hexagon/releases/download/v0.2.0/hexagon-x86_64-pc-windows-msvc.msi","view_path":null,"checksum_file":11},["Windows x64"]],[12,{"name":"hexagon-x86_64-pc-windows-msvc.zip","download_url":"https://github.com/Master-Bw3/Hexagon/releases/download/v0.2.0/hexagon-x86_64-pc-windows-msvc.zip","view_path":null,"checksum_file":13},["Windows x64"]],[15,{"name":"hexagon-x86_64-unknown-linux-gnu.tar.xz","download_url":"https://github.com/Master-Bw3/Hexagon/releases/download/v0.2.0/hexagon-x86_64-unknown-linux-gnu.tar.xz","view_path":null,"checksum_file":16},["Linux x64"]]],"release":{"artifacts":{"files":[{"name":"dist-manifest.json","download_url":"https://github.com/Master-Bw3/Hexagon/releases/download/v0.2.0/dist-manifest.json","view_path":null,"checksum_file":null},{"name":"hexagon-aarch64-apple-darwin-update","download_url":"https://github.com/Master-Bw3/Hexagon/releases/download/v0.2.0/hexagon-aarch64-apple-darwin-update","view_path":null,"checksum_file":null},{"name":"hexagon-aarch64-apple-darwin.tar.xz","download_url":"https://github.com/Master-Bw3/Hexagon/releases/download/v0.2.0/hexagon-aarch64-apple-darwin.tar.xz","view_path":null,"checksum_file":3},{"name":"hexagon-aarch64-apple-darwin.tar.xz.sha256","download_url":"https://github.com/Master-Bw3/Hexagon/releases/download/v0.2.0/hexagon-aarch64-apple-darwin.tar.xz.sha256","view_path":null,"checksum_file":null},{"name":"hexagon-installer.ps1","download_url":"https://github.com/Master-Bw3/Hexagon/releases/download/v0.2.0/hexagon-installer.ps1","view_path":"hexagon-installer.ps1.txt","checksum_file":null},{"name":"hexagon-installer.sh","download_url":"https://github.com/Master-Bw3/Hexagon/releases/download/v0.2.0/hexagon-installer.sh","view_path":"hexagon-installer.sh.txt","checksum_file":null},{"name":"hexagon-x86_64-apple-darwin-update","download_url":"https://github.com/Master-Bw3/Hexagon/releases/download/v0.2.0/hexagon-x86_64-apple-darwin-update","view_path":null,"checksum_file":null},{"name":"hexagon-x86_64-apple-darwin.tar.xz","download_url":"https://github.com/Master-Bw3/Hexagon/releases/download/v0.2.0/hexagon-x86_64-apple-darwin.tar.xz","view_path":null,"checksum_file":8},{"name":"hexagon-x86_64-apple-darwin.tar.xz.sha256","download_url":"https://github.com/Master-Bw3/Hexagon/releases/download/v0.2.0/hexagon-x86_64-apple-darwin.tar.xz.sha256","view_path":null,"checksum_file":null},{"name":"hexagon-x86_64-pc-windows-msvc-update","download_url":"https://github.com/Master-Bw3/Hexagon/releases/download/v0.2.0/hexagon-x86_64-pc-windows-msvc-update","view_path":null,"checksum_file":null},{"name":"hexagon-x86_64-pc-windows-msvc.msi","download_url":"https://github.com/Master-Bw3/Hexagon/releases/download/v0.2.0/hexagon-x86_64-pc-windows-msvc.msi","view_path":null,"checksum_file":11},{"name":"hexagon-x86_64-pc-windows-msvc.msi.sha256","download_url":"https://github.com/Master-Bw3/Hexagon/releases/download/v0.2.0/hexagon-x86_64-pc-windows-msvc.msi.sha256","view_path":null,"checksum_file":null},{"name":"hexagon-x86_64-pc-windows-msvc.zip","download_url":"https://github.com/Master-Bw3/Hexagon/releases/download/v0.2.0/hexagon-x86_64-pc-windows-msvc.zip","view_path":null,"checksum_file":13},{"name":"hexagon-x86_64-pc-windows-msvc.zip.sha256","download_url":"https://github.com/Master-Bw3/Hexagon/releases/download/v0.2.0/hexagon-x86_64-pc-windows-msvc.zip.sha256","view_path":null,"checksum_file":null},{"name":"hexagon-x86_64-unknown-linux-gnu-update","download_url":"https://github.com/Master-Bw3/Hexagon/releases/download/v0.2.0/hexagon-x86_64-unknown-linux-gnu-update","view_path":null,"checksum_file":null},{"name":"hexagon-x86_64-unknown-linux-gnu.tar.xz","download_url":"https://github.com/Master-Bw3/Hexagon/releases/download/v0.2.0/hexagon-x86_64-unknown-linux-gnu.tar.xz","view_path":null,"checksum_file":16},{"name":"hexagon-x86_64-unknown-linux-gnu.tar.xz.sha256","download_url":"https://github.com/Master-Bw3/Hexagon/releases/download/v0.2.0/hexagon-x86_64-unknown-linux-gnu.tar.xz.sha256","view_path":null,"checksum_file":null},{"name":"source.tar.gz","download_url":"https://github.com/Master-Bw3/Hexagon/releases/download/v0.2.0/source.tar.gz","view_path":null,"checksum_file":18},{"name":"source.tar.gz.sha256","download_url":"https://github.com/Master-Bw3/Hexagon/releases/download/v0.2.0/source.tar.gz.sha256","view_path":null,"checksum_file":null}],"installers":[{"label":"tarball","description":"","app_name":null,"method":{"type":"Download","file":2}},{"label":"tarball","description":"","app_name":null,"method":{"type":"Download","file":7}},{"label":"zip","description":"","app_name":null,"method":{"type":"Download","file":12}},{"label":"msi","description":"install via msi","app_name":null,"method":{"type":"Download","file":10}},{"label":"tarball","description":"","app_name":null,"method":{"type":"Download","file":15}},{"label":"powershell","description":"","app_name":null,"method":{"type":"Run","file":4,"run_hint":"powershell -c \"irm https://github.com/Master-Bw3/Hexagon/releases/download/v0.2.0/hexagon-installer.ps1 | iex\""}},{"label":"shell","description":"","app_name":null,"method":{"type":"Run","file":5,"run_hint":"curl --proto '=https' --tlsv1.2 -LsSf https://github.com/Master-Bw3/Hexagon/releases/download/v0.2.0/hexagon-installer.sh | sh"}}],"targets":{"aarch64-apple-darwin":[6,0],"aarch64-pc-windows-msvc":[5],"aarch64-unknown-linux-gnu":[6],"aarch64-unknown-linux-musl":[6],"i686-apple-darwin":[6],"i686-pc-windows-msvc":[5],"i686-unknown-linux-gnu":[6],"i686-unknown-linux-musl":[6],"x86_64-apple-darwin":[6,1],"x86_64-pc-windows-msvc":[5,3,2],"x86_64-unknown-linux-gnu":[6,4],"x86_64-unknown-linux-musl":[6]}}},"os_script":"/Hexagon/artifacts.js","has_checksum_files":true} \ No newline at end of file diff --git a/artifacts/index.html b/artifacts/index.html new file mode 100644 index 0000000..920e48b --- /dev/null +++ b/artifacts/index.html @@ -0,0 +1,254 @@ + + + + hexagon + + + + + + + + + + + + + + + + + + +
+
+ + + + +
+
+ +

hexagon

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

powershell

+
+
+powershell -c "irm https://github.com/Master-Bw3/Hexagon/releases/download/v0.2.0/hexagon-installer.ps1 | iex"
+ + + + + + + + + Source + +
+
+ + + + +
+

shell

+
+
+curl --proto '=https' --tlsv1.2 -LsSf https://github.com/Master-Bw3/Hexagon/releases/download/v0.2.0/hexagon-installer.sh | sh
+ + + + + + + + + Source + +
+
+ + + + + + + + + + +
+
+

Downloads

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
FilePlatformChecksum
hexagon-aarch64-apple-darwin.tar.xz + + + macOS Apple Silicon + + + checksum
hexagon-x86_64-apple-darwin.tar.xz + + + macOS Intel + + + checksum
hexagon-x86_64-pc-windows-msvc.msi + + + Windows x64 + + + checksum
hexagon-x86_64-pc-windows-msvc.zip + + + Windows x64 + + + checksum
hexagon-x86_64-unknown-linux-gnu.tar.xz + + + Linux x64 + + + checksum
+
+
+ +
+
+ +
+ + + + + hexagon + +
+
+ + + + + + + + + \ No newline at end of file diff --git a/changelog.rss b/changelog.rss new file mode 100644 index 0000000..0fa9ca9 --- /dev/null +++ b/changelog.rss @@ -0,0 +1,6 @@ +hexagon Changeloghttp://127.0.0.1:7979/Hexagon/changelogChangelog information for hexagonhexagon Changelogv0.2.0http://127.0.0.1:7979/Hexagon/changelog/v0.2.0hexagon Changeloghttp://127.0.0.1:7979/Hexagon/changelog/v0.2.0 +
  • Fixed some scenarios where a mishap would cause Hexagon to crash
  • +
  • Added CI releases via cargo-dist
  • +
  • Added Homepage via oranda
  • + +]]>
    0.0.2http://127.0.0.1:7979/Hexagon/changelog/0.0.2hexagon Changeloghttp://127.0.0.1:7979/Hexagon/changelog/0.0.2Hexagon v0.0.1http://127.0.0.1:7979/Hexagon/changelog/v0.0.1hexagon Changeloghttp://127.0.0.1:7979/Hexagon/changelog/v0.0.1
    \ No newline at end of file diff --git a/changelog/0.0.2/index.html b/changelog/0.0.2/index.html new file mode 100644 index 0000000..2584b75 --- /dev/null +++ b/changelog/0.0.2/index.html @@ -0,0 +1,108 @@ + + + + hexagon + + + + + + + + + + + + + + + + + + +
    +
    + + + + +
    +
    + +

    hexagon

    + + + +
    + + +
    +

    0.0.2

    +
    + + +
    + +
    + + + + + 0.0.2 + + + + + Jul 25 2023 at 16:26 UTC + + +
    +
    + +
    +
    +
    +
    + +
    +
    + +
    + + + + + hexagon + +
    +
    + + + + + + + \ No newline at end of file diff --git a/changelog/index.html b/changelog/index.html new file mode 100644 index 0000000..5c46cad --- /dev/null +++ b/changelog/index.html @@ -0,0 +1,218 @@ + + + + hexagon + + + + + + + + + + + + + + + + + + +
    +
    + + + + +
    +
    + +

    hexagon

    + + + +
    + + +
    +

    + Releases + + + + + + +

    +
    + + +
    + + +
    +

    + + + v0.2.0 + + +

    +
    + + + + + v0.2.0 + + + + + May 21 2024 at 22:42 UTC + + +
    +
    +
      +
    • Fixed some scenarios where a mishap would cause Hexagon to crash
    • +
    • Added CI releases via cargo-dist
    • +
    • Added Homepage via oranda
    • +
    + +
    +
    + + + + + + + +
    +
    +
    + +
    +
    + +
    + + + + + hexagon + +
    +
    + + + + + + + + + \ No newline at end of file diff --git a/changelog/v0.0.1/index.html b/changelog/v0.0.1/index.html new file mode 100644 index 0000000..7009e45 --- /dev/null +++ b/changelog/v0.0.1/index.html @@ -0,0 +1,108 @@ + + + + hexagon + + + + + + + + + + + + + + + + + + +
    +
    + + + + +
    +
    + +

    hexagon

    + + + +
    + + +
    +

    Hexagon v0.0.1

    +
    + + +
    + +
    + + + + + v0.0.1 + + + + + Jul 16 2023 at 19:15 UTC + + +
    +
    + +
    +
    +
    +
    + +
    +
    + +
    + + + + + hexagon + +
    +
    + + + + + + + \ No newline at end of file diff --git a/changelog/v0.2.0/index.html b/changelog/v0.2.0/index.html new file mode 100644 index 0000000..4a46151 --- /dev/null +++ b/changelog/v0.2.0/index.html @@ -0,0 +1,113 @@ + + + + hexagon + + + + + + + + + + + + + + + + + + +
    +
    + + + + +
    +
    + +

    hexagon

    + + + +
    + + +
    +

    v0.2.0

    +
    + + +
    + +
    + + + + + v0.2.0 + + + + + May 21 2024 at 22:42 UTC + + +
    +
    +
      +
    • Fixed some scenarios where a mishap would cause Hexagon to crash
    • +
    • Added CI releases via cargo-dist
    • +
    • Added Homepage via oranda
    • +
    + +
    +
    +
    +
    + +
    +
    + +
    + + + + + hexagon + +
    +
    + + + + + + + \ No newline at end of file diff --git a/favicon.ico b/favicon.ico new file mode 100644 index 0000000000000000000000000000000000000000..7cbd0085ff7e7ac8843025df9db00f1cfb78bd6d GIT binary patch literal 15406 zcmeHOd2m%{6@M=~*?9rT}>z6+UYJCUC`hVrd@Z2dNF-HXPoDb!L<6J_hi zDbH?{8Mm=YDGN0vA1ji7=Qzsq z7diepc)I(-%fk;%Is4F+zr=ZOK*N?@4(4w}R>p3mC3mAD{}8Hj7i{C-o_`SC1&2|d z+>6%CNo5`F_3yVlXBQVYMW56(Y|F2WinI=*-zmJ@&Gdsr}3Tk$J1nj(%NT+^^`z0nk$2R{> z5&75>Q?8V`xp>%Z@9OG_-0WE-P`|QLcc4V0r!|=qsNB30IdOI9qAqx_uG%kuZ|G0# zjG0#@FR@Q+{Av5N&V{;KQGOcz-7g?CWD9(K!ZEP@NoyI$IM?%)Rc(&D==NXa9_lpcIUBKFjw;MgL|vE^R%zznx?9 z@eEYzTukdJCdWmFN|+S zC~da-{J-!U7oLkG`V6@eBa7_ry_-4D0IpwE!4gWiXWePjnv0L2YujDuk*oBB@S$C- z&zeS8!EFe>!L>F~cYC^@M|jv)<(r9Zn&^KS3A8nZ^#6Ue53Kr@6ZIcQ70c4;Tkq+A z#b(!&xlZ?T55}5OR<&7ceS$cK-i~L`Sp5-%2Bo5-{y|%Nd;9-b-%Gag`NmHmntOJx z<^t~Odfw^2WnA7HLeW%r5nU~hV*}S#=5LNFLH?Fu^z*%b?34AEP?0u5Ur>hAJ6?gW zrwPZ}p2A|oCHknaRrU4lwa+GEf`R_8Bc66yeIH2wSW|QarSw7WcKnQBs3!Wi-lAg= zT%oqhH#gvc!S7)s*HC@8{;!ex?CM1Q6`N^Kwku@`{<2qgYrV71L45L1{X>{+eH_!R zPhh(FF=8s!zufpdy{K>M-c#47D0^D5|C7|`xX42IQKtgA&jkwy`a~d!KH+xyo#Wjv zqKS4uZ70972mQT*u6m~}*WYg-u4>=@8AboSdGGBNj9p!-{|kaW|96zW$CrH=jYgd4 z{xa`P^ueKu{-13BJOa6&^!=>&oK1VOF!e`-69eqvI!k>w`uIIPUtT3k{J)e*ouh3} zBQ7`%PtE=X&9s;6^`kEryp}`ExRZN6ZW&)SSDwW{^CuPmn@RkwZ&OHoe2n8d(DDRE zE6ytAS+s@s4SZX{mMYHGx3l*gNWY!4b(Xl%iu=?$-dtY~o1U%SbDr)#$~RE!%dZ<{ zbQ9Y}6XR;%-|F{1Tnm3={!L`ju>O>M_If+|F8ZTp-_I;0B)J=)0GB(zr zIH{ZWJ~uQT@xS%-F}~c_GB2?=qx8oG5^vDoH<#SGN`8OYNer^Ap878MQ`$(|V4p}F zYIqp2^oP!@QCwUNMh0F%0dc2b&`$byYkQ*u{Jr9T7aAW$n7^4Z(SBUm`F-SR{MfaQ z!PV6RrG>X)Z1B7Ar;VGSKlEc95YITwLZ7Ucv#|XsB(u!K`JUPFEn=W3To`^8L&Qn$ zl%=n~*0aBVoZ^3TXmi!rEhZulee~rWmFM7V$Cmli9*+{U@1te38U#^Rxp;7;oh<-qH3QL>py~8_?F# z-un^13H~e0I{?`So{Zhbd%vo1Xwvs&`!iR`m$plt&mlZ8LE+L)_kRN$XpcnicQ9tS zz&#Z1zj0L?ZJ+vk@jb=ld!|NyiiprG^fW%Aw3oG?>$MYqbG)j}IoR@P#D`|$(&(=+ zPG^l=f1`l9jC*O13Jz=!%P-y?v!v^4n^ z;%FPCzSy(o(mOHO@Q|&oR*u}y63_P1$EcWP3wftUiNk_uQ$?nUvb%Ek2h!< z2>GS}hcfgs*LxP8Fq#}vA92Pw_k4P4zYTwu5DV`c{t?>Q=P-TmJpHTKAxARB7M`Nb zS!jI{y^LiD5E{>+~2Rj2OYfZ}AZ4mdkQSvaa>L z=uH4If_#T-ZF8gbgfEQ@NFY}c_#f-@M#ubqd;2!;de$X#({_|`KWyVw&Z~k~$>sst z{j1~7>ydpk+qk&6D)v7*d@CXt*9#x#%6!KHZTKC#evT8CpW~$E7r2YpDPn$!0fY~Y zC2x?xd`U2Uhs10*b4+?!60@bI_7b<7R`rukZeWbO%t+f6Oc19HHGM+K1G*8Pc`(^0_@jE;-MEeTp{n!*!l>^DiL;`q$I@2tTRk!L zFz4w=);`7|9jv3qu7Z0mPric~`ZP<~DZH@oFHDi6x|#Sv#v*yEGWy@y@!w)Q@nsO> z5g9{2@uY>htF%q6C}VEw@UEXBh5Uk}@n`c)z`0$op^IE<*jDg?@NO;S|Mn045PN8Iw(`8gS~gP3 zO1UpjG7oU?@J}!*oPj2u7cRVrIP_yfuj1m)A0RGhv%|GmYs}iR2|ldu*coYyKrKlzPv?jrhe($I{z#=ht=mtoR{OAf3%)ivA15% z$$7WO`CgPSz95n|MXspjD~xf0J$-pEjNhtX)^9EQ;OOv=aX0i zi>$e7na6)hC*_=w5B-&39sOFFxX;?EK8(GLsb&}#7t$9?92vy-(e%~Pp&5wb70WAv zv5lN#siu#+v+wKp5beu&)p>;4@l&qsD~SH=dd^1Z#~4E{te?D4HhsO9CY}(SwzK`S z=q7)hOddFg_;QZ9TCt&e8S1mx&O68_m9cKNxgPt7H;xboX>FI}m)f#sa6fa+TVtyn z%2H*n_v=m`K)8od#<@crUyO3bf;KKB9gFm5VZl}#E&5Q!vqHO<^HKKXF7o_IGvh{8 zcg*}ok5JEIgCz%RL>lwR=Lf!phb_NEEn{Kf>g>t6o_7JnD&6FP4(<6Xx%*kf(l!f! zB06N1XGAH_^G!0h?nwS&o-wJ_oac(9&wZHVPo|IQ$lZr$_x*$CO1^*yCpc|KeQDnd zR){4Z(ANAYdB>lSgV>>9&gsE#ql$P&IG|{rNthtVT0vf2+g5wul6wG4owT}!MG$n{q7mvC=0#1>1t zU&qniZ=job0v~enj{1>&);P~tTp;edNPBded`k-XW~ncGK=`a#?&-&gNoR=TyfwJm zk<9hpr*f?Y|HN~@*~|UQnFHZX0+uQytIqttW52 za)l??*q!z2->h=sPSkT}H%sRKiyYBq(JSpGG4ZW1f6?DI#<>GLV>CoQcbNNigx3)L zwD*5O57$~V*&ACJM|IZRk0!=U;fyzAe-;x*G%&~0$g7!G3$J?S4g_1oFzy^+tT^K8Yt`(46l*Go(8K%m5o8m>lo+Dhj77Rd9ob8Saxw+{~eh?pnSp`Ms&_s`IO z%q#r!eYik--@|jtT3jkPD~eckjQPWq<$Ud0Yq(xnF!4ca%VQWMZpkNKF6U;XjpVKu z$KODbxsGdYjlnt@5B88tcO-L+=QW3E*Ol0dZ6u#~Y5eyJ_aJTLTunDI$VUghgF9M3 z12cIpN3xuGFC4UBph@y+7RIjT*ox)+%j=v+l&y~<>dg#!EJw2CEKnuusO6#Lvt<0@ z!{kiN{X7$JdGvKu6X)Gr?%Am1U$QesacJ(ZsH-@mocmrJdjrWl2Pgj6lfJT(Yuig7 ztd39rJ6`uO3^9ize3jsXJjUuWe(}3gmG|P={r}*(qH$&HTAk9%apqa}V;pl7+sXS4 zQHOG~ryKAr--?S%kRM{#sOVCt1q(T zEMgn6lblOB&i#=~Os?H;&Wu@GH#xZn<6P$ojxm7PN5#HUN9>7UpfdI==O=@>j@ojq z9J!a6Tyoh})S(t~8mYv~S_~oOf<330L%TvAsG7Mdy$olcy}8z6gS5Plvof5mFS;XV z^CX|@Y}@zi-`f0)eETTc?YQtfn3u13{>IUFY2)1Y!grRvYT}+vp$$!lDPw#epx6ux zIoSiu;U46*)cX={XKbPwJKD1=iE-7;U%!ey z^l1l)3wDvW_f^idns|;j)OPvv-giT=^1ma39nO)bK20Bce&lD&0avfuqhg1$I7i`7 zZgdWbiS3vmPN*YBle6zC4{TX5KCJF$+$zcL@urFLS4 z2Q07I{=Z7(#4wgysCy7srv89(JGmui=OfrAhPu(hb3zvKRK+~IB-kg4IXm&cqCZxd zMwIb?<|aFyb~ygS%zFv{ppHQ}f8kFOcn&FqF=Ze9;e+Jvjy8WvS$})qTy5*zFYyEO zFPZ$GohAP7P6K^?H0`tGUsm`ZBdWOeqtp*avKPs%G;_^WY+xo, at your +# option. This file may not be copied, modified, or distributed +# except according to those terms. + +<# +.SYNOPSIS + +The installer for hexagon 0.2.0 + +.DESCRIPTION + +This script detects what platform you're on and fetches an appropriate archive from +https://github.com/Master-Bw3/Hexagon/releases/download/v0.2.0 +then unpacks the binaries and installs them to + + $env:CARGO_HOME/bin (or $HOME/.cargo/bin) + +It will then add that dir to PATH by editing your Environment.Path registry key + +.PARAMETER ArtifactDownloadUrl +The URL of the directory where artifacts can be fetched from + +.PARAMETER NoModifyPath +Don't add the install directory to PATH + +.PARAMETER Help +Print help + +#> + +param ( + [Parameter(HelpMessage = "The URL of the directory where artifacts can be fetched from")] + [string]$ArtifactDownloadUrl = 'https://github.com/Master-Bw3/Hexagon/releases/download/v0.2.0', + [Parameter(HelpMessage = "Don't add the install directory to PATH")] + [switch]$NoModifyPath, + [Parameter(HelpMessage = "Print Help")] + [switch]$Help +) + +$app_name = 'hexagon' +$app_version = '0.2.0' + +$receipt = @" +{"binaries":["CARGO_DIST_BINS"],"binary_aliases":{},"install_prefix":"AXO_INSTALL_PREFIX","provider":{"source":"cargo-dist","version":"0.14.1"},"source":{"app_name":"hexagon","name":"Hexagon","owner":"Master-Bw3","release_type":"github"},"version":"0.2.0"} +"@ +$receipt_home = "${env:LOCALAPPDATA}\hexagon" + +function Install-Binary($install_args) { + if ($Help) { + Get-Help $PSCommandPath -Detailed + Exit + } + + Initialize-Environment + + # Platform info injected by cargo-dist + $platforms = @{ + "aarch64-pc-windows-msvc" = @{ + "artifact_name" = "hexagon-x86_64-pc-windows-msvc.zip" + "bins" = "hexagon.exe" + "zip_ext" = ".zip" + "aliases" = @{ + } + "aliases_json" = '{}' + "updater" = @{ + "artifact_name" = "hexagon-x86_64-pc-windows-msvc-update" + "bin" = "hexagon-x86_64-pc-windows-msvc-update" + } + } + "x86_64-pc-windows-msvc" = @{ + "artifact_name" = "hexagon-x86_64-pc-windows-msvc.zip" + "bins" = "hexagon.exe" + "zip_ext" = ".zip" + "aliases" = @{ + } + "aliases_json" = '{}' + "updater" = @{ + "artifact_name" = "hexagon-x86_64-pc-windows-msvc-update" + "bin" = "hexagon-x86_64-pc-windows-msvc-update" + } + } + } + + $fetched = Download "$ArtifactDownloadUrl" $platforms + # FIXME: add a flag that lets the user not do this step + Invoke-Installer -bin_paths $fetched -platforms $platforms "$install_args" +} + +function Get-TargetTriple() { + try { + # NOTE: this might return X64 on ARM64 Windows, which is OK since emulation is available. + # It works correctly starting in PowerShell Core 7.3 and Windows PowerShell in Win 11 22H2. + # Ideally this would just be + # [System.Runtime.InteropServices.RuntimeInformation]::OSArchitecture + # but that gets a type from the wrong assembly on Windows PowerShell (i.e. not Core) + $a = [System.Reflection.Assembly]::LoadWithPartialName("System.Runtime.InteropServices.RuntimeInformation") + $t = $a.GetType("System.Runtime.InteropServices.RuntimeInformation") + $p = $t.GetProperty("OSArchitecture") + # Possible OSArchitecture Values: https://learn.microsoft.com/dotnet/api/system.runtime.interopservices.architecture + # Rust supported platforms: https://doc.rust-lang.org/stable/rustc/platform-support.html + switch ($p.GetValue($null).ToString()) + { + "X86" { return "i686-pc-windows-msvc" } + "X64" { return "x86_64-pc-windows-msvc" } + "Arm" { return "thumbv7a-pc-windows-msvc" } + "Arm64" { return "aarch64-pc-windows-msvc" } + } + } catch { + # The above was added in .NET 4.7.1, so Windows PowerShell in versions of Windows + # prior to Windows 10 v1709 may not have this API. + Write-Verbose "Get-TargetTriple: Exception when trying to determine OS architecture." + Write-Verbose $_ + } + + # This is available in .NET 4.0. We already checked for PS 5, which requires .NET 4.5. + Write-Verbose("Get-TargetTriple: falling back to Is64BitOperatingSystem.") + if ([System.Environment]::Is64BitOperatingSystem) { + return "x86_64-pc-windows-msvc" + } else { + return "i686-pc-windows-msvc" + } +} + +function Download($download_url, $platforms) { + $arch = Get-TargetTriple + + if (-not $platforms.ContainsKey($arch)) { + $platforms_json = ConvertTo-Json $platforms + throw "ERROR: could not find binaries for this platform. Last platform tried: $arch platform info: $platforms_json" + } + + # Lookup what we expect this platform to look like + $info = $platforms[$arch] + $zip_ext = $info["zip_ext"] + $bin_names = $info["bins"] + $artifact_name = $info["artifact_name"] + + # Make a new temp dir to unpack things to + $tmp = New-Temp-Dir + $dir_path = "$tmp\$app_name$zip_ext" + + # Download and unpack! + $url = "$download_url/$artifact_name" + Write-Information "Downloading $app_name $app_version ($arch)" + Write-Verbose " from $url" + Write-Verbose " to $dir_path" + $wc = New-Object Net.Webclient + $wc.downloadFile($url, $dir_path) + + Write-Verbose "Unpacking to $tmp" + + # Select the tool to unpack the files with. + # + # As of windows 10(?), powershell comes with tar preinstalled, but in practice + # it only seems to support .tar.gz, and not xz/zstd. Still, we should try to + # forward all tars to it in case the user has a machine that can handle it! + switch -Wildcard ($zip_ext) { + ".zip" { + Expand-Archive -Path $dir_path -DestinationPath "$tmp"; + Break + } + ".tar.*" { + tar xf $dir_path --strip-components 1 -C "$tmp"; + Break + } + Default { + throw "ERROR: unknown archive format $zip_ext" + } + } + + # Let the next step know what to copy + $bin_paths = @() + foreach ($bin_name in $bin_names) { + Write-Verbose " Unpacked $bin_name" + $bin_paths += "$tmp\$bin_name" + } + + if ($null -ne $info["updater"]) { + $updater_id = $info["updater"]["artifact_name"] + $updater_url = "$download_url/$updater_id" + $out_name = "$tmp\hexagon-update.exe" + + $wc.downloadFile($updater_url, $out_name) + $bin_paths += $out_name + } + + return $bin_paths +} + +function Invoke-Installer($bin_paths, $platforms) { + # Replaces the placeholder binary entry with the actual list of binaries + $arch = Get-TargetTriple + + if (-not $platforms.ContainsKey($arch)) { + $platforms_json = ConvertTo-Json $platforms + throw "ERROR: could not find binaries for this platform. Last platform tried: $arch platform info: $platforms_json" + } + + $info = $platforms[$arch] + + $dest_dir = $null + # Before actually consulting the configured install strategy, see + # if we're overriding it. + if (($env:CARGO_DIST_FORCE_INSTALL_DIR)) { + + $dest_dir = Join-Path $env:CARGO_DIST_FORCE_INSTALL_DIR "bin" + } + if (-Not $dest_dir) { + # first try $env:CARGO_HOME, then fallback to $HOME + # (for whatever reason $HOME is not a normal env var and doesn't need the $env: prefix) + $root = if (($base_dir = $env:CARGO_HOME)) { + $base_dir + } elseif (($base_dir = $HOME)) { + Join-Path $base_dir ".cargo" + } else { + throw "ERROR: could not find your HOME dir or CARGO_HOME to install binaries to" + } + + $dest_dir = Join-Path $root "bin" + } + + # Looks like all of the above assignments failed + if (-Not $dest_dir) { + throw "ERROR: could not find a valid path to install to; please check the installation instructions" + } + + # The replace call here ensures proper escaping is inlined into the receipt + $receipt = $receipt.Replace('AXO_INSTALL_PREFIX', $dest_dir.replace("\", "\\")) + + $dest_dir = New-Item -Force -ItemType Directory -Path $dest_dir + Write-Information "Installing to $dest_dir" + # Just copy the binaries from the temp location to the install dir + foreach ($bin_path in $bin_paths) { + $installed_file = Split-Path -Path "$bin_path" -Leaf + Copy-Item "$bin_path" -Destination "$dest_dir" + Remove-Item "$bin_path" -Recurse -Force + Write-Information " $installed_file" + + if (($dests = $info["aliases"][$installed_file])) { + $source = Join-Path "$dest_dir" "$installed_file" + foreach ($dest_name in $dests) { + $dest = Join-Path $dest_dir $dest_name + $null = New-Item -ItemType HardLink -Target "$source" -Path "$dest" -Force + } + } + } + + $formatted_bins = ($info["bins"] | ForEach-Object { '"' + $_ + '"' }) -join "," + $receipt = $receipt.Replace('"CARGO_DIST_BINS"', $formatted_bins) + # Also replace the aliases with the arch-specific one + $receipt = $receipt.Replace('"binary_aliases":{}', -join('"binary_aliases":', $info['aliases_json'])) + + # Write the install receipt + $null = New-Item -Path $receipt_home -ItemType "directory" -ErrorAction SilentlyContinue + # Trying to get Powershell 5.1 (not 6+, which is fake and lies) to write utf8 is a crime + # because "Out-File -Encoding utf8" actually still means utf8BOM, so we need to pull out + # .NET's APIs which actually do what you tell them (also apparently utf8NoBOM is the + # default in newer .NETs but I'd rather not rely on that at this point). + $Utf8NoBomEncoding = New-Object System.Text.UTF8Encoding $False + [IO.File]::WriteAllLines("$receipt_home/hexagon-receipt.json", "$receipt", $Utf8NoBomEncoding) + + Write-Information "Everything's installed!" + if (-not $NoModifyPath) { + if (Add-Path $dest_dir) { + Write-Information "" + Write-Information "$dest_dir was added to your PATH, you may need to restart your shell for that to take effect." + } + } +} + +# Try to add the given path to PATH via the registry +# +# Returns true if the registry was modified, otherwise returns false +# (indicating it was already on PATH) +function Add-Path($OrigPathToAdd) { + Write-Verbose "Adding $OrigPathToAdd to your PATH" + $RegistryPath = "HKCU:\Environment" + $PropertyName = "Path" + $PathToAdd = $OrigPathToAdd + + $Item = if (Test-Path $RegistryPath) { + # If the registry key exists, get it + Get-Item -Path $RegistryPath + } else { + # If the registry key doesn't exist, create it + Write-Verbose "Creating $RegistryPath" + New-Item -Path $RegistryPath -Force + } + + $OldPath = "" + try { + # Try to get the old PATH value. If that fails, assume we're making it from scratch. + # Otherwise assume there's already paths in here and use a ; separator + $OldPath = $Item | Get-ItemPropertyValue -Name $PropertyName + $PathToAdd = "$PathToAdd;" + } catch { + # We'll be creating the PATH from scratch + Write-Verbose "No $PropertyName Property exists on $RegistryPath (we'll make one)" + } + + # Check if the path is already there + # + # We don't want to incorrectly match "C:\blah\" to "C:\blah\blah\", so we include the semicolon + # delimiters when searching, ensuring exact matches. To avoid corner cases we add semicolons to + # both sides of the input, allowing us to pretend we're always in the middle of a list. + Write-Verbose "Old $PropertyName Property is $OldPath" + if (";$OldPath;" -like "*;$OrigPathToAdd;*") { + # Already on path, nothing to do + Write-Verbose "install dir already on PATH, all done!" + return $false + } else { + # Actually update PATH + Write-Verbose "Actually mutating $PropertyName Property" + $NewPath = $PathToAdd + $OldPath + # We use -Force here to make the value already existing not be an error + $Item | New-ItemProperty -Name $PropertyName -Value $NewPath -PropertyType String -Force | Out-Null + return $true + } +} + +function Initialize-Environment() { + If (($PSVersionTable.PSVersion.Major) -lt 5) { + throw @" +Error: PowerShell 5 or later is required to install $app_name. +Upgrade PowerShell: + + https://docs.microsoft.com/en-us/powershell/scripting/setup/installing-windows-powershell + +"@ + } + + # show notification to change execution policy: + $allowedExecutionPolicy = @('Unrestricted', 'RemoteSigned', 'ByPass') + If ((Get-ExecutionPolicy).ToString() -notin $allowedExecutionPolicy) { + throw @" +Error: PowerShell requires an execution policy in [$($allowedExecutionPolicy -join ", ")] to run $app_name. For example, to set the execution policy to 'RemoteSigned' please run: + + Set-ExecutionPolicy RemoteSigned -scope CurrentUser + +"@ + } + + # GitHub requires TLS 1.2 + If ([System.Enum]::GetNames([System.Net.SecurityProtocolType]) -notcontains 'Tls12') { + throw @" +Error: Installing $app_name requires at least .NET Framework 4.5 +Please download and install it first: + + https://www.microsoft.com/net/download + +"@ + } +} + +function New-Temp-Dir() { + [CmdletBinding(SupportsShouldProcess)] + param() + $parent = [System.IO.Path]::GetTempPath() + [string] $name = [System.Guid]::NewGuid() + New-Item -ItemType Directory -Path (Join-Path $parent $name) +} + +# PSScriptAnalyzer doesn't like how we use our params as globals, this calms it +$Null = $ArtifactDownloadUrl, $NoModifyPath, $Help +# Make Write-Information statements be visible +$InformationPreference = "Continue" + +# The default interactive handler +try { + Install-Binary "$Args" +} catch { + Write-Information $_ + exit 1 +} diff --git a/hexagon-installer.sh.txt b/hexagon-installer.sh.txt new file mode 100644 index 0000000..bf72502 --- /dev/null +++ b/hexagon-installer.sh.txt @@ -0,0 +1,963 @@ +#!/bin/sh +# shellcheck shell=dash +# +# Licensed under the MIT license +# , at your +# option. This file may not be copied, modified, or distributed +# except according to those terms. + +if [ "$KSH_VERSION" = 'Version JM 93t+ 2010-03-05' ]; then + # The version of ksh93 that ships with many illumos systems does not + # support the "local" extension. Print a message rather than fail in + # subtle ways later on: + echo 'this installer does not work with this ksh93 version; please try bash!' >&2 + exit 1 +fi + +set -u + +APP_NAME="hexagon" +APP_VERSION="0.2.0" +ARTIFACT_DOWNLOAD_URL="${INSTALLER_DOWNLOAD_URL:-https://github.com/Master-Bw3/Hexagon/releases/download/v0.2.0}" +PRINT_VERBOSE=${INSTALLER_PRINT_VERBOSE:-0} +PRINT_QUIET=${INSTALLER_PRINT_QUIET:-0} +NO_MODIFY_PATH=${INSTALLER_NO_MODIFY_PATH:-0} +read -r RECEIPT <&2 + say_verbose " from $_url" 1>&2 + say_verbose " to $_file" 1>&2 + + ensure mkdir -p "$_dir" + + if ! downloader "$_url" "$_file"; then + say "failed to download $_url" + say "this may be a standard network error, but it may also indicate" + say "that $APP_NAME's release process is not working. When in doubt" + say "please feel free to open an issue!" + exit 1 + fi + + # ...and then the updater, if it exists + if [ -n "$_updater_name" ]; then + local _updater_url="$ARTIFACT_DOWNLOAD_URL/$_updater_name" + # This renames the artifact while doing the download, removing the + # target triple and leaving just the appname-update format + local _updater_file="$_dir/$APP_NAME-update" + + if ! downloader "$_updater_url" "$_updater_file"; then + say "failed to download $_updater_url" + say "this may be a standard network error, but it may also indicate" + say "that $APP_NAME's release process is not working. When in doubt" + say "please feel free to open an issue!" + exit 1 + fi + + # Add the updater to the list of binaries to install + _bins="$_bins $APP_NAME-update" + fi + + # unpack the archive + case "$_zip_ext" in + ".zip") + ensure unzip -q "$_file" -d "$_dir" + ;; + + ".tar."*) + ensure tar xf "$_file" --strip-components 1 -C "$_dir" + ;; + *) + err "unknown archive format: $_zip_ext" + ;; + esac + + install "$_dir" "$_bins" "$_arch" "$@" + local _retval=$? + if [ "$_retval" != 0 ]; then + return "$_retval" + fi + + ignore rm -rf "$_dir" + + # Install the install receipt + mkdir -p "$RECEIPT_HOME" || { + err "unable to create receipt directory at $RECEIPT_HOME" + } + echo "$RECEIPT" > "$RECEIPT_HOME/$APP_NAME-receipt.json" + # shellcheck disable=SC2320 + local _retval=$? + + return "$_retval" +} + +# Replaces $HOME with the variable name for display to the user, +# only if $HOME is defined. +replace_home() { + local _str="$1" + + if [ -n "${HOME:-}" ]; then + echo "$_str" | sed "s,$HOME,\$HOME," + else + echo "$_str" + fi +} + +json_binary_aliases() { + local _arch="$1" + + case "$_arch" in + "aarch64-apple-darwin") + echo '{}' + ;; + "x86_64-apple-darwin") + echo '{}' + ;; + "x86_64-pc-windows-gnu") + echo '{}' + ;; + "x86_64-unknown-linux-gnu") + echo '{}' + ;; + esac +} + +aliases_for_binary() { + local _bin="$1" + local _arch="$2" + + case "$_arch" in + "aarch64-apple-darwin") + case "$_bin" in + *) + echo "" + ;; + esac + ;; + "x86_64-apple-darwin") + case "$_bin" in + *) + echo "" + ;; + esac + ;; + "x86_64-pc-windows-gnu") + case "$_bin" in + *) + echo "" + ;; + esac + ;; + "x86_64-unknown-linux-gnu") + case "$_bin" in + *) + echo "" + ;; + esac + ;; + esac +} + +# See discussion of late-bound vs early-bound for why we use single-quotes with env vars +# shellcheck disable=SC2016 +install() { + # This code needs to both compute certain paths for itself to write to, and + # also write them to shell/rc files so that they can look them up to e.g. + # add them to PATH. This requires an active distinction between paths + # and expressions that can compute them. + # + # The distinction lies in when we want env-vars to be evaluated. For instance + # if we determine that we want to install to $HOME/.myapp, which do we add + # to e.g. $HOME/.profile: + # + # * early-bound: export PATH="/home/myuser/.myapp:$PATH" + # * late-bound: export PATH="$HOME/.myapp:$PATH" + # + # In this case most people would prefer the late-bound version, but in other + # cases the early-bound version might be a better idea. In particular when using + # other env-vars than $HOME, they are more likely to be only set temporarily + # for the duration of this install script, so it's more advisable to erase their + # existence with early-bounding. + # + # This distinction is handled by "double-quotes" (early) vs 'single-quotes' (late). + # + # However if we detect that "$SOME_VAR/..." is a subdir of $HOME, we try to rewrite + # it to be '$HOME/...' to get the best of both worlds. + # + # This script has a few different variants, the most complex one being the + # CARGO_HOME version which attempts to install things to Cargo's bin dir, + # potentially setting up a minimal version if the user hasn't ever installed Cargo. + # + # In this case we need to: + # + # * Install to $HOME/.cargo/bin/ + # * Create a shell script at $HOME/.cargo/env that: + # * Checks if $HOME/.cargo/bin/ is on PATH + # * and if not prepends it to PATH + # * Edits $HOME/.profile to run $HOME/.cargo/env (if the line doesn't exist) + # + # To do this we need these 4 values: + + # The actual path we're going to install to + local _install_dir + # Path to the an shell script that adds install_dir to PATH + local _env_script_path + # Potentially-late-bound version of install_dir to write env_script + local _install_dir_expr + # Potentially-late-bound version of env_script_path to write to rcfiles like $HOME/.profile + local _env_script_path_expr + + # Before actually consulting the configured install strategy, see + # if we're overriding it. + if [ -n "${CARGO_DIST_FORCE_INSTALL_DIR:-}" ]; then + _install_dir="$CARGO_DIST_FORCE_INSTALL_DIR/bin" + _env_script_path="$CARGO_DIST_FORCE_INSTALL_DIR/env" + _install_dir_expr="$(replace_home "$CARGO_DIST_FORCE_INSTALL_DIR/bin")" + _env_script_path_expr="$(replace_home "$CARGO_DIST_FORCE_INSTALL_DIR/env")" + fi + if [ -z "${_install_dir:-}" ]; then + # first try $CARGO_HOME, then fallback to $HOME/.cargo + if [ -n "${CARGO_HOME:-}" ]; then + _install_dir="$CARGO_HOME/bin" + _env_script_path="$CARGO_HOME/env" + # Initially make this early-bound to erase the potentially-temporary env-var + _install_dir_expr="$_install_dir" + _env_script_path_expr="$_env_script_path" + # If CARGO_HOME was set but it ended up being the default $HOME-based path, + # then keep things late-bound. Otherwise bake the value for safety. + # This is what rustup does, and accurately reproducing it is useful. + if [ -n "${HOME:-}" ]; then + if [ "$HOME/.cargo/bin" = "$_install_dir" ]; then + _install_dir_expr='$HOME/.cargo/bin' + _env_script_path_expr='$HOME/.cargo/env' + fi + fi + elif [ -n "${HOME:-}" ]; then + _install_dir="$HOME/.cargo/bin" + _env_script_path="$HOME/.cargo/env" + _install_dir_expr='$HOME/.cargo/bin' + _env_script_path_expr='$HOME/.cargo/env' + fi + fi + + if [ -z "$_install_dir_expr" ]; then + err "could not find a valid path to install to!" + fi + + # Identical to the sh version, just with a .fish file extension + # We place it down here to wait until it's been assigned in every + # path. + _fish_env_script_path="${_env_script_path}.fish" + _fish_env_script_path_expr="${_env_script_path_expr}.fish" + + # Replace the temporary cargo home with the calculated one + RECEIPT=$(echo "$RECEIPT" | sed "s,AXO_INSTALL_PREFIX,$_install_dir,") + # Also replace the aliases with the arch-specific one + RECEIPT=$(echo "$RECEIPT" | sed "s'\"binary_aliases\":{}'\"binary_aliases\":$(json_binary_aliases "$_arch")'") + + say "installing to $_install_dir" + ensure mkdir -p "$_install_dir" + + # copy all the binaries to the install dir + local _src_dir="$1" + local _bins="$2" + local _arch="$3" + for _bin_name in $_bins; do + local _bin="$_src_dir/$_bin_name" + ensure mv "$_bin" "$_install_dir" + # unzip seems to need this chmod + ensure chmod +x "$_install_dir/$_bin_name" + for _dest in $(aliases_for_binary "$_bin_name" "$_arch"); do + ln -sf "$_install_dir/$_bin_name" "$_install_dir/$_dest" + done + say " $_bin_name" + done + + say "everything's installed!" + + if [ "0" = "$NO_MODIFY_PATH" ]; then + add_install_dir_to_path "$_install_dir_expr" "$_env_script_path" "$_env_script_path_expr" ".profile" "sh" + exit1=$? + add_install_dir_to_path "$_install_dir_expr" "$_env_script_path" "$_env_script_path_expr" ".bash_profile .bash_login .bashrc" "sh" + exit2=$? + add_install_dir_to_path "$_install_dir_expr" "$_env_script_path" "$_env_script_path_expr" ".zshrc .zshenv" "sh" + exit3=$? + # This path may not exist by default + ensure mkdir -p "$HOME/.config/fish/conf.d" + exit4=$? + add_install_dir_to_path "$_install_dir_expr" "$_fish_env_script_path" "$_fish_env_script_path_expr" ".config/fish/conf.d/$APP_NAME.env.fish" "fish" + exit5=$? + + if [ "${exit1:-0}" = 1 ] || [ "${exit2:-0}" = 1 ] || [ "${exit3:-0}" = 1 ] || [ "${exit4:-0}" = 1 ] || [ "${exit5:-0}" = 1 ]; then + say "" + say "To add $_install_dir_expr to your PATH, either restart your shell or run:" + say "" + say " source $_env_script_path_expr (sh, bash, zsh)" + say " source $_fish_env_script_path_expr (fish)" + fi + fi +} + +print_home_for_script() { + local script="$1" + + local _home + case "$script" in + # zsh has a special ZDOTDIR directory, which if set + # should be considered instead of $HOME + .zsh*) + if [ -n "${ZDOTDIR:-}" ]; then + _home="$ZDOTDIR" + else + _home="$HOME" + fi + ;; + *) + _home="$HOME" + ;; + esac + + echo "$_home" +} + +add_install_dir_to_path() { + # Edit rcfiles ($HOME/.profile) to add install_dir to $PATH + # + # We do this slightly indirectly by creating an "env" shell script which checks if install_dir + # is on $PATH already, and prepends it if not. The actual line we then add to rcfiles + # is to just source that script. This allows us to blast it into lots of different rcfiles and + # have it run multiple times without causing problems. It's also specifically compatible + # with the system rustup uses, so that we don't conflict with it. + local _install_dir_expr="$1" + local _env_script_path="$2" + local _env_script_path_expr="$3" + local _rcfiles="$4" + local _shell="$5" + + if [ -n "${HOME:-}" ]; then + local _target + local _home + + # Find the first file in the array that exists and choose + # that as our target to write to + for _rcfile_relative in $_rcfiles; do + _home="$(print_home_for_script "$_rcfile_relative")" + local _rcfile="$_home/$_rcfile_relative" + + if [ -f "$_rcfile" ]; then + _target="$_rcfile" + break + fi + done + + # If we didn't find anything, pick the first entry in the + # list as the default to create and write to + if [ -z "${_target:-}" ]; then + local _rcfile_relative + _rcfile_relative="$(echo "$_rcfiles" | awk '{ print $1 }')" + _home="$(print_home_for_script "$_rcfile_relative")" + _target="$_home/$_rcfile_relative" + fi + + # `source x` is an alias for `. x`, and the latter is more portable/actually-posix. + # This apparently comes up a lot on freebsd. It's easy enough to always add + # the more robust line to rcfiles, but when telling the user to apply the change + # to their current shell ". x" is pretty easy to misread/miscopy, so we use the + # prettier "source x" line there. Hopefully people with Weird Shells are aware + # this is a thing and know to tweak it (or just restart their shell). + local _robust_line=". \"$_env_script_path_expr\"" + local _pretty_line="source \"$_env_script_path_expr\"" + + # Add the env script if it doesn't already exist + if [ ! -f "$_env_script_path" ]; then + say_verbose "creating $_env_script_path" + if [ "$_shell" = "sh" ]; then + write_env_script_sh "$_install_dir_expr" "$_env_script_path" + else + write_env_script_fish "$_install_dir_expr" "$_env_script_path" + fi + else + say_verbose "$_env_script_path already exists" + fi + + # Check if the line is already in the rcfile + # grep: 0 if matched, 1 if no match, and 2 if an error occurred + # + # Ideally we could use quiet grep (-q), but that makes "match" and "error" + # have the same behaviour, when we want "no match" and "error" to be the same + # (on error we want to create the file, which >> conveniently does) + # + # We search for both kinds of line here just to do the right thing in more cases. + if ! grep -F "$_robust_line" "$_target" > /dev/null 2>/dev/null && \ + ! grep -F "$_pretty_line" "$_target" > /dev/null 2>/dev/null + then + # If the script now exists, add the line to source it to the rcfile + # (This will also create the rcfile if it doesn't exist) + if [ -f "$_env_script_path" ]; then + local _line + # Fish has deprecated `.` as an alias for `source` and + # it will be removed in a later version. + # https://fishshell.com/docs/current/cmds/source.html + # By contrast, `.` is the traditional syntax in sh and + # `source` isn't always supported in all circumstances. + if [ "$_shell" = "fish" ]; then + _line="$_pretty_line" + else + _line="$_robust_line" + fi + say_verbose "adding $_line to $_target" + # prepend an extra newline in case the user's file is missing a trailing one + ensure echo "" >> "$_target" + ensure echo "$_line" >> "$_target" + return 1 + fi + else + say_verbose "$_install_dir already on PATH" + fi + fi +} + +write_env_script_sh() { + # write this env script to the given path (this cat/EOF stuff is a "heredoc" string) + local _install_dir_expr="$1" + local _env_script_path="$2" + ensure cat < "$_env_script_path" +#!/bin/sh +# add binaries to PATH if they aren't added yet +# affix colons on either side of \$PATH to simplify matching +case ":\${PATH}:" in + *:"$_install_dir_expr":*) + ;; + *) + # Prepending path in case a system-installed binary needs to be overridden + export PATH="$_install_dir_expr:\$PATH" + ;; +esac +EOF +} + +write_env_script_fish() { + # write this env script to the given path (this cat/EOF stuff is a "heredoc" string) + local _install_dir_expr="$1" + local _env_script_path="$2" + ensure cat < "$_env_script_path" +if not contains "$_install_dir_expr" \$PATH + # Prepending path in case a system-installed binary needs to be overridden + set -x PATH "$_install_dir_expr" \$PATH +end +EOF +} + +check_proc() { + # Check for /proc by looking for the /proc/self/exe link + # This is only run on Linux + if ! test -L /proc/self/exe ; then + err "fatal: Unable to find /proc/self/exe. Is /proc mounted? Installation cannot proceed without /proc." + fi +} + +get_bitness() { + need_cmd head + # Architecture detection without dependencies beyond coreutils. + # ELF files start out "\x7fELF", and the following byte is + # 0x01 for 32-bit and + # 0x02 for 64-bit. + # The printf builtin on some shells like dash only supports octal + # escape sequences, so we use those. + local _current_exe_head + _current_exe_head=$(head -c 5 /proc/self/exe ) + if [ "$_current_exe_head" = "$(printf '\177ELF\001')" ]; then + echo 32 + elif [ "$_current_exe_head" = "$(printf '\177ELF\002')" ]; then + echo 64 + else + err "unknown platform bitness" + fi +} + +is_host_amd64_elf() { + need_cmd head + need_cmd tail + # ELF e_machine detection without dependencies beyond coreutils. + # Two-byte field at offset 0x12 indicates the CPU, + # but we're interested in it being 0x3E to indicate amd64, or not that. + local _current_exe_machine + _current_exe_machine=$(head -c 19 /proc/self/exe | tail -c 1) + [ "$_current_exe_machine" = "$(printf '\076')" ] +} + +get_endianness() { + local cputype=$1 + local suffix_eb=$2 + local suffix_el=$3 + + # detect endianness without od/hexdump, like get_bitness() does. + need_cmd head + need_cmd tail + + local _current_exe_endianness + _current_exe_endianness="$(head -c 6 /proc/self/exe | tail -c 1)" + if [ "$_current_exe_endianness" = "$(printf '\001')" ]; then + echo "${cputype}${suffix_el}" + elif [ "$_current_exe_endianness" = "$(printf '\002')" ]; then + echo "${cputype}${suffix_eb}" + else + err "unknown platform endianness" + fi +} + +get_architecture() { + local _ostype + local _cputype + _ostype="$(uname -s)" + _cputype="$(uname -m)" + local _clibtype="gnu" + local _local_glibc + + if [ "$_ostype" = Linux ]; then + if [ "$(uname -o)" = Android ]; then + _ostype=Android + fi + if ldd --version 2>&1 | grep -q 'musl'; then + _clibtype="musl-dynamic" + # glibc, but is it a compatible glibc? + else + # Parsing version out from line 1 like: + # ldd (Ubuntu GLIBC 2.35-0ubuntu3.1) 2.35 + _local_glibc="$(ldd --version | awk -F' ' '{ if (FNR<=1) print $NF }')" + + if [ "$(echo "${_local_glibc}" | awk -F. '{ print $1 }')" = $BUILDER_GLIBC_MAJOR ] && [ "$(echo "${_local_glibc}" | awk -F. '{ print $2 }')" -ge $BUILDER_GLIBC_SERIES ]; then + _clibtype="gnu" + else + say "System glibc version (\`${_local_glibc}') is too old; using musl" >&2 + _clibtype="musl-static" + fi + fi + fi + + if [ "$_ostype" = Darwin ] && [ "$_cputype" = i386 ]; then + # Darwin `uname -m` lies + if sysctl hw.optional.x86_64 | grep -q ': 1'; then + _cputype=x86_64 + fi + fi + + if [ "$_ostype" = Darwin ] && [ "$_cputype" = x86_64 ]; then + # Rosetta on aarch64 + if [ "$(sysctl -n hw.optional.arm64 2>/dev/null)" = "1" ]; then + _cputype=aarch64 + fi + fi + + if [ "$_ostype" = SunOS ]; then + # Both Solaris and illumos presently announce as "SunOS" in "uname -s" + # so use "uname -o" to disambiguate. We use the full path to the + # system uname in case the user has coreutils uname first in PATH, + # which has historically sometimes printed the wrong value here. + if [ "$(/usr/bin/uname -o)" = illumos ]; then + _ostype=illumos + fi + + # illumos systems have multi-arch userlands, and "uname -m" reports the + # machine hardware name; e.g., "i86pc" on both 32- and 64-bit x86 + # systems. Check for the native (widest) instruction set on the + # running kernel: + if [ "$_cputype" = i86pc ]; then + _cputype="$(isainfo -n)" + fi + fi + + case "$_ostype" in + + Android) + _ostype=linux-android + ;; + + Linux) + check_proc + _ostype=unknown-linux-$_clibtype + _bitness=$(get_bitness) + ;; + + FreeBSD) + _ostype=unknown-freebsd + ;; + + NetBSD) + _ostype=unknown-netbsd + ;; + + DragonFly) + _ostype=unknown-dragonfly + ;; + + Darwin) + _ostype=apple-darwin + ;; + + illumos) + _ostype=unknown-illumos + ;; + + MINGW* | MSYS* | CYGWIN* | Windows_NT) + _ostype=pc-windows-gnu + ;; + + *) + err "unrecognized OS type: $_ostype" + ;; + + esac + + case "$_cputype" in + + i386 | i486 | i686 | i786 | x86) + _cputype=i686 + ;; + + xscale | arm) + _cputype=arm + if [ "$_ostype" = "linux-android" ]; then + _ostype=linux-androideabi + fi + ;; + + armv6l) + _cputype=arm + if [ "$_ostype" = "linux-android" ]; then + _ostype=linux-androideabi + else + _ostype="${_ostype}eabihf" + fi + ;; + + armv7l | armv8l) + _cputype=armv7 + if [ "$_ostype" = "linux-android" ]; then + _ostype=linux-androideabi + else + _ostype="${_ostype}eabihf" + fi + ;; + + aarch64 | arm64) + _cputype=aarch64 + ;; + + x86_64 | x86-64 | x64 | amd64) + _cputype=x86_64 + ;; + + mips) + _cputype=$(get_endianness mips '' el) + ;; + + mips64) + if [ "$_bitness" -eq 64 ]; then + # only n64 ABI is supported for now + _ostype="${_ostype}abi64" + _cputype=$(get_endianness mips64 '' el) + fi + ;; + + ppc) + _cputype=powerpc + ;; + + ppc64) + _cputype=powerpc64 + ;; + + ppc64le) + _cputype=powerpc64le + ;; + + s390x) + _cputype=s390x + ;; + riscv64) + _cputype=riscv64gc + ;; + loongarch64) + _cputype=loongarch64 + ;; + *) + err "unknown CPU type: $_cputype" + + esac + + # Detect 64-bit linux with 32-bit userland + if [ "${_ostype}" = unknown-linux-gnu ] && [ "${_bitness}" -eq 32 ]; then + case $_cputype in + x86_64) + # 32-bit executable for amd64 = x32 + if is_host_amd64_elf; then { + err "x32 linux unsupported" + }; else + _cputype=i686 + fi + ;; + mips64) + _cputype=$(get_endianness mips '' el) + ;; + powerpc64) + _cputype=powerpc + ;; + aarch64) + _cputype=armv7 + if [ "$_ostype" = "linux-android" ]; then + _ostype=linux-androideabi + else + _ostype="${_ostype}eabihf" + fi + ;; + riscv64gc) + err "riscv64 with 32-bit userland unsupported" + ;; + esac + fi + + # treat armv7 systems without neon as plain arm + if [ "$_ostype" = "unknown-linux-gnueabihf" ] && [ "$_cputype" = armv7 ]; then + if ensure grep '^Features' /proc/cpuinfo | grep -q -v neon; then + # At least one processor does not have NEON. + _cputype=arm + fi + fi + + _arch="${_cputype}-${_ostype}" + + RETVAL="$_arch" +} + +say() { + if [ "0" = "$PRINT_QUIET" ]; then + echo "$1" + fi +} + +say_verbose() { + if [ "1" = "$PRINT_VERBOSE" ]; then + echo "$1" + fi +} + +err() { + if [ "0" = "$PRINT_QUIET" ]; then + local red + local reset + red=$(tput setaf 1 2>/dev/null || echo '') + reset=$(tput sgr0 2>/dev/null || echo '') + say "${red}ERROR${reset}: $1" >&2 + fi + exit 1 +} + +need_cmd() { + if ! check_cmd "$1" + then err "need '$1' (command not found)" + fi +} + +check_cmd() { + command -v "$1" > /dev/null 2>&1 + return $? +} + +assert_nz() { + if [ -z "$1" ]; then err "assert_nz $2"; fi +} + +# Run a command that should never fail. If the command fails execution +# will immediately terminate with an error showing the failing +# command. +ensure() { + if ! "$@"; then err "command failed: $*"; fi +} + +# This is just for indicating that commands' results are being +# intentionally ignored. Usually, because it's being executed +# as part of error handling. +ignore() { + "$@" +} + +# This wraps curl or wget. Try curl first, if not installed, +# use wget instead. +downloader() { + if check_cmd curl + then _dld=curl + elif check_cmd wget + then _dld=wget + else _dld='curl or wget' # to be used in error message of need_cmd + fi + + if [ "$1" = --check ] + then need_cmd "$_dld" + elif [ "$_dld" = curl ] + then curl -sSfL "$1" -o "$2" + elif [ "$_dld" = wget ] + then wget "$1" -O "$2" + else err "Unknown downloader" # should not reach here + fi +} + +download_binary_and_run_installer "$@" || exit 1 diff --git a/index.html b/index.html new file mode 100644 index 0000000..993b2c5 --- /dev/null +++ b/index.html @@ -0,0 +1,625 @@ + + + + hexagon + + + + + + + + + + + + + + + + + + +
    +
    + + + + +
    +
    + +

    hexagon

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

    Install v0.2.0

    + +
    Published on May 21 2024 at 22:42 UTC
    + + + +
    + + + + + + + + + +
    + View all installation options + + + +
    +
    + +View all installation options + + +

    Hexagon

    +

    Hexagon is a programming language for Hex Casting. Hexagon is a superset of the hexpattern format, adding variables, if statements, and more.

    +

    Installing

    +

    Either download the latest release file or install via Cargo: +cargo install --git https://github.com/Master-Bw3/Hexagon

    +

    Usage

    +

    Interpret a file

    +
    hexagon run filename.hexagon
    +
    + +

    Compile a file

    +
    hexagon build filename.hexagon
    +
    + +

    Send a hex to Hex Server

    +
    hexagon send http://localhost:9000/hexPost filename.hexagon
    +
    + +

    Syntax

    +

    Actions are written in the hexpattern format

    +
    Mind's Reflection
    +Compass Purification
    +
    + +

    Actions that retrieve information from the world must have a value set for the interpreter (not needed for compiler)

    +
    Scout's Distillation: Null
    +Zone Distillation: Player: [@Caster]
    +
    + +

    Numerical Reflection and Bookkeepers also require a value to be set

    +
    Numerical Reflection: 1
    +Bookkeeper's Gambit: v-vv-
    +
    + +

    Iota Syntax

    +

    Iotas are written in the following format:

    +
    1                              //Number
    +(1,2,3)                        //Vector
    +[1, (1, 2, 3)]                 //List
    +@Caster                        //Entity 
    +Null                           //Null
    +Garbage                        //Garbage
    +True                           //Bool
    +NORTHEAST qaq                  //Pattern via signature
    +Numerical Reflection: 1        //Pattern via name
    +"hello world"                  //String
    +[(3, 2) | 1, 1; 2, 2; 3, 3]    //Matrix
    +[(0, 0)]                    //Empty Matrix
    +
    + +

    Embedding Iotas

    +
    <Iota>: direct insertion, no escape
    +<{Iota}>: embed with intro/retro/flock
    +<\Iota>: embed with consideration(s)
    +<<Iota>>: embed with intro or considerations, whichever is shorter
    +
    + +

    Variables

    +

    Note: currently, all variables are global and are never deallocated.

    +
    Mind's Reflection
    +Compass Purification 
    +Store($pos)               //Remove top iota from stack and store in $pos
    +
    +Mind's Reflection
    +Compass Purification 
    +Copy($pos)                //Copy top iota on stack and store in $pos
    +
    +$pos                      //Push pos to the stack
    +Place Block
    +
    + +

    If / Else

    +
    <\True>
    +Store($condition)
    +...
    +if {$condition} then {
    +	...
    +} else {
    +	...
    +}
    +
    +//else branch is optional
    +if {$condition} then {
    +	...
    +}
    +
    +//else if
    +if {$condition1} then {
    +	...
    +} else if ($condition2) then {
    +	...
    +} else {
    +	...
    +}
    +
    + +

    If statements will evaluate the condition and use the top Iota on the stack to determine which branch to take. Note that this does not isolate the stack, so the code below is perfectly valid:

    +
    <\True>
    +if {} then {
    +	//this branch will be pushed to the stack
    +	...
    +} else {
    +	...
    +}
    +
    + +

    The then and else blocks will be pushed to the stack. To evaluate the block, use Hermes' Gambit or its ilk.

    +
    if {<\True>} then {
    +	...
    +} else {
    +	...
    +}
    +Hermes' Gambit //evaluates the 'then' branch
    +
    +
    +
    + +

    Macros

    +

    Macros are defined using this syntax:

    +
    #define Macro Name (DIRECTION signature) ... {
    +...
    +}
    +
    + +

    As an example:

    +
    #define Duplicate Thrice (SOUTH_EAST edd) = num, num -> num {
    +	Numerical Reflection: 3
    +	Gemini Gambit
    +}
    +
    + +

    Note: everything between the signature and first curly bracket is ignored, so the following is also valid:

    +
    #define Duplicate Thrice (SOUTH_EAST edd)
    +{
    +	Numerical Reflection: 3
    +	Gemini Gambit
    +}
    +
    + +

    When macros are used in a hex, they get expanded, not evaluated.

    +
    Mind's Reflection
    +Duplicate Thrice     //expand a macro
    +
    +{
    +	Duplicate Thrice //expand a macro into a list
    +}
    +
    +
    +
    +
    +<\Duplicate Thrice>  //embed the pattern associated with the macro
    +
    +<Duplicate Thrice>   //will cause a mishap
    +
    + +

    Config

    +

    By default, Hexagon looks for a config.toml file in the current directory. A different file can also be specified:

    +
    hexagon run example.hexagon example.toml
    +
    + +

    Config Syntax

    +
    //register an akashic library
    +[[libraries]]
    +location = [0, 0, 0]
    +"adda" = "@Zombie"
    +"qaaq" = "5"
    +
    +//register another library
    +[[libraries]]
    +location = [1, 2, 3]
    +
    +//register an entity
    +[[entities]]
    +name = "Zombie"
    +uuid = "[I;542246046,714361767,-2088965103,2106423580]" //optional, defaults to 0s
    +type = "Monster"
    +item = "Focus" //optional, defaults to None
    +iota = "1"     //optional, defaults to None
    +
    + + + + +
    +
    + +
    + + + + + hexagon + +
    +
    + + + + + + + + + + + \ No newline at end of file diff --git a/oranda-v0.6.1.css b/oranda-v0.6.1.css new file mode 100644 index 0000000..461aea7 --- /dev/null +++ b/oranda-v0.6.1.css @@ -0,0 +1,3 @@ +@import url("https://fonts.googleapis.com/css2?family=Fira+Sans:wght@400;700;900&display=swap");@import url("https://fonts.googleapis.com/css2?family=Comfortaa:wght@400;700&display=swap");@import url("https://fonts.googleapis.com/css2?family=IBM+Plex+Mono:wght@400;600;700&display=swap");@import url("https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600&display=swap");:root{--dark-fg-color:#fff;--light-fg-color:#141414;--light-bg-color:var(--dark-fg-color);--dark-bg-color:var(--light-fg-color);--fg-color:var(--light-fg-color);--bg-color:var(--light-bg-color);--light-link-color:#0284c7;--dark-link-color:#8bb9fe;--link-color:var(--light-link-color);--light-highlight-bg-color:#ededed;--light-highlight-fg-color:#595959;--dark-highlight-bg-color:#27272a;--dark-highlight-fg-color:#ededed;--highlight-fg-color:var(--light-highlight-fg-color);--highlight-bg-color:var(--light-highlight-bg-color);--font-face:"Fira Sans",sans-serif}:root.dark{--fg-color:var(--dark-fg-color);--bg-color:var(--dark-bg-color);--link-color:var(--dark-link-color);--highlight-fg-color:var(--dark-highlight-fg-color);--highlight-bg-color:var(--dark-highlight-bg-color)} + +/*! tailwindcss v3.4.3 | MIT License | https://tailwindcss.com*/*,:after,:before{border:0 solid #e5e7eb;box-sizing:border-box}:after,:before{--tw-content:""}:host,html{-webkit-text-size-adjust:100%;font-feature-settings:normal;-webkit-tap-highlight-color:transparent;font-family:ui-sans-serif,system-ui,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol,Noto Color Emoji;font-variation-settings:normal;line-height:1.5;-moz-tab-size:4;-o-tab-size:4;tab-size:4}body{line-height:inherit;margin:0}hr{border-top-width:1px;color:inherit;height:0}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;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,pre,samp{font-feature-settings:normal;font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace;font-size:1em;font-variation-settings:normal}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:initial}sub{bottom:-.25em}sup{top:-.5em}table{border-collapse:collapse;border-color:inherit;text-indent:0}button,input,optgroup,select,textarea{font-feature-settings:inherit;color:inherit;font-family:inherit;font-size:100%;font-variation-settings:inherit;font-weight:inherit;letter-spacing:inherit;line-height:inherit;margin:0;padding:0}button,select{text-transform:none}button,input:where([type=button]),input:where([type=reset]),input:where([type=submit]){-webkit-appearance:button;background-color:initial;background-image:none}:-moz-focusring{outline:auto}:-moz-ui-invalid{box-shadow:none}progress{vertical-align:initial}::-webkit-inner-spin-button,::-webkit-outer-spin-button{height:auto}[type=search]{-webkit-appearance:textfield;outline-offset:-2px}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}summary{display:list-item}blockquote,dd,dl,figure,h1,h2,h3,h4,h5,h6,hr,p,pre{margin:0}fieldset{margin:0}fieldset,legend{padding:0}menu,ol,ul{list-style:none;margin:0;padding:0}dialog{padding:0}textarea{resize:vertical}input::-moz-placeholder,textarea::-moz-placeholder{color:#9ca3af;opacity:1}input::placeholder,textarea::placeholder{color:#9ca3af;opacity:1}[role=button],button{cursor:pointer}:disabled{cursor:default}audio,canvas,embed,iframe,img,object,svg,video{display:block;vertical-align:middle}img,video{height:auto;max-width:100%}[hidden]{display:none}[multiple],[type=date],[type=datetime-local],[type=email],[type=month],[type=number],[type=password],[type=search],[type=tel],[type=text],[type=time],[type=url],[type=week],select,textarea{--tw-shadow:0 0 #0000;-webkit-appearance:none;-moz-appearance:none;appearance:none;background-color:#fff;border-color:#6b7280;border-radius:0;border-width:1px;font-size:1rem;line-height:1.5rem;padding:.5rem .75rem}[multiple]:focus,[type=date]:focus,[type=datetime-local]:focus,[type=email]:focus,[type=month]:focus,[type=number]:focus,[type=password]:focus,[type=search]:focus,[type=tel]:focus,[type=text]:focus,[type=time]:focus,[type=url]:focus,[type=week]:focus,select:focus,textarea:focus{--tw-ring-inset:var(--tw-empty,/*!*/ /*!*/);--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-color:#2563eb;--tw-ring-offset-shadow:var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color);border-color:#2563eb;box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow);outline:2px solid #0000;outline-offset:2px}input::-moz-placeholder,textarea::-moz-placeholder{color:#6b7280;opacity:1}input::placeholder,textarea::placeholder{color:#6b7280;opacity:1}::-webkit-datetime-edit-fields-wrapper{padding:0}::-webkit-date-and-time-value{min-height:1.5em}::-webkit-datetime-edit,::-webkit-datetime-edit-day-field,::-webkit-datetime-edit-hour-field,::-webkit-datetime-edit-meridiem-field,::-webkit-datetime-edit-millisecond-field,::-webkit-datetime-edit-minute-field,::-webkit-datetime-edit-month-field,::-webkit-datetime-edit-second-field,::-webkit-datetime-edit-year-field{padding-bottom:0;padding-top:0}select{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='none' viewBox='0 0 20 20'%3E%3Cpath stroke='%236b7280' stroke-linecap='round' stroke-linejoin='round' stroke-width='1.5' d='m6 8 4 4 4-4'/%3E%3C/svg%3E");background-position:right .5rem center;background-repeat:no-repeat;background-size:1.5em 1.5em;padding-right:2.5rem;-webkit-print-color-adjust:exact;print-color-adjust:exact}[multiple]{background-image:none;background-position:0 0;background-repeat:unset;background-size:initial;padding-right:.75rem;-webkit-print-color-adjust:unset;print-color-adjust:unset}[type=checkbox],[type=radio]{--tw-shadow:0 0 #0000;-webkit-appearance:none;-moz-appearance:none;appearance:none;background-color:#fff;background-origin:border-box;border-color:#6b7280;border-width:1px;color:#2563eb;display:inline-block;flex-shrink:0;height:1rem;padding:0;-webkit-print-color-adjust:exact;print-color-adjust:exact;-webkit-user-select:none;-moz-user-select:none;user-select:none;vertical-align:middle;width:1rem}[type=checkbox]{border-radius:0}[type=radio]{border-radius:100%}[type=checkbox]:focus,[type=radio]:focus{--tw-ring-inset:var(--tw-empty,/*!*/ /*!*/);--tw-ring-offset-width:2px;--tw-ring-offset-color:#fff;--tw-ring-color:#2563eb;--tw-ring-offset-shadow:var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow);outline:2px solid #0000;outline-offset:2px}[type=checkbox]:checked,[type=radio]:checked{background-color:currentColor;background-position:50%;background-repeat:no-repeat;background-size:100% 100%;border-color:#0000}[type=checkbox]:checked{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='%23fff' viewBox='0 0 16 16'%3E%3Cpath d='M12.207 4.793a1 1 0 0 1 0 1.414l-5 5a1 1 0 0 1-1.414 0l-2-2a1 1 0 0 1 1.414-1.414L6.5 9.086l4.293-4.293a1 1 0 0 1 1.414 0z'/%3E%3C/svg%3E")}[type=radio]:checked{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='%23fff' viewBox='0 0 16 16'%3E%3Ccircle cx='8' cy='8' r='3'/%3E%3C/svg%3E")}[type=checkbox]:checked:focus,[type=checkbox]:checked:hover,[type=checkbox]:indeterminate,[type=radio]:checked:focus,[type=radio]:checked:hover{background-color:currentColor;border-color:#0000}[type=checkbox]:indeterminate{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='none' viewBox='0 0 16 16'%3E%3Cpath stroke='%23fff' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='M4 8h8'/%3E%3C/svg%3E");background-position:50%;background-repeat:no-repeat;background-size:100% 100%}[type=checkbox]:indeterminate:focus,[type=checkbox]:indeterminate:hover{background-color:currentColor;border-color:#0000}[type=file]{background:unset;border-color:inherit;border-radius:0;border-width:0;font-size:unset;line-height:inherit;padding:0}[type=file]:focus{outline:1px solid ButtonText;outline:1px auto -webkit-focus-ring-color}:root{--color-inherit:inherit;--color-current:currentColor;--color-transparent:#0000;--color-black:#000;--color-white:#fff;--color-slate-50:#f8fafc;--color-slate-100:#f1f5f9;--color-slate-200:#e2e8f0;--color-slate-300:#cbd5e1;--color-slate-400:#94a3b8;--color-slate-500:#64748b;--color-slate-600:#475569;--color-slate-700:#334155;--color-slate-800:#1e293b;--color-slate-900:#0f172a;--color-slate-950:#020617;--color-gray-50:#f9fafb;--color-gray-100:#f3f4f6;--color-gray-200:#e5e7eb;--color-gray-300:#d1d5db;--color-gray-400:#9ca3af;--color-gray-500:#6b7280;--color-gray-600:#4b5563;--color-gray-700:#374151;--color-gray-800:#1f2937;--color-gray-900:#111827;--color-gray-950:#030712;--color-zinc-50:#fafafa;--color-zinc-100:#f4f4f5;--color-zinc-200:#e4e4e7;--color-zinc-300:#d4d4d8;--color-zinc-400:#a1a1aa;--color-zinc-500:#71717a;--color-zinc-600:#52525b;--color-zinc-700:#3f3f46;--color-zinc-800:#27272a;--color-zinc-900:#18181b;--color-zinc-950:#09090b;--color-neutral-50:#fafafa;--color-neutral-100:#f5f5f5;--color-neutral-200:#e5e5e5;--color-neutral-300:#d4d4d4;--color-neutral-400:#a3a3a3;--color-neutral-500:#737373;--color-neutral-600:#525252;--color-neutral-700:#404040;--color-neutral-800:#262626;--color-neutral-900:#171717;--color-neutral-950:#0a0a0a;--color-stone-50:#fafaf9;--color-stone-100:#f5f5f4;--color-stone-200:#e7e5e4;--color-stone-300:#d6d3d1;--color-stone-400:#a8a29e;--color-stone-500:#78716c;--color-stone-600:#57534e;--color-stone-700:#44403c;--color-stone-800:#292524;--color-stone-900:#1c1917;--color-stone-950:#0c0a09;--color-red-50:#fef2f2;--color-red-100:#fee2e2;--color-red-200:#fecaca;--color-red-300:#fca5a5;--color-red-400:#f87171;--color-red-500:#ef4444;--color-red-600:#dc2626;--color-red-700:#b91c1c;--color-red-800:#991b1b;--color-red-900:#7f1d1d;--color-red-950:#450a0a;--color-orange-50:#fff7ed;--color-orange-100:#ffedd5;--color-orange-200:#fed7aa;--color-orange-300:#fdba74;--color-orange-400:#fb923c;--color-orange-500:#f97316;--color-orange-600:#ea580c;--color-orange-700:#c2410c;--color-orange-800:#9a3412;--color-orange-900:#7c2d12;--color-orange-950:#431407;--color-amber-50:#fffbeb;--color-amber-100:#fef3c7;--color-amber-200:#fde68a;--color-amber-300:#fcd34d;--color-amber-400:#fbbf24;--color-amber-500:#f59e0b;--color-amber-600:#d97706;--color-amber-700:#b45309;--color-amber-800:#92400e;--color-amber-900:#78350f;--color-amber-950:#451a03;--color-yellow-50:#fefce8;--color-yellow-100:#fef9c3;--color-yellow-200:#fef08a;--color-yellow-300:#fde047;--color-yellow-400:#facc15;--color-yellow-500:#eab308;--color-yellow-600:#ca8a04;--color-yellow-700:#a16207;--color-yellow-800:#854d0e;--color-yellow-900:#713f12;--color-yellow-950:#422006;--color-lime-50:#f7fee7;--color-lime-100:#ecfccb;--color-lime-200:#d9f99d;--color-lime-300:#bef264;--color-lime-400:#a3e635;--color-lime-500:#84cc16;--color-lime-600:#65a30d;--color-lime-700:#4d7c0f;--color-lime-800:#3f6212;--color-lime-900:#365314;--color-lime-950:#1a2e05;--color-green-50:#f0fdf4;--color-green-100:#dcfce7;--color-green-200:#bbf7d0;--color-green-300:#86efac;--color-green-400:#4ade80;--color-green-500:#22c55e;--color-green-600:#16a34a;--color-green-700:#15803d;--color-green-800:#166534;--color-green-900:#14532d;--color-green-950:#052e16;--color-emerald-50:#ecfdf5;--color-emerald-100:#d1fae5;--color-emerald-200:#a7f3d0;--color-emerald-300:#6ee7b7;--color-emerald-400:#34d399;--color-emerald-500:#10b981;--color-emerald-600:#059669;--color-emerald-700:#047857;--color-emerald-800:#065f46;--color-emerald-900:#064e3b;--color-emerald-950:#022c22;--color-teal-50:#f0fdfa;--color-teal-100:#ccfbf1;--color-teal-200:#99f6e4;--color-teal-300:#5eead4;--color-teal-400:#2dd4bf;--color-teal-500:#14b8a6;--color-teal-600:#0d9488;--color-teal-700:#0f766e;--color-teal-800:#115e59;--color-teal-900:#134e4a;--color-teal-950:#042f2e;--color-cyan-50:#ecfeff;--color-cyan-100:#cffafe;--color-cyan-200:#a5f3fc;--color-cyan-300:#67e8f9;--color-cyan-400:#22d3ee;--color-cyan-500:#06b6d4;--color-cyan-600:#0891b2;--color-cyan-700:#0e7490;--color-cyan-800:#155e75;--color-cyan-900:#164e63;--color-cyan-950:#083344;--color-sky-50:#f0f9ff;--color-sky-100:#e0f2fe;--color-sky-200:#bae6fd;--color-sky-300:#7dd3fc;--color-sky-400:#38bdf8;--color-sky-500:#0ea5e9;--color-sky-600:#0284c7;--color-sky-700:#0369a1;--color-sky-800:#075985;--color-sky-900:#0c4a6e;--color-sky-950:#082f49;--color-blue-50:#eff6ff;--color-blue-100:#dbeafe;--color-blue-200:#bfdbfe;--color-blue-300:#93c5fd;--color-blue-400:#60a5fa;--color-blue-500:#3b82f6;--color-blue-600:#2563eb;--color-blue-700:#1d4ed8;--color-blue-800:#1e40af;--color-blue-900:#1e3a8a;--color-blue-950:#172554;--color-indigo-50:#eef2ff;--color-indigo-100:#e0e7ff;--color-indigo-200:#c7d2fe;--color-indigo-300:#a5b4fc;--color-indigo-400:#818cf8;--color-indigo-500:#6366f1;--color-indigo-600:#4f46e5;--color-indigo-700:#4338ca;--color-indigo-800:#3730a3;--color-indigo-900:#312e81;--color-indigo-950:#1e1b4b;--color-violet-50:#f5f3ff;--color-violet-100:#ede9fe;--color-violet-200:#ddd6fe;--color-violet-300:#c4b5fd;--color-violet-400:#a78bfa;--color-violet-500:#8b5cf6;--color-violet-600:#7c3aed;--color-violet-700:#6d28d9;--color-violet-800:#5b21b6;--color-violet-900:#4c1d95;--color-violet-950:#2e1065;--color-purple-50:#faf5ff;--color-purple-100:#f3e8ff;--color-purple-200:#e9d5ff;--color-purple-300:#d8b4fe;--color-purple-400:#c084fc;--color-purple-500:#a855f7;--color-purple-600:#9333ea;--color-purple-700:#7e22ce;--color-purple-800:#6b21a8;--color-purple-900:#581c87;--color-purple-950:#3b0764;--color-fuchsia-50:#fdf4ff;--color-fuchsia-100:#fae8ff;--color-fuchsia-200:#f5d0fe;--color-fuchsia-300:#f0abfc;--color-fuchsia-400:#e879f9;--color-fuchsia-500:#d946ef;--color-fuchsia-600:#c026d3;--color-fuchsia-700:#a21caf;--color-fuchsia-800:#86198f;--color-fuchsia-900:#701a75;--color-fuchsia-950:#4a044e;--color-pink-50:#fdf2f8;--color-pink-100:#fce7f3;--color-pink-200:#fbcfe8;--color-pink-300:#f9a8d4;--color-pink-400:#f472b6;--color-pink-500:#ec4899;--color-pink-600:#db2777;--color-pink-700:#be185d;--color-pink-800:#9d174d;--color-pink-900:#831843;--color-pink-950:#500724;--color-rose-50:#fff1f2;--color-rose-100:#ffe4e6;--color-rose-200:#fecdd3;--color-rose-300:#fda4af;--color-rose-400:#fb7185;--color-rose-500:#f43f5e;--color-rose-600:#e11d48;--color-rose-700:#be123c;--color-rose-800:#9f1239;--color-rose-900:#881337;--color-rose-950:#4c0519;--color-axo-pink:#ff75c3;--color-axo-pink-dark:#cc5c9b;--color-axo-orange:#f57070;--color-axo-orange-dark:#e85e68;--color-axo-highlighter:#ffd900;--color-axo-black:#141414;--color-axo-light-gray:#ededed;--color-axo-dark-gray:#595959}*,::backdrop,:after,:before{--tw-border-spacing-x:0;--tw-border-spacing-y:0;--tw-translate-x:0;--tw-translate-y:0;--tw-rotate:0;--tw-skew-x:0;--tw-skew-y:0;--tw-scale-x:1;--tw-scale-y:1;--tw-pan-x: ;--tw-pan-y: ;--tw-pinch-zoom: ;--tw-scroll-snap-strictness:proximity;--tw-gradient-from-position: ;--tw-gradient-via-position: ;--tw-gradient-to-position: ;--tw-ordinal: ;--tw-slashed-zero: ;--tw-numeric-figure: ;--tw-numeric-spacing: ;--tw-numeric-fraction: ;--tw-ring-inset: ;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-color:#3b82f680;--tw-ring-offset-shadow:0 0 #0000;--tw-ring-shadow:0 0 #0000;--tw-shadow:0 0 #0000;--tw-shadow-colored:0 0 #0000;--tw-blur: ;--tw-brightness: ;--tw-contrast: ;--tw-grayscale: ;--tw-hue-rotate: ;--tw-invert: ;--tw-saturate: ;--tw-sepia: ;--tw-drop-shadow: ;--tw-backdrop-blur: ;--tw-backdrop-brightness: ;--tw-backdrop-contrast: ;--tw-backdrop-grayscale: ;--tw-backdrop-hue-rotate: ;--tw-backdrop-invert: ;--tw-backdrop-opacity: ;--tw-backdrop-saturate: ;--tw-backdrop-sepia: ;--tw-contain-size: ;--tw-contain-layout: ;--tw-contain-paint: ;--tw-contain-style: }body,html{font-family:var(--font-face);height:100%;scroll-behavior:smooth}.container{display:flex;flex-direction:column;min-height:100%}.page-body{flex-grow:1}:focus{outline-offset:4px;outline-style:solid;outline-width:2px}body{background-color:var(--bg-color);color:var(--fg-color)}a{color:var(--link-color)}a:hover{text-decoration-line:underline;text-underline-offset:4px}.title{font-size:3.75rem;line-height:1;padding-bottom:.5rem;text-align:center}@media (min-width:640px){.title{font-size:6rem;line-height:1}}h1{font-size:1.875rem;font-weight:900;line-height:2.25rem;line-height:1.25;margin-bottom:2rem}@media (min-width:640px){h1{font-size:3.75rem;line-height:1}}h2{font-size:1.5rem;font-weight:700;line-height:2rem;line-height:1.25;margin-bottom:1.5rem}@media (min-width:640px){h2{font-size:3rem;line-height:1}}h2,h3{margin-top:3rem}@media (min-width:640px){h2,h3{margin-top:6rem}}h3{font-size:1.5rem;font-weight:700;line-height:2rem;line-height:1.25;margin-bottom:1rem}@media (min-width:640px){h3{font-size:2.25rem;line-height:2.5rem}}h4{font-size:1.5rem;line-height:2rem;line-height:1.25;margin-bottom:1rem}@media (min-width:640px){h4{font-size:1.875rem;line-height:2.25rem}}h5{color:rgb(51 65 85/var(--tw-text-opacity));font-size:1.25rem;font-weight:700;line-height:1.75rem;line-height:1.25;margin-bottom:1rem}h5,h5:is(.dark *){--tw-text-opacity:1}h5:is(.dark *){color:rgb(226 232 240/var(--tw-text-opacity))}@media (min-width:640px){h5{font-size:1.5rem;line-height:2rem}}h6{color:rgb(30 41 59/var(--tw-text-opacity));font-size:1.25rem;font-weight:700;line-height:1.75rem;line-height:1.25;margin-bottom:1rem}h6,h6:is(.dark *){--tw-text-opacity:1}h6:is(.dark *){color:rgb(203 213 225/var(--tw-text-opacity))}@media (min-width:640px){h6{font-size:1.25rem;line-height:1.75rem}}p,table{font-size:1rem;line-height:1.5rem;line-height:1.625;margin-bottom:2rem}@media (min-width:640px){p,table{font-size:1.125rem;line-height:1.75rem}}b,li{font-size:1rem;line-height:1.5rem;line-height:1.625}@media (min-width:640px){b,li{font-size:1.125rem;line-height:1.75rem}}table{margin-bottom:4rem;margin-top:4rem}table th{padding:1rem;text-align:left;text-transform:uppercase}table td{font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace;padding:1rem;vertical-align:top}table td,table td>code{font-size:.875rem;line-height:1.25rem}table tbody tr{border-color:var(--fg-color);border-top-width:1px}div.table{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));margin-bottom:4rem;margin-top:4rem;width:100%}div.table .th{font-size:1.125rem;font-weight:700;line-height:1.75rem;text-align:left;text-transform:uppercase}div.table .th,div.table span:not(.th){border-color:var(--fg-color);border-top-width:1px;padding:1rem}div.table span:not(.th){font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace;font-size:.875rem;line-height:1.25rem}li,ul{list-style-type:none}.rendered-markdown li,.rendered-markdown ul{list-style-type:disc}li{margin-bottom:1rem;margin-left:1rem}@media (min-width:640px){li{margin-left:2rem}}code{font-size:1rem;line-height:1.5rem;line-height:1.625;margin-bottom:1rem;white-space:pre-wrap}@media (min-width:640px){code{font-size:1.125rem;line-height:1.75rem}}code{color:var(--link-color)}div.table code{font-size:.875rem;line-height:1.25rem}h1 code,h2 code,h3 code,h4 code,h5 code,h6 code{font-size:inherit;line-height:inherit}pre{margin-bottom:4rem;margin-top:4rem;overflow:auto;padding:1rem}pre>code{font-size:.75rem;line-height:1rem}@media (min-width:640px){pre>code{font-size:1rem;line-height:1.5rem}}hr{border-style:dashed;border-width:1px;margin:5rem auto;text-align:center;width:16rem}@media (min-width:768px){hr{width:24rem}}img{display:inline}p>img:only-child{display:block;margin:auto}blockquote{border-color:var(--link-color);border-left-width:2px;font-size:1.5rem;line-height:2rem;padding-left:1.5rem}main{margin:6rem auto;max-width:80%}@media (min-width:1024px){main{max-width:56rem}}.github-icon{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath fill='%23fff' d='M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12'/%3E%3C/svg%3E");height:1.25rem;width:1.25rem}.dark .github-icon{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath fill='%23141414' d='M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12'/%3E%3C/svg%3E")}.dark .artifacts,.light .artifacts{padding:2rem}.logo{display:block;margin:auto;max-width:20rem}.inline-code{text-align:center;word-break:break-all}.oblique{font-style:oblique}.well-color{--tw-bg-opacity:1;background-color:rgb(17 24 39/var(--tw-bg-opacity))}.oranda-hide{display:none}.heading-1{font-size:1.875rem;font-weight:900;line-height:2.25rem;line-height:1.25;margin-bottom:2rem}@media (min-width:640px){.heading-1{font-size:3.75rem;line-height:1}}.heading-2{font-size:1.5rem;font-weight:700;line-height:2rem;line-height:1.25;margin-bottom:1.5rem}@media (min-width:640px){.heading-2{font-size:3rem;line-height:1}}.heading-3{font-size:1.5rem;font-weight:700;line-height:2rem;line-height:1.25;margin-bottom:1rem}@media (min-width:640px){.heading-3{font-size:2.25rem;line-height:2.5rem}}.heading-4{font-size:1.5rem;line-height:2rem;line-height:1.25;margin-bottom:1rem}@media (min-width:640px){.heading-4{font-size:1.875rem;line-height:2.25rem}}.heading-5{--tw-text-opacity:1;color:rgb(51 65 85/var(--tw-text-opacity));font-size:1.25rem;font-weight:700;line-height:1.75rem;line-height:1.25;margin-bottom:1rem}.heading-5:is(.dark *){--tw-text-opacity:1;color:rgb(226 232 240/var(--tw-text-opacity))}@media (min-width:640px){.heading-5{font-size:1.5rem;line-height:2rem}}.heading-6{--tw-text-opacity:1;color:rgb(30 41 59/var(--tw-text-opacity));font-size:1.25rem;font-weight:700;line-height:1.75rem;line-height:1.25;margin-bottom:1rem}.heading-6:is(.dark *){--tw-text-opacity:1;color:rgb(203 213 225/var(--tw-text-opacity))}@media (min-width:640px){.heading-6{font-size:1.25rem;line-height:1.75rem}}.hidden{display:none}.inline-icon>svg{display:inline-block;height:25px;width:25px}.button{border-radius:.25rem;border-width:2px;cursor:pointer;font-size:1.125rem;line-height:1.75rem;min-width:-moz-max-content;min-width:max-content;padding:.75rem;transition-duration:.15s;transition-property:color,background-color,border-color,text-decoration-color,fill,stroke,opacity,box-shadow,transform,filter,-webkit-backdrop-filter;transition-property:color,background-color,border-color,text-decoration-color,fill,stroke,opacity,box-shadow,transform,filter,backdrop-filter;transition-property:color,background-color,border-color,text-decoration-color,fill,stroke,opacity,box-shadow,transform,filter,backdrop-filter,-webkit-backdrop-filter;transition-timing-function:cubic-bezier(.4,0,.2,1);width:10rem}.button:disabled{cursor:default;opacity:.6}.button.primary{border-color:#0000}.button.primary,.button.secondary{background-color:var(--bg-color);color:var(--fg-color)}.button.secondary{border-color:var(--fg-color)}.button.secondary:hover{background-color:var(--fg-color);border-color:var(--bg-color);color:var(--bg-color)}select{background-color:var(--bg-color);color:var(--fg-color)}footer{align-items:center;background-color:var(--fg-color);color:var(--bg-color);display:flex;flex-grow:0;flex-shrink:1;font-size:.75rem;justify-content:space-between;line-height:1rem;padding:.5rem 1rem;width:100%}.nav{margin-bottom:3rem}.nav,.nav ul{padding:0;text-align:center}.nav ul{align-items:center;display:flex;flex-wrap:wrap;gap:1.5rem;justify-content:center;list-style-type:none}.nav ul li{margin:0;text-transform:capitalize}.repo_banner{background-color:var(--fg-color);color:var(--bg-color);padding-bottom:.375rem;padding-top:.375rem}.repo_banner>a{align-items:flex-start;display:flex;gap:.5rem;height:20px;justify-content:center}.repo_banner>a,.repo_banner>a:hover{--tw-text-opacity:1;color:rgb(248 250 252/var(--tw-text-opacity))}.repo_banner>a:hover{text-decoration-color:#f8fafc;text-decoration-line:underline;text-underline-offset:1px}.repo_banner>a:is(.dark *){color:#141414}.repo_banner>a:hover:is(.dark *){color:#141414;text-decoration-color:#141414}.funding-wrapper{align-items:center;display:flex;flex-direction:column;margin-top:2rem}.funding-list{gap:1rem;grid-template-columns:repeat(2,minmax(0,1fr));margin-bottom:3rem;margin-top:3rem;width:100%}@media (min-width:1024px){.funding-list{display:grid}}.funding-list li{margin:0 0 1rem}.funding-list li a{align-items:center;display:flex;gap:.5rem}.funding-list li a:hover button{--tw-text-opacity:1;background-color:#e85e68;background-color:var(--fg-color);border-color:#e85e68;border-color:var(--bg-color);color:rgb(241 245 249/var(--tw-text-opacity));color:var(--bg-color)}.funding-list .button{display:block;margin-right:.5rem;width:auto}.preferred-funding-list{grid-template-columns:repeat(1,minmax(0,1fr))}.preferred-funding-list li a{flex-direction:column;font-size:2.25rem;font-weight:700;line-height:2.5rem}.preferred-funding-list svg{height:3rem;width:3rem}.preferred-funding-list .button{border-width:0}.package-managers-downloads ul{margin-bottom:4rem;margin-top:4rem}.package-managers-downloads ul li{margin-left:0}.package-managers-downloads pre{margin-bottom:0;margin-top:0}.artifacts{align-items:center;display:none;flex-direction:column;margin-bottom:2rem;padding:0}@media (min-width:640px){.artifacts{display:flex}}.artifacts{background-color:var(--highlight-bg-color);color:var(--highlight-fg-color)}.artifacts-table{display:block;max-width:100%;overflow:auto}ul.tabs{border-bottom-width:2px;border-color:var(--highlight-fg-color);display:flex}ul.tabs li{font-size:1rem;line-height:1.5rem;margin:0;padding:.5rem .75rem}ul.tabs li:hover{cursor:pointer}ul.tabs li small{--tw-text-opacity:1;color:rgb(156 163 175/var(--tw-text-opacity));display:block;font-size:.75rem;line-height:1rem}ul.tabs li.selected,ul.tabs li.selected small{background-color:var(--highlight-fg-color);color:var(--highlight-bg-color)}.install-content{margin:0;max-width:100%;padding:0}.detect{padding-right:.5rem;text-align:center}@media (min-width:768px){.detect{padding-right:0}}.detect+a{display:block;margin-bottom:.5rem;margin-top:.5rem}@media (min-width:640px){.detect+a{display:inline;margin-bottom:0;margin-top:0}}.detect .detected-os{text-transform:capitalize}.artifact-header pre{margin:0 auto}.artifact-header>h4{font-weight:700;margin-bottom:-.5rem;text-align:center}.artifact-header{max-width:100%;width:100%}.artifact-header>div:not(.install-code-wrapper){align-items:center;justify-content:center;margin-top:1rem;text-align:center}@media (min-width:768px){.artifact-header>div:not(.install-code-wrapper){display:flex;gap:1rem;text-align:left}}.backup-download:hover{text-decoration-line:none}.bottom-options{align-items:center;display:flex;flex-direction:row;justify-content:space-between;width:100%}.bottom-options.one{justify-content:center}.install-code-wrapper{align-items:stretch;display:flex}.install-code-wrapper>pre{flex-grow:1;flex-shrink:1}.install-code-wrapper>.button{align-items:center;border-bottom-left-radius:0;border-top-left-radius:0;display:flex;width:auto}.install-code-wrapper>.button:hover{text-decoration-line:none}.install-code-wrapper>.button:focus{outline-offset:-2px}.install-code-wrapper>.button.copy-clipboard-button{border-radius:0}.download-wrapper{display:flex;flex-direction:row;justify-content:center}.button .button-subtitle{display:block;font-size:.75rem;line-height:1rem}.published-date{display:block;margin-bottom:.5rem}.arch{margin:0;padding:1rem 0 0}.arch .contents{min-height:7rem;padding-top:1rem}.mobile-download{display:block;margin-bottom:3rem;margin-left:auto;margin-right:auto}@media (min-width:640px){.mobile-download{display:none}}.install-code-wrapper>.button svg{height:1.5rem;width:1.5rem}.release-body{margin-top:2rem;word-break:break-word}.release-body h1{font-size:1.5rem;font-weight:700;line-height:2rem;line-height:1.25;margin-bottom:1.5rem;margin-top:3rem}@media (min-width:640px){.release-body h1{font-size:3rem;line-height:1}}.release-body h2{font-size:1.5rem;font-weight:700;line-height:2rem;line-height:1.25;margin-bottom:1rem;margin-top:3rem}@media (min-width:640px){.release-body h2{font-size:2.25rem;line-height:2.5rem}}.release-body h3{font-size:1.5rem;line-height:2rem;line-height:1.25;margin-bottom:1rem}@media (min-width:640px){.release-body h3{font-size:1.875rem;line-height:2.25rem}}.release-body h4{--tw-text-opacity:1;color:rgb(51 65 85/var(--tw-text-opacity));font-size:1.25rem;font-weight:700;line-height:1.75rem;line-height:1.25;margin-bottom:1rem}.release-body h4:is(.dark *){--tw-text-opacity:1;color:rgb(226 232 240/var(--tw-text-opacity))}@media (min-width:640px){.release-body h4{font-size:1.5rem;line-height:2rem}}.release-body h5{--tw-text-opacity:1;color:rgb(30 41 59/var(--tw-text-opacity));font-size:1.25rem;font-weight:700;line-height:1.75rem;line-height:1.25;margin-bottom:1rem}.release-body h5:is(.dark *){--tw-text-opacity:1;color:rgb(203 213 225/var(--tw-text-opacity))}@media (min-width:640px){.release-body h5{font-size:1.25rem;line-height:1.75rem}}.release-body li,.release-body ul{list-style-type:disc}.releases-nav{align-self:flex-start;position:sticky;top:3rem;width:-moz-max-content;width:max-content}.release>h2{margin-top:0}.release>h2 a{color:var(--fg-color)}.releases-list{display:flex;flex-direction:column;gap:8rem}.releases-wrapper{gap:3rem;margin-top:3rem;position:relative}@media (min-width:768px){.releases-wrapper{display:grid}}.releases-wrapper{grid-template-columns:160px minmax(0,1fr)}.releases-nav ul{border-left-width:4px;display:none;flex-direction:column;gap:.5rem;list-style-type:none;margin:0;padding-left:1rem}@media (min-width:768px){.releases-nav ul{display:flex}}.releases-nav ul{border-color:var(--fg-color)}.releases-nav ul li{font-size:.875rem;line-height:1.25rem;margin:0 0 0 .25rem;position:relative}.releases-nav ul li:before{--tw-translate-y:-50%;background-color:var(--fg-color);content:"";display:block;height:.25rem;left:-1.25rem;position:absolute;top:50%;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));width:1rem}.releases-nav ul li a{text-decoration-color:#0000;text-underline-offset:2px}.releases-nav ul li a:hover{text-decoration-line:underline}.releases-nav ul li a{color:var(--fg-color)}.release-info{display:flex;font-size:1rem;gap:2rem;line-height:1.5rem}.prereleases-toggle,.release-info{align-items:center}.prereleases-toggle{display:none;margin-bottom:1.5rem;position:relative;width:-moz-max-content;width:max-content}@media (min-width:768px){.prereleases-toggle{display:flex}}.prereleases-toggle input{border-radius:.25rem;color:var(--fg-color);height:1.25rem;width:1.25rem}.prereleases-toggle label{font-weight:500;margin-left:.75rem}.release-info svg{height:1.5rem;width:1.5rem}.release-info>span{align-items:center;display:flex;gap:.5rem}ul.index-grid{align-items:stretch;display:grid;gap:2rem;margin-top:4rem}@media (min-width:768px){ul.index-grid{grid-template-columns:repeat(2,minmax(0,1fr))}}@media (min-width:1024px){ul.index-grid{grid-template-columns:repeat(2,minmax(0,1fr))}}.index-grid li{border-color:var(--bg-color);border-radius:.25rem;border-width:1px;box-shadow:0 0 0 8px #0000004d;flex-direction:column;margin-left:0}.index-grid .content,.index-grid li{display:flex;justify-content:space-between}.index-grid .content{padding:1rem}.index-grid .links{display:flex;width:100%}.index-grid .links>:not([hidden])~:not([hidden]){--tw-divide-x-reverse:0;border-left-width:calc(1px*(1 - var(--tw-divide-x-reverse)));border-right-width:calc(1px*var(--tw-divide-x-reverse))}.index-grid .links{border-top-width:1px}.index-grid .links a{align-items:center;display:inline-flex;width:50%}.index-grid .links a>:not([hidden])~:not([hidden]){--tw-space-x-reverse:0;margin-left:calc(.5rem*(1 - var(--tw-space-x-reverse)));margin-right:calc(.5rem*var(--tw-space-x-reverse))}.index-grid .links a{padding:1rem 1.5rem}.index-grid .content .index-logo{flex-shrink:0;height:5rem;position:relative;width:5rem}.index-grid li.preferred{grid-column:span 2/span 2}.index-about h2{margin-top:0}html.axo{--highlight-color:#a78bfa;--axo-orange-color:#f57070;--axo-pink-color:#ff75c3;--light-fg-color:#141414;--light-link-color:var(--axo-pink-color);--dark-link-color:var(--axo-pink-color);--light-highlight-bg-color:var(--light-bg-color);--light-highlight-fg-color:var(--light-fg-color);--dark-highlight-bg-color:var(--light-fg-color);--dark-highlight-fg-color:var(--light-bg-color);--font-face:"Comfortaa",sans-serif}code,h1,h2,h3{color:var(--highlight-color)}html.axo .button.primary{background-color:var(--link-color)}html.axo .repo_banner,html.axo footer{animation-duration:3s;animation-fill-mode:forwards;animation-iteration-count:infinite;animation-name:animation-gradient-title;background:-webkit-linear-gradient(left,var(--axo-orange-color),var(--axo-pink-color),var(--axo-orange-color));background-size:1600px 200px}@media (prefers-reduced-motion){html.axo .repo_banner,html.axo footer{animation-duration:0s}}html.hacker html.axo .repo_banner,html.hacker html.axo footer{background:-webkit-linear-gradient(left,var(--hacker-green),var(--color-green-600),var(--hacker-green))}html.cupcake html.axo .repo_banner,html.cupcake html.axo footer{background:var(--secondary)}html.axo h1.title{-webkit-text-fill-color:#0000;animation-duration:3s;animation-fill-mode:forwards;animation-iteration-count:infinite;animation-name:animation-gradient-title;background:-webkit-linear-gradient(left,var(--axo-orange-color),var(--axo-pink-color),var(--axo-orange-color));background-size:1600px 200px}@media (prefers-reduced-motion){html.axo h1.title{animation-duration:0s}}html.hacker html.axo h1.title{background:-webkit-linear-gradient(left,var(--hacker-green),var(--color-green-600),var(--hacker-green))}html.cupcake html.axo h1.title{background:var(--secondary)}html.axo h1.title{-webkit-background-clip:text;background-clip:text}.axo-gradient{animation-duration:3s;animation-fill-mode:forwards;animation-iteration-count:infinite;animation-name:animation-gradient-title;background:-webkit-linear-gradient(left,var(--axo-orange-color),var(--axo-pink-color),var(--axo-orange-color));background-size:1600px 200px}.text-fill-transparent{-webkit-text-fill-color:#0000}.axo-gradient-text{-webkit-text-fill-color:#0000;animation-duration:3s;animation-fill-mode:forwards;animation-iteration-count:infinite;animation-name:animation-gradient-title;background:-webkit-linear-gradient(left,var(--axo-orange-color),var(--axo-pink-color),var(--axo-orange-color));background-size:1600px 200px}@media (prefers-reduced-motion){.axo-gradient-text{animation-duration:0s}}html.hacker .axo-gradient-text{background:-webkit-linear-gradient(left,var(--hacker-green),var(--color-green-600),var(--hacker-green))}html.cupcake .axo-gradient-text{background:var(--secondary)}.axo-gradient-text{-webkit-background-clip:text;background-clip:text}@media (prefers-reduced-motion){.axo-gradient{animation-duration:0s}}@keyframes slide-in{0%{top:-100vh}to{top:0}}@keyframes animation-gradient-title{0%{background-position:0 1600px}to{background-position:1600px 0}}html.hacker{--light-highlight-bg-color:var(--dark-highlight-bg-color);--light-highlight-fg-color:var(--dark-highlight-fg-color);--hacker-green:#20c20e}html.hacker ::-moz-selection{background-color:#20c20e;color:#141414}html.hacker ::selection{background-color:#20c20e;color:#141414}html.hacker body{--tw-text-opacity:1;background-color:#141414;font-family:IBM Plex Mono,monospace}html.hacker .button.secondary,html.hacker body{color:rgb(203 213 225/var(--tw-text-opacity))}html.hacker .button.secondary{--tw-border-opacity:1;--tw-text-opacity:1;border-color:rgb(249 115 22/var(--tw-border-opacity))}html.hacker .button.secondary:hover{--tw-bg-opacity:1;background-color:rgb(249 115 22/var(--tw-bg-opacity));color:#141414}html.hacker h2,html.hacker h3,html.hacker h4,html.hacker h5,html.hacker h6{--tw-text-opacity:1;color:rgb(124 58 237/var(--tw-text-opacity))}html.hacker .repo_banner>a,html.hacker footer{color:var(--light-color);padding-bottom:.5rem;padding-top:.5rem}html.hacker p,html.hacker table{--tw-text-opacity:1;color:rgb(203 213 225/var(--tw-text-opacity))}html.hacker .title{display:inline-block;margin-left:2rem;position:relative;text-align:left}@keyframes blink-animation{to{visibility:hidden}}html.hacker .title:after{animation:blink-animation 1s steps(5,start) infinite;background:var(--hacker-green);content:"";display:block;height:70px;left:100%;margin-left:.75rem;position:absolute;top:.75rem;width:1rem}html.hacker .title:before{--tw-translate-y:-50%;--tw-text-opacity:1;color:rgb(31 41 55/var(--tw-text-opacity));content:"> ";display:block;font-size:3rem;left:-2rem;line-height:1;margin-top:.5rem;position:absolute;top:50%;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}html.hacker .title,html.hacker div.table .th,html.hacker h1{color:var(--hacker-green)}html.hacker a{--tw-text-opacity:1;color:rgb(249 115 22/var(--tw-text-opacity))}html.hacker a:hover{text-decoration-color:#f97316}html.hacker .axo-gradient{background:-webkit-linear-gradient(left,var(--hacker-green),var(--color-green-600),var(--hacker-green))}html.hacker .nav ul{justify-content:flex-start}html.hacker .button.primary{--tw-bg-opacity:1;background-color:rgb(249 115 22/var(--tw-bg-opacity));border-color:#0000;color:#141414}html.hacker .button.primary:hover{--tw-bg-opacity:1;background-color:rgb(234 88 12/var(--tw-bg-opacity))}html.hacker .artifact-header>h4{color:var(--light-color);text-align:left}html.hacker .releases-nav ul li a{--tw-text-opacity:1;color:rgb(226 232 240/var(--tw-text-opacity))}html.hacker .releases-nav ul li:before{--tw-bg-opacity:1;background-color:rgb(75 85 99/var(--tw-bg-opacity))}html.hacker .releases-nav ul{--tw-border-opacity:1;border-left-color:rgb(75 85 99/var(--tw-border-opacity))}html.hacker .prereleases-toggle input:checked{--tw-bg-opacity:1;background-color:rgb(249 115 22/var(--tw-bg-opacity))}html.hacker .releases-nav ul li a:hover{text-decoration-color:#f97316}html.hacker .funding-wrapper{align-items:flex-start}html.hacker .artifacts{padding:2rem}html.hacker .published-date{display:block;width:100%}html.hacker .logo{display:block;margin:0}html.cupcake body{--b1:#faf7f5;--b2:#dfaff7;--text:#291334cc;--links:#291334;--primary:#65c3c8;--secondary:#291334;--secondary-100:#210f2a;--code:#291334;background-color:var(--b1);color:var(--text);font-family:Inter,sans-serif}html.cupcake ::-moz-selection{-webkit-text-fill-color:var(--code);background-color:var(--b2);color:var(--code)}html.cupcake ::selection{-webkit-text-fill-color:var(--code);background-color:var(--b2);color:var(--code)}html.cupcake .button.primary{background:var(--secondary);border-color:#0000;color:var(--b2);text-decoration-line:none}html.cupcake .button.primary:hover{--tw-bg-opacity:1;background-color:rgb(234 88 12/var(--tw-bg-opacity));background:var(--secondary-100)}html.cupcake .button.secondary{border:1px solid var(--secondary);color:var(--secondary-100)}html.cupcake .button.secondary:hover{background:var(--secondary);color:var(--b2)}html.cupcake h1,html.cupcake h2,html.cupcake h3,html.cupcake h4,html.cupcake h5,html.cupcake h6,html.cupcake p,html.cupcake table{color:var(--text)}html.cupcake .title{color:var(--primary)}html.cupcake a{color:var(--links);font-weight:500;text-decoration-line:underline;text-underline-offset:4px}html.cupcake a:hover{color:var(--code);text-underline-offset:2px}html.cupcake .axo-gradient{background:var(--secondary)}html.cupcake .github-icon{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath fill='%23dfaff7' d='M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12'/%3E%3C/svg%3E")}html.cupcake .repo_banner>a,html.cupcake footer{color:var(--b2);text-decoration:none}html.cupcake code{color:var(--code);font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace;font-weight:500}html.cupcake .prereleases-toggle input:checked{background-color:var(--primary)}html.cupcake .artifacts{padding:2rem}html.cupcake .releases-nav ul li a{color:var(--links)}html.cupcake .releases-nav ul li:before{--tw-bg-opacity:1;background-color:rgb(209 213 219/var(--tw-bg-opacity))}html.cupcake .releases-nav ul{--tw-border-opacity:1;border-left-color:rgb(209 213 219/var(--tw-border-opacity))}html.cupcake div.table .th{color:var(--primary)} \ No newline at end of file