diff --git a/assets/css/app.css b/assets/css/app.css index 378c8f9..69cfff7 100644 --- a/assets/css/app.css +++ b/assets/css/app.css @@ -3,3 +3,12 @@ @import "tailwindcss/utilities"; /* This file is for your main application CSS */ +code .highlighted { + @apply bg-ctp-mauve/10; + transition:background-color .5s; + margin:0 -24px; + padding:0 24px; + width:calc(100% + 48px); + display:inline-block +} + diff --git a/assets/js/app.js b/assets/js/app.js index b466707..a9f0021 100644 --- a/assets/js/app.js +++ b/assets/js/app.js @@ -22,16 +22,9 @@ import { Socket } from "phoenix"; import { LiveSocket } from "phoenix_live_view"; import topbar from "../vendor/topbar"; import CodeBlockHook from "./hooks/code_block_hook"; -import { - DropdownAnimation, - SearchableDropdown, -} from "./hooks/searchable_dropdown"; +import { SelectHook } from "./hooks/select"; -let Hooks = { - CodeBlockHook, - SearchableDropdown, - DropdownAnimation, -}; +let Hooks = { CodeBlockHook, SelectHook }; Hooks.ClickOutside = { mounted() { diff --git a/assets/js/hooks/code_block_hook.js b/assets/js/hooks/code_block_hook.js index 3868d18..ffa43f9 100644 --- a/assets/js/hooks/code_block_hook.js +++ b/assets/js/hooks/code_block_hook.js @@ -9,11 +9,10 @@ const CodeBlockHook = { this.el.dataset.highlightedLines || "[]", ); - console.log(code); - console.log("language", language); - const lines = code.split("\n"); + console.log(lines.length, lines); + // Convert line numbers to decorations const decorations = highlightedLines .map((line) => { @@ -40,7 +39,16 @@ const CodeBlockHook = { codeToHtml(code, { lang: language, theme: "catppuccin-mocha", - decorations, + transformers: [ + { + line(node, line) { + node.properties["data-line"] = line; + if (highlightedLines.includes(line)) { + this.addClassToHast(node, "highlighted"); + } + }, + }, + ], }).then((html) => { console.log(html); diff --git a/assets/js/hooks/searchable_dropdown.js b/assets/js/hooks/searchable_dropdown.js deleted file mode 100644 index 27d2f8e..0000000 --- a/assets/js/hooks/searchable_dropdown.js +++ /dev/null @@ -1,32 +0,0 @@ -SearchableDropdown = { - mounted() { - this.el.addEventListener("input", (e) => { - const query = e.target.value.toLowerCase(); - const dropdownId = this.el.dataset.dropdownId; - const optionsContainer = document.querySelector(`#${dropdownId}-options`); - const options = optionsContainer.querySelectorAll("li button"); - - options.forEach((option) => { - const text = option.textContent.toLowerCase(); - option.parentElement.style.display = text.includes(query) - ? "block" - : "none"; - }); - }); - }, -}; - -const DropdownAnimation = { - mounted() { - this.el.addEventListener("transitionend", (e) => { - if ( - e.propertyName === "opacity" && - this.el.classList.contains("fade-out") - ) { - this.el.classList.add("hidden"); - } - }); - }, -}; - -export { SearchableDropdown, DropdownAnimation }; diff --git a/assets/js/hooks/select.js b/assets/js/hooks/select.js new file mode 100644 index 0000000..3d6454d --- /dev/null +++ b/assets/js/hooks/select.js @@ -0,0 +1,186 @@ +const SelectHook = { + mounted() { + const container = this.el; + const trigger = container.querySelector('[id$="-trigger"]'); + const dropdown = container.querySelector('[id$="-dropdown"]'); + const search = container.querySelector('[id$="-search"]'); + const options = container.querySelector('[id$="-options"]'); + const hiddenInput = container.querySelector('input[type="hidden"]'); + const selectedText = container.querySelector('[id$="-selected"]'); + + const toggleDropdown = (event) => { + // Prevent the event from bubbling up to any parent form + if (event) { + event.preventDefault(); + event.stopPropagation(); + } + + const isExpanded = dropdown.classList.contains("block"); + if (!isExpanded) { + dropdown.classList.remove("hidden"); + // Add animation classes + dropdown.classList.add( + "block", + "animate-in", + "fade-in", + "duration-200", + ); + search.value = ""; + filterOptions(""); + search.focus(); + } else { + // Add animation classes for hiding + dropdown.classList.remove("animate-in", "fade-in"); + dropdown.classList.add("animate-out", "fade-out"); + setTimeout(() => { + dropdown.classList.remove("block", "animate-out", "fade-out"); + dropdown.classList.add("hidden"); + }, 200); + } + }; + + const filterOptions = (query) => { + const items = options.querySelectorAll("li"); + items.forEach((item) => { + const text = item.textContent.toLowerCase(); + if (text.includes(query.toLowerCase())) { + item.style.display = ""; + } else { + item.style.display = "none"; + } + }); + }; + + const selectOption = (option, event) => { + // Prevent form submission + if (event) { + event.preventDefault(); + event.stopPropagation(); + } + + const value = option.dataset.value; + const label = option.querySelector("span").textContent; + + // Update hidden input + hiddenInput.value = value; + + // Update visible text + selectedText.textContent = label; + + // Update check mark position + options.querySelectorAll("li").forEach((li) => { + const checkmark = li.querySelector("span:last-child"); + if (checkmark) checkmark.remove(); + + if (li.dataset.value === value) { + li.setAttribute("aria-selected", "true"); + const checkMarkSpan = document.createElement("span"); + checkMarkSpan.className = + "absolute inset-y-0 right-0 flex items-center pr-4 ctp-text-lavender"; + checkMarkSpan.innerHTML = ` + + + + `; + li.appendChild(checkMarkSpan); + } else { + li.setAttribute("aria-selected", "false"); + } + }); + + toggleDropdown(); + + // Dispatch change event without bubbling + const changeEvent = new Event("change", { bubbles: false }); + hiddenInput.dispatchEvent(changeEvent); + + // Push the value to the LiveView + this.pushEventTo(this.el, "change", { value: value }); + }; + + // Event Listeners + trigger.addEventListener("click", (e) => { + e.preventDefault(); + e.stopPropagation(); + toggleDropdown(e); + }); + + search.addEventListener("input", (e) => { + e.preventDefault(); + e.stopPropagation(); + filterOptions(e.target.value); + }); + + options.querySelectorAll("li").forEach((option) => { + option.addEventListener("click", (e) => { + e.preventDefault(); + e.stopPropagation(); + selectOption(option, e); + }); + }); + + // Prevent dropdowns from causing form submission + container.addEventListener("submit", (e) => { + e.preventDefault(); + e.stopPropagation(); + return false; + }); + + // Close dropdown when clicking outside + document.addEventListener("click", (e) => { + if (!container.contains(e.target)) { + dropdown.classList.add("hidden"); + dropdown.classList.remove("block"); + } + }); + + // Keyboard navigation + container.addEventListener("keydown", (e) => { + const items = Array.from(options.querySelectorAll("li")).filter( + (li) => li.style.display !== "none", + ); + const currentIdx = items.findIndex((li) => li === document.activeElement); + + switch (e.key) { + case "ArrowDown": + e.preventDefault(); + if (currentIdx < items.length - 1) { + items[currentIdx + 1].focus(); + } + break; + case "ArrowUp": + e.preventDefault(); + if (currentIdx > 0) { + items[currentIdx - 1].focus(); + } + break; + case "Enter": + e.preventDefault(); + if (document.activeElement.tagName === "LI") { + selectOption(document.activeElement, e); + } + break; + case "Escape": + e.preventDefault(); + toggleDropdown(e); + break; + } + }); + + // Prevent the dropdown from closing when clicking inside it + dropdown.addEventListener("click", (e) => { + e.stopPropagation(); + }); + + // Prevent the search input from submitting the form + search.addEventListener("keydown", (e) => { + if (e.key === "Enter") { + e.preventDefault(); + e.stopPropagation(); + return false; + } + }); + }, +}; + +export { SelectHook }; diff --git a/assets/node-packages.nix b/assets/node-packages.nix index b8e14c8..af4ce1e 100644 --- a/assets/node-packages.nix +++ b/assets/node-packages.nix @@ -3,17 +3,1857 @@ {nodeEnv, fetchurl, fetchgit, nix-gitignore, stdenv, lib, globalBuildInputs ? []}: let - sources = {}; + sources = { + "@alloc/quick-lru-5.2.0" = { + name = "_at_alloc_slash_quick-lru"; + packageName = "@alloc/quick-lru"; + version = "5.2.0"; + src = fetchurl { + url = "https://registry.npmjs.org/@alloc/quick-lru/-/quick-lru-5.2.0.tgz"; + sha512 = "UrcABB+4bUrFABwbluTIBErXwvbsU/V7TZWfmbgJfbkwiBuziS9gxdODUyuiecfdGQ85jglMW6juS3+z5TsKLw=="; + }; + }; + "@catppuccin/tailwindcss-0.1.6" = { + name = "_at_catppuccin_slash_tailwindcss"; + packageName = "@catppuccin/tailwindcss"; + version = "0.1.6"; + src = fetchurl { + url = "https://registry.npmjs.org/@catppuccin/tailwindcss/-/tailwindcss-0.1.6.tgz"; + sha512 = "V+Y0AwZ5SSyvOVAcDl7Ng30xy+m82OKnEJ+9+kcZZ7lRyXuZrAb2GScdq9XR3v+ggt8qiZ/G4TvaC9cJ88AAXA=="; + }; + }; + "@cspotcode/source-map-support-0.8.1" = { + name = "_at_cspotcode_slash_source-map-support"; + packageName = "@cspotcode/source-map-support"; + version = "0.8.1"; + src = fetchurl { + url = "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz"; + sha512 = "IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw=="; + }; + }; + "@esbuild/linux-x64-0.24.0" = { + name = "_at_esbuild_slash_linux-x64"; + packageName = "@esbuild/linux-x64"; + version = "0.24.0"; + src = fetchurl { + url = "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.24.0.tgz"; + sha512 = "vbutsFqQ+foy3wSSbmjBXXIJ6PL3scghJoM8zCL142cGaZKAdCZHyf+Bpu/MmX9zT9Q0zFBVKb36Ma5Fzfa8xA=="; + }; + }; + "@isaacs/cliui-8.0.2" = { + name = "_at_isaacs_slash_cliui"; + packageName = "@isaacs/cliui"; + version = "8.0.2"; + src = fetchurl { + url = "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz"; + sha512 = "O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA=="; + }; + }; + "@jridgewell/gen-mapping-0.3.5" = { + name = "_at_jridgewell_slash_gen-mapping"; + packageName = "@jridgewell/gen-mapping"; + version = "0.3.5"; + src = fetchurl { + url = "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.5.tgz"; + sha512 = "IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg=="; + }; + }; + "@jridgewell/resolve-uri-3.1.2" = { + name = "_at_jridgewell_slash_resolve-uri"; + packageName = "@jridgewell/resolve-uri"; + version = "3.1.2"; + src = fetchurl { + url = "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz"; + sha512 = "bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw=="; + }; + }; + "@jridgewell/set-array-1.2.1" = { + name = "_at_jridgewell_slash_set-array"; + packageName = "@jridgewell/set-array"; + version = "1.2.1"; + src = fetchurl { + url = "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.2.1.tgz"; + sha512 = "R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A=="; + }; + }; + "@jridgewell/sourcemap-codec-1.5.0" = { + name = "_at_jridgewell_slash_sourcemap-codec"; + packageName = "@jridgewell/sourcemap-codec"; + version = "1.5.0"; + src = fetchurl { + url = "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz"; + sha512 = "gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ=="; + }; + }; + "@jridgewell/trace-mapping-0.3.25" = { + name = "_at_jridgewell_slash_trace-mapping"; + packageName = "@jridgewell/trace-mapping"; + version = "0.3.25"; + src = fetchurl { + url = "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz"; + sha512 = "vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ=="; + }; + }; + "@jridgewell/trace-mapping-0.3.9" = { + name = "_at_jridgewell_slash_trace-mapping"; + packageName = "@jridgewell/trace-mapping"; + version = "0.3.9"; + src = fetchurl { + url = "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz"; + sha512 = "3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ=="; + }; + }; + "@nodelib/fs.scandir-2.1.5" = { + name = "_at_nodelib_slash_fs.scandir"; + packageName = "@nodelib/fs.scandir"; + version = "2.1.5"; + src = fetchurl { + url = "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz"; + sha512 = "vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g=="; + }; + }; + "@nodelib/fs.stat-2.0.5" = { + name = "_at_nodelib_slash_fs.stat"; + packageName = "@nodelib/fs.stat"; + version = "2.0.5"; + src = fetchurl { + url = "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz"; + sha512 = "RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A=="; + }; + }; + "@nodelib/fs.walk-1.2.8" = { + name = "_at_nodelib_slash_fs.walk"; + packageName = "@nodelib/fs.walk"; + version = "1.2.8"; + src = fetchurl { + url = "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz"; + sha512 = "oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg=="; + }; + }; + "@shikijs/core-1.22.2" = { + name = "_at_shikijs_slash_core"; + packageName = "@shikijs/core"; + version = "1.22.2"; + src = fetchurl { + url = "https://registry.npmjs.org/@shikijs/core/-/core-1.22.2.tgz"; + sha512 = "bvIQcd8BEeR1yFvOYv6HDiyta2FFVePbzeowf5pPS1avczrPK+cjmaxxh0nx5QzbON7+Sv0sQfQVciO7bN72sg=="; + }; + }; + "@shikijs/engine-javascript-1.22.2" = { + name = "_at_shikijs_slash_engine-javascript"; + packageName = "@shikijs/engine-javascript"; + version = "1.22.2"; + src = fetchurl { + url = "https://registry.npmjs.org/@shikijs/engine-javascript/-/engine-javascript-1.22.2.tgz"; + sha512 = "iOvql09ql6m+3d1vtvP8fLCVCK7BQD1pJFmHIECsujB0V32BJ0Ab6hxk1ewVSMFA58FI0pR2Had9BKZdyQrxTw=="; + }; + }; + "@shikijs/engine-oniguruma-1.22.2" = { + name = "_at_shikijs_slash_engine-oniguruma"; + packageName = "@shikijs/engine-oniguruma"; + version = "1.22.2"; + src = fetchurl { + url = "https://registry.npmjs.org/@shikijs/engine-oniguruma/-/engine-oniguruma-1.22.2.tgz"; + sha512 = "GIZPAGzQOy56mGvWMoZRPggn0dTlBf1gutV5TdceLCZlFNqWmuc7u+CzD0Gd9vQUTgLbrt0KLzz6FNprqYAxlA=="; + }; + }; + "@shikijs/types-1.22.2" = { + name = "_at_shikijs_slash_types"; + packageName = "@shikijs/types"; + version = "1.22.2"; + src = fetchurl { + url = "https://registry.npmjs.org/@shikijs/types/-/types-1.22.2.tgz"; + sha512 = "NCWDa6LGZqTuzjsGfXOBWfjS/fDIbDdmVDug+7ykVe1IKT4c1gakrvlfFYp5NhAXH/lyqLM8wsAPo5wNy73Feg=="; + }; + }; + "@shikijs/vscode-textmate-9.3.0" = { + name = "_at_shikijs_slash_vscode-textmate"; + packageName = "@shikijs/vscode-textmate"; + version = "9.3.0"; + src = fetchurl { + url = "https://registry.npmjs.org/@shikijs/vscode-textmate/-/vscode-textmate-9.3.0.tgz"; + sha512 = "jn7/7ky30idSkd/O5yDBfAnVt+JJpepofP/POZ1iMOxK59cOfqIgg/Dj0eFsjOTMw+4ycJN0uhZH/Eb0bs/EUA=="; + }; + }; + "@swc/core-1.9.2" = { + name = "_at_swc_slash_core"; + packageName = "@swc/core"; + version = "1.9.2"; + src = fetchurl { + url = "https://registry.npmjs.org/@swc/core/-/core-1.9.2.tgz"; + sha512 = "dYyEkO6mRYtZFpnOsnYzv9rY69fHAHoawYOjGOEcxk9WYtaJhowMdP/w6NcOKnz2G7GlZaenjkzkMa6ZeQeMsg=="; + }; + }; + "@swc/counter-0.1.3" = { + name = "_at_swc_slash_counter"; + packageName = "@swc/counter"; + version = "0.1.3"; + src = fetchurl { + url = "https://registry.npmjs.org/@swc/counter/-/counter-0.1.3.tgz"; + sha512 = "e2BR4lsJkkRlKZ/qCHPw9ZaSxc0MVUd7gtbtaB7aMvHeJVYe8sOB8DBZkP2DtISHGSku9sCK6T6cnY0CtXrOCQ=="; + }; + }; + "@swc/helpers-0.5.15" = { + name = "_at_swc_slash_helpers"; + packageName = "@swc/helpers"; + version = "0.5.15"; + src = fetchurl { + url = "https://registry.npmjs.org/@swc/helpers/-/helpers-0.5.15.tgz"; + sha512 = "JQ5TuMi45Owi4/BIMAJBoSQoOJu12oOk/gADqlcUL9JEdHB8vyjUSsxqeNXnmXHjYKMi2WcYtezGEEhqUI/E2g=="; + }; + }; + "@swc/types-0.1.15" = { + name = "_at_swc_slash_types"; + packageName = "@swc/types"; + version = "0.1.15"; + src = fetchurl { + url = "https://registry.npmjs.org/@swc/types/-/types-0.1.15.tgz"; + sha512 = "XKaZ+dzDIQ9Ot9o89oJQ/aluI17+VvUnIpYJTcZtvv1iYX6MzHh3Ik2CSR7MdPKpPwfZXHBeCingb2b4PoDVdw=="; + }; + }; + "@swc/wasm-1.9.2" = { + name = "_at_swc_slash_wasm"; + packageName = "@swc/wasm"; + version = "1.9.2"; + src = fetchurl { + url = "https://registry.npmjs.org/@swc/wasm/-/wasm-1.9.2.tgz"; + sha512 = "Upy/08XJ4nw6Zv6k/lj/w1DdHHAL7iYjBJYAe1EjYe2yJCdlK301I+gl0pUdaq+87dEAzDeqOuCUE/YyEUVDAg=="; + }; + }; + "@tailwindcss/forms-0.5.9" = { + name = "_at_tailwindcss_slash_forms"; + packageName = "@tailwindcss/forms"; + version = "0.5.9"; + src = fetchurl { + url = "https://registry.npmjs.org/@tailwindcss/forms/-/forms-0.5.9.tgz"; + sha512 = "tM4XVr2+UVTxXJzey9Twx48c1gcxFStqn1pQz0tRsX8o3DvxhN5oY5pvyAbUx7VTaZxpej4Zzvc6h+1RJBzpIg=="; + }; + }; + "@tsconfig/node10-1.0.11" = { + name = "_at_tsconfig_slash_node10"; + packageName = "@tsconfig/node10"; + version = "1.0.11"; + src = fetchurl { + url = "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.11.tgz"; + sha512 = "DcRjDCujK/kCk/cUe8Xz8ZSpm8mS3mNNpta+jGCA6USEDfktlNvm1+IuZ9eTcDbNk41BHwpHHeW+N1lKCz4zOw=="; + }; + }; + "@tsconfig/node12-1.0.11" = { + name = "_at_tsconfig_slash_node12"; + packageName = "@tsconfig/node12"; + version = "1.0.11"; + src = fetchurl { + url = "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.11.tgz"; + sha512 = "cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag=="; + }; + }; + "@tsconfig/node14-1.0.3" = { + name = "_at_tsconfig_slash_node14"; + packageName = "@tsconfig/node14"; + version = "1.0.3"; + src = fetchurl { + url = "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.3.tgz"; + sha512 = "ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow=="; + }; + }; + "@tsconfig/node16-1.0.4" = { + name = "_at_tsconfig_slash_node16"; + packageName = "@tsconfig/node16"; + version = "1.0.4"; + src = fetchurl { + url = "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.4.tgz"; + sha512 = "vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA=="; + }; + }; + "@types/hast-3.0.4" = { + name = "_at_types_slash_hast"; + packageName = "@types/hast"; + version = "3.0.4"; + src = fetchurl { + url = "https://registry.npmjs.org/@types/hast/-/hast-3.0.4.tgz"; + sha512 = "WPs+bbQw5aCj+x6laNGWLH3wviHtoCv/P3+otBhbOhJgG8qtpdAMlTCxLtsTWA7LH1Oh/bFCHsBn0TPS5m30EQ=="; + }; + }; + "@types/mdast-4.0.4" = { + name = "_at_types_slash_mdast"; + packageName = "@types/mdast"; + version = "4.0.4"; + src = fetchurl { + url = "https://registry.npmjs.org/@types/mdast/-/mdast-4.0.4.tgz"; + sha512 = "kGaNbPh1k7AFzgpud/gMdvIm5xuECykRR+JnWKQno9TAXVa6WIVCGTPvYGekIDL4uwCZQSYbUxNBSb1aUo79oA=="; + }; + }; + "@types/node-22.9.0" = { + name = "_at_types_slash_node"; + packageName = "@types/node"; + version = "22.9.0"; + src = fetchurl { + url = "https://registry.npmjs.org/@types/node/-/node-22.9.0.tgz"; + sha512 = "vuyHg81vvWA1Z1ELfvLko2c8f34gyA0zaic0+Rllc5lbCnbSyuvb2Oxpm6TAUAC/2xZN3QGqxBNggD1nNR2AfQ=="; + }; + }; + "@types/unist-3.0.3" = { + name = "_at_types_slash_unist"; + packageName = "@types/unist"; + version = "3.0.3"; + src = fetchurl { + url = "https://registry.npmjs.org/@types/unist/-/unist-3.0.3.tgz"; + sha512 = "ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q=="; + }; + }; + "@ungap/structured-clone-1.2.0" = { + name = "_at_ungap_slash_structured-clone"; + packageName = "@ungap/structured-clone"; + version = "1.2.0"; + src = fetchurl { + url = "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.2.0.tgz"; + sha512 = "zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ=="; + }; + }; + "acorn-8.14.0" = { + name = "acorn"; + packageName = "acorn"; + version = "8.14.0"; + src = fetchurl { + url = "https://registry.npmjs.org/acorn/-/acorn-8.14.0.tgz"; + sha512 = "cl669nCJTZBsL97OF4kUQm5g5hC2uihk0NxY3WENAC0TYdILVkAyHymAntgxGkl7K+t0cXIrH5siy5S4XkFycA=="; + }; + }; + "acorn-walk-8.3.4" = { + name = "acorn-walk"; + packageName = "acorn-walk"; + version = "8.3.4"; + src = fetchurl { + url = "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.3.4.tgz"; + sha512 = "ueEepnujpqee2o5aIYnvHU6C0A42MNdsIDeqy5BydrkuC5R1ZuUFnm27EeFJGoEHJQgn3uleRvmTXaJgfXbt4g=="; + }; + }; + "ansi-regex-5.0.1" = { + name = "ansi-regex"; + packageName = "ansi-regex"; + version = "5.0.1"; + src = fetchurl { + url = "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz"; + sha512 = "quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ=="; + }; + }; + "ansi-regex-6.1.0" = { + name = "ansi-regex"; + packageName = "ansi-regex"; + version = "6.1.0"; + src = fetchurl { + url = "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.1.0.tgz"; + sha512 = "7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA=="; + }; + }; + "ansi-styles-4.3.0" = { + name = "ansi-styles"; + packageName = "ansi-styles"; + version = "4.3.0"; + src = fetchurl { + url = "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz"; + sha512 = "zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg=="; + }; + }; + "ansi-styles-6.2.1" = { + name = "ansi-styles"; + packageName = "ansi-styles"; + version = "6.2.1"; + src = fetchurl { + url = "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz"; + sha512 = "bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug=="; + }; + }; + "any-promise-1.3.0" = { + name = "any-promise"; + packageName = "any-promise"; + version = "1.3.0"; + src = fetchurl { + url = "https://registry.npmjs.org/any-promise/-/any-promise-1.3.0.tgz"; + sha512 = "7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A=="; + }; + }; + "anymatch-3.1.3" = { + name = "anymatch"; + packageName = "anymatch"; + version = "3.1.3"; + src = fetchurl { + url = "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz"; + sha512 = "KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw=="; + }; + }; + "arg-4.1.3" = { + name = "arg"; + packageName = "arg"; + version = "4.1.3"; + src = fetchurl { + url = "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz"; + sha512 = "58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA=="; + }; + }; + "arg-5.0.2" = { + name = "arg"; + packageName = "arg"; + version = "5.0.2"; + src = fetchurl { + url = "https://registry.npmjs.org/arg/-/arg-5.0.2.tgz"; + sha512 = "PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg=="; + }; + }; + "balanced-match-1.0.2" = { + name = "balanced-match"; + packageName = "balanced-match"; + version = "1.0.2"; + src = fetchurl { + url = "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz"; + sha512 = "3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw=="; + }; + }; + "binary-extensions-2.3.0" = { + name = "binary-extensions"; + packageName = "binary-extensions"; + version = "2.3.0"; + src = fetchurl { + url = "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.3.0.tgz"; + sha512 = "Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw=="; + }; + }; + "brace-expansion-2.0.1" = { + name = "brace-expansion"; + packageName = "brace-expansion"; + version = "2.0.1"; + src = fetchurl { + url = "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz"; + sha512 = "XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA=="; + }; + }; + "braces-3.0.3" = { + name = "braces"; + packageName = "braces"; + version = "3.0.3"; + src = fetchurl { + url = "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz"; + sha512 = "yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA=="; + }; + }; + "camelcase-css-2.0.1" = { + name = "camelcase-css"; + packageName = "camelcase-css"; + version = "2.0.1"; + src = fetchurl { + url = "https://registry.npmjs.org/camelcase-css/-/camelcase-css-2.0.1.tgz"; + sha512 = "QOSvevhslijgYwRx6Rv7zKdMF8lbRmx+uQGx2+vDc+KI/eBnsy9kit5aj23AgGu3pa4t9AgwbnXWqS+iOY+2aA=="; + }; + }; + "ccount-2.0.1" = { + name = "ccount"; + packageName = "ccount"; + version = "2.0.1"; + src = fetchurl { + url = "https://registry.npmjs.org/ccount/-/ccount-2.0.1.tgz"; + sha512 = "eyrF0jiFpY+3drT6383f1qhkbGsLSifNAjA61IUjZjmLCWjItY6LB9ft9YhoDgwfmclB2zhu51Lc7+95b8NRAg=="; + }; + }; + "character-entities-html4-2.1.0" = { + name = "character-entities-html4"; + packageName = "character-entities-html4"; + version = "2.1.0"; + src = fetchurl { + url = "https://registry.npmjs.org/character-entities-html4/-/character-entities-html4-2.1.0.tgz"; + sha512 = "1v7fgQRj6hnSwFpq1Eu0ynr/CDEw0rXo2B61qXrLNdHZmPKgb7fqS1a2JwF0rISo9q77jDI8VMEHoApn8qDoZA=="; + }; + }; + "character-entities-legacy-3.0.0" = { + name = "character-entities-legacy"; + packageName = "character-entities-legacy"; + version = "3.0.0"; + src = fetchurl { + url = "https://registry.npmjs.org/character-entities-legacy/-/character-entities-legacy-3.0.0.tgz"; + sha512 = "RpPp0asT/6ufRm//AJVwpViZbGM/MkjQFxJccQRHmISF/22NBtsHqAWmL+/pmkPWoIUJdWyeVleTl1wydHATVQ=="; + }; + }; + "chokidar-3.6.0" = { + name = "chokidar"; + packageName = "chokidar"; + version = "3.6.0"; + src = fetchurl { + url = "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz"; + sha512 = "7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw=="; + }; + }; + "color-convert-2.0.1" = { + name = "color-convert"; + packageName = "color-convert"; + version = "2.0.1"; + src = fetchurl { + url = "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz"; + sha512 = "RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ=="; + }; + }; + "color-name-1.1.4" = { + name = "color-name"; + packageName = "color-name"; + version = "1.1.4"; + src = fetchurl { + url = "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz"; + sha512 = "dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA=="; + }; + }; + "comma-separated-tokens-2.0.3" = { + name = "comma-separated-tokens"; + packageName = "comma-separated-tokens"; + version = "2.0.3"; + src = fetchurl { + url = "https://registry.npmjs.org/comma-separated-tokens/-/comma-separated-tokens-2.0.3.tgz"; + sha512 = "Fu4hJdvzeylCfQPp9SGWidpzrMs7tTrlu6Vb8XGaRGck8QSNZJJp538Wrb60Lax4fPwR64ViY468OIUTbRlGZg=="; + }; + }; + "commander-4.1.1" = { + name = "commander"; + packageName = "commander"; + version = "4.1.1"; + src = fetchurl { + url = "https://registry.npmjs.org/commander/-/commander-4.1.1.tgz"; + sha512 = "NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA=="; + }; + }; + "create-require-1.1.1" = { + name = "create-require"; + packageName = "create-require"; + version = "1.1.1"; + src = fetchurl { + url = "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz"; + sha512 = "dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ=="; + }; + }; + "cross-spawn-7.0.5" = { + name = "cross-spawn"; + packageName = "cross-spawn"; + version = "7.0.5"; + src = fetchurl { + url = "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.5.tgz"; + sha512 = "ZVJrKKYunU38/76t0RMOulHOnUcbU9GbpWKAOZ0mhjr7CX6FVrH+4FrAapSOekrgFQ3f/8gwMEuIft0aKq6Hug=="; + }; + }; + "cssesc-3.0.0" = { + name = "cssesc"; + packageName = "cssesc"; + version = "3.0.0"; + src = fetchurl { + url = "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz"; + sha512 = "/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg=="; + }; + }; + "dequal-2.0.3" = { + name = "dequal"; + packageName = "dequal"; + version = "2.0.3"; + src = fetchurl { + url = "https://registry.npmjs.org/dequal/-/dequal-2.0.3.tgz"; + sha512 = "0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA=="; + }; + }; + "devlop-1.1.0" = { + name = "devlop"; + packageName = "devlop"; + version = "1.1.0"; + src = fetchurl { + url = "https://registry.npmjs.org/devlop/-/devlop-1.1.0.tgz"; + sha512 = "RWmIqhcFf1lRYBvNmr7qTNuyCt/7/ns2jbpp1+PalgE/rDQcBT0fioSMUpJ93irlUhC5hrg4cYqe6U+0ImW0rA=="; + }; + }; + "didyoumean-1.2.2" = { + name = "didyoumean"; + packageName = "didyoumean"; + version = "1.2.2"; + src = fetchurl { + url = "https://registry.npmjs.org/didyoumean/-/didyoumean-1.2.2.tgz"; + sha512 = "gxtyfqMg7GKyhQmb056K7M3xszy/myH8w+B4RT+QXBQsvAOdc3XymqDDPHx1BgPgsdAA5SIifona89YtRATDzw=="; + }; + }; + "diff-4.0.2" = { + name = "diff"; + packageName = "diff"; + version = "4.0.2"; + src = fetchurl { + url = "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz"; + sha512 = "58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A=="; + }; + }; + "dlv-1.1.3" = { + name = "dlv"; + packageName = "dlv"; + version = "1.1.3"; + src = fetchurl { + url = "https://registry.npmjs.org/dlv/-/dlv-1.1.3.tgz"; + sha512 = "+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA=="; + }; + }; + "eastasianwidth-0.2.0" = { + name = "eastasianwidth"; + packageName = "eastasianwidth"; + version = "0.2.0"; + src = fetchurl { + url = "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz"; + sha512 = "I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA=="; + }; + }; + "emoji-regex-8.0.0" = { + name = "emoji-regex"; + packageName = "emoji-regex"; + version = "8.0.0"; + src = fetchurl { + url = "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz"; + sha512 = "MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A=="; + }; + }; + "emoji-regex-9.2.2" = { + name = "emoji-regex"; + packageName = "emoji-regex"; + version = "9.2.2"; + src = fetchurl { + url = "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz"; + sha512 = "L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg=="; + }; + }; + "esbuild-0.24.0" = { + name = "esbuild"; + packageName = "esbuild"; + version = "0.24.0"; + src = fetchurl { + url = "https://registry.npmjs.org/esbuild/-/esbuild-0.24.0.tgz"; + sha512 = "FuLPevChGDshgSicjisSooU0cemp/sGXR841D5LHMB7mTVOmsEHcAxaH3irL53+8YDIeVNQEySh4DaYU/iuPqQ=="; + }; + }; + "fast-glob-3.3.2" = { + name = "fast-glob"; + packageName = "fast-glob"; + version = "3.3.2"; + src = fetchurl { + url = "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.2.tgz"; + sha512 = "oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow=="; + }; + }; + "fastq-1.17.1" = { + name = "fastq"; + packageName = "fastq"; + version = "1.17.1"; + src = fetchurl { + url = "https://registry.npmjs.org/fastq/-/fastq-1.17.1.tgz"; + sha512 = "sRVD3lWVIXWg6By68ZN7vho9a1pQcN/WBFaAAsDDFzlJjvoGx0P8z7V1t72grFJfJhu3YPZBuu25f7Kaw2jN1w=="; + }; + }; + "fill-range-7.1.1" = { + name = "fill-range"; + packageName = "fill-range"; + version = "7.1.1"; + src = fetchurl { + url = "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz"; + sha512 = "YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg=="; + }; + }; + "foreground-child-3.3.0" = { + name = "foreground-child"; + packageName = "foreground-child"; + version = "3.3.0"; + src = fetchurl { + url = "https://registry.npmjs.org/foreground-child/-/foreground-child-3.3.0.tgz"; + sha512 = "Ld2g8rrAyMYFXBhEqMz8ZAHBi4J4uS1i/CxGMDnjyFWddMXLVcDp051DZfu+t7+ab7Wv6SMqpWmyFIj5UbfFvg=="; + }; + }; + "function-bind-1.1.2" = { + name = "function-bind"; + packageName = "function-bind"; + version = "1.1.2"; + src = fetchurl { + url = "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz"; + sha512 = "7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA=="; + }; + }; + "glob-10.4.5" = { + name = "glob"; + packageName = "glob"; + version = "10.4.5"; + src = fetchurl { + url = "https://registry.npmjs.org/glob/-/glob-10.4.5.tgz"; + sha512 = "7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg=="; + }; + }; + "glob-parent-5.1.2" = { + name = "glob-parent"; + packageName = "glob-parent"; + version = "5.1.2"; + src = fetchurl { + url = "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz"; + sha512 = "AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow=="; + }; + }; + "glob-parent-6.0.2" = { + name = "glob-parent"; + packageName = "glob-parent"; + version = "6.0.2"; + src = fetchurl { + url = "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz"; + sha512 = "XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A=="; + }; + }; + "hasown-2.0.2" = { + name = "hasown"; + packageName = "hasown"; + version = "2.0.2"; + src = fetchurl { + url = "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz"; + sha512 = "0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ=="; + }; + }; + "hast-util-to-html-9.0.3" = { + name = "hast-util-to-html"; + packageName = "hast-util-to-html"; + version = "9.0.3"; + src = fetchurl { + url = "https://registry.npmjs.org/hast-util-to-html/-/hast-util-to-html-9.0.3.tgz"; + sha512 = "M17uBDzMJ9RPCqLMO92gNNUDuBSq10a25SDBI08iCCxmorf4Yy6sYHK57n9WAbRAAaU+DuR4W6GN9K4DFZesYg=="; + }; + }; + "hast-util-whitespace-3.0.0" = { + name = "hast-util-whitespace"; + packageName = "hast-util-whitespace"; + version = "3.0.0"; + src = fetchurl { + url = "https://registry.npmjs.org/hast-util-whitespace/-/hast-util-whitespace-3.0.0.tgz"; + sha512 = "88JUN06ipLwsnv+dVn+OIYOvAuvBMy/Qoi6O7mQHxdPXpjy+Cd6xRkWwux7DKO+4sYILtLBRIKgsdpS2gQc7qw=="; + }; + }; + "html-void-elements-3.0.0" = { + name = "html-void-elements"; + packageName = "html-void-elements"; + version = "3.0.0"; + src = fetchurl { + url = "https://registry.npmjs.org/html-void-elements/-/html-void-elements-3.0.0.tgz"; + sha512 = "bEqo66MRXsUGxWHV5IP0PUiAWwoEjba4VCzg0LjFJBpchPaTfyfCKTG6bc5F8ucKec3q5y6qOdGyYTSBEvhCrg=="; + }; + }; + "i-0.3.7" = { + name = "i"; + packageName = "i"; + version = "0.3.7"; + src = fetchurl { + url = "https://registry.npmjs.org/i/-/i-0.3.7.tgz"; + sha512 = "FYz4wlXgkQwIPqhzC5TdNMLSE5+GS1IIDJZY/1ZiEPCT2S3COUVZeT5OW4BmW4r5LHLQuOosSwsvnroG9GR59Q=="; + }; + }; + "is-binary-path-2.1.0" = { + name = "is-binary-path"; + packageName = "is-binary-path"; + version = "2.1.0"; + src = fetchurl { + url = "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz"; + sha512 = "ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw=="; + }; + }; + "is-core-module-2.15.1" = { + name = "is-core-module"; + packageName = "is-core-module"; + version = "2.15.1"; + src = fetchurl { + url = "https://registry.npmjs.org/is-core-module/-/is-core-module-2.15.1.tgz"; + sha512 = "z0vtXSwucUJtANQWldhbtbt7BnL0vxiFjIdDLAatwhDYty2bad6s+rijD6Ri4YuYJubLzIJLUidCh09e1djEVQ=="; + }; + }; + "is-extglob-2.1.1" = { + name = "is-extglob"; + packageName = "is-extglob"; + version = "2.1.1"; + src = fetchurl { + url = "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz"; + sha512 = "SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ=="; + }; + }; + "is-fullwidth-code-point-3.0.0" = { + name = "is-fullwidth-code-point"; + packageName = "is-fullwidth-code-point"; + version = "3.0.0"; + src = fetchurl { + url = "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz"; + sha512 = "zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg=="; + }; + }; + "is-glob-4.0.3" = { + name = "is-glob"; + packageName = "is-glob"; + version = "4.0.3"; + src = fetchurl { + url = "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz"; + sha512 = "xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg=="; + }; + }; + "is-number-7.0.0" = { + name = "is-number"; + packageName = "is-number"; + version = "7.0.0"; + src = fetchurl { + url = "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz"; + sha512 = "41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng=="; + }; + }; + "isexe-2.0.0" = { + name = "isexe"; + packageName = "isexe"; + version = "2.0.0"; + src = fetchurl { + url = "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz"; + sha512 = "RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw=="; + }; + }; + "jackspeak-3.4.3" = { + name = "jackspeak"; + packageName = "jackspeak"; + version = "3.4.3"; + src = fetchurl { + url = "https://registry.npmjs.org/jackspeak/-/jackspeak-3.4.3.tgz"; + sha512 = "OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw=="; + }; + }; + "jiti-1.21.6" = { + name = "jiti"; + packageName = "jiti"; + version = "1.21.6"; + src = fetchurl { + url = "https://registry.npmjs.org/jiti/-/jiti-1.21.6.tgz"; + sha512 = "2yTgeWTWzMWkHu6Jp9NKgePDaYHbntiwvYuuJLbbN9vl7DC9DvXKOB2BC3ZZ92D3cvV/aflH0osDfwpHepQ53w=="; + }; + }; + "lilconfig-2.1.0" = { + name = "lilconfig"; + packageName = "lilconfig"; + version = "2.1.0"; + src = fetchurl { + url = "https://registry.npmjs.org/lilconfig/-/lilconfig-2.1.0.tgz"; + sha512 = "utWOt/GHzuUxnLKxB6dk81RoOeoNeHgbrXiuGk4yyF5qlRz+iIVWu56E2fqGHFrXz0QNUhLB/8nKqvRH66JKGQ=="; + }; + }; + "lilconfig-3.1.2" = { + name = "lilconfig"; + packageName = "lilconfig"; + version = "3.1.2"; + src = fetchurl { + url = "https://registry.npmjs.org/lilconfig/-/lilconfig-3.1.2.tgz"; + sha512 = "eop+wDAvpItUys0FWkHIKeC9ybYrTGbU41U5K7+bttZZeohvnY7M9dZ5kB21GNWiFT2q1OoPTvncPCgSOVO5ow=="; + }; + }; + "lines-and-columns-1.2.4" = { + name = "lines-and-columns"; + packageName = "lines-and-columns"; + version = "1.2.4"; + src = fetchurl { + url = "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz"; + sha512 = "7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg=="; + }; + }; + "lru-cache-10.4.3" = { + name = "lru-cache"; + packageName = "lru-cache"; + version = "10.4.3"; + src = fetchurl { + url = "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz"; + sha512 = "JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ=="; + }; + }; + "make-error-1.3.6" = { + name = "make-error"; + packageName = "make-error"; + version = "1.3.6"; + src = fetchurl { + url = "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz"; + sha512 = "s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw=="; + }; + }; + "mdast-util-to-hast-13.2.0" = { + name = "mdast-util-to-hast"; + packageName = "mdast-util-to-hast"; + version = "13.2.0"; + src = fetchurl { + url = "https://registry.npmjs.org/mdast-util-to-hast/-/mdast-util-to-hast-13.2.0.tgz"; + sha512 = "QGYKEuUsYT9ykKBCMOEDLsU5JRObWQusAolFMeko/tYPufNkRffBAQjIE+99jbA87xv6FgmjLtwjh9wBWajwAA=="; + }; + }; + "merge2-1.4.1" = { + name = "merge2"; + packageName = "merge2"; + version = "1.4.1"; + src = fetchurl { + url = "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz"; + sha512 = "8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg=="; + }; + }; + "micromark-util-character-2.1.1" = { + name = "micromark-util-character"; + packageName = "micromark-util-character"; + version = "2.1.1"; + src = fetchurl { + url = "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.1.tgz"; + sha512 = "wv8tdUTJ3thSFFFJKtpYKOYiGP2+v96Hvk4Tu8KpCAsTMs6yi+nVmGh1syvSCsaxz45J6Jbw+9DD6g97+NV67Q=="; + }; + }; + "micromark-util-encode-2.0.1" = { + name = "micromark-util-encode"; + packageName = "micromark-util-encode"; + version = "2.0.1"; + src = fetchurl { + url = "https://registry.npmjs.org/micromark-util-encode/-/micromark-util-encode-2.0.1.tgz"; + sha512 = "c3cVx2y4KqUnwopcO9b/SCdo2O67LwJJ/UyqGfbigahfegL9myoEFoDYZgkT7f36T0bLrM9hZTAaAyH+PCAXjw=="; + }; + }; + "micromark-util-sanitize-uri-2.0.1" = { + name = "micromark-util-sanitize-uri"; + packageName = "micromark-util-sanitize-uri"; + version = "2.0.1"; + src = fetchurl { + url = "https://registry.npmjs.org/micromark-util-sanitize-uri/-/micromark-util-sanitize-uri-2.0.1.tgz"; + sha512 = "9N9IomZ/YuGGZZmQec1MbgxtlgougxTodVwDzzEouPKo3qFWvymFHWcnDi2vzV1ff6kas9ucW+o3yzJK9YB1AQ=="; + }; + }; + "micromark-util-symbol-2.0.1" = { + name = "micromark-util-symbol"; + packageName = "micromark-util-symbol"; + version = "2.0.1"; + src = fetchurl { + url = "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.1.tgz"; + sha512 = "vs5t8Apaud9N28kgCrRUdEed4UJ+wWNvicHLPxCa9ENlYuAY31M0ETy5y1vA33YoNPDFTghEbnh6efaE8h4x0Q=="; + }; + }; + "micromark-util-types-2.0.1" = { + name = "micromark-util-types"; + packageName = "micromark-util-types"; + version = "2.0.1"; + src = fetchurl { + url = "https://registry.npmjs.org/micromark-util-types/-/micromark-util-types-2.0.1.tgz"; + sha512 = "534m2WhVTddrcKVepwmVEVnUAmtrx9bfIjNoQHRqfnvdaHQiFytEhJoTgpWJvDEXCO5gLTQh3wYC1PgOJA4NSQ=="; + }; + }; + "micromatch-4.0.8" = { + name = "micromatch"; + packageName = "micromatch"; + version = "4.0.8"; + src = fetchurl { + url = "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz"; + sha512 = "PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA=="; + }; + }; + "mini-svg-data-uri-1.4.4" = { + name = "mini-svg-data-uri"; + packageName = "mini-svg-data-uri"; + version = "1.4.4"; + src = fetchurl { + url = "https://registry.npmjs.org/mini-svg-data-uri/-/mini-svg-data-uri-1.4.4.tgz"; + sha512 = "r9deDe9p5FJUPZAk3A59wGH7Ii9YrjjWw0jmw/liSbHl2CHiyXj6FcDXDu2K3TjVAXqiJdaw3xxwlZZr9E6nHg=="; + }; + }; + "minimatch-9.0.5" = { + name = "minimatch"; + packageName = "minimatch"; + version = "9.0.5"; + src = fetchurl { + url = "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz"; + sha512 = "G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow=="; + }; + }; + "minipass-7.1.2" = { + name = "minipass"; + packageName = "minipass"; + version = "7.1.2"; + src = fetchurl { + url = "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz"; + sha512 = "qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw=="; + }; + }; + "mz-2.7.0" = { + name = "mz"; + packageName = "mz"; + version = "2.7.0"; + src = fetchurl { + url = "https://registry.npmjs.org/mz/-/mz-2.7.0.tgz"; + sha512 = "z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q=="; + }; + }; + "nanoid-3.3.7" = { + name = "nanoid"; + packageName = "nanoid"; + version = "3.3.7"; + src = fetchurl { + url = "https://registry.npmjs.org/nanoid/-/nanoid-3.3.7.tgz"; + sha512 = "eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g=="; + }; + }; + "normalize-path-3.0.0" = { + name = "normalize-path"; + packageName = "normalize-path"; + version = "3.0.0"; + src = fetchurl { + url = "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz"; + sha512 = "6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA=="; + }; + }; + "object-assign-4.1.1" = { + name = "object-assign"; + packageName = "object-assign"; + version = "4.1.1"; + src = fetchurl { + url = "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz"; + sha512 = "rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg=="; + }; + }; + "object-hash-3.0.0" = { + name = "object-hash"; + packageName = "object-hash"; + version = "3.0.0"; + src = fetchurl { + url = "https://registry.npmjs.org/object-hash/-/object-hash-3.0.0.tgz"; + sha512 = "RSn9F68PjH9HqtltsSnqYC1XXoWe9Bju5+213R98cNGttag9q9yAOTzdbsqvIa7aNm5WffBZFpWYr2aWrklWAw=="; + }; + }; + "oniguruma-to-js-0.4.3" = { + name = "oniguruma-to-js"; + packageName = "oniguruma-to-js"; + version = "0.4.3"; + src = fetchurl { + url = "https://registry.npmjs.org/oniguruma-to-js/-/oniguruma-to-js-0.4.3.tgz"; + sha512 = "X0jWUcAlxORhOqqBREgPMgnshB7ZGYszBNspP+tS9hPD3l13CdaXcHbgImoHUHlrvGx/7AvFEkTRhAGYh+jzjQ=="; + }; + }; + "package-json-from-dist-1.0.1" = { + name = "package-json-from-dist"; + packageName = "package-json-from-dist"; + version = "1.0.1"; + src = fetchurl { + url = "https://registry.npmjs.org/package-json-from-dist/-/package-json-from-dist-1.0.1.tgz"; + sha512 = "UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw=="; + }; + }; + "path-key-3.1.1" = { + name = "path-key"; + packageName = "path-key"; + version = "3.1.1"; + src = fetchurl { + url = "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz"; + sha512 = "ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q=="; + }; + }; + "path-parse-1.0.7" = { + name = "path-parse"; + packageName = "path-parse"; + version = "1.0.7"; + src = fetchurl { + url = "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz"; + sha512 = "LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw=="; + }; + }; + "path-scurry-1.11.1" = { + name = "path-scurry"; + packageName = "path-scurry"; + version = "1.11.1"; + src = fetchurl { + url = "https://registry.npmjs.org/path-scurry/-/path-scurry-1.11.1.tgz"; + sha512 = "Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA=="; + }; + }; + "phoenix-1.7.14" = { + name = "phoenix"; + packageName = "phoenix"; + version = "1.7.14"; + src = fetchurl { + url = "https://registry.npmjs.org/phoenix/-/phoenix-1.7.14.tgz"; + sha512 = "3tZ76PiH/2g+Kyzhz8+GIFYrnx3lRnwi/Qt3ZUH04xpMxXL7Guerd5aaxtpWal73X+H8iLAjo2c+AgRy2KYQcQ=="; + }; + }; + "phoenix_html-3.3.4" = { + name = "phoenix_html"; + packageName = "phoenix_html"; + version = "3.3.4"; + src = fetchurl { + url = "https://registry.npmjs.org/phoenix_html/-/phoenix_html-3.3.4.tgz"; + sha512 = "IkKAeP4sAuFzwtSSUbSNP/nL0H6WHcHfpe+/F7wOzyjYtijkAO2wTH8maA7vpTRhUBU5Dck5V8SEEhDuUy1mMA=="; + }; + }; + "phoenix_live_view-1.0.0-rc.7" = { + name = "phoenix_live_view"; + packageName = "phoenix_live_view"; + version = "1.0.0-rc.7"; + src = fetchurl { + url = "https://registry.npmjs.org/phoenix_live_view/-/phoenix_live_view-1.0.0-rc.7.tgz"; + sha512 = "G3fv7X/JtzrHIpNqR7REc9gAxTZkhICQWhQs6VvDgzXfkyHMQs9NqOpN00HOgCXHJPb1jxYhSMPRuyLBOmbgng=="; + }; + }; + "picocolors-1.1.1" = { + name = "picocolors"; + packageName = "picocolors"; + version = "1.1.1"; + src = fetchurl { + url = "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz"; + sha512 = "xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA=="; + }; + }; + "picomatch-2.3.1" = { + name = "picomatch"; + packageName = "picomatch"; + version = "2.3.1"; + src = fetchurl { + url = "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz"; + sha512 = "JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA=="; + }; + }; + "pify-2.3.0" = { + name = "pify"; + packageName = "pify"; + version = "2.3.0"; + src = fetchurl { + url = "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz"; + sha512 = "udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog=="; + }; + }; + "pirates-4.0.6" = { + name = "pirates"; + packageName = "pirates"; + version = "4.0.6"; + src = fetchurl { + url = "https://registry.npmjs.org/pirates/-/pirates-4.0.6.tgz"; + sha512 = "saLsH7WeYYPiD25LDuLRRY/i+6HaPYr6G1OUlN39otzkSTxKnubR9RTxS3/Kk50s1g2JTgFwWQDQyplC5/SHZg=="; + }; + }; + "postcss-8.4.49" = { + name = "postcss"; + packageName = "postcss"; + version = "8.4.49"; + src = fetchurl { + url = "https://registry.npmjs.org/postcss/-/postcss-8.4.49.tgz"; + sha512 = "OCVPnIObs4N29kxTjzLfUryOkvZEq+pf8jTF0lg8E7uETuWHA+v7j3c/xJmiqpX450191LlmZfUKkXxkTry7nA=="; + }; + }; + "postcss-import-15.1.0" = { + name = "postcss-import"; + packageName = "postcss-import"; + version = "15.1.0"; + src = fetchurl { + url = "https://registry.npmjs.org/postcss-import/-/postcss-import-15.1.0.tgz"; + sha512 = "hpr+J05B2FVYUAXHeK1YyI267J/dDDhMU6B6civm8hSY1jYJnBXxzKDKDswzJmtLHryrjhnDjqqp/49t8FALew=="; + }; + }; + "postcss-js-4.0.1" = { + name = "postcss-js"; + packageName = "postcss-js"; + version = "4.0.1"; + src = fetchurl { + url = "https://registry.npmjs.org/postcss-js/-/postcss-js-4.0.1.tgz"; + sha512 = "dDLF8pEO191hJMtlHFPRa8xsizHaM82MLfNkUHdUtVEV3tgTp5oj+8qbEqYM57SLfc74KSbw//4SeJma2LRVIw=="; + }; + }; + "postcss-load-config-4.0.2" = { + name = "postcss-load-config"; + packageName = "postcss-load-config"; + version = "4.0.2"; + src = fetchurl { + url = "https://registry.npmjs.org/postcss-load-config/-/postcss-load-config-4.0.2.tgz"; + sha512 = "bSVhyJGL00wMVoPUzAVAnbEoWyqRxkjv64tUl427SKnPrENtq6hJwUojroMz2VB+Q1edmi4IfrAPpami5VVgMQ=="; + }; + }; + "postcss-nested-6.2.0" = { + name = "postcss-nested"; + packageName = "postcss-nested"; + version = "6.2.0"; + src = fetchurl { + url = "https://registry.npmjs.org/postcss-nested/-/postcss-nested-6.2.0.tgz"; + sha512 = "HQbt28KulC5AJzG+cZtj9kvKB93CFCdLvog1WFLf1D+xmMvPGlBstkpTEZfK5+AN9hfJocyBFCNiqyS48bpgzQ=="; + }; + }; + "postcss-selector-parser-6.1.2" = { + name = "postcss-selector-parser"; + packageName = "postcss-selector-parser"; + version = "6.1.2"; + src = fetchurl { + url = "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.1.2.tgz"; + sha512 = "Q8qQfPiZ+THO/3ZrOrO0cJJKfpYCagtMUkXbnEfmgUjwXg6z/WBeOyS9APBBPCTSiDV+s4SwQGu8yFsiMRIudg=="; + }; + }; + "postcss-value-parser-4.2.0" = { + name = "postcss-value-parser"; + packageName = "postcss-value-parser"; + version = "4.2.0"; + src = fetchurl { + url = "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz"; + sha512 = "1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ=="; + }; + }; + "property-information-6.5.0" = { + name = "property-information"; + packageName = "property-information"; + version = "6.5.0"; + src = fetchurl { + url = "https://registry.npmjs.org/property-information/-/property-information-6.5.0.tgz"; + sha512 = "PgTgs/BlvHxOu8QuEN7wi5A0OmXaBcHpmCSTehcs6Uuu9IkDIEo13Hy7n898RHfrQ49vKCoGeWZSaAK01nwVig=="; + }; + }; + "queue-microtask-1.2.3" = { + name = "queue-microtask"; + packageName = "queue-microtask"; + version = "1.2.3"; + src = fetchurl { + url = "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz"; + sha512 = "NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A=="; + }; + }; + "read-cache-1.0.0" = { + name = "read-cache"; + packageName = "read-cache"; + version = "1.0.0"; + src = fetchurl { + url = "https://registry.npmjs.org/read-cache/-/read-cache-1.0.0.tgz"; + sha512 = "Owdv/Ft7IjOgm/i0xvNDZ1LrRANRfew4b2prF3OWMQLxLfu3bS8FVhCsrSCMK4lR56Y9ya+AThoTpDCTxCmpRA=="; + }; + }; + "readdirp-3.6.0" = { + name = "readdirp"; + packageName = "readdirp"; + version = "3.6.0"; + src = fetchurl { + url = "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz"; + sha512 = "hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA=="; + }; + }; + "regex-4.4.0" = { + name = "regex"; + packageName = "regex"; + version = "4.4.0"; + src = fetchurl { + url = "https://registry.npmjs.org/regex/-/regex-4.4.0.tgz"; + sha512 = "uCUSuobNVeqUupowbdZub6ggI5/JZkYyJdDogddJr60L764oxC2pMZov1fQ3wM9bdyzUILDG+Sqx6NAKAz9rKQ=="; + }; + }; + "resolve-1.22.8" = { + name = "resolve"; + packageName = "resolve"; + version = "1.22.8"; + src = fetchurl { + url = "https://registry.npmjs.org/resolve/-/resolve-1.22.8.tgz"; + sha512 = "oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw=="; + }; + }; + "reusify-1.0.4" = { + name = "reusify"; + packageName = "reusify"; + version = "1.0.4"; + src = fetchurl { + url = "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz"; + sha512 = "U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw=="; + }; + }; + "run-parallel-1.2.0" = { + name = "run-parallel"; + packageName = "run-parallel"; + version = "1.2.0"; + src = fetchurl { + url = "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz"; + sha512 = "5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA=="; + }; + }; + "shebang-command-2.0.0" = { + name = "shebang-command"; + packageName = "shebang-command"; + version = "2.0.0"; + src = fetchurl { + url = "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz"; + sha512 = "kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA=="; + }; + }; + "shebang-regex-3.0.0" = { + name = "shebang-regex"; + packageName = "shebang-regex"; + version = "3.0.0"; + src = fetchurl { + url = "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz"; + sha512 = "7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A=="; + }; + }; + "shiki-1.22.2" = { + name = "shiki"; + packageName = "shiki"; + version = "1.22.2"; + src = fetchurl { + url = "https://registry.npmjs.org/shiki/-/shiki-1.22.2.tgz"; + sha512 = "3IZau0NdGKXhH2bBlUk4w1IHNxPh6A5B2sUpyY+8utLu2j/h1QpFkAaUA1bAMxOWWGtTWcAh531vnS4NJKS/lA=="; + }; + }; + "signal-exit-4.1.0" = { + name = "signal-exit"; + packageName = "signal-exit"; + version = "4.1.0"; + src = fetchurl { + url = "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz"; + sha512 = "bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw=="; + }; + }; + "source-map-js-1.2.1" = { + name = "source-map-js"; + packageName = "source-map-js"; + version = "1.2.1"; + src = fetchurl { + url = "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz"; + sha512 = "UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA=="; + }; + }; + "space-separated-tokens-2.0.2" = { + name = "space-separated-tokens"; + packageName = "space-separated-tokens"; + version = "2.0.2"; + src = fetchurl { + url = "https://registry.npmjs.org/space-separated-tokens/-/space-separated-tokens-2.0.2.tgz"; + sha512 = "PEGlAwrG8yXGXRjW32fGbg66JAlOAwbObuqVoJpv/mRgoWDQfgH1wDPvtzWyUSNAXBGSk8h755YDbbcEy3SH2Q=="; + }; + }; + "string-width-4.2.3" = { + name = "string-width"; + packageName = "string-width"; + version = "4.2.3"; + src = fetchurl { + url = "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz"; + sha512 = "wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g=="; + }; + }; + "string-width-5.1.2" = { + name = "string-width"; + packageName = "string-width"; + version = "5.1.2"; + src = fetchurl { + url = "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz"; + sha512 = "HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA=="; + }; + }; + "string-width-cjs-4.2.3" = { + name = "string-width-cjs"; + packageName = "string-width-cjs"; + version = "4.2.3"; + src = fetchurl { + url = "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz"; + sha512 = "wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g=="; + }; + }; + "stringify-entities-4.0.4" = { + name = "stringify-entities"; + packageName = "stringify-entities"; + version = "4.0.4"; + src = fetchurl { + url = "https://registry.npmjs.org/stringify-entities/-/stringify-entities-4.0.4.tgz"; + sha512 = "IwfBptatlO+QCJUo19AqvrPNqlVMpW9YEL2LIVY+Rpv2qsjCGxaDLNRgeGsQWJhfItebuJhsGSLjaBbNSQ+ieg=="; + }; + }; + "strip-ansi-6.0.1" = { + name = "strip-ansi"; + packageName = "strip-ansi"; + version = "6.0.1"; + src = fetchurl { + url = "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz"; + sha512 = "Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A=="; + }; + }; + "strip-ansi-7.1.0" = { + name = "strip-ansi"; + packageName = "strip-ansi"; + version = "7.1.0"; + src = fetchurl { + url = "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz"; + sha512 = "iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ=="; + }; + }; + "strip-ansi-cjs-6.0.1" = { + name = "strip-ansi-cjs"; + packageName = "strip-ansi-cjs"; + version = "6.0.1"; + src = fetchurl { + url = "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz"; + sha512 = "Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A=="; + }; + }; + "sucrase-3.35.0" = { + name = "sucrase"; + packageName = "sucrase"; + version = "3.35.0"; + src = fetchurl { + url = "https://registry.npmjs.org/sucrase/-/sucrase-3.35.0.tgz"; + sha512 = "8EbVDiu9iN/nESwxeSxDKe0dunta1GOlHufmSSXxMD2z2/tMZpDMpvXQGsc+ajGo8y2uYUmixaSRUc/QPoQ0GA=="; + }; + }; + "supports-preserve-symlinks-flag-1.0.0" = { + name = "supports-preserve-symlinks-flag"; + packageName = "supports-preserve-symlinks-flag"; + version = "1.0.0"; + src = fetchurl { + url = "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz"; + sha512 = "ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w=="; + }; + }; + "tailwind-scrollbar-3.1.0" = { + name = "tailwind-scrollbar"; + packageName = "tailwind-scrollbar"; + version = "3.1.0"; + src = fetchurl { + url = "https://registry.npmjs.org/tailwind-scrollbar/-/tailwind-scrollbar-3.1.0.tgz"; + sha512 = "pmrtDIZeHyu2idTejfV59SbaJyvp1VRjYxAjZBH0jnyrPRo6HL1kD5Glz8VPagasqr6oAx6M05+Tuw429Z8jxg=="; + }; + }; + "tailwindcss-3.4.14" = { + name = "tailwindcss"; + packageName = "tailwindcss"; + version = "3.4.14"; + src = fetchurl { + url = "https://registry.npmjs.org/tailwindcss/-/tailwindcss-3.4.14.tgz"; + sha512 = "IcSvOcTRcUtQQ7ILQL5quRDg7Xs93PdJEk1ZLbhhvJc7uj/OAhYOnruEiwnGgBvUtaUAJ8/mhSw1o8L2jCiENA=="; + }; + }; + "tailwindcss-animate-1.0.7" = { + name = "tailwindcss-animate"; + packageName = "tailwindcss-animate"; + version = "1.0.7"; + src = fetchurl { + url = "https://registry.npmjs.org/tailwindcss-animate/-/tailwindcss-animate-1.0.7.tgz"; + sha512 = "bl6mpH3T7I3UFxuvDEXLxy/VuFxBk5bbzplh7tXI68mwMokNYd1t9qPBHlnyTwfa4JGC4zP516I1hYYtQ/vspA=="; + }; + }; + "thenify-3.3.1" = { + name = "thenify"; + packageName = "thenify"; + version = "3.3.1"; + src = fetchurl { + url = "https://registry.npmjs.org/thenify/-/thenify-3.3.1.tgz"; + sha512 = "RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw=="; + }; + }; + "thenify-all-1.6.0" = { + name = "thenify-all"; + packageName = "thenify-all"; + version = "1.6.0"; + src = fetchurl { + url = "https://registry.npmjs.org/thenify-all/-/thenify-all-1.6.0.tgz"; + sha512 = "RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA=="; + }; + }; + "to-regex-range-5.0.1" = { + name = "to-regex-range"; + packageName = "to-regex-range"; + version = "5.0.1"; + src = fetchurl { + url = "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz"; + sha512 = "65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ=="; + }; + }; + "trim-lines-3.0.1" = { + name = "trim-lines"; + packageName = "trim-lines"; + version = "3.0.1"; + src = fetchurl { + url = "https://registry.npmjs.org/trim-lines/-/trim-lines-3.0.1.tgz"; + sha512 = "kRj8B+YHZCc9kQYdWfJB2/oUl9rA99qbowYYBtr4ui4mZyAQ2JpvVBd/6U2YloATfqBhBTSMhTpgBHtU0Mf3Rg=="; + }; + }; + "ts-interface-checker-0.1.13" = { + name = "ts-interface-checker"; + packageName = "ts-interface-checker"; + version = "0.1.13"; + src = fetchurl { + url = "https://registry.npmjs.org/ts-interface-checker/-/ts-interface-checker-0.1.13.tgz"; + sha512 = "Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA=="; + }; + }; + "ts-node-10.9.2" = { + name = "ts-node"; + packageName = "ts-node"; + version = "10.9.2"; + src = fetchurl { + url = "https://registry.npmjs.org/ts-node/-/ts-node-10.9.2.tgz"; + sha512 = "f0FFpIdcHgn8zcPSbf1dRevwt047YMnaiJM3u2w2RewrB+fob/zePZcrOyQoLMMO7aBIddLcQIEK5dYjkLnGrQ=="; + }; + }; + "tslib-2.8.1" = { + name = "tslib"; + packageName = "tslib"; + version = "2.8.1"; + src = fetchurl { + url = "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz"; + sha512 = "oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w=="; + }; + }; + "typescript-5.6.3" = { + name = "typescript"; + packageName = "typescript"; + version = "5.6.3"; + src = fetchurl { + url = "https://registry.npmjs.org/typescript/-/typescript-5.6.3.tgz"; + sha512 = "hjcS1mhfuyi4WW8IWtjP7brDrG2cuDZukyrYrSauoXGNgx0S7zceP07adYkJycEr56BOUTNPzbInooiN3fn1qw=="; + }; + }; + "undici-types-6.19.8" = { + name = "undici-types"; + packageName = "undici-types"; + version = "6.19.8"; + src = fetchurl { + url = "https://registry.npmjs.org/undici-types/-/undici-types-6.19.8.tgz"; + sha512 = "ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw=="; + }; + }; + "unist-util-is-6.0.0" = { + name = "unist-util-is"; + packageName = "unist-util-is"; + version = "6.0.0"; + src = fetchurl { + url = "https://registry.npmjs.org/unist-util-is/-/unist-util-is-6.0.0.tgz"; + sha512 = "2qCTHimwdxLfz+YzdGfkqNlH0tLi9xjTnHddPmJwtIG9MGsdbutfTc4P+haPD7l7Cjxf/WZj+we5qfVPvvxfYw=="; + }; + }; + "unist-util-position-5.0.0" = { + name = "unist-util-position"; + packageName = "unist-util-position"; + version = "5.0.0"; + src = fetchurl { + url = "https://registry.npmjs.org/unist-util-position/-/unist-util-position-5.0.0.tgz"; + sha512 = "fucsC7HjXvkB5R3kTCO7kUjRdrS0BJt3M/FPxmHMBOm8JQi2BsHAHFsy27E0EolP8rp0NzXsJ+jNPyDWvOJZPA=="; + }; + }; + "unist-util-stringify-position-4.0.0" = { + name = "unist-util-stringify-position"; + packageName = "unist-util-stringify-position"; + version = "4.0.0"; + src = fetchurl { + url = "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-4.0.0.tgz"; + sha512 = "0ASV06AAoKCDkS2+xw5RXJywruurpbC4JZSm7nr7MOt1ojAzvyyaO+UxZf18j8FCF6kmzCZKcAgN/yu2gm2XgQ=="; + }; + }; + "unist-util-visit-5.0.0" = { + name = "unist-util-visit"; + packageName = "unist-util-visit"; + version = "5.0.0"; + src = fetchurl { + url = "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-5.0.0.tgz"; + sha512 = "MR04uvD+07cwl/yhVuVWAtw+3GOR/knlL55Nd/wAdblk27GCVt3lqpTivy/tkJcZoNPzTwS1Y+KMojlLDhoTzg=="; + }; + }; + "unist-util-visit-parents-6.0.1" = { + name = "unist-util-visit-parents"; + packageName = "unist-util-visit-parents"; + version = "6.0.1"; + src = fetchurl { + url = "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-6.0.1.tgz"; + sha512 = "L/PqWzfTP9lzzEa6CKs0k2nARxTdZduw3zyh8d2NVBnsyvHjSX4TWse388YrrQKbvI8w20fGjGlhgT96WwKykw=="; + }; + }; + "util-deprecate-1.0.2" = { + name = "util-deprecate"; + packageName = "util-deprecate"; + version = "1.0.2"; + src = fetchurl { + url = "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz"; + sha512 = "EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw=="; + }; + }; + "v8-compile-cache-lib-3.0.1" = { + name = "v8-compile-cache-lib"; + packageName = "v8-compile-cache-lib"; + version = "3.0.1"; + src = fetchurl { + url = "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz"; + sha512 = "wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg=="; + }; + }; + "vfile-6.0.3" = { + name = "vfile"; + packageName = "vfile"; + version = "6.0.3"; + src = fetchurl { + url = "https://registry.npmjs.org/vfile/-/vfile-6.0.3.tgz"; + sha512 = "KzIbH/9tXat2u30jf+smMwFCsno4wHVdNmzFyL+T/L3UGqqk6JKfVqOFOZEpZSHADH1k40ab6NUIXZq422ov3Q=="; + }; + }; + "vfile-message-4.0.2" = { + name = "vfile-message"; + packageName = "vfile-message"; + version = "4.0.2"; + src = fetchurl { + url = "https://registry.npmjs.org/vfile-message/-/vfile-message-4.0.2.tgz"; + sha512 = "jRDZ1IMLttGj41KcZvlrYAaI3CfqpLpfpf+Mfig13viT6NKvRzWZ+lXz0Y5D60w6uJIBAOGq9mSHf0gktF0duw=="; + }; + }; + "which-2.0.2" = { + name = "which"; + packageName = "which"; + version = "2.0.2"; + src = fetchurl { + url = "https://registry.npmjs.org/which/-/which-2.0.2.tgz"; + sha512 = "BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA=="; + }; + }; + "wrap-ansi-8.1.0" = { + name = "wrap-ansi"; + packageName = "wrap-ansi"; + version = "8.1.0"; + src = fetchurl { + url = "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz"; + sha512 = "si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ=="; + }; + }; + "wrap-ansi-cjs-7.0.0" = { + name = "wrap-ansi-cjs"; + packageName = "wrap-ansi-cjs"; + version = "7.0.0"; + src = fetchurl { + url = "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz"; + sha512 = "YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q=="; + }; + }; + "yaml-2.6.0" = { + name = "yaml"; + packageName = "yaml"; + version = "2.6.0"; + src = fetchurl { + url = "https://registry.npmjs.org/yaml/-/yaml-2.6.0.tgz"; + sha512 = "a6ae//JvKDEra2kdi1qzCyrJW/WZCgFi8ydDV+eXExl95t+5R+ijnqHJbz9tmMh8FUjx3iv2fCQ4dclAQlO2UQ=="; + }; + }; + "yn-3.1.1" = { + name = "yn"; + packageName = "yn"; + version = "3.1.1"; + src = fetchurl { + url = "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz"; + sha512 = "Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q=="; + }; + }; + "zwitch-2.0.4" = { + name = "zwitch"; + packageName = "zwitch"; + version = "2.0.4"; + src = fetchurl { + url = "https://registry.npmjs.org/zwitch/-/zwitch-2.0.4.tgz"; + sha512 = "bXE4cR/kVZhKZX/RjPEflHaKVhUVl85noU3v6b8apfQEc1x4A+zBxjZ4lN8LqGd6WZ3dl98pY4o717VFmoPp+A=="; + }; + }; + }; args = { name = "zoeys-computer-assets"; packageName = "zoeys-computer-assets"; src = ./.; + dependencies = [ + sources."@alloc/quick-lru-5.2.0" + sources."@catppuccin/tailwindcss-0.1.6" + (sources."@cspotcode/source-map-support-0.8.1" // { + dependencies = [ + sources."@jridgewell/trace-mapping-0.3.9" + ]; + }) + sources."@esbuild/linux-x64-0.24.0" + sources."@isaacs/cliui-8.0.2" + sources."@jridgewell/gen-mapping-0.3.5" + sources."@jridgewell/resolve-uri-3.1.2" + sources."@jridgewell/set-array-1.2.1" + sources."@jridgewell/sourcemap-codec-1.5.0" + sources."@jridgewell/trace-mapping-0.3.25" + sources."@nodelib/fs.scandir-2.1.5" + sources."@nodelib/fs.stat-2.0.5" + sources."@nodelib/fs.walk-1.2.8" + sources."@shikijs/core-1.22.2" + sources."@shikijs/engine-javascript-1.22.2" + sources."@shikijs/engine-oniguruma-1.22.2" + sources."@shikijs/types-1.22.2" + sources."@shikijs/vscode-textmate-9.3.0" + sources."@swc/core-1.9.2" + sources."@swc/counter-0.1.3" + sources."@swc/helpers-0.5.15" + sources."@swc/types-0.1.15" + sources."@swc/wasm-1.9.2" + sources."@tailwindcss/forms-0.5.9" + sources."@tsconfig/node10-1.0.11" + sources."@tsconfig/node12-1.0.11" + sources."@tsconfig/node14-1.0.3" + sources."@tsconfig/node16-1.0.4" + sources."@types/hast-3.0.4" + sources."@types/mdast-4.0.4" + sources."@types/node-22.9.0" + sources."@types/unist-3.0.3" + sources."@ungap/structured-clone-1.2.0" + sources."acorn-8.14.0" + sources."acorn-walk-8.3.4" + sources."ansi-regex-5.0.1" + sources."ansi-styles-6.2.1" + sources."any-promise-1.3.0" + sources."anymatch-3.1.3" + sources."arg-5.0.2" + sources."balanced-match-1.0.2" + sources."binary-extensions-2.3.0" + sources."brace-expansion-2.0.1" + sources."braces-3.0.3" + sources."camelcase-css-2.0.1" + sources."ccount-2.0.1" + sources."character-entities-html4-2.1.0" + sources."character-entities-legacy-3.0.0" + (sources."chokidar-3.6.0" // { + dependencies = [ + sources."glob-parent-5.1.2" + ]; + }) + sources."color-convert-2.0.1" + sources."color-name-1.1.4" + sources."comma-separated-tokens-2.0.3" + sources."commander-4.1.1" + sources."create-require-1.1.1" + sources."cross-spawn-7.0.5" + sources."cssesc-3.0.0" + sources."dequal-2.0.3" + sources."devlop-1.1.0" + sources."didyoumean-1.2.2" + sources."diff-4.0.2" + sources."dlv-1.1.3" + sources."eastasianwidth-0.2.0" + sources."emoji-regex-9.2.2" + sources."esbuild-0.24.0" + (sources."fast-glob-3.3.2" // { + dependencies = [ + sources."glob-parent-5.1.2" + ]; + }) + sources."fastq-1.17.1" + sources."fill-range-7.1.1" + sources."foreground-child-3.3.0" + sources."function-bind-1.1.2" + sources."glob-10.4.5" + sources."glob-parent-6.0.2" + sources."hasown-2.0.2" + sources."hast-util-to-html-9.0.3" + sources."hast-util-whitespace-3.0.0" + sources."html-void-elements-3.0.0" + sources."i-0.3.7" + sources."is-binary-path-2.1.0" + sources."is-core-module-2.15.1" + sources."is-extglob-2.1.1" + sources."is-fullwidth-code-point-3.0.0" + sources."is-glob-4.0.3" + sources."is-number-7.0.0" + sources."isexe-2.0.0" + sources."jackspeak-3.4.3" + sources."jiti-1.21.6" + sources."lilconfig-2.1.0" + sources."lines-and-columns-1.2.4" + sources."lru-cache-10.4.3" + sources."make-error-1.3.6" + sources."mdast-util-to-hast-13.2.0" + sources."merge2-1.4.1" + sources."micromark-util-character-2.1.1" + sources."micromark-util-encode-2.0.1" + sources."micromark-util-sanitize-uri-2.0.1" + sources."micromark-util-symbol-2.0.1" + sources."micromark-util-types-2.0.1" + sources."micromatch-4.0.8" + sources."mini-svg-data-uri-1.4.4" + sources."minimatch-9.0.5" + sources."minipass-7.1.2" + sources."mz-2.7.0" + sources."nanoid-3.3.7" + sources."normalize-path-3.0.0" + sources."object-assign-4.1.1" + sources."object-hash-3.0.0" + sources."oniguruma-to-js-0.4.3" + sources."package-json-from-dist-1.0.1" + sources."path-key-3.1.1" + sources."path-parse-1.0.7" + sources."path-scurry-1.11.1" + sources."phoenix-1.7.14" + sources."phoenix_html-3.3.4" + sources."phoenix_live_view-1.0.0-rc.7" + sources."picocolors-1.1.1" + sources."picomatch-2.3.1" + sources."pify-2.3.0" + sources."pirates-4.0.6" + sources."postcss-8.4.49" + sources."postcss-import-15.1.0" + sources."postcss-js-4.0.1" + (sources."postcss-load-config-4.0.2" // { + dependencies = [ + sources."lilconfig-3.1.2" + ]; + }) + sources."postcss-nested-6.2.0" + sources."postcss-selector-parser-6.1.2" + sources."postcss-value-parser-4.2.0" + sources."property-information-6.5.0" + sources."queue-microtask-1.2.3" + sources."read-cache-1.0.0" + sources."readdirp-3.6.0" + sources."regex-4.4.0" + sources."resolve-1.22.8" + sources."reusify-1.0.4" + sources."run-parallel-1.2.0" + sources."shebang-command-2.0.0" + sources."shebang-regex-3.0.0" + sources."shiki-1.22.2" + sources."signal-exit-4.1.0" + sources."source-map-js-1.2.1" + sources."space-separated-tokens-2.0.2" + sources."string-width-5.1.2" + (sources."string-width-cjs-4.2.3" // { + dependencies = [ + sources."emoji-regex-8.0.0" + sources."strip-ansi-6.0.1" + ]; + }) + sources."stringify-entities-4.0.4" + (sources."strip-ansi-7.1.0" // { + dependencies = [ + sources."ansi-regex-6.1.0" + ]; + }) + sources."strip-ansi-cjs-6.0.1" + sources."sucrase-3.35.0" + sources."supports-preserve-symlinks-flag-1.0.0" + sources."tailwind-scrollbar-3.1.0" + sources."tailwindcss-3.4.14" + sources."tailwindcss-animate-1.0.7" + sources."thenify-3.3.1" + sources."thenify-all-1.6.0" + sources."to-regex-range-5.0.1" + sources."trim-lines-3.0.1" + sources."ts-interface-checker-0.1.13" + (sources."ts-node-10.9.2" // { + dependencies = [ + sources."arg-4.1.3" + ]; + }) + sources."tslib-2.8.1" + sources."typescript-5.6.3" + sources."undici-types-6.19.8" + sources."unist-util-is-6.0.0" + sources."unist-util-position-5.0.0" + sources."unist-util-stringify-position-4.0.0" + sources."unist-util-visit-5.0.0" + sources."unist-util-visit-parents-6.0.1" + sources."util-deprecate-1.0.2" + sources."v8-compile-cache-lib-3.0.1" + sources."vfile-6.0.3" + sources."vfile-message-4.0.2" + sources."which-2.0.2" + sources."wrap-ansi-8.1.0" + (sources."wrap-ansi-cjs-7.0.0" // { + dependencies = [ + sources."ansi-styles-4.3.0" + sources."emoji-regex-8.0.0" + sources."string-width-4.2.3" + sources."strip-ansi-6.0.1" + ]; + }) + sources."yaml-2.6.0" + sources."yn-3.1.1" + sources."zwitch-2.0.4" + ]; buildInputs = globalBuildInputs; meta = { }; production = true; bypassCache = true; - reconstructLock = false; + reconstructLock = true; }; in { diff --git a/assets/package-lock.json b/assets/package-lock.json index e8ff1de..2d33191 100644 --- a/assets/package-lock.json +++ b/assets/package-lock.json @@ -15,6 +15,7 @@ "phoenix_html": "^3.3.4", "phoenix_live_view": "^1.0.0-rc.7", "shiki": "^1.22.1", + "tailwind-scrollbar": "^3.1.0", "tailwindcss": "^3.4.14", "tailwindcss-animate": "^1.0.7" }, @@ -2056,6 +2057,18 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/tailwind-scrollbar": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/tailwind-scrollbar/-/tailwind-scrollbar-3.1.0.tgz", + "integrity": "sha512-pmrtDIZeHyu2idTejfV59SbaJyvp1VRjYxAjZBH0jnyrPRo6HL1kD5Glz8VPagasqr6oAx6M05+Tuw429Z8jxg==", + "license": "MIT", + "engines": { + "node": ">=12.13.0" + }, + "peerDependencies": { + "tailwindcss": "3.x" + } + }, "node_modules/tailwindcss": { "version": "3.4.14", "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-3.4.14.tgz", diff --git a/assets/package.json b/assets/package.json index 2952499..139b3c7 100644 --- a/assets/package.json +++ b/assets/package.json @@ -16,6 +16,7 @@ "phoenix_html": "^3.3.4", "phoenix_live_view": "^1.0.0-rc.7", "shiki": "^1.22.1", + "tailwind-scrollbar": "^3.1.0", "tailwindcss": "^3.4.14", "tailwindcss-animate": "^1.0.7" }, diff --git a/assets/tailwind.config.js b/assets/tailwind.config.js index 3c3c0e8..35f3060 100644 --- a/assets/tailwind.config.js +++ b/assets/tailwind.config.js @@ -68,6 +68,7 @@ module.exports = { prefix: "ctp", defaultFlavor: "mocha", }), + require("tailwind-scrollbar"), plugin(({ addVariant }) => addVariant("phx-click-loading", [ ".phx-click-loading&", diff --git a/deps.nix b/deps.nix index f21bb8c..fc38545 100644 --- a/deps.nix +++ b/deps.nix @@ -465,6 +465,108 @@ let beamDeps = [ decimal ]; }; + makeup = + let + version = "1.1.2"; + in + buildMix { + inherit version; + name = "makeup"; + + src = fetchHex { + inherit version; + pkg = "makeup"; + sha256 = "cce1566b81fbcbd21eca8ffe808f33b221f9eee2cbc7a1706fc3da9ff18e6cac"; + }; + + beamDeps = [ nimble_parsec ]; + }; + + makeup_elixir = + let + version = "0.16.2"; + in + buildMix { + inherit version; + name = "makeup_elixir"; + + src = fetchHex { + inherit version; + pkg = "makeup_elixir"; + sha256 = "41193978704763f6bbe6cc2758b84909e62984c7752b3784bd3c218bb341706b"; + }; + + beamDeps = [ makeup nimble_parsec ]; + }; + + makeup_erlang = + let + version = "0.1.5"; + in + buildMix { + inherit version; + name = "makeup_erlang"; + + src = fetchHex { + inherit version; + pkg = "makeup_erlang"; + sha256 = "94d2e986428585a21516d7d7149781480013c56e30c6a233534bedf38867a59a"; + }; + + beamDeps = [ makeup ]; + }; + + makeup_html = + let + version = "0.1.1"; + in + buildMix { + inherit version; + name = "makeup_html"; + + src = fetchHex { + inherit version; + pkg = "makeup_html"; + sha256 = "44f2a61bc5243645dd7fafeaa6cc28793cd22f3c76b861e066168f9a5b2c26a4"; + }; + + beamDeps = [ makeup ]; + }; + + makeup_js = + let + version = "0.1.0"; + in + buildMix { + inherit version; + name = "makeup_js"; + + src = fetchHex { + inherit version; + pkg = "makeup_js"; + sha256 = "3f0c1a5eb52c9737b1679c926574e83bb260ccdedf08b58ee96cca7c685dea75"; + }; + + beamDeps = [ makeup ]; + }; + + makeup_rust = + let + version = "0.3.0"; + in + buildMix { + inherit version; + name = "makeup_rust"; + + src = fetchHex { + inherit version; + pkg = "makeup_rust"; + sha256 = "1e79ee1995a3b9df9b7d90af7dc02525989efc41390a52065c23782c94ea94e1"; + }; + + beamDeps = [ makeup nimble_parsec ]; + }; + metrics = let version = "1.0.1"; @@ -557,6 +659,21 @@ let }; }; + nimble_parsec = + let + version = "1.4.0"; + in + buildMix { + inherit version; + name = "nimble_parsec"; + + src = fetchHex { + inherit version; + pkg = "nimble_parsec"; + sha256 = "9c565862810fb383e9838c1dd2d7d2c437b3d13b267414ba6af33e50d2d1cf28"; + }; + }; + nimble_pool = let version = "1.1.0"; @@ -636,6 +753,23 @@ let }; }; + phoenix_html_helpers = + let + version = "1.0.1"; + in + buildMix { + inherit version; + name = "phoenix_html_helpers"; + + src = fetchHex { + inherit version; + pkg = "phoenix_html_helpers"; + sha256 = "cffd2385d1fa4f78b04432df69ab8da63dc5cf63e07b713a4dcf36a3740e3090"; + }; + + beamDeps = [ phoenix_html plug ]; + }; + phoenix_live_dashboard = let version = "0.8.4"; diff --git a/flake.nix b/flake.nix index f6fe2e0..10720e1 100644 --- a/flake.nix +++ b/flake.nix @@ -232,7 +232,7 @@ StartLimitBurst = 3; StartLimitInterval = 10; }; - path = [pkgs.bash pkgs.imagemagick]; + path = [pkgs.bash pkgs.imagemagick pkgs.librsvg]; }; }; }; @@ -318,6 +318,7 @@ nodejs mix2nix node2nix + librsvg imagemagick # Add the language server of your choice. inputs.lexical.packages.${system}.default diff --git a/lib/zoeyscomputer/gists.ex b/lib/zoeyscomputer/gists.ex index 6951c36..7f31bed 100644 --- a/lib/zoeyscomputer/gists.ex +++ b/lib/zoeyscomputer/gists.ex @@ -6,6 +6,7 @@ defmodule Zoeyscomputer.Gists do import Ecto.Query, warn: false alias Zoeyscomputer.Repo + alias Zoeyscomputer.Users.User alias Zoeyscomputer.Gists.Gist @doc """ @@ -21,6 +22,12 @@ defmodule Zoeyscomputer.Gists do Repo.all(Gist) end + def list_gists_for_user(%User{} = user) do + Gist + |> where([a], a.author_id == ^user.id) + |> Repo.all() + end + @doc """ Gets a single gist. @@ -35,7 +42,7 @@ defmodule Zoeyscomputer.Gists do ** (Ecto.NoResultsError) """ - def get_gist!(id), do: Repo.get!(Gist, id) + def get_gist!(id), do: Repo.get!(Gist, id) |> Repo.preload([:author]) @doc """ Creates a gist. @@ -49,7 +56,10 @@ defmodule Zoeyscomputer.Gists do {:error, %Ecto.Changeset{}} """ - def create_gist(attrs \\ %{}) do + def create_gist(user, attrs \\ %{}) do + IO.puts("hereo") + attrs = Map.put(attrs, "author_id", user.id) + %Gist{} |> Gist.changeset(attrs) |> Repo.insert() diff --git a/lib/zoeyscomputer/gists/gist.ex b/lib/zoeyscomputer/gists/gist.ex index 3cd67df..55d4d99 100644 --- a/lib/zoeyscomputer/gists/gist.ex +++ b/lib/zoeyscomputer/gists/gist.ex @@ -1,10 +1,16 @@ defmodule Zoeyscomputer.Gists.Gist do + alias Zoeyscomputer.IdGenerator use Ecto.Schema import Ecto.Changeset + alias Zoeyscomputer.Users.User + @primary_key {:id, :string, autogenerate: false} schema "gists" do field :code, :string field :lang, :string + field :title, :string + field :desc, :string + belongs_to :author, User timestamps(type: :utc_datetime) end @@ -12,7 +18,17 @@ defmodule Zoeyscomputer.Gists.Gist do @doc false def changeset(gist, attrs) do gist - |> cast(attrs, [:code, :lang]) - |> validate_required([:code, :lang]) + |> cast(attrs, [:code, :lang, :title, :desc, :author_id]) + |> validate_required([:code, :lang, :title, :author_id]) + |> put_new_id() + end + + defp put_new_id(changeset) do + IO.puts("assigning new id") + + case get_field(changeset, :id) do + nil -> put_change(changeset, :id, IdGenerator.generate(7)) + _id -> changeset + end end end diff --git a/lib/zoeyscomputer_web/components/code_block.ex b/lib/zoeyscomputer_web/components/code_block.ex index 2217398..73e2be6 100644 --- a/lib/zoeyscomputer_web/components/code_block.ex +++ b/lib/zoeyscomputer_web/components/code_block.ex @@ -1,6 +1,7 @@ defmodule ZoeyscomputerWeb.CodeBlock do use Phoenix.Component - alias Phoenix.LiveView.JS + + import ZoeyscomputerWeb.CoreComponents @moduledoc """ A code block component with syntax highlighting using Shiki. @@ -37,6 +38,7 @@ defmodule ZoeyscomputerWeb.CodeBlock do attr :code, :string, required: true attr :language, :string, required: true attr :title, :string, default: nil + attr :class, :string, default: "" attr :line_numbers, :boolean, default: false attr :highlighted_lines, :list, default: [] @@ -44,48 +46,49 @@ defmodule ZoeyscomputerWeb.CodeBlock do # Calculate the number of lines for line numbers assigns = assign(assigns, :num_lines, String.split(assigns.code, "\n") |> length()) + id = System.unique_integer() + ~H""" -
+
<%= if @title do %> -
-

<%= @title %>

+
+

<%= @title %>

<% end %> -
- <%= if @line_numbers do %> -
- <%= for line_num <- 1..@num_lines do %> - - <%= line_num %> - - <% end %> -
- <% end %> +
+
+ <%= if @line_numbers do %> +
+ <%= for line_num <- 1..@num_lines do %> + + <%= line_num %> + + <% end %> +
+ <% end %> -
-
<%= @code %>
+
+
<%= @code %>
+
- -
- +
+ <.copy_button id="code-copy-btn" content={"code-block-#{id}"} />
""" diff --git a/lib/zoeyscomputer_web/components/core_components.ex b/lib/zoeyscomputer_web/components/core_components.ex index 615bc5d..412a678 100644 --- a/lib/zoeyscomputer_web/components/core_components.ex +++ b/lib/zoeyscomputer_web/components/core_components.ex @@ -70,7 +70,7 @@ defmodule ZoeyscomputerWeb.CoreComponents do phx-window-keydown={JS.exec("data-cancel", to: "##{@id}")} phx-key="escape" phx-click-away={JS.exec("data-cancel", to: "##{@id}")} - class="shadow-zinc-700/10 ring-zinc-700/10 relative hidden rounded-2xl bg-ctp-base p-14 shadow-lg ring-1 transition" + class="shadow-ctp-mauve/10 ring-ctp-mauve/10 relative hidden rounded-2xl bg-ctp-base p-14 shadow-lg ring-1 transition" >
@@ -499,7 +500,7 @@ defmodule ZoeyscomputerWeb.CoreComponents do ~H"""
- + - +
<%= col[:label] %> @@ -510,27 +511,35 @@ defmodule ZoeyscomputerWeb.CoreComponents do
- - + + <%= render_slot(col, @row_item.(row)) %>
- + + <%= render_slot(action, @row_item.(row)) %> @@ -560,9 +569,9 @@ defmodule ZoeyscomputerWeb.CoreComponents do def list(assigns) do ~H"""
-
+
-
<%= item.title %>
+
<%= item.title %>
<%= render_slot(item) %>
diff --git a/lib/zoeyscomputer_web/components/layouts/app.html.heex b/lib/zoeyscomputer_web/components/layouts/app.html.heex index 3f97e57..bff3361 100644 --- a/lib/zoeyscomputer_web/components/layouts/app.html.heex +++ b/lib/zoeyscomputer_web/components/layouts/app.html.heex @@ -1,5 +1,5 @@
-
+
<.flash_group flash={@flash} /> <%= @inner_content %>
diff --git a/lib/zoeyscomputer_web/components/searchable_dropdown.ex b/lib/zoeyscomputer_web/components/searchable_dropdown.ex deleted file mode 100644 index 94a5152..0000000 --- a/lib/zoeyscomputer_web/components/searchable_dropdown.ex +++ /dev/null @@ -1,81 +0,0 @@ -defmodule ZoeyscomputerWeb.SearchableDropdown do - use Phoenix.Component - alias Phoenix.LiveView.JS - - attr :id, :string, required: true - attr :options, :list, required: true - attr :selected, :string, default: nil - attr :class, :string, default: nil - attr :name, :string, required: true - attr :form, :any, required: true - - def searchable_dropdown(assigns) do - ~H""" -
-
- - - -
-
- """ - end -end diff --git a/lib/zoeyscomputer_web/controllers/gist_controller.ex b/lib/zoeyscomputer_web/controllers/gist_controller.ex index 138da01..d63bacd 100644 --- a/lib/zoeyscomputer_web/controllers/gist_controller.ex +++ b/lib/zoeyscomputer_web/controllers/gist_controller.ex @@ -8,11 +8,14 @@ defmodule ZoeyscomputerWeb.GistController do def index(conn, _params) do gists = Gists.list_gists() + IO.inspect(gists) render(conn, :index, gists: gists) end - def create(conn, %{"gist" => gist_params}) do - with {:ok, %Gist{} = gist} <- Gists.create_gist(gist_params) do + def create(conn, params) do + gist_params = decode_params(params) + + with {:ok, %Gist{} = gist} <- Gists.create_gist(conn.assigns.current_user, gist_params) do conn |> put_status(:created) |> put_resp_header("location", ~p"/api/gists/#{gist}") @@ -20,6 +23,32 @@ defmodule ZoeyscomputerWeb.GistController do end end + # Private function to handle param decoding + defp decode_params(params) when is_map(params) do + cond do + # Handle regular JSON params + Map.has_key?(params, "title") and + Map.has_key?(params, "desc") and + Map.has_key?(params, "code") and + Map.has_key?(params, "language") -> + params + + # Handle params wrapped in "gist" key + Map.has_key?(params, "gist") -> + params["gist"] + + # Handle string JSON that needs parsing + Enum.any?(params, fn {k, _v} -> String.starts_with?(k, "{") end) -> + params + |> Map.keys() + |> List.first() + |> Jason.decode!() + + true -> + params + end + end + def show(conn, %{"id" => id}) do gist = Gists.get_gist!(id) render(conn, :show, gist: gist) diff --git a/lib/zoeyscomputer_web/controllers/gist_json.ex b/lib/zoeyscomputer_web/controllers/gist_json.ex index aaea474..5be96f5 100644 --- a/lib/zoeyscomputer_web/controllers/gist_json.ex +++ b/lib/zoeyscomputer_web/controllers/gist_json.ex @@ -19,7 +19,10 @@ defmodule ZoeyscomputerWeb.GistJSON do %{ id: gist.id, code: gist.code, - lang: gist.lang + lang: gist.lang, + author_id: gist.author_id, + desc: gist.desc, + title: gist.title } end end diff --git a/lib/zoeyscomputer_web/controllers/gist_preview_controller.ex b/lib/zoeyscomputer_web/controllers/gist_preview_controller.ex new file mode 100644 index 0000000..a15950e --- /dev/null +++ b/lib/zoeyscomputer_web/controllers/gist_preview_controller.ex @@ -0,0 +1,30 @@ +defmodule ZoeyscomputerWeb.GistPreviewController do + use ZoeyscomputerWeb, :controller + + require Logger + alias Zoeyscomputer.Gists + + def show(conn, %{"id" => id}) do + gist = Gists.get_gist!(id) + + {:ok, webp} = ZoeyscomputerWeb.GistLive.OgImage.get_webp(gist) + + conn + |> put_resp_content_type("image/webp") + |> put_resp_header("cache-control", "public, max-age=300") + |> send_resp(200, webp) + |> halt() + end + + def raw(conn, %{"id" => id}) do + gist = Gists.get_gist!(id) + + webp = ZoeyscomputerWeb.GistLive.OgImage.generate_preview(gist) + + conn + |> put_resp_content_type("image/svg+xml") + |> put_resp_header("cache-control", "public, max-age=300") + |> send_resp(200, webp) + |> halt() + end +end diff --git a/lib/zoeyscomputer_web/live/gist_live/form_component.ex b/lib/zoeyscomputer_web/live/gist_live/form_component.ex index ad6039b..f5256d5 100644 --- a/lib/zoeyscomputer_web/live/gist_live/form_component.ex +++ b/lib/zoeyscomputer_web/live/gist_live/form_component.ex @@ -1,6 +1,8 @@ defmodule ZoeyscomputerWeb.GistLive.FormComponent do use ZoeyscomputerWeb, :live_component + import ZoeyscomputerWeb.GistLive.Select + alias Zoeyscomputer.Gists @impl true @@ -11,7 +13,6 @@ defmodule ZoeyscomputerWeb.GistLive.FormComponent do <%= @title %> <:subtitle>Use this form to manage gist records in your database. - <.simple_form for={@form} id="gist-form" @@ -19,8 +20,22 @@ defmodule ZoeyscomputerWeb.GistLive.FormComponent do phx-change="validate" phx-submit="save" > - <.input field={@form[:code]} type="text" label="Code" /> - <.input field={@form[:lang]} type="text" label="Lang" /> + <.input field={@form[:title]} type="text" label="Title" /> + <.input field={@form[:desc]} type="textarea" label="Description" /> + <.input field={@form[:code]} type="textarea" label="Code" /> + <.select + id="lang-select" + form={@form} + field={:lang} + label="Language" + options={[ + {"JavaScript", "javascript"}, + {"Python", "python"}, + {"Elixir", "elixir"}, + {"Ruby", "ruby"}, + {"Rust", "rust"} + ]} + /> <:actions> <.button phx-disable-with="Saving...">Save Gist @@ -49,6 +64,14 @@ defmodule ZoeyscomputerWeb.GistLive.FormComponent do save_gist(socket, socket.assigns.action, gist_params) end + # Updated to use lang instead of language + def handle_event("change", %{"value" => value}, socket) do + current_params = socket.assigns.form.params || %{} + updated_params = Map.put(current_params, "lang", value) + changeset = Gists.change_gist(socket.assigns.gist, updated_params) + {:noreply, assign(socket, form: to_form(changeset, action: :validate))} + end + defp save_gist(socket, :edit, gist_params) do case Gists.update_gist(socket.assigns.gist, gist_params) do {:ok, gist} -> @@ -65,7 +88,7 @@ defmodule ZoeyscomputerWeb.GistLive.FormComponent do end defp save_gist(socket, :new, gist_params) do - case Gists.create_gist(gist_params) do + case Gists.create_gist(socket.assigns.current_user, gist_params) do {:ok, gist} -> notify_parent({:saved, gist}) @@ -75,6 +98,7 @@ defmodule ZoeyscomputerWeb.GistLive.FormComponent do |> push_patch(to: socket.assigns.patch)} {:error, %Ecto.Changeset{} = changeset} -> + IO.inspect(changeset) {:noreply, assign(socket, form: to_form(changeset))} end end diff --git a/lib/zoeyscomputer_web/live/gist_live/index.ex b/lib/zoeyscomputer_web/live/gist_live/index.ex index 607c8d4..ed68a8e 100644 --- a/lib/zoeyscomputer_web/live/gist_live/index.ex +++ b/lib/zoeyscomputer_web/live/gist_live/index.ex @@ -6,24 +6,42 @@ defmodule ZoeyscomputerWeb.GistLive.Index do @impl true def mount(_params, _session, socket) do - {:ok, stream(socket, :gists, Gists.list_gists())} + socket = socket |> assign(:current_user, socket.assigns.current_user) + + if connected?(socket) && socket.assigns.current_user do + {:ok, stream(socket, :gists, Gists.list_gists_for_user(socket.assigns.current_user))} + else + {:ok, stream(socket, :gists, [])} + end end @impl true def handle_params(params, _url, socket) do - {:noreply, apply_action(socket, socket.assigns.live_action, params)} + live_action = socket.assigns.live_action || :index + {:noreply, apply_action(socket, live_action, params)} end defp apply_action(socket, :edit, %{"id" => id}) do socket |> assign(:page_title, "Edit Gist") + |> assign(:current_user, socket.assigns.current_user) |> assign(:gist, Gists.get_gist!(id)) end defp apply_action(socket, :new, _params) do socket |> assign(:page_title, "New Gist") - |> assign(:gist, %Gist{}) + |> assign(:current_user, socket.assigns.current_user) + |> assign(:gist, %Gist{ + code: "", + lang: nil + }) + end + + defp apply_action(socket, :show, %{"id" => id}) do + socket + |> assign(:page_title, "Show Gist") + |> assign(:gist, Gists.get_gist!(id)) end defp apply_action(socket, :index, _params) do @@ -32,6 +50,13 @@ defmodule ZoeyscomputerWeb.GistLive.Index do |> assign(:gist, nil) end + # Catch-all clause for when live_action is nil + defp apply_action(socket, nil, _params) do + socket + |> assign(:page_title, "Listing Gists") + |> assign(:gist, nil) + end + @impl true def handle_info({ZoeyscomputerWeb.GistLive.FormComponent, {:saved, gist}}, socket) do {:noreply, stream_insert(socket, :gists, gist)} diff --git a/lib/zoeyscomputer_web/live/gist_live/index.html.heex b/lib/zoeyscomputer_web/live/gist_live/index.html.heex index 88b300b..9e1d880 100644 --- a/lib/zoeyscomputer_web/live/gist_live/index.html.heex +++ b/lib/zoeyscomputer_web/live/gist_live/index.html.heex @@ -12,7 +12,9 @@ rows={@streams.gists} row_click={fn {_id, gist} -> JS.navigate(~p"/gists/#{gist}") end} > - <:col :let={{_id, gist}} label="Code"><%= gist.code %> + <:col :let={{_id, gist}} label="Code"> +

<%= gist.title || gist.code %>

+ <:col :let={{_id, gist}} label="Lang"><%= gist.lang %> <:action :let={{_id, gist}}>
@@ -36,6 +38,7 @@ id={@gist.id || :new} title={@page_title} action={@live_action} + current_user={@current_user} gist={@gist} patch={~p"/gists"} /> diff --git a/lib/zoeyscomputer_web/live/gist_live/languages.ex b/lib/zoeyscomputer_web/live/gist_live/languages.ex new file mode 100644 index 0000000..e309eca --- /dev/null +++ b/lib/zoeyscomputer_web/live/gist_live/languages.ex @@ -0,0 +1,15 @@ +defmodule ZoeyscomputerWeb.GistLive.Languages do + @languages [ + %{name: "JavaScript", val: "javascript"}, + %{name: "TypeScript", val: "typescript"}, + %{name: "Rust", val: "rust"}, + %{name: "Elixir", val: "elixir"} + ] + + def search_languages(name) do + @languages + |> Enum.filter(fn language -> + String.contains?(String.downcase(language.name), String.downcase(name)) + end) + end +end diff --git a/lib/zoeyscomputer_web/live/gist_live/og_image.ex b/lib/zoeyscomputer_web/live/gist_live/og_image.ex new file mode 100644 index 0000000..cbfae82 --- /dev/null +++ b/lib/zoeyscomputer_web/live/gist_live/og_image.ex @@ -0,0 +1,282 @@ +defmodule ZoeyscomputerWeb.GistLive.OgImage do + @moduledoc """ + Generates OpenGraph preview images for Gists using SVG with syntax highlighting. + """ + require Logger + + @external_resource "priv/static/fonts/WOFF2/Iosevka-Bold.woff2" + @external_resource "priv/static/fonts/WOFF2/Iosevka-Regular.woff2" + @font_bold File.read!("priv/static/fonts/WOFF2/Iosevka-Bold.woff2") + @font_regular File.read!("priv/static/fonts/WOFF2/Iosevka-Regular.woff2") + + @line_height 36 + @code_start_y 210 + @code_start_x 80 + @font_size 24 + @char_width 12 + @space_width @char_width + + defp font_face_styles do + """ + @font-face { + font-family: 'Iosevka'; + src: url(data:font/woff2;charset=utf-8;base64,#{Base.encode64(@font_regular)}) format('woff2'); + font-weight: 400; + font-style: normal; + } + + @font-face { + font-family: 'Iosevka'; + src: url(data:font/woff2;charset=utf-8;base64,#{Base.encode64(@font_bold)}) format('woff2'); + font-weight: 700; + font-style: normal; + } + """ + end + + def generate_preview(gist) do + code_lines = + gist.code + |> preview_code() + |> highlight_code(gist.lang) + |> render_code_lines() + + """ + + + + + + + + + + + + + + + + + + + #{escape_text(gist.title || "Gist: #{gist.id}")} + + + + #{escape_text(gist.desc || "No description")} + + + + + + + + #{code_lines} + + + + + + """ + end + + defp render_code_lines(highlighted_html) do + highlighted_html + |> String.split("\n") + |> Enum.with_index() + |> Enum.map_join("\n", fn {line, index} -> + indent_level = calculate_indent_level(line) + y_position = @code_start_y + index * @line_height + render_line(String.trim_leading(line), y_position, indent_level) + end) + end + + defp calculate_indent_level(line) do + leading_spaces = + line + |> String.replace(~r/^(\s+).*$/, "\\1") + |> String.length() + + if String.length(line) == leading_spaces do + div(0, 2) + else + div(leading_spaces, 2) + end + end + + defp render_line("", _y_position, _indent), do: "" + + defp render_line(line, y_position, indent_level) do + spans = parse_spans(line) + indent_offset = indent_level * 2 * @space_width + + spans + |> Enum.reduce({[], indent_offset}, fn {content, class}, {spans, x_offset} -> + unescaped_content = unescape_html(content) + span = render_span(unescaped_content, class, x_offset, y_position) + {[span | spans], x_offset + String.length(unescaped_content) * @char_width} + end) + |> elem(0) + |> Enum.reverse() + |> Enum.join("\n") + end + + defp unescape_html(text) do + text + |> String.replace("&", "&") + |> String.replace("<", "<") + |> String.replace(">", ">") + |> String.replace(""", "\"") + |> String.replace("'", "'") + |> String.replace("'", "'") + |> String.replace("/", "/") + |> String.replace("/", "/") + |> String.replace(" ", " ") + end + + defp parse_spans(""), do: [] + + defp parse_spans(line) do + line + |> String.split(~r{(|)}, include_captures: true) + |> Enum.reduce({[], nil}, fn + <<">, {acc, nil} -> + class = rest |> String.replace_suffix("\">", "") + {acc, class} + + "", {acc, _class} -> + {acc, nil} + + content, {acc, class} when byte_size(content) > 0 -> + {[{content, class || "default"} | acc], class} + + _, acc_class -> + acc_class + end) + |> elem(0) + |> Enum.reverse() + end + + defp render_span(content, class, x_offset, y_position) when byte_size(content) > 0 do + x = @code_start_x + x_offset + # Re-escape the content for the SVG output + safe_content = escape_text(content) + "#{safe_content}" + end + + defp render_span(_, _, _, _), do: "" + + defp preview_code(content) do + content + |> String.split("\n") + |> Enum.take(15) + |> Enum.join("\n") + end + + defp escape_text(text) do + text + |> String.replace("&", "&") + |> String.replace("<", "<") + |> String.replace(">", ">") + end + + defp highlight_code(code, language) when is_binary(language) do + lexer = get_lexer_for_language(language) + + String.trim( + code + |> Makeup.highlight_inner_html( + lexer: lexer, + formatter_opts: [ + highlight_tag: "span", + css_class: "makeup", + highlight_css_class: "hll" + ] + ) + |> to_string() + ) + end + + defp highlight_code(code, nil) do + escape_text(code) + end + + defp get_lexer_for_language(language) do + case language do + "elixir" -> Makeup.Lexers.ElixirLexer + "erlang" -> Makeup.Lexers.ErlangLexer + "html" -> Makeup.Lexers.HtmlLexer + "javascript" -> Makeup.Lexers.JsLexer + "python" -> Makeup.Lexers.PythonLexer + "ruby" -> Makeup.Lexers.RubyLexer + "rust" -> Makeup.Lexers.RustLexer + end + end + + def get_webp(gist) do + svg = generate_preview(gist) + tmp_svg_path = Path.join(System.tmp_dir(), "temp_#{:rand.uniform(999_999)}.svg") + + Logger.debug(tmp_svg_path) + + try do + File.write!(tmp_svg_path, svg) + + Logger.debug("wrote svg") + + try do + image = + tmp_svg_path + |> Mogrify.open() + |> Mogrify.custom("define", "svg:include-fonts=true") + |> Mogrify.format("webp") + |> Mogrify.save() + + Logger.debug("wrote image #{image.path}") + + {:ok, image_binary} = File.read(image.path) + + Logger.debug("returning binary") + + {:ok, image_binary} + rescue + e in Mogrify.Error -> + { + :error, + "Conversion failed: #{Exception.message(e)}" + } + end + rescue + e -> {:error, "File operation failed: #{Exception.message(e)}"} + after + File.rm(tmp_svg_path) + end + end +end diff --git a/lib/zoeyscomputer_web/live/gist_live/select.ex b/lib/zoeyscomputer_web/live/gist_live/select.ex new file mode 100644 index 0000000..7701ee9 --- /dev/null +++ b/lib/zoeyscomputer_web/live/gist_live/select.ex @@ -0,0 +1,125 @@ +defmodule ZoeyscomputerWeb.GistLive.Select do + use Phoenix.Component + + import Phoenix.HTML.Form, only: [input_value: 2] + + attr :id, :string, required: true + attr :form, :any, required: true + attr :field, :atom, required: true + attr :options, :list, required: true + attr :label, :string, default: nil + attr :prompt, :string, default: "Select an option..." + attr :class, :string, default: nil + attr :disabled, :boolean, default: false + + def select(assigns) do + selected_value = input_value(assigns.form, assigns.field) + + assigns = assign(assigns, :selected_value, selected_value) + + ~H""" +
"-container"} phx-hook="SelectHook"> + + + + +
"-dropdown"} + phx-update="ignore" + class={ + [ + "absolute z-10 mt-1 w-full rounded-md py-1 shadow-lg", + "bg-ctp-base border-ctp-surface0 border", + # Initially hidden, toggled by JS + "hidden" + ] + } + > +
+ "-search"} + placeholder="Search..." + class={[ + "w-full rounded-md py-1.5 px-3", + "bg-ctp-mantle text-ctp-text placeholder-ctp-overlay0", + "focus:outline-none focus:ring-2 focus:ring-offset-0 focus:ring-ctp-lavender", + "transition-colors duration-200" + ]} + /> +
+ +
    "-options"} role="listbox" tabindex="-1"> + <%= for {label, value} <- @options do %> +
  • + <%= label %> + <%= if to_string(value) == to_string(@selected_value) do %> + + + + + + <% end %> +
  • + <% end %> +
+
+ + +
+ """ + end + + defp selected_option(_options, value) when is_nil(value), do: nil + + defp selected_option(options, value) do + case Enum.find(options, fn {_label, val} -> to_string(val) == to_string(value) end) do + {label, _value} -> label + _ -> nil + end + end + + defp input_id(%{id: id}, field) when is_atom(field), do: "#{id}_#{field}" + defp input_name(%{name: name}, field), do: "#{name}[#{field}]" +end diff --git a/lib/zoeyscomputer_web/live/gist_live/show.ex b/lib/zoeyscomputer_web/live/gist_live/show.ex index 6013783..836264e 100644 --- a/lib/zoeyscomputer_web/live/gist_live/show.ex +++ b/lib/zoeyscomputer_web/live/gist_live/show.ex @@ -1,5 +1,6 @@ defmodule ZoeyscomputerWeb.GistLive.Show do use ZoeyscomputerWeb, :live_view + import ZoeyscomputerWeb.CodeBlock alias Zoeyscomputer.Gists diff --git a/lib/zoeyscomputer_web/live/gist_live/show.html.heex b/lib/zoeyscomputer_web/live/gist_live/show.html.heex index 5a428fd..3031c0a 100644 --- a/lib/zoeyscomputer_web/live/gist_live/show.html.heex +++ b/lib/zoeyscomputer_web/live/gist_live/show.html.heex @@ -1,17 +1,29 @@ <.header> - Gist <%= @gist.id %> + <%= @gist.title || "Gist: #{@gist.id}" %> <:subtitle>This is a gist record from your database. <:actions> - <.link patch={~p"/gists/#{@gist}/show/edit"} phx-click={JS.push_focus()}> - <.button>Edit gist - + <%= if(@current_user && @gist.author.email == @current_user.email) do %> + <.link patch={~p"/gists/#{@gist}/show/edit"} phx-click={JS.push_focus()}> + <.button>Edit gist + + <% end %> -<.list> - <:item title="Code"><%= @gist.code %> - <:item title="Lang"><%= @gist.lang %> - + + + + + + + +<.code_block + class="mt-4" + code={@gist.code} + language={@gist.lang} + title={@gist.title} + line_numbers={true} +/> <.back navigate={~p"/gists"}>Back to gists diff --git a/lib/zoeyscomputer_web/live/image_live/form_component.ex b/lib/zoeyscomputer_web/live/image_live/form_component.ex index 518f0c4..e2035a0 100644 --- a/lib/zoeyscomputer_web/live/image_live/form_component.ex +++ b/lib/zoeyscomputer_web/live/image_live/form_component.ex @@ -1,4 +1,6 @@ defmodule ZoeyscomputerWeb.ImageLive.FormComponent do + import Mogrify + alias Zoeyscomputer.IdGenerator use ZoeyscomputerWeb, :live_component alias Zoeyscomputer.Images @@ -19,7 +21,24 @@ defmodule ZoeyscomputerWeb.ImageLive.FormComponent do phx-change="validate" phx-submit="save" > - <.input field={@form[:file]} type="text" label="File" /> + <.live_file_input upload={@uploads.image} /> +
+ <%= for entry <- @uploads.image.entries do %> +
+
+ <.live_img_preview entry={entry} /> +
<%= entry.client_name %>
+
+ + <%= entry.progress %> + +
+ <% end %> + + <%= for err <- upload_errors(@uploads.image) do %> +

<%= error_to_string(err) %>

+ <% end %> +
<:actions> <.button phx-disable-with="Saving...">Save Image @@ -28,8 +47,18 @@ defmodule ZoeyscomputerWeb.ImageLive.FormComponent do """ end + defp error_to_string(:too_large), do: "Too Large" + defp error_to_string(:not_accepted), do: "Not Accepted" + + defp error_to_string(:too_manu_files), do: "Too many files!" + @impl true def update(%{image: image} = assigns, socket) do + socket = + socket + |> assign(:uploaded_files, []) + |> allow_upload(:image, accept: ~w(.jpg .jpeg .png), max_entries: 2) + {:ok, socket |> assign(assigns) @@ -44,8 +73,29 @@ defmodule ZoeyscomputerWeb.ImageLive.FormComponent do {:noreply, assign(socket, form: to_form(changeset, action: :validate))} end - def handle_event("save", %{"image" => image_params}, socket) do - save_image(socket, socket.assigns.action, image_params) + @impl true + def handle_event("save", _params, socket) do + uploaded_files = + consume_uploaded_entries(socket, :image, fn %{path: path}, _entry -> + dest = Path.join("/tmp/", Path.basename(path)) + File.cp(path, dest) + + handle_upload(dest) + end) + + update(socket, :uploaded_files, &(&1 ++ uploaded_files)) + + save_image(socket, socket.assigns.action, %{file: uploaded_files}) + end + + @impl true + def handle_event("validate", _params, socket) do + {:noreply, socket} + end + + @impl true + def handle_event("cancel-upload", %{"ref" => ref}, socket) do + {:noreply, cancel_upload(socket, :image, ref)} end defp save_image(socket, :edit, image_params) do @@ -63,6 +113,27 @@ defmodule ZoeyscomputerWeb.ImageLive.FormComponent do end end + defp handle_upload(path) do + id = IdGenerator.generate() + key = "uploads/#{id}.png" + bucket = "imgs" + + try do + image = open(path) |> format("png") |> save() + IO.inspect(image) + + {:ok, new_file_binary} = File.read(image.path) + + case ExAws.S3.put_object(bucket, key, new_file_binary, %{content_type: "image/png"}) + |> ExAws.request() do + {:ok, _response} -> {:ok, id} + {:error, reason} -> {:error, reason} + end + after + File.rm(path) + end + end + defp save_image(socket, :new, image_params) do case Images.create_image(image_params) do {:ok, image} -> diff --git a/lib/zoeyscomputer_web/live/image_live/index.ex b/lib/zoeyscomputer_web/live/image_live/index.ex index c109462..790e6e5 100644 --- a/lib/zoeyscomputer_web/live/image_live/index.ex +++ b/lib/zoeyscomputer_web/live/image_live/index.ex @@ -7,6 +7,7 @@ defmodule ZoeyscomputerWeb.ImageLive.Index do @impl true def mount(_params, _session, socket) do current_user = socket.assigns.current_user + {:ok, stream(socket, :images, Images.list_images_by_user(current_user))} end diff --git a/lib/zoeyscomputer_web/router.ex b/lib/zoeyscomputer_web/router.ex index 51b2023..e320851 100644 --- a/lib/zoeyscomputer_web/router.ex +++ b/lib/zoeyscomputer_web/router.ex @@ -110,6 +110,9 @@ defmodule ZoeyscomputerWeb.Router do live "/users/confirm", UserConfirmationInstructionsLive, :new live "/", HomeLive, :index + get "/gists/:id/preview", GistPreviewController, :show + get "/gists/:id/preview/raw", GistPreviewController, :raw + live "/images/:id", ImageLive.Show, :show live "/gists/:id", GistLive.Show, :show end diff --git a/mix.exs b/mix.exs index adb0120..2c92b67 100644 --- a/mix.exs +++ b/mix.exs @@ -47,6 +47,7 @@ defmodule Zoeyscomputer.MixProject do {:esbuild, "~> 0.8", runtime: Mix.env() == :dev}, {:tailwind, "~> 0.2", runtime: Mix.env() == :dev}, {:mogrify, "~> 0.9.3"}, + {:phoenix_html_helpers, "~> 1.0"}, {:heroicons, github: "tailwindlabs/heroicons", tag: "v2.1.1", @@ -54,6 +55,12 @@ defmodule Zoeyscomputer.MixProject do app: false, compile: false, depth: 1}, + {:makeup, "~> 1.1"}, + {:makeup_elixir, "~> 0.16"}, + {:makeup_erlang, "~> 0.1"}, + {:makeup_html, "~> 0.1"}, + {:makeup_js, "~> 0.1"}, + {:makeup_rust, "~> 0.3.0"}, {:swoosh, "~> 1.5"}, {:ex_aws, "~> 2.1"}, {:ex_aws_s3, "~> 2.0"}, diff --git a/mix.lock b/mix.lock index cf4aa5c..d8c9fbc 100644 --- a/mix.lock +++ b/mix.lock @@ -11,7 +11,7 @@ "ecto": {:hex, :ecto, "3.12.4", "267c94d9f2969e6acc4dd5e3e3af5b05cdae89a4d549925f3008b2b7eb0b93c3", [:mix], [{:decimal, "~> 2.0", [hex: :decimal, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}, {:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "ef04e4101688a67d061e1b10d7bc1fbf00d1d13c17eef08b71d070ff9188f747"}, "ecto_psql_extras": {:hex, :ecto_psql_extras, "0.8.2", "79350a53246ac5ec27326d208496aebceb77fa82a91744f66a9154560f0759d3", [:mix], [{:ecto_sql, "~> 3.7", [hex: :ecto_sql, repo: "hexpm", optional: false]}, {:postgrex, "> 0.16.0 and < 0.20.0", [hex: :postgrex, repo: "hexpm", optional: false]}, {:table_rex, "~> 3.1.1 or ~> 4.0.0", [hex: :table_rex, repo: "hexpm", optional: false]}], "hexpm", "6149c1c4a5ba6602a76cb09ee7a269eb60dab9694a1dbbb797f032555212de75"}, "ecto_sql": {:hex, :ecto_sql, "3.12.1", "c0d0d60e85d9ff4631f12bafa454bc392ce8b9ec83531a412c12a0d415a3a4d0", [:mix], [{:db_connection, "~> 2.4.1 or ~> 2.5", [hex: :db_connection, repo: "hexpm", optional: false]}, {:ecto, "~> 3.12", [hex: :ecto, repo: "hexpm", optional: false]}, {:myxql, "~> 0.7", [hex: :myxql, repo: "hexpm", optional: true]}, {:postgrex, "~> 0.19 or ~> 1.0", [hex: :postgrex, repo: "hexpm", optional: true]}, {:tds, "~> 2.1.1 or ~> 2.2", [hex: :tds, repo: "hexpm", optional: true]}, {:telemetry, "~> 0.4.0 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "aff5b958a899762c5f09028c847569f7dfb9cc9d63bdb8133bff8a5546de6bf5"}, - "elixir_make": {:hex, :elixir_make, "0.8.4", "4960a03ce79081dee8fe119d80ad372c4e7badb84c493cc75983f9d3bc8bde0f", [:mix], [{:castore, "~> 0.1 or ~> 1.0", [hex: :castore, repo: "hexpm", optional: true]}, {:certifi, "~> 2.0", [hex: :certifi, repo: "hexpm", optional: true]}], "hexpm", "6e7f1d619b5f61dfabd0a20aa268e575572b542ac31723293a4c1a567d5ef040"}, + "elixir_make": {:hex, :elixir_make, "0.7.8", "505026f266552ee5aabca0b9f9c229cbb496c689537c9f922f3eb5431157efc7", [:mix], [{:castore, "~> 0.1 or ~> 1.0", [hex: :castore, repo: "hexpm", optional: true]}, {:certifi, "~> 2.0", [hex: :certifi, repo: "hexpm", optional: true]}], "hexpm", "7a71945b913d37ea89b06966e1342c85cfe549b15e6d6d081e8081c493062c07"}, "esbuild": {:hex, :esbuild, "0.8.2", "5f379dfa383ef482b738e7771daf238b2d1cfb0222bef9d3b20d4c8f06c7a7ac", [:mix], [{:castore, ">= 0.0.0", [hex: :castore, repo: "hexpm", optional: false]}, {:jason, "~> 1.4", [hex: :jason, repo: "hexpm", optional: false]}], "hexpm", "558a8a08ed78eb820efbfda1de196569d8bfa9b51e8371a1934fbb31345feda7"}, "ex_aws": {:hex, :ex_aws, "2.5.6", "6f642e0f82eff10a9b470044f084b81a791cf15b393d647ea5f3e65da2794e3d", [:mix], [{:configparser_ex, "~> 4.0", [hex: :configparser_ex, repo: "hexpm", optional: true]}, {:hackney, "~> 1.16", [hex: :hackney, repo: "hexpm", optional: true]}, {:jason, "~> 1.1", [hex: :jason, repo: "hexpm", optional: true]}, {:jsx, "~> 2.8 or ~> 3.0", [hex: :jsx, repo: "hexpm", optional: true]}, {:mime, "~> 1.2 or ~> 2.0", [hex: :mime, repo: "hexpm", optional: false]}, {:req, "~> 0.3", [hex: :req, repo: "hexpm", optional: true]}, {:sweet_xml, "~> 0.7", [hex: :sweet_xml, repo: "hexpm", optional: true]}, {:telemetry, "~> 0.4.3 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "c69eec59e31fdd89d0beeb1d97e16518dd1b23ad95b3d5c9f1dcfec23d97f960"}, "ex_aws_s3": {:hex, :ex_aws_s3, "2.5.4", "87aaf4a2f24a48f516d7f5aaced9d128dd5d0f655c4431f9037a11a85c71109c", [:mix], [{:ex_aws, "~> 2.0", [hex: :ex_aws, repo: "hexpm", optional: false]}, {:sweet_xml, ">= 0.0.0", [hex: :sweet_xml, repo: "hexpm", optional: true]}], "hexpm", "c06e7f68b33f7c0acba1361dbd951c79661a28f85aa2e0582990fccca4425355"}, @@ -25,6 +25,12 @@ "hpax": {:hex, :hpax, "1.0.0", "28dcf54509fe2152a3d040e4e3df5b265dcb6cb532029ecbacf4ce52caea3fd2", [:mix], [], "hexpm", "7f1314731d711e2ca5fdc7fd361296593fc2542570b3105595bb0bc6d0fad601"}, "idna": {:hex, :idna, "6.1.1", "8a63070e9f7d0c62eb9d9fcb360a7de382448200fbbd1b106cc96d3d8099df8d", [:rebar3], [{:unicode_util_compat, "~> 0.7.0", [hex: :unicode_util_compat, repo: "hexpm", optional: false]}], "hexpm", "92376eb7894412ed19ac475e4a86f7b413c1b9fbb5bd16dccd57934157944cea"}, "jason": {:hex, :jason, "1.4.4", "b9226785a9aa77b6857ca22832cffa5d5011a667207eb2a0ad56adb5db443b8a", [:mix], [{:decimal, "~> 1.0 or ~> 2.0", [hex: :decimal, repo: "hexpm", optional: true]}], "hexpm", "c5eb0cab91f094599f94d55bc63409236a8ec69a21a67814529e8d5f6cc90b3b"}, + "makeup": {:hex, :makeup, "1.1.2", "9ba8837913bdf757787e71c1581c21f9d2455f4dd04cfca785c70bbfff1a76a3", [:mix], [{:nimble_parsec, "~> 1.2.2 or ~> 1.3", [hex: :nimble_parsec, repo: "hexpm", optional: false]}], "hexpm", "cce1566b81fbcbd21eca8ffe808f33b221f9eee2cbc7a1706fc3da9ff18e6cac"}, + "makeup_elixir": {:hex, :makeup_elixir, "0.16.2", "627e84b8e8bf22e60a2579dad15067c755531fea049ae26ef1020cad58fe9578", [:mix], [{:makeup, "~> 1.0", [hex: :makeup, repo: "hexpm", optional: false]}, {:nimble_parsec, "~> 1.2.3 or ~> 1.3", [hex: :nimble_parsec, repo: "hexpm", optional: false]}], "hexpm", "41193978704763f6bbe6cc2758b84909e62984c7752b3784bd3c218bb341706b"}, + "makeup_erlang": {:hex, :makeup_erlang, "0.1.5", "e0ff5a7c708dda34311f7522a8758e23bfcd7d8d8068dc312b5eb41c6fd76eba", [:mix], [{:makeup, "~> 1.0", [hex: :makeup, repo: "hexpm", optional: false]}], "hexpm", "94d2e986428585a21516d7d7149781480013c56e30c6a233534bedf38867a59a"}, + "makeup_html": {:hex, :makeup_html, "0.1.1", "c3d4abd39d5f7e925faca72ada6e9cc5c6f5fa7cd5bc0158315832656cf14d7f", [:mix], [{:makeup, "~> 1.0", [hex: :makeup, repo: "hexpm", optional: false]}], "hexpm", "44f2a61bc5243645dd7fafeaa6cc28793cd22f3c76b861e066168f9a5b2c26a4"}, + "makeup_js": {:hex, :makeup_js, "0.1.0", "ffa8ce9db95d14dcd09045334539d5992d540d63598c592d4805b7674bdd6675", [:mix], [{:makeup, "~> 1.0", [hex: :makeup, repo: "hexpm", optional: false]}], "hexpm", "3f0c1a5eb52c9737b1679c926574e83bb260ccdedf08b58ee96cca7c685dea75"}, + "makeup_rust": {:hex, :makeup_rust, "0.3.0", "6fc4a6a1508a7fbea35d08f15c19bb3ae3a3d62ffd2aaca7ee4825a8b1204cef", [:mix], [{:makeup, "~> 1.1", [hex: :makeup, repo: "hexpm", optional: false]}, {:nimble_parsec, "~> 1.4.0", [hex: :nimble_parsec, repo: "hexpm", optional: false]}], "hexpm", "1e79ee1995a3b9df9b7d90af7dc02525989efc41390a52065c23782c94ea94e1"}, "metrics": {:hex, :metrics, "1.0.1", "25f094dea2cda98213cecc3aeff09e940299d950904393b2a29d191c346a8486", [:rebar3], [], "hexpm", "69b09adddc4f74a40716ae54d140f93beb0fb8978d8636eaded0c31b6f099f16"}, "mime": {:hex, :mime, "2.0.6", "8f18486773d9b15f95f4f4f1e39b710045fa1de891fada4516559967276e4dc2", [:mix], [], "hexpm", "c9945363a6b26d747389aac3643f8e0e09d30499a138ad64fe8fd1d13d9b153e"}, "mimerl": {:hex, :mimerl, "1.3.0", "d0cd9fc04b9061f82490f6581e0128379830e78535e017f7780f37fea7545726", [:rebar3], [], "hexpm", "a1e15a50d1887217de95f0b9b0793e32853f7c258a5cd227650889b38839fe9d"}, @@ -32,11 +38,13 @@ "mogrify": {:hex, :mogrify, "0.9.3", "238c782f00271dace01369ad35ae2e9dd020feee3443b9299ea5ea6bed559841", [:mix], [], "hexpm", "0189b1e1de27455f2b9ae8cf88239cefd23d38de9276eb5add7159aea51731e6"}, "nanoid": {:hex, :nanoid, "2.1.0", "d192a5bf1d774258bc49762b480fca0e3128178fa6d35a464af2a738526607fd", [:mix], [], "hexpm", "ebc7a342d02d213534a7f93a091d569b9fea7f26fcd3a638dc655060fc1f76ac"}, "nimble_options": {:hex, :nimble_options, "1.1.1", "e3a492d54d85fc3fd7c5baf411d9d2852922f66e69476317787a7b2bb000a61b", [:mix], [], "hexpm", "821b2470ca9442c4b6984882fe9bb0389371b8ddec4d45a9504f00a66f650b44"}, + "nimble_parsec": {:hex, :nimble_parsec, "1.4.0", "51f9b613ea62cfa97b25ccc2c1b4216e81df970acd8e16e8d1bdc58fef21370d", [:mix], [], "hexpm", "9c565862810fb383e9838c1dd2d7d2c437b3d13b267414ba6af33e50d2d1cf28"}, "nimble_pool": {:hex, :nimble_pool, "1.1.0", "bf9c29fbdcba3564a8b800d1eeb5a3c58f36e1e11d7b7fb2e084a643f645f06b", [:mix], [], "hexpm", "af2e4e6b34197db81f7aad230c1118eac993acc0dae6bc83bac0126d4ae0813a"}, "parse_trans": {:hex, :parse_trans, "3.4.1", "6e6aa8167cb44cc8f39441d05193be6e6f4e7c2946cb2759f015f8c56b76e5ff", [:rebar3], [], "hexpm", "620a406ce75dada827b82e453c19cf06776be266f5a67cff34e1ef2cbb60e49a"}, "phoenix": {:hex, :phoenix, "1.7.14", "a7d0b3f1bc95987044ddada111e77bd7f75646a08518942c72a8440278ae7825", [:mix], [{:castore, ">= 0.0.0", [hex: :castore, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}, {:phoenix_pubsub, "~> 2.1", [hex: :phoenix_pubsub, repo: "hexpm", optional: false]}, {:phoenix_template, "~> 1.0", [hex: :phoenix_template, repo: "hexpm", optional: false]}, {:phoenix_view, "~> 2.0", [hex: :phoenix_view, repo: "hexpm", optional: true]}, {:plug, "~> 1.14", [hex: :plug, repo: "hexpm", optional: false]}, {:plug_cowboy, "~> 2.7", [hex: :plug_cowboy, repo: "hexpm", optional: true]}, {:plug_crypto, "~> 1.2 or ~> 2.0", [hex: :plug_crypto, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}, {:websock_adapter, "~> 0.5.3", [hex: :websock_adapter, repo: "hexpm", optional: false]}], "hexpm", "c7859bc56cc5dfef19ecfc240775dae358cbaa530231118a9e014df392ace61a"}, "phoenix_ecto": {:hex, :phoenix_ecto, "4.6.2", "3b83b24ab5a2eb071a20372f740d7118767c272db386831b2e77638c4dcc606d", [:mix], [{:ecto, "~> 3.5", [hex: :ecto, repo: "hexpm", optional: false]}, {:phoenix_html, "~> 2.14.2 or ~> 3.0 or ~> 4.1", [hex: :phoenix_html, repo: "hexpm", optional: true]}, {:plug, "~> 1.9", [hex: :plug, repo: "hexpm", optional: false]}, {:postgrex, "~> 0.16 or ~> 1.0", [hex: :postgrex, repo: "hexpm", optional: true]}], "hexpm", "3f94d025f59de86be00f5f8c5dd7b5965a3298458d21ab1c328488be3b5fcd59"}, "phoenix_html": {:hex, :phoenix_html, "4.1.1", "4c064fd3873d12ebb1388425a8f2a19348cef56e7289e1998e2d2fa758aa982e", [:mix], [], "hexpm", "f2f2df5a72bc9a2f510b21497fd7d2b86d932ec0598f0210fed4114adc546c6f"}, + "phoenix_html_helpers": {:hex, :phoenix_html_helpers, "1.0.1", "7eed85c52eff80a179391036931791ee5d2f713d76a81d0d2c6ebafe1e11e5ec", [:mix], [{:phoenix_html, "~> 4.0", [hex: :phoenix_html, repo: "hexpm", optional: false]}, {:plug, "~> 1.5", [hex: :plug, repo: "hexpm", optional: true]}], "hexpm", "cffd2385d1fa4f78b04432df69ab8da63dc5cf63e07b713a4dcf36a3740e3090"}, "phoenix_live_dashboard": {:hex, :phoenix_live_dashboard, "0.8.4", "4508e481f791ce62ec6a096e13b061387158cbeefacca68c6c1928e1305e23ed", [:mix], [{:ecto, "~> 3.6.2 or ~> 3.7", [hex: :ecto, repo: "hexpm", optional: true]}, {:ecto_mysql_extras, "~> 0.5", [hex: :ecto_mysql_extras, repo: "hexpm", optional: true]}, {:ecto_psql_extras, "~> 0.7", [hex: :ecto_psql_extras, repo: "hexpm", optional: true]}, {:ecto_sqlite3_extras, "~> 1.1.7 or ~> 1.2.0", [hex: :ecto_sqlite3_extras, repo: "hexpm", optional: true]}, {:mime, "~> 1.6 or ~> 2.0", [hex: :mime, repo: "hexpm", optional: false]}, {:phoenix_live_view, "~> 0.19 or ~> 1.0", [hex: :phoenix_live_view, repo: "hexpm", optional: false]}, {:telemetry_metrics, "~> 0.6 or ~> 1.0", [hex: :telemetry_metrics, repo: "hexpm", optional: false]}], "hexpm", "2984aae96994fbc5c61795a73b8fb58153b41ff934019cfb522343d2d3817d59"}, "phoenix_live_reload": {:hex, :phoenix_live_reload, "1.5.3", "f2161c207fda0e4fb55165f650f7f8db23f02b29e3bff00ff7ef161d6ac1f09d", [:mix], [{:file_system, "~> 0.3 or ~> 1.0", [hex: :file_system, repo: "hexpm", optional: false]}, {:phoenix, "~> 1.4", [hex: :phoenix, repo: "hexpm", optional: false]}], "hexpm", "b4ec9cd73cb01ff1bd1cac92e045d13e7030330b74164297d1aee3907b54803c"}, "phoenix_live_view": {:hex, :phoenix_live_view, "1.0.0-rc.7", "d2abca526422adea88896769529addb6443390b1d4f1ff9cbe694312d8875fb2", [:mix], [{:floki, "~> 0.36", [hex: :floki, repo: "hexpm", optional: true]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}, {:phoenix, "~> 1.6.15 or ~> 1.7.0", [hex: :phoenix, repo: "hexpm", optional: false]}, {:phoenix_html, "~> 3.3 or ~> 4.0", [hex: :phoenix_html, repo: "hexpm", optional: false]}, {:phoenix_template, "~> 1.0", [hex: :phoenix_template, repo: "hexpm", optional: false]}, {:phoenix_view, "~> 2.0", [hex: :phoenix_view, repo: "hexpm", optional: true]}, {:plug, "~> 1.15", [hex: :plug, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4.2 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "b82a4575f6f3eb5b97922ec6874b0c52b3ca0cc5dcb4b14ddc478cbfa135dd01"}, @@ -45,6 +53,7 @@ "plug": {:hex, :plug, "1.16.1", "40c74619c12f82736d2214557dedec2e9762029b2438d6d175c5074c933edc9d", [:mix], [{:mime, "~> 1.0 or ~> 2.0", [hex: :mime, repo: "hexpm", optional: false]}, {:plug_crypto, "~> 1.1.1 or ~> 1.2 or ~> 2.0", [hex: :plug_crypto, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4.3 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "a13ff6b9006b03d7e33874945b2755253841b238c34071ed85b0e86057f8cddc"}, "plug_crypto": {:hex, :plug_crypto, "2.1.0", "f44309c2b06d249c27c8d3f65cfe08158ade08418cf540fd4f72d4d6863abb7b", [:mix], [], "hexpm", "131216a4b030b8f8ce0f26038bc4421ae60e4bb95c5cf5395e1421437824c4fa"}, "postgrex": {:hex, :postgrex, "0.19.1", "73b498508b69aded53907fe48a1fee811be34cc720e69ef4ccd568c8715495ea", [:mix], [{:db_connection, "~> 2.1", [hex: :db_connection, repo: "hexpm", optional: false]}, {:decimal, "~> 1.5 or ~> 2.0", [hex: :decimal, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}, {:table, "~> 0.1.0", [hex: :table, repo: "hexpm", optional: true]}], "hexpm", "8bac7885a18f381e091ec6caf41bda7bb8c77912bb0e9285212829afe5d8a8f8"}, + "rsvg": {:git, "https://github.com/teamon/rsvg.git", "fa9505fa332e9d5da15f80c08f616a4136079735", []}, "ssl_verify_fun": {:hex, :ssl_verify_fun, "1.1.7", "354c321cf377240c7b8716899e182ce4890c5938111a1296add3ec74cf1715df", [:make, :mix, :rebar3], [], "hexpm", "fe4c190e8f37401d30167c8c405eda19469f34577987c76dde613e838bbc67f8"}, "sweet_xml": {:hex, :sweet_xml, "0.7.4", "a8b7e1ce7ecd775c7e8a65d501bc2cd933bff3a9c41ab763f5105688ef485d08", [:mix], [], "hexpm", "e7c4b0bdbf460c928234951def54fe87edf1a170f6896675443279e2dbeba167"}, "swoosh": {:hex, :swoosh, "1.17.2", "73611f08fc7cb9fa15f4909db36eeb12b70727d5c8b6a7fa0d4a31c6575db29e", [:mix], [{:bandit, ">= 1.0.0", [hex: :bandit, repo: "hexpm", optional: true]}, {:cowboy, "~> 1.1 or ~> 2.4", [hex: :cowboy, repo: "hexpm", optional: true]}, {:ex_aws, "~> 2.1", [hex: :ex_aws, repo: "hexpm", optional: true]}, {:finch, "~> 0.6", [hex: :finch, repo: "hexpm", optional: true]}, {:gen_smtp, "~> 0.13 or ~> 1.0", [hex: :gen_smtp, repo: "hexpm", optional: true]}, {:hackney, "~> 1.9", [hex: :hackney, repo: "hexpm", optional: true]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}, {:mail, "~> 0.2", [hex: :mail, repo: "hexpm", optional: true]}, {:mime, "~> 1.1 or ~> 2.0", [hex: :mime, repo: "hexpm", optional: false]}, {:mua, "~> 0.2.3", [hex: :mua, repo: "hexpm", optional: true]}, {:multipart, "~> 0.4", [hex: :multipart, repo: "hexpm", optional: true]}, {:plug, "~> 1.9", [hex: :plug, repo: "hexpm", optional: true]}, {:plug_cowboy, ">= 1.0.0", [hex: :plug_cowboy, repo: "hexpm", optional: true]}, {:req, "~> 0.5 or ~> 1.0", [hex: :req, repo: "hexpm", optional: true]}, {:telemetry, "~> 0.4.2 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "de914359f0ddc134dc0d7735e28922d49d0503f31e4bd66b44e26039c2226d39"}, diff --git a/priv/repo/migrations/20241026212840_update_gists_code_type.exs b/priv/repo/migrations/20241026212840_update_gists_code_type.exs new file mode 100644 index 0000000..2296547 --- /dev/null +++ b/priv/repo/migrations/20241026212840_update_gists_code_type.exs @@ -0,0 +1,9 @@ +defmodule Zoeyscomputer.Repo.Migrations.UpdateGistsCodeType do + use Ecto.Migration + + def change do + alter table(:gists) do + modify :code, :text + end + end +end diff --git a/priv/repo/migrations/20241026223550_add_gists_info.exs b/priv/repo/migrations/20241026223550_add_gists_info.exs new file mode 100644 index 0000000..f2c3c8a --- /dev/null +++ b/priv/repo/migrations/20241026223550_add_gists_info.exs @@ -0,0 +1,10 @@ +defmodule Zoeyscomputer.Repo.Migrations.AddGistsInfo do + use Ecto.Migration + + def change do + alter table(:gists) do + add :title, :string + add :desc, :text + end + end +end diff --git a/priv/repo/migrations/20241027003540_change_gists_id.exs b/priv/repo/migrations/20241027003540_change_gists_id.exs new file mode 100644 index 0000000..0bb1c89 --- /dev/null +++ b/priv/repo/migrations/20241027003540_change_gists_id.exs @@ -0,0 +1,26 @@ +defmodule Zoeyscomputer.Repo.Migrations.ChangeGistsId do + alias Ecto.Repo + alias Zoeyscomputer.IdGenerator + use Ecto.Migration + + import Ecto.Query, only: [from: 2] + + def change do + alter table(:gists) do + add(:new_id, :string) + end + + flush() + + execute """ + UPDATE gists SET new_id = substring(md5(random()::text), 0, 8) + """ + + alter table(:gists) do + remove(:id) + modify(:new_id, :string, primary_key: true) + end + + rename(table(:gists), :new_id, to: :id) + end +end diff --git a/priv/repo/migrations/20241027005245_gists_author_field.exs b/priv/repo/migrations/20241027005245_gists_author_field.exs new file mode 100644 index 0000000..f865814 --- /dev/null +++ b/priv/repo/migrations/20241027005245_gists_author_field.exs @@ -0,0 +1,9 @@ +defmodule Zoeyscomputer.Repo.Migrations.GistsAuthorField do + use Ecto.Migration + + def change do + alter table(:gists) do + add :author_id, references(:users, on_delete: :nothing) + end + end +end diff --git a/priv/static/fonts/Iosevka.css b/priv/static/fonts/Iosevka.css index f9f3062..5c19018 100644 --- a/priv/static/fonts/Iosevka.css +++ b/priv/static/fonts/Iosevka.css @@ -5,7 +5,7 @@ font-weight: 100; font-stretch: normal; font-style: normal; - src: url('WOFF2/Iosevka-Thin.woff2') format('woff2'), url('TTF/Iosevka-Thin.ttf') format('truetype'); + src: url('/fonts/WOFF2/Iosevka-Thin.woff2') format('woff2'), url('TTF/Iosevka-Thin.ttf') format('truetype'); } @font-face { @@ -14,7 +14,7 @@ font-weight: 100; font-stretch: expanded; font-style: normal; - src: url('WOFF2/Iosevka-ExtendedThin.woff2') format('woff2'), url('TTF/Iosevka-ExtendedThin.ttf') format('truetype'); + src: url('/fonts/WOFF2/Iosevka-ExtendedThin.woff2') format('woff2'), url('TTF/Iosevka-ExtendedThin.ttf') format('truetype'); } @font-face { @@ -23,7 +23,7 @@ font-weight: 100; font-stretch: normal; font-style: oblique; - src: url('WOFF2/Iosevka-ThinOblique.woff2') format('woff2'), url('TTF/Iosevka-ThinOblique.ttf') format('truetype'); + src: url('/fonts/WOFF2/Iosevka-ThinOblique.woff2') format('woff2'), url('TTF/Iosevka-ThinOblique.ttf') format('truetype'); } @font-face { @@ -31,7 +31,7 @@ font-display: swap; font-weight: 100; font-stretch: normal; - src: url('WOFF2/Iosevka-ThinOblique.woff2') format('woff2'), url('TTF/Iosevka-ThinOblique.ttf') format('truetype'); + src: url('/fonts/WOFF2/Iosevka-ThinOblique.woff2') format('woff2'), url('TTF/Iosevka-ThinOblique.ttf') format('truetype'); } @font-face { @@ -40,7 +40,7 @@ font-weight: 100; font-stretch: expanded; font-style: oblique; - src: url('WOFF2/Iosevka-ExtendedThinOblique.woff2') format('woff2'), url('TTF/Iosevka-ExtendedThinOblique.ttf') format('truetype'); + src: url('/fonts/WOFF2/Iosevka-ExtendedThinOblique.woff2') format('woff2'), url('TTF/Iosevka-ExtendedThinOblique.ttf') format('truetype'); } @font-face { @@ -48,7 +48,7 @@ font-display: swap; font-weight: 100; font-stretch: expanded; - src: url('WOFF2/Iosevka-ExtendedThinOblique.woff2') format('woff2'), url('TTF/Iosevka-ExtendedThinOblique.ttf') format('truetype'); + src: url('/fonts/WOFF2/Iosevka-ExtendedThinOblique.woff2') format('woff2'), url('TTF/Iosevka-ExtendedThinOblique.ttf') format('truetype'); } @font-face { @@ -57,7 +57,7 @@ font-weight: 100; font-stretch: normal; font-style: italic; - src: url('WOFF2/Iosevka-ThinItalic.woff2') format('woff2'), url('TTF/Iosevka-ThinItalic.ttf') format('truetype'); + src: url('/fonts/WOFF2/Iosevka-ThinItalic.woff2') format('woff2'), url('TTF/Iosevka-ThinItalic.ttf') format('truetype'); } @font-face { @@ -66,7 +66,7 @@ font-weight: 100; font-stretch: expanded; font-style: italic; - src: url('WOFF2/Iosevka-ExtendedThinItalic.woff2') format('woff2'), url('TTF/Iosevka-ExtendedThinItalic.ttf') format('truetype'); + src: url('/fonts/WOFF2/Iosevka-ExtendedThinItalic.woff2') format('woff2'), url('TTF/Iosevka-ExtendedThinItalic.ttf') format('truetype'); } @font-face { @@ -75,7 +75,7 @@ font-weight: 200; font-stretch: normal; font-style: normal; - src: url('WOFF2/Iosevka-ExtraLight.woff2') format('woff2'), url('TTF/Iosevka-ExtraLight.ttf') format('truetype'); + src: url('/fonts/WOFF2/Iosevka-ExtraLight.woff2') format('woff2'), url('TTF/Iosevka-ExtraLight.ttf') format('truetype'); } @font-face { @@ -84,7 +84,7 @@ font-weight: 200; font-stretch: expanded; font-style: normal; - src: url('WOFF2/Iosevka-ExtendedExtraLight.woff2') format('woff2'), url('TTF/Iosevka-ExtendedExtraLight.ttf') format('truetype'); + src: url('/fonts/WOFF2/Iosevka-ExtendedExtraLight.woff2') format('woff2'), url('TTF/Iosevka-ExtendedExtraLight.ttf') format('truetype'); } @font-face { @@ -93,7 +93,7 @@ font-weight: 200; font-stretch: normal; font-style: oblique; - src: url('WOFF2/Iosevka-ExtraLightOblique.woff2') format('woff2'), url('TTF/Iosevka-ExtraLightOblique.ttf') format('truetype'); + src: url('/fonts/WOFF2/Iosevka-ExtraLightOblique.woff2') format('woff2'), url('TTF/Iosevka-ExtraLightOblique.ttf') format('truetype'); } @font-face { @@ -101,7 +101,7 @@ font-display: swap; font-weight: 200; font-stretch: normal; - src: url('WOFF2/Iosevka-ExtraLightOblique.woff2') format('woff2'), url('TTF/Iosevka-ExtraLightOblique.ttf') format('truetype'); + src: url('/fonts/WOFF2/Iosevka-ExtraLightOblique.woff2') format('woff2'), url('TTF/Iosevka-ExtraLightOblique.ttf') format('truetype'); } @font-face { @@ -110,7 +110,7 @@ font-weight: 200; font-stretch: expanded; font-style: oblique; - src: url('WOFF2/Iosevka-ExtendedExtraLightOblique.woff2') format('woff2'), url('TTF/Iosevka-ExtendedExtraLightOblique.ttf') format('truetype'); + src: url('/fonts/WOFF2/Iosevka-ExtendedExtraLightOblique.woff2') format('woff2'), url('TTF/Iosevka-ExtendedExtraLightOblique.ttf') format('truetype'); } @font-face { @@ -118,7 +118,7 @@ font-display: swap; font-weight: 200; font-stretch: expanded; - src: url('WOFF2/Iosevka-ExtendedExtraLightOblique.woff2') format('woff2'), url('TTF/Iosevka-ExtendedExtraLightOblique.ttf') format('truetype'); + src: url('/fonts/WOFF2/Iosevka-ExtendedExtraLightOblique.woff2') format('woff2'), url('TTF/Iosevka-ExtendedExtraLightOblique.ttf') format('truetype'); } @font-face { @@ -127,7 +127,7 @@ font-weight: 200; font-stretch: normal; font-style: italic; - src: url('WOFF2/Iosevka-ExtraLightItalic.woff2') format('woff2'), url('TTF/Iosevka-ExtraLightItalic.ttf') format('truetype'); + src: url('/fonts/WOFF2/Iosevka-ExtraLightItalic.woff2') format('woff2'), url('TTF/Iosevka-ExtraLightItalic.ttf') format('truetype'); } @font-face { @@ -136,7 +136,7 @@ font-weight: 200; font-stretch: expanded; font-style: italic; - src: url('WOFF2/Iosevka-ExtendedExtraLightItalic.woff2') format('woff2'), url('TTF/Iosevka-ExtendedExtraLightItalic.ttf') format('truetype'); + src: url('/fonts/WOFF2/Iosevka-ExtendedExtraLightItalic.woff2') format('woff2'), url('TTF/Iosevka-ExtendedExtraLightItalic.ttf') format('truetype'); } @font-face { @@ -145,7 +145,7 @@ font-weight: 300; font-stretch: normal; font-style: normal; - src: url('WOFF2/Iosevka-Light.woff2') format('woff2'), url('TTF/Iosevka-Light.ttf') format('truetype'); + src: url('/fonts/WOFF2/Iosevka-Light.woff2') format('woff2'), url('TTF/Iosevka-Light.ttf') format('truetype'); } @font-face { @@ -154,7 +154,7 @@ font-weight: 300; font-stretch: expanded; font-style: normal; - src: url('WOFF2/Iosevka-ExtendedLight.woff2') format('woff2'), url('TTF/Iosevka-ExtendedLight.ttf') format('truetype'); + src: url('/fonts/WOFF2/Iosevka-ExtendedLight.woff2') format('woff2'), url('TTF/Iosevka-ExtendedLight.ttf') format('truetype'); } @font-face { @@ -163,7 +163,7 @@ font-weight: 300; font-stretch: normal; font-style: oblique; - src: url('WOFF2/Iosevka-LightOblique.woff2') format('woff2'), url('TTF/Iosevka-LightOblique.ttf') format('truetype'); + src: url('/fonts/WOFF2/Iosevka-LightOblique.woff2') format('woff2'), url('TTF/Iosevka-LightOblique.ttf') format('truetype'); } @font-face { @@ -171,7 +171,7 @@ font-display: swap; font-weight: 300; font-stretch: normal; - src: url('WOFF2/Iosevka-LightOblique.woff2') format('woff2'), url('TTF/Iosevka-LightOblique.ttf') format('truetype'); + src: url('/fonts/WOFF2/Iosevka-LightOblique.woff2') format('woff2'), url('TTF/Iosevka-LightOblique.ttf') format('truetype'); } @font-face { @@ -180,7 +180,7 @@ font-weight: 300; font-stretch: expanded; font-style: oblique; - src: url('WOFF2/Iosevka-ExtendedLightOblique.woff2') format('woff2'), url('TTF/Iosevka-ExtendedLightOblique.ttf') format('truetype'); + src: url('/fonts/WOFF2/Iosevka-ExtendedLightOblique.woff2') format('woff2'), url('TTF/Iosevka-ExtendedLightOblique.ttf') format('truetype'); } @font-face { @@ -188,7 +188,7 @@ font-display: swap; font-weight: 300; font-stretch: expanded; - src: url('WOFF2/Iosevka-ExtendedLightOblique.woff2') format('woff2'), url('TTF/Iosevka-ExtendedLightOblique.ttf') format('truetype'); + src: url('/fonts/WOFF2/Iosevka-ExtendedLightOblique.woff2') format('woff2'), url('TTF/Iosevka-ExtendedLightOblique.ttf') format('truetype'); } @font-face { @@ -197,7 +197,7 @@ font-weight: 300; font-stretch: normal; font-style: italic; - src: url('WOFF2/Iosevka-LightItalic.woff2') format('woff2'), url('TTF/Iosevka-LightItalic.ttf') format('truetype'); + src: url('/fonts/WOFF2/Iosevka-LightItalic.woff2') format('woff2'), url('TTF/Iosevka-LightItalic.ttf') format('truetype'); } @font-face { @@ -206,7 +206,7 @@ font-weight: 300; font-stretch: expanded; font-style: italic; - src: url('WOFF2/Iosevka-ExtendedLightItalic.woff2') format('woff2'), url('TTF/Iosevka-ExtendedLightItalic.ttf') format('truetype'); + src: url('/fonts/WOFF2/Iosevka-ExtendedLightItalic.woff2') format('woff2'), url('TTF/Iosevka-ExtendedLightItalic.ttf') format('truetype'); } @font-face { @@ -215,7 +215,7 @@ font-weight: 400; font-stretch: normal; font-style: normal; - src: url('WOFF2/Iosevka-Regular.woff2') format('woff2'), url('TTF/Iosevka-Regular.ttf') format('truetype'); + src: url('/fonts/WOFF2/Iosevka-Regular.woff2') format('woff2'), url('TTF/Iosevka-Regular.ttf') format('truetype'); } @font-face { @@ -224,7 +224,7 @@ font-weight: 400; font-stretch: expanded; font-style: normal; - src: url('WOFF2/Iosevka-Extended.woff2') format('woff2'), url('TTF/Iosevka-Extended.ttf') format('truetype'); + src: url('/fonts/WOFF2/Iosevka-Extended.woff2') format('woff2'), url('TTF/Iosevka-Extended.ttf') format('truetype'); } @font-face { @@ -233,7 +233,7 @@ font-weight: 400; font-stretch: normal; font-style: oblique; - src: url('WOFF2/Iosevka-Oblique.woff2') format('woff2'), url('TTF/Iosevka-Oblique.ttf') format('truetype'); + src: url('/fonts/WOFF2/Iosevka-Oblique.woff2') format('woff2'), url('TTF/Iosevka-Oblique.ttf') format('truetype'); } @font-face { @@ -241,7 +241,7 @@ font-display: swap; font-weight: 400; font-stretch: normal; - src: url('WOFF2/Iosevka-Oblique.woff2') format('woff2'), url('TTF/Iosevka-Oblique.ttf') format('truetype'); + src: url('/fonts/WOFF2/Iosevka-Oblique.woff2') format('woff2'), url('TTF/Iosevka-Oblique.ttf') format('truetype'); } @font-face { @@ -250,7 +250,7 @@ font-weight: 400; font-stretch: expanded; font-style: oblique; - src: url('WOFF2/Iosevka-ExtendedOblique.woff2') format('woff2'), url('TTF/Iosevka-ExtendedOblique.ttf') format('truetype'); + src: url('/fonts/WOFF2/Iosevka-ExtendedOblique.woff2') format('woff2'), url('TTF/Iosevka-ExtendedOblique.ttf') format('truetype'); } @font-face { @@ -258,7 +258,7 @@ font-display: swap; font-weight: 400; font-stretch: expanded; - src: url('WOFF2/Iosevka-ExtendedOblique.woff2') format('woff2'), url('TTF/Iosevka-ExtendedOblique.ttf') format('truetype'); + src: url('/fonts/WOFF2/Iosevka-ExtendedOblique.woff2') format('woff2'), url('TTF/Iosevka-ExtendedOblique.ttf') format('truetype'); } @font-face { @@ -267,7 +267,7 @@ font-weight: 400; font-stretch: normal; font-style: italic; - src: url('WOFF2/Iosevka-Italic.woff2') format('woff2'), url('TTF/Iosevka-Italic.ttf') format('truetype'); + src: url('/fonts/WOFF2/Iosevka-Italic.woff2') format('woff2'), url('TTF/Iosevka-Italic.ttf') format('truetype'); } @font-face { @@ -276,7 +276,7 @@ font-weight: 400; font-stretch: expanded; font-style: italic; - src: url('WOFF2/Iosevka-ExtendedItalic.woff2') format('woff2'), url('TTF/Iosevka-ExtendedItalic.ttf') format('truetype'); + src: url('/fonts/WOFF2/Iosevka-ExtendedItalic.woff2') format('woff2'), url('TTF/Iosevka-ExtendedItalic.ttf') format('truetype'); } @font-face { @@ -285,7 +285,7 @@ font-weight: 500; font-stretch: normal; font-style: normal; - src: url('WOFF2/Iosevka-Medium.woff2') format('woff2'), url('TTF/Iosevka-Medium.ttf') format('truetype'); + src: url('/fonts/WOFF2/Iosevka-Medium.woff2') format('woff2'), url('TTF/Iosevka-Medium.ttf') format('truetype'); } @font-face { @@ -294,7 +294,7 @@ font-weight: 500; font-stretch: expanded; font-style: normal; - src: url('WOFF2/Iosevka-ExtendedMedium.woff2') format('woff2'), url('TTF/Iosevka-ExtendedMedium.ttf') format('truetype'); + src: url('/fonts/WOFF2/Iosevka-ExtendedMedium.woff2') format('woff2'), url('TTF/Iosevka-ExtendedMedium.ttf') format('truetype'); } @font-face { @@ -303,7 +303,7 @@ font-weight: 500; font-stretch: normal; font-style: oblique; - src: url('WOFF2/Iosevka-MediumOblique.woff2') format('woff2'), url('TTF/Iosevka-MediumOblique.ttf') format('truetype'); + src: url('/fonts/WOFF2/Iosevka-MediumOblique.woff2') format('woff2'), url('TTF/Iosevka-MediumOblique.ttf') format('truetype'); } @font-face { @@ -311,7 +311,7 @@ font-display: swap; font-weight: 500; font-stretch: normal; - src: url('WOFF2/Iosevka-MediumOblique.woff2') format('woff2'), url('TTF/Iosevka-MediumOblique.ttf') format('truetype'); + src: url('/fonts/WOFF2/Iosevka-MediumOblique.woff2') format('woff2'), url('TTF/Iosevka-MediumOblique.ttf') format('truetype'); } @font-face { @@ -320,7 +320,7 @@ font-weight: 500; font-stretch: expanded; font-style: oblique; - src: url('WOFF2/Iosevka-ExtendedMediumOblique.woff2') format('woff2'), url('TTF/Iosevka-ExtendedMediumOblique.ttf') format('truetype'); + src: url('/fonts/WOFF2/Iosevka-ExtendedMediumOblique.woff2') format('woff2'), url('TTF/Iosevka-ExtendedMediumOblique.ttf') format('truetype'); } @font-face { @@ -328,7 +328,7 @@ font-display: swap; font-weight: 500; font-stretch: expanded; - src: url('WOFF2/Iosevka-ExtendedMediumOblique.woff2') format('woff2'), url('TTF/Iosevka-ExtendedMediumOblique.ttf') format('truetype'); + src: url('/fonts/WOFF2/Iosevka-ExtendedMediumOblique.woff2') format('woff2'), url('TTF/Iosevka-ExtendedMediumOblique.ttf') format('truetype'); } @font-face { @@ -337,7 +337,7 @@ font-weight: 500; font-stretch: normal; font-style: italic; - src: url('WOFF2/Iosevka-MediumItalic.woff2') format('woff2'), url('TTF/Iosevka-MediumItalic.ttf') format('truetype'); + src: url('/fonts/WOFF2/Iosevka-MediumItalic.woff2') format('woff2'), url('TTF/Iosevka-MediumItalic.ttf') format('truetype'); } @font-face { @@ -346,7 +346,7 @@ font-weight: 500; font-stretch: expanded; font-style: italic; - src: url('WOFF2/Iosevka-ExtendedMediumItalic.woff2') format('woff2'), url('TTF/Iosevka-ExtendedMediumItalic.ttf') format('truetype'); + src: url('/fonts/WOFF2/Iosevka-ExtendedMediumItalic.woff2') format('woff2'), url('TTF/Iosevka-ExtendedMediumItalic.ttf') format('truetype'); } @font-face { @@ -355,7 +355,7 @@ font-weight: 600; font-stretch: normal; font-style: normal; - src: url('WOFF2/Iosevka-SemiBold.woff2') format('woff2'), url('TTF/Iosevka-SemiBold.ttf') format('truetype'); + src: url('/fonts/WOFF2/Iosevka-SemiBold.woff2') format('woff2'), url('TTF/Iosevka-SemiBold.ttf') format('truetype'); } @font-face { @@ -364,7 +364,7 @@ font-weight: 600; font-stretch: expanded; font-style: normal; - src: url('WOFF2/Iosevka-ExtendedSemiBold.woff2') format('woff2'), url('TTF/Iosevka-ExtendedSemiBold.ttf') format('truetype'); + src: url('/fonts/WOFF2/Iosevka-ExtendedSemiBold.woff2') format('woff2'), url('TTF/Iosevka-ExtendedSemiBold.ttf') format('truetype'); } @font-face { @@ -373,7 +373,7 @@ font-weight: 600; font-stretch: normal; font-style: oblique; - src: url('WOFF2/Iosevka-SemiBoldOblique.woff2') format('woff2'), url('TTF/Iosevka-SemiBoldOblique.ttf') format('truetype'); + src: url('/fonts/WOFF2/Iosevka-SemiBoldOblique.woff2') format('woff2'), url('TTF/Iosevka-SemiBoldOblique.ttf') format('truetype'); } @font-face { @@ -381,7 +381,7 @@ font-display: swap; font-weight: 600; font-stretch: normal; - src: url('WOFF2/Iosevka-SemiBoldOblique.woff2') format('woff2'), url('TTF/Iosevka-SemiBoldOblique.ttf') format('truetype'); + src: url('/fonts/WOFF2/Iosevka-SemiBoldOblique.woff2') format('woff2'), url('TTF/Iosevka-SemiBoldOblique.ttf') format('truetype'); } @font-face { @@ -390,7 +390,7 @@ font-weight: 600; font-stretch: expanded; font-style: oblique; - src: url('WOFF2/Iosevka-ExtendedSemiBoldOblique.woff2') format('woff2'), url('TTF/Iosevka-ExtendedSemiBoldOblique.ttf') format('truetype'); + src: url('/fonts/WOFF2/Iosevka-ExtendedSemiBoldOblique.woff2') format('woff2'), url('TTF/Iosevka-ExtendedSemiBoldOblique.ttf') format('truetype'); } @font-face { @@ -398,7 +398,7 @@ font-display: swap; font-weight: 600; font-stretch: expanded; - src: url('WOFF2/Iosevka-ExtendedSemiBoldOblique.woff2') format('woff2'), url('TTF/Iosevka-ExtendedSemiBoldOblique.ttf') format('truetype'); + src: url('/fonts/WOFF2/Iosevka-ExtendedSemiBoldOblique.woff2') format('woff2'), url('TTF/Iosevka-ExtendedSemiBoldOblique.ttf') format('truetype'); } @font-face { @@ -407,7 +407,7 @@ font-weight: 600; font-stretch: normal; font-style: italic; - src: url('WOFF2/Iosevka-SemiBoldItalic.woff2') format('woff2'), url('TTF/Iosevka-SemiBoldItalic.ttf') format('truetype'); + src: url('/fonts/WOFF2/Iosevka-SemiBoldItalic.woff2') format('woff2'), url('TTF/Iosevka-SemiBoldItalic.ttf') format('truetype'); } @font-face { @@ -416,7 +416,7 @@ font-weight: 600; font-stretch: expanded; font-style: italic; - src: url('WOFF2/Iosevka-ExtendedSemiBoldItalic.woff2') format('woff2'), url('TTF/Iosevka-ExtendedSemiBoldItalic.ttf') format('truetype'); + src: url('/fonts/WOFF2/Iosevka-ExtendedSemiBoldItalic.woff2') format('woff2'), url('TTF/Iosevka-ExtendedSemiBoldItalic.ttf') format('truetype'); } @font-face { @@ -425,7 +425,7 @@ font-weight: 700; font-stretch: normal; font-style: normal; - src: url('WOFF2/Iosevka-Bold.woff2') format('woff2'), url('TTF/Iosevka-Bold.ttf') format('truetype'); + src: url('/fonts/WOFF2/Iosevka-Bold.woff2') format('woff2'), url('TTF/Iosevka-Bold.ttf') format('truetype'); } @font-face { @@ -434,7 +434,7 @@ font-weight: 700; font-stretch: expanded; font-style: normal; - src: url('WOFF2/Iosevka-ExtendedBold.woff2') format('woff2'), url('TTF/Iosevka-ExtendedBold.ttf') format('truetype'); + src: url('/fonts/WOFF2/Iosevka-ExtendedBold.woff2') format('woff2'), url('TTF/Iosevka-ExtendedBold.ttf') format('truetype'); } @font-face { @@ -443,7 +443,7 @@ font-weight: 700; font-stretch: normal; font-style: oblique; - src: url('WOFF2/Iosevka-BoldOblique.woff2') format('woff2'), url('TTF/Iosevka-BoldOblique.ttf') format('truetype'); + src: url('/fonts/WOFF2/Iosevka-BoldOblique.woff2') format('woff2'), url('TTF/Iosevka-BoldOblique.ttf') format('truetype'); } @font-face { @@ -451,7 +451,7 @@ font-display: swap; font-weight: 700; font-stretch: normal; - src: url('WOFF2/Iosevka-BoldOblique.woff2') format('woff2'), url('TTF/Iosevka-BoldOblique.ttf') format('truetype'); + src: url('/fonts/WOFF2/Iosevka-BoldOblique.woff2') format('woff2'), url('TTF/Iosevka-BoldOblique.ttf') format('truetype'); } @font-face { @@ -460,7 +460,7 @@ font-weight: 700; font-stretch: expanded; font-style: oblique; - src: url('WOFF2/Iosevka-ExtendedBoldOblique.woff2') format('woff2'), url('TTF/Iosevka-ExtendedBoldOblique.ttf') format('truetype'); + src: url('/fonts/WOFF2/Iosevka-ExtendedBoldOblique.woff2') format('woff2'), url('TTF/Iosevka-ExtendedBoldOblique.ttf') format('truetype'); } @font-face { @@ -468,7 +468,7 @@ font-display: swap; font-weight: 700; font-stretch: expanded; - src: url('WOFF2/Iosevka-ExtendedBoldOblique.woff2') format('woff2'), url('TTF/Iosevka-ExtendedBoldOblique.ttf') format('truetype'); + src: url('/fonts/WOFF2/Iosevka-ExtendedBoldOblique.woff2') format('woff2'), url('TTF/Iosevka-ExtendedBoldOblique.ttf') format('truetype'); } @font-face { @@ -477,7 +477,7 @@ font-weight: 700; font-stretch: normal; font-style: italic; - src: url('WOFF2/Iosevka-BoldItalic.woff2') format('woff2'), url('TTF/Iosevka-BoldItalic.ttf') format('truetype'); + src: url('/fonts/WOFF2/Iosevka-BoldItalic.woff2') format('woff2'), url('TTF/Iosevka-BoldItalic.ttf') format('truetype'); } @font-face { @@ -486,7 +486,7 @@ font-weight: 700; font-stretch: expanded; font-style: italic; - src: url('WOFF2/Iosevka-ExtendedBoldItalic.woff2') format('woff2'), url('TTF/Iosevka-ExtendedBoldItalic.ttf') format('truetype'); + src: url('/fonts/WOFF2/Iosevka-ExtendedBoldItalic.woff2') format('woff2'), url('TTF/Iosevka-ExtendedBoldItalic.ttf') format('truetype'); } @font-face { @@ -495,7 +495,7 @@ font-weight: 800; font-stretch: normal; font-style: normal; - src: url('WOFF2/Iosevka-ExtraBold.woff2') format('woff2'), url('TTF/Iosevka-ExtraBold.ttf') format('truetype'); + src: url('/fonts/WOFF2/Iosevka-ExtraBold.woff2') format('woff2'), url('TTF/Iosevka-ExtraBold.ttf') format('truetype'); } @font-face { @@ -504,7 +504,7 @@ font-weight: 800; font-stretch: expanded; font-style: normal; - src: url('WOFF2/Iosevka-ExtendedExtraBold.woff2') format('woff2'), url('TTF/Iosevka-ExtendedExtraBold.ttf') format('truetype'); + src: url('/fonts/WOFF2/Iosevka-ExtendedExtraBold.woff2') format('woff2'), url('TTF/Iosevka-ExtendedExtraBold.ttf') format('truetype'); } @font-face { @@ -513,7 +513,7 @@ font-weight: 800; font-stretch: normal; font-style: oblique; - src: url('WOFF2/Iosevka-ExtraBoldOblique.woff2') format('woff2'), url('TTF/Iosevka-ExtraBoldOblique.ttf') format('truetype'); + src: url('/fonts/WOFF2/Iosevka-ExtraBoldOblique.woff2') format('woff2'), url('TTF/Iosevka-ExtraBoldOblique.ttf') format('truetype'); } @font-face { @@ -521,7 +521,7 @@ font-display: swap; font-weight: 800; font-stretch: normal; - src: url('WOFF2/Iosevka-ExtraBoldOblique.woff2') format('woff2'), url('TTF/Iosevka-ExtraBoldOblique.ttf') format('truetype'); + src: url('/fonts/WOFF2/Iosevka-ExtraBoldOblique.woff2') format('woff2'), url('TTF/Iosevka-ExtraBoldOblique.ttf') format('truetype'); } @font-face { @@ -530,7 +530,7 @@ font-weight: 800; font-stretch: expanded; font-style: oblique; - src: url('WOFF2/Iosevka-ExtendedExtraBoldOblique.woff2') format('woff2'), url('TTF/Iosevka-ExtendedExtraBoldOblique.ttf') format('truetype'); + src: url('/fonts/WOFF2/Iosevka-ExtendedExtraBoldOblique.woff2') format('woff2'), url('TTF/Iosevka-ExtendedExtraBoldOblique.ttf') format('truetype'); } @font-face { @@ -538,7 +538,7 @@ font-display: swap; font-weight: 800; font-stretch: expanded; - src: url('WOFF2/Iosevka-ExtendedExtraBoldOblique.woff2') format('woff2'), url('TTF/Iosevka-ExtendedExtraBoldOblique.ttf') format('truetype'); + src: url('/fonts/WOFF2/Iosevka-ExtendedExtraBoldOblique.woff2') format('woff2'), url('TTF/Iosevka-ExtendedExtraBoldOblique.ttf') format('truetype'); } @font-face { @@ -547,7 +547,7 @@ font-weight: 800; font-stretch: normal; font-style: italic; - src: url('WOFF2/Iosevka-ExtraBoldItalic.woff2') format('woff2'), url('TTF/Iosevka-ExtraBoldItalic.ttf') format('truetype'); + src: url('/fonts/WOFF2/Iosevka-ExtraBoldItalic.woff2') format('woff2'), url('TTF/Iosevka-ExtraBoldItalic.ttf') format('truetype'); } @font-face { @@ -556,7 +556,7 @@ font-weight: 800; font-stretch: expanded; font-style: italic; - src: url('WOFF2/Iosevka-ExtendedExtraBoldItalic.woff2') format('woff2'), url('TTF/Iosevka-ExtendedExtraBoldItalic.ttf') format('truetype'); + src: url('/fonts/WOFF2/Iosevka-ExtendedExtraBoldItalic.woff2') format('woff2'), url('TTF/Iosevka-ExtendedExtraBoldItalic.ttf') format('truetype'); } @font-face { @@ -565,7 +565,7 @@ font-weight: 900; font-stretch: normal; font-style: normal; - src: url('WOFF2/Iosevka-Heavy.woff2') format('woff2'), url('TTF/Iosevka-Heavy.ttf') format('truetype'); + src: url('/fonts/WOFF2/Iosevka-Heavy.woff2') format('woff2'), url('TTF/Iosevka-Heavy.ttf') format('truetype'); } @font-face { @@ -574,7 +574,7 @@ font-weight: 900; font-stretch: expanded; font-style: normal; - src: url('WOFF2/Iosevka-ExtendedHeavy.woff2') format('woff2'), url('TTF/Iosevka-ExtendedHeavy.ttf') format('truetype'); + src: url('/fonts/WOFF2/Iosevka-ExtendedHeavy.woff2') format('woff2'), url('TTF/Iosevka-ExtendedHeavy.ttf') format('truetype'); } @font-face { @@ -583,7 +583,7 @@ font-weight: 900; font-stretch: normal; font-style: oblique; - src: url('WOFF2/Iosevka-HeavyOblique.woff2') format('woff2'), url('TTF/Iosevka-HeavyOblique.ttf') format('truetype'); + src: url('/fonts/WOFF2/Iosevka-HeavyOblique.woff2') format('woff2'), url('TTF/Iosevka-HeavyOblique.ttf') format('truetype'); } @font-face { @@ -591,7 +591,7 @@ font-display: swap; font-weight: 900; font-stretch: normal; - src: url('WOFF2/Iosevka-HeavyOblique.woff2') format('woff2'), url('TTF/Iosevka-HeavyOblique.ttf') format('truetype'); + src: url('/fonts/WOFF2/Iosevka-HeavyOblique.woff2') format('woff2'), url('TTF/Iosevka-HeavyOblique.ttf') format('truetype'); } @font-face { @@ -600,7 +600,7 @@ font-weight: 900; font-stretch: expanded; font-style: oblique; - src: url('WOFF2/Iosevka-ExtendedHeavyOblique.woff2') format('woff2'), url('TTF/Iosevka-ExtendedHeavyOblique.ttf') format('truetype'); + src: url('/fonts/WOFF2/Iosevka-ExtendedHeavyOblique.woff2') format('woff2'), url('TTF/Iosevka-ExtendedHeavyOblique.ttf') format('truetype'); } @font-face { @@ -608,7 +608,7 @@ font-display: swap; font-weight: 900; font-stretch: expanded; - src: url('WOFF2/Iosevka-ExtendedHeavyOblique.woff2') format('woff2'), url('TTF/Iosevka-ExtendedHeavyOblique.ttf') format('truetype'); + src: url('/fonts/WOFF2/Iosevka-ExtendedHeavyOblique.woff2') format('woff2'), url('TTF/Iosevka-ExtendedHeavyOblique.ttf') format('truetype'); } @font-face { @@ -617,7 +617,7 @@ font-weight: 900; font-stretch: normal; font-style: italic; - src: url('WOFF2/Iosevka-HeavyItalic.woff2') format('woff2'), url('TTF/Iosevka-HeavyItalic.ttf') format('truetype'); + src: url('/fonts/WOFF2/Iosevka-HeavyItalic.woff2') format('woff2'), url('TTF/Iosevka-HeavyItalic.ttf') format('truetype'); } @font-face { @@ -626,5 +626,5 @@ font-weight: 900; font-stretch: expanded; font-style: italic; - src: url('WOFF2/Iosevka-ExtendedHeavyItalic.woff2') format('woff2'), url('TTF/Iosevka-ExtendedHeavyItalic.ttf') format('truetype'); + src: url('/fonts/WOFF2/Iosevka-ExtendedHeavyItalic.woff2') format('woff2'), url('TTF/Iosevka-ExtendedHeavyItalic.ttf') format('truetype'); }