diff --git a/NOTICE b/NOTICE index 547f55d09..67d8975de 100644 --- a/NOTICE +++ b/NOTICE @@ -41,3 +41,17 @@ NumPy (optional dependency) Copyright (c) 2005-2024, NumPy Developers Licensed under the BSD 3-Clause License https://github.com/numpy/numpy + +Vendored dashboard assets (headroom/dashboard/static/) +------------------------------------------------------ +Tailwind CSS 3.4.17 (Play CDN build) — MIT License +Copyright (c) Tailwind Labs, Inc. +https://github.com/tailwindlabs/tailwindcss + +htmx 1.9.10 — Zero-Clause BSD License +Copyright (c) 2020, Big Sky Software +https://github.com/bigskysoftware/htmx + +Alpine.js 3.13.3 — MIT License +Copyright (c) 2019-2025 Caleb Porzio and contributors +https://github.com/alpinejs/alpine diff --git a/headroom/dashboard/__init__.py b/headroom/dashboard/__init__.py index 4bb1e360f..f23a3cd46 100644 --- a/headroom/dashboard/__init__.py +++ b/headroom/dashboard/__init__.py @@ -4,6 +4,10 @@ from pathlib import Path DASHBOARD_DIR = Path(__file__).parent TEMPLATES_DIR = DASHBOARD_DIR / "templates" +# Vendored tailwind/htmx/alpine. Served locally because Edge's Tracking +# Prevention and corporate proxies block unpkg.com/cdn.tailwindcss.com, which +# left the dashboard unstyled and dataless on some Windows machines. +STATIC_DIR = DASHBOARD_DIR / "static" def get_dashboard_html() -> str: diff --git a/headroom/dashboard/static/alpine.min.js b/headroom/dashboard/static/alpine.min.js new file mode 100644 index 000000000..af7df6438 --- /dev/null +++ b/headroom/dashboard/static/alpine.min.js @@ -0,0 +1,5 @@ +(()=>{var tt=!1,rt=!1,V=[],nt=-1;function Vt(e){Sn(e)}function Sn(e){V.includes(e)||V.push(e),An()}function Ee(e){let t=V.indexOf(e);t!==-1&&t>nt&&V.splice(t,1)}function An(){!rt&&!tt&&(tt=!0,queueMicrotask(On))}function On(){tt=!1,rt=!0;for(let e=0;ee.effect(t,{scheduler:r=>{it?Vt(r):r()}}),ot=e.raw}function st(e){k=e}function Wt(e){let t=()=>{};return[n=>{let i=k(n);return e._x_effects||(e._x_effects=new Set,e._x_runEffects=()=>{e._x_effects.forEach(o=>o())}),e._x_effects.add(i),t=()=>{i!==void 0&&(e._x_effects.delete(i),$(i))},i},()=>{t()}]}function q(e,t,r={}){e.dispatchEvent(new CustomEvent(t,{detail:r,bubbles:!0,composed:!0,cancelable:!0}))}function O(e,t){if(typeof ShadowRoot=="function"&&e instanceof ShadowRoot){Array.from(e.children).forEach(i=>O(i,t));return}let r=!1;if(t(e,()=>r=!0),r)return;let n=e.firstElementChild;for(;n;)O(n,t,!1),n=n.nextElementSibling}function v(e,...t){console.warn(`Alpine Warning: ${e}`,...t)}var Gt=!1;function Jt(){Gt&&v("Alpine has already been initialized on this page. Calling Alpine.start() more than once can cause problems."),Gt=!0,document.body||v("Unable to initialize. Trying to load Alpine before `` is available. Did you forget to add `defer` in Alpine's ` - - + + + - + +