From 47e1f19edddf4c55af07c56581dfbaba19a032c4 Mon Sep 17 00:00:00 2001 From: Mikkel Georgsen Date: Sun, 1 Mar 2026 03:54:29 +0100 Subject: [PATCH] feat(01-10): SvelteKit frontend scaffold with Catppuccin theme and clients - SvelteKit SPA with adapter-static, prerender, SSR disabled - Catppuccin Mocha/Latte theme CSS with semantic color tokens - WebSocket client with auto-reconnect and exponential backoff - HTTP API client with JWT auth and 401 handling - Auth state store with localStorage persistence (Svelte 5 runes) - Tournament state store handling all WS message types (Svelte 5 runes) - PIN login page with numpad, 48px touch targets - Updated Makefile frontend target for real SvelteKit build Co-Authored-By: Claude Opus 4.6 --- Makefile | 6 +- frontend/.gitignore | 2 + frontend/build/_app/env.js | 1 + .../_app/immutable/assets/0.LvVNMuLM.css | 1 + .../_app/immutable/assets/2.lCQ6RyE1.css | 1 + .../_app/immutable/assets/3.C7Q2VT44.css | 1 + .../build/_app/immutable/chunks/B6M6q2Zo.js | 1 + .../build/_app/immutable/chunks/B9dvBo0E.js | 1 + .../build/_app/immutable/chunks/Bfwrz3i4.js | 1 + .../build/_app/immutable/chunks/DMqvp7vx.js | 1 + .../build/_app/immutable/chunks/Da6yQRl8.js | 1 + .../build/_app/immutable/chunks/De6rLmuB.js | 1 + .../build/_app/immutable/chunks/Ym0WvvUy.js | 1 + .../build/_app/immutable/chunks/dTRRgeF-.js | 2 + .../build/_app/immutable/chunks/giww_vF6.js | 1 + .../_app/immutable/entry/app.DWnDWHgs.js | 2 + .../_app/immutable/entry/start.Cw5np0_P.js | 1 + .../build/_app/immutable/nodes/0.CNxjQThJ.js | 1 + .../build/_app/immutable/nodes/1.DQmxvu2E.js | 1 + .../build/_app/immutable/nodes/2.CwK2tdGg.js | 1 + .../build/_app/immutable/nodes/3.BjUxkFGX.js | 2 + frontend/build/_app/version.json | 1 + frontend/build/favicon.png | Bin 0 -> 70 bytes frontend/build/index.html | 75 +- frontend/build/login.html | 39 + frontend/package-lock.json | 1627 +++++++++++++++++ frontend/package.json | 22 + frontend/src/app.css | 138 ++ frontend/src/app.d.ts | 13 + frontend/src/app.html | 13 + frontend/src/lib/api.ts | 124 ++ frontend/src/lib/stores/auth.svelte.ts | 109 ++ frontend/src/lib/stores/tournament.svelte.ts | 326 ++++ frontend/src/lib/theme/catppuccin.css | 163 ++ frontend/src/lib/ws.ts | 199 ++ frontend/src/routes/+layout.svelte | 7 + frontend/src/routes/+layout.ts | 2 + frontend/src/routes/+page.svelte | 45 + frontend/src/routes/login/+page.svelte | 302 +++ frontend/static/favicon.png | Bin 0 -> 70 bytes frontend/svelte.config.js | 17 + frontend/tsconfig.json | 14 + frontend/vite.config.ts | 6 + 43 files changed, 3230 insertions(+), 42 deletions(-) create mode 100644 frontend/.gitignore create mode 100644 frontend/build/_app/env.js create mode 100644 frontend/build/_app/immutable/assets/0.LvVNMuLM.css create mode 100644 frontend/build/_app/immutable/assets/2.lCQ6RyE1.css create mode 100644 frontend/build/_app/immutable/assets/3.C7Q2VT44.css create mode 100644 frontend/build/_app/immutable/chunks/B6M6q2Zo.js create mode 100644 frontend/build/_app/immutable/chunks/B9dvBo0E.js create mode 100644 frontend/build/_app/immutable/chunks/Bfwrz3i4.js create mode 100644 frontend/build/_app/immutable/chunks/DMqvp7vx.js create mode 100644 frontend/build/_app/immutable/chunks/Da6yQRl8.js create mode 100644 frontend/build/_app/immutable/chunks/De6rLmuB.js create mode 100644 frontend/build/_app/immutable/chunks/Ym0WvvUy.js create mode 100644 frontend/build/_app/immutable/chunks/dTRRgeF-.js create mode 100644 frontend/build/_app/immutable/chunks/giww_vF6.js create mode 100644 frontend/build/_app/immutable/entry/app.DWnDWHgs.js create mode 100644 frontend/build/_app/immutable/entry/start.Cw5np0_P.js create mode 100644 frontend/build/_app/immutable/nodes/0.CNxjQThJ.js create mode 100644 frontend/build/_app/immutable/nodes/1.DQmxvu2E.js create mode 100644 frontend/build/_app/immutable/nodes/2.CwK2tdGg.js create mode 100644 frontend/build/_app/immutable/nodes/3.BjUxkFGX.js create mode 100644 frontend/build/_app/version.json create mode 100644 frontend/build/favicon.png create mode 100644 frontend/build/login.html create mode 100644 frontend/package-lock.json create mode 100644 frontend/package.json create mode 100644 frontend/src/app.css create mode 100644 frontend/src/app.d.ts create mode 100644 frontend/src/app.html create mode 100644 frontend/src/lib/api.ts create mode 100644 frontend/src/lib/stores/auth.svelte.ts create mode 100644 frontend/src/lib/stores/tournament.svelte.ts create mode 100644 frontend/src/lib/theme/catppuccin.css create mode 100644 frontend/src/lib/ws.ts create mode 100644 frontend/src/routes/+layout.svelte create mode 100644 frontend/src/routes/+layout.ts create mode 100644 frontend/src/routes/+page.svelte create mode 100644 frontend/src/routes/login/+page.svelte create mode 100644 frontend/static/favicon.png create mode 100644 frontend/svelte.config.js create mode 100644 frontend/tsconfig.json create mode 100644 frontend/vite.config.ts diff --git a/Makefile b/Makefile index d7dfb10..859c3f0 100644 --- a/Makefile +++ b/Makefile @@ -18,11 +18,7 @@ test: CGO_ENABLED=1 go test ./... frontend: - @mkdir -p frontend/build - @if [ ! -f frontend/build/index.html ]; then \ - echo 'Felt

Felt

Loading...

' > frontend/build/index.html; \ - fi - @echo "Frontend build complete (stub)" + cd frontend && npm install && npm run build all: frontend build diff --git a/frontend/.gitignore b/frontend/.gitignore new file mode 100644 index 0000000..e37309a --- /dev/null +++ b/frontend/.gitignore @@ -0,0 +1,2 @@ +node_modules/ +.svelte-kit/ diff --git a/frontend/build/_app/env.js b/frontend/build/_app/env.js new file mode 100644 index 0000000..f5427da --- /dev/null +++ b/frontend/build/_app/env.js @@ -0,0 +1 @@ +export const env={} \ No newline at end of file diff --git a/frontend/build/_app/immutable/assets/0.LvVNMuLM.css b/frontend/build/_app/immutable/assets/0.LvVNMuLM.css new file mode 100644 index 0000000..17c1cc0 --- /dev/null +++ b/frontend/build/_app/immutable/assets/0.LvVNMuLM.css @@ -0,0 +1 @@ +[data-theme=mocha],:root{--ctp-rosewater: #f5e0dc;--ctp-flamingo: #f2cdcd;--ctp-pink: #f5c2e7;--ctp-mauve: #cba6f7;--ctp-red: #f38ba8;--ctp-maroon: #eba0ac;--ctp-peach: #fab387;--ctp-yellow: #f9e2af;--ctp-green: #a6e3a1;--ctp-teal: #94e2d5;--ctp-sky: #89dceb;--ctp-sapphire: #74c7ec;--ctp-blue: #89b4fa;--ctp-lavender: #b4befe;--ctp-text: #cdd6f4;--ctp-subtext1: #bac2de;--ctp-subtext0: #a6adc8;--ctp-overlay2: #9399b2;--ctp-overlay1: #7f849c;--ctp-overlay0: #6c7086;--ctp-surface2: #585b70;--ctp-surface1: #45475a;--ctp-surface0: #313244;--ctp-base: #1e1e2e;--ctp-mantle: #181825;--ctp-crust: #11111b;--color-bg: var(--ctp-base);--color-bg-elevated: var(--ctp-mantle);--color-bg-sunken: var(--ctp-crust);--color-surface: var(--ctp-surface0);--color-surface-hover: var(--ctp-surface1);--color-surface-active: var(--ctp-surface2);--color-text: var(--ctp-text);--color-text-secondary: var(--ctp-subtext1);--color-text-muted: var(--ctp-subtext0);--color-primary: var(--ctp-blue);--color-success: var(--ctp-green);--color-warning: var(--ctp-yellow);--color-error: var(--ctp-red);--color-accent: var(--ctp-mauve);--color-border: var(--ctp-surface1);--color-overlay: var(--ctp-overlay0);--color-felt: var(--ctp-green);--color-card: var(--ctp-text);--color-bounty: var(--ctp-pink);--color-prize: var(--ctp-yellow);--color-chip: var(--ctp-peach);--color-clock: var(--ctp-sapphire);--color-break: var(--ctp-teal);--color-elimination: var(--ctp-red)}[data-theme=latte]{--ctp-rosewater: #dc8a78;--ctp-flamingo: #dd7878;--ctp-pink: #ea76cb;--ctp-mauve: #8839ef;--ctp-red: #d20f39;--ctp-maroon: #e64553;--ctp-peach: #fe640b;--ctp-yellow: #df8e1d;--ctp-green: #40a02b;--ctp-teal: #179299;--ctp-sky: #04a5e5;--ctp-sapphire: #209fb5;--ctp-blue: #1e66f5;--ctp-lavender: #7287fd;--ctp-text: #4c4f69;--ctp-subtext1: #5c5f77;--ctp-subtext0: #6c6f85;--ctp-overlay2: #7c7f93;--ctp-overlay1: #8c8fa1;--ctp-overlay0: #9ca0b0;--ctp-surface2: #acb0be;--ctp-surface1: #bcc0cc;--ctp-surface0: #ccd0da;--ctp-base: #eff1f5;--ctp-mantle: #e6e9ef;--ctp-crust: #dce0e8}:root{--font-body: system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;--font-mono: "JetBrains Mono", "Fira Code", ui-monospace, "Cascadia Code", "Source Code Pro", Menlo, Consolas, "DejaVu Sans Mono", monospace;--text-xs: .75rem;--text-sm: .875rem;--text-base: 1rem;--text-lg: 1.125rem;--text-xl: 1.25rem;--text-2xl: 1.5rem;--text-3xl: 1.875rem;--text-4xl: 2.25rem;--leading-tight: 1.25;--leading-normal: 1.5;--leading-relaxed: 1.75;--space-1: .25rem;--space-2: .5rem;--space-3: .75rem;--space-4: 1rem;--space-6: 1.5rem;--space-8: 2rem;--space-12: 3rem;--radius-sm: .25rem;--radius-md: .5rem;--radius-lg: .75rem;--radius-xl: 1rem;--radius-full: 9999px;--shadow-sm: 0 1px 2px rgba(0, 0, 0, .3);--shadow-md: 0 4px 6px rgba(0, 0, 0, .3);--shadow-lg: 0 10px 15px rgba(0, 0, 0, .3);--transition-fast: .1s ease;--transition-normal: .2s ease;--transition-slow: .3s ease;--touch-target: 48px}*,*:before,*:after{box-sizing:border-box;margin:0;padding:0}html{font-family:var(--font-body);font-size:16px;line-height:var(--leading-normal);color:var(--color-text);background-color:var(--color-bg);-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;scrollbar-gutter:stable}body{min-height:100dvh;color:var(--color-text);background-color:var(--color-bg)}button,a,input,select,textarea,[role=button],[role=tab],[role=menuitem]{touch-action:manipulation}.touch-target,button,[role=button],[role=tab]{min-height:var(--touch-target);min-width:var(--touch-target)}button:active,[role=button]:active,[role=tab]:active,.touch-target:active{transform:scale(.97);opacity:.9;transition:transform var(--transition-fast),opacity var(--transition-fast)}:focus-visible{outline:2px solid var(--color-primary);outline-offset:2px}:focus:not(:focus-visible){outline:none}::-webkit-scrollbar{width:8px;height:8px}::-webkit-scrollbar-track{background:var(--color-bg)}::-webkit-scrollbar-thumb{background:var(--color-surface-active);border-radius:var(--radius-full)}::-webkit-scrollbar-thumb:hover{background:var(--color-overlay)}*{scrollbar-width:thin;scrollbar-color:var(--color-surface-active) var(--color-bg)}.font-mono{font-family:var(--font-mono)}.timer,.number,.blinds,.chips,.currency{font-family:var(--font-mono);font-variant-numeric:tabular-nums}.visually-hidden{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0} diff --git a/frontend/build/_app/immutable/assets/2.lCQ6RyE1.css b/frontend/build/_app/immutable/assets/2.lCQ6RyE1.css new file mode 100644 index 0000000..d24b205 --- /dev/null +++ b/frontend/build/_app/immutable/assets/2.lCQ6RyE1.css @@ -0,0 +1 @@ +.container.svelte-1uha8ag{display:flex;flex-direction:column;align-items:center;justify-content:center;min-height:100dvh;padding:1rem;gap:.5rem}h1.svelte-1uha8ag{font-size:2rem;font-weight:700;color:var(--color-primary)}.text-secondary.svelte-1uha8ag{color:var(--color-text-secondary)} diff --git a/frontend/build/_app/immutable/assets/3.C7Q2VT44.css b/frontend/build/_app/immutable/assets/3.C7Q2VT44.css new file mode 100644 index 0000000..b092835 --- /dev/null +++ b/frontend/build/_app/immutable/assets/3.C7Q2VT44.css @@ -0,0 +1 @@ +.login-container.svelte-1x05zx6{display:flex;align-items:center;justify-content:center;min-height:100dvh;padding:var(--space-4);background-color:var(--color-bg)}.login-card.svelte-1x05zx6{width:100%;max-width:360px;display:flex;flex-direction:column;align-items:center;gap:var(--space-6)}.logo.svelte-1x05zx6{text-align:center}.logo.svelte-1x05zx6 h1:where(.svelte-1x05zx6){font-size:var(--text-4xl);font-weight:700;color:var(--color-primary);letter-spacing:-.02em}.subtitle.svelte-1x05zx6{color:var(--color-text-secondary);font-size:var(--text-sm);margin-top:var(--space-1)}.pin-display.svelte-1x05zx6{display:flex;gap:var(--space-3);padding:var(--space-4) 0}.pin-dot.svelte-1x05zx6{width:16px;height:16px;border-radius:var(--radius-full);border:2px solid var(--color-surface-active);background-color:transparent;transition:background-color var(--transition-fast),border-color var(--transition-fast)}.pin-dot.filled.svelte-1x05zx6{background-color:var(--color-primary);border-color:var(--color-primary)}.error-message.svelte-1x05zx6{color:var(--color-error);font-size:var(--text-sm);text-align:center;padding:var(--space-2) var(--space-4);background-color:color-mix(in srgb,var(--color-error) 10%,transparent);border-radius:var(--radius-md);width:100%}.numpad.svelte-1x05zx6{display:grid;grid-template-columns:repeat(3,1fr);gap:var(--space-3);width:100%}.numpad-btn.svelte-1x05zx6{display:flex;align-items:center;justify-content:center;height:64px;font-size:var(--text-2xl);font-weight:600;color:var(--color-text);background-color:var(--color-surface);border:1px solid var(--color-border);border-radius:var(--radius-lg);cursor:pointer;-webkit-user-select:none;user-select:none;-webkit-tap-highlight-color:transparent;transition:background-color var(--transition-fast)}.numpad-btn.svelte-1x05zx6:hover:not(:disabled){background-color:var(--color-surface-hover)}.numpad-btn.svelte-1x05zx6:disabled{opacity:.4;cursor:not-allowed;transform:none}.numpad-fn.svelte-1x05zx6{font-size:var(--text-sm);font-weight:500;color:var(--color-text-secondary)}.submit-btn.svelte-1x05zx6{width:100%;height:56px;font-size:var(--text-lg);font-weight:600;color:var(--color-bg);background-color:var(--color-primary);border:none;border-radius:var(--radius-lg);cursor:pointer;-webkit-user-select:none;user-select:none;-webkit-tap-highlight-color:transparent;transition:background-color var(--transition-fast),opacity var(--transition-fast)}.submit-btn.svelte-1x05zx6:hover:not(:disabled){opacity:.9}.submit-btn.svelte-1x05zx6:disabled{opacity:.4;cursor:not-allowed;transform:none} diff --git a/frontend/build/_app/immutable/chunks/B6M6q2Zo.js b/frontend/build/_app/immutable/chunks/B6M6q2Zo.js new file mode 100644 index 0000000..a292ca5 --- /dev/null +++ b/frontend/build/_app/immutable/chunks/B6M6q2Zo.js @@ -0,0 +1 @@ +import{N as p,m as u,O as c,P as f,Q as E,T as g,R as w,h as d,j as s,S as N,c as y,U as M,f as x,V as A}from"./Ym0WvvUy.js";var l;const i=((l=globalThis==null?void 0:globalThis.window)==null?void 0:l.trustedTypes)&&globalThis.window.trustedTypes.createPolicy("svelte-trusted-html",{createHTML:t=>t});function L(t){return(i==null?void 0:i.createHTML(t))??t}function O(t){var r=p("template");return r.innerHTML=L(t.replaceAll("","")),r.content}function n(t,r){var e=c;e.nodes===null&&(e.nodes={start:t,end:r,a:null,t:null})}function b(t,r){var e=(r&g)!==0,m=(r&w)!==0,a,v=!t.startsWith("");return()=>{if(d)return n(s,null),s;a===void 0&&(a=O(v?t:""+t),e||(a=f(a)));var o=m||E?document.importNode(a,!0):a.cloneNode(!0);if(e){var T=f(o),h=o.lastChild;n(T,h)}else n(o,o);return o}}function C(t=""){if(!d){var r=u(t+"");return n(r,r),r}var e=s;return e.nodeType!==M?(e.before(e=u()),x(e)):A(e),n(e,e),e}function I(){if(d)return n(s,null),s;var t=document.createDocumentFragment(),r=document.createComment(""),e=u();return t.append(r,e),n(r,e),t}function S(t,r){if(d){var e=c;((e.f&N)===0||e.nodes.end===null)&&(e.nodes.end=s),y();return}t!==null&&t.before(r)}const P="5";var _;typeof window<"u"&&((_=window.__svelte??(window.__svelte={})).v??(_.v=new Set)).add(P);export{S as a,n as b,I as c,b as f,C as t}; diff --git a/frontend/build/_app/immutable/chunks/B9dvBo0E.js b/frontend/build/_app/immutable/chunks/B9dvBo0E.js new file mode 100644 index 0000000..3a3f498 --- /dev/null +++ b/frontend/build/_app/immutable/chunks/B9dvBo0E.js @@ -0,0 +1 @@ +import{b as T,h as o,c as b,E as v,r as p,H as A,d as E,e as R,f as g,i as l,j as m}from"./Ym0WvvUy.js";import{B as d}from"./Da6yQRl8.js";function H(_,u,c=!1){var i;o&&(i=m,b());var n=new d(_),h=c?v:0;function f(a,s){if(o){var r=p(i),e;if(r===A?e=0:r===E?e=!1:e=parseInt(r.substring(1)),a!==e){var t=R();g(t),n.anchor=t,l(!1),n.ensure(a,s),l(!0);return}}n.ensure(a,s)}T(()=>{var a=!1;u((s,r=0)=>{a=!0,f(r,s)}),a||f(!1,null)},h)}export{H as i}; diff --git a/frontend/build/_app/immutable/chunks/Bfwrz3i4.js b/frontend/build/_app/immutable/chunks/Bfwrz3i4.js new file mode 100644 index 0000000..5c309e1 --- /dev/null +++ b/frontend/build/_app/immutable/chunks/Bfwrz3i4.js @@ -0,0 +1 @@ +import{D as o,B as t,M as c,F as u}from"./Ym0WvvUy.js";function l(n){throw new Error("https://svelte.dev/e/lifecycle_outside_component")}function r(n){t===null&&l(),c&&t.l!==null?a(t).m.push(n):o(()=>{const e=u(n);if(typeof e=="function")return e})}function a(n){var e=n.l;return e.u??(e.u={a:[],b:[],m:[]})}export{r as o}; diff --git a/frontend/build/_app/immutable/chunks/DMqvp7vx.js b/frontend/build/_app/immutable/chunks/DMqvp7vx.js new file mode 100644 index 0000000..75b5b63 --- /dev/null +++ b/frontend/build/_app/immutable/chunks/DMqvp7vx.js @@ -0,0 +1 @@ +var h=e=>{throw TypeError(e)};var m=(e,t,o)=>t.has(e)||h("Cannot "+o);var r=(e,t,o)=>(m(e,t,"read from private field"),o?o.call(e):t.get(e)),l=(e,t,o)=>t.has(e)?h("Cannot add the same private member more than once"):t instanceof WeakSet?t.add(e):t.set(e,o);import{s as c,g,a as u}from"./Ym0WvvUy.js";const n="felt_token",i="felt_operator";var a,s;class p{constructor(){l(this,a,c(null));l(this,s,c(null));typeof window<"u"&&this.loadFromStorage()}get token(){return g(r(this,a))}set token(t){u(r(this,a),t,!0)}get operator(){return g(r(this,s))}set operator(t){u(r(this,s),t,!0)}get isAuthenticated(){return this.token!==null}get isAdmin(){var t;return((t=this.operator)==null?void 0:t.role)==="admin"}get isFloor(){var t;return["admin","floor"].includes(((t=this.operator)==null?void 0:t.role)??"")}login(t,o){this.token=t,this.operator=o,this.saveToStorage()}logout(){this.token=null,this.operator=null,this.clearStorage()}loadFromStorage(){try{const t=localStorage.getItem(n),o=localStorage.getItem(i);t&&o&&(this.token=t,this.operator=JSON.parse(o))}catch(t){console.warn("auth: failed to load from storage:",t),this.clearStorage()}}saveToStorage(){try{this.token&&this.operator&&(localStorage.setItem(n,this.token),localStorage.setItem(i,JSON.stringify(this.operator)))}catch(t){console.warn("auth: failed to save to storage:",t)}}clearStorage(){try{localStorage.removeItem(n),localStorage.removeItem(i)}catch(t){console.warn("auth: failed to clear storage:",t)}}}a=new WeakMap,s=new WeakMap;const f=new p;export{f as a}; diff --git a/frontend/build/_app/immutable/chunks/Da6yQRl8.js b/frontend/build/_app/immutable/chunks/Da6yQRl8.js new file mode 100644 index 0000000..23a77c9 --- /dev/null +++ b/frontend/build/_app/immutable/chunks/Da6yQRl8.js @@ -0,0 +1 @@ +var B=Object.defineProperty;var g=i=>{throw TypeError(i)};var D=(i,e,s)=>e in i?B(i,e,{enumerable:!0,configurable:!0,writable:!0,value:s}):i[e]=s;var w=(i,e,s)=>D(i,typeof e!="symbol"?e+"":e,s),y=(i,e,s)=>e.has(i)||g("Cannot "+s);var t=(i,e,s)=>(y(i,e,"read from private field"),s?s.call(i):e.get(i)),l=(i,e,s)=>e.has(i)?g("Cannot add the same private member more than once"):e instanceof WeakSet?e.add(i):e.set(i,s),M=(i,e,s,a)=>(y(i,e,"write to private field"),a?a.call(i,s):e.set(i,s),s);import{k as F,l as b,p as j,m as x,n as A,o as q,h as C,j as S,q as z,t as E}from"./Ym0WvvUy.js";var h,n,r,u,p,_,v;class I{constructor(e,s=!0){w(this,"anchor");l(this,h,new Map);l(this,n,new Map);l(this,r,new Map);l(this,u,new Set);l(this,p,!0);l(this,_,e=>{if(t(this,h).has(e)){var s=t(this,h).get(e),a=t(this,n).get(s);if(a)F(a),t(this,u).delete(s);else{var c=t(this,r).get(s);c&&(t(this,n).set(s,c.effect),t(this,r).delete(s),c.fragment.lastChild.remove(),this.anchor.before(c.fragment),a=c.effect)}for(const[f,o]of t(this,h)){if(t(this,h).delete(f),f===e)break;const d=t(this,r).get(o);d&&(b(d.effect),t(this,r).delete(o))}for(const[f,o]of t(this,n)){if(f===s||t(this,u).has(f))continue;const d=()=>{if(Array.from(t(this,h).values()).includes(f)){var k=document.createDocumentFragment();z(o,k),k.append(x()),t(this,r).set(f,{effect:o,fragment:k})}else b(o);t(this,u).delete(f),t(this,n).delete(f)};t(this,p)||!a?(t(this,u).add(f),j(o,d,!1)):d()}}});l(this,v,e=>{t(this,h).delete(e);const s=Array.from(t(this,h).values());for(const[a,c]of t(this,r))s.includes(a)||(b(c.effect),t(this,r).delete(a))});this.anchor=e,M(this,p,s)}ensure(e,s){var a=q,c=E();if(s&&!t(this,n).has(e)&&!t(this,r).has(e))if(c){var f=document.createDocumentFragment(),o=x();f.append(o),t(this,r).set(e,{effect:A(()=>s(o)),fragment:f})}else t(this,n).set(e,A(()=>s(this.anchor)));if(t(this,h).set(a,e),c){for(const[d,m]of t(this,n))d===e?a.unskip_effect(m):a.skip_effect(m);for(const[d,m]of t(this,r))d===e?a.unskip_effect(m.effect):a.skip_effect(m.effect);a.oncommit(t(this,_)),a.ondiscard(t(this,v))}else C&&(this.anchor=S),t(this,_).call(this,a)}}h=new WeakMap,n=new WeakMap,r=new WeakMap,u=new WeakMap,p=new WeakMap,_=new WeakMap,v=new WeakMap;export{I as B}; diff --git a/frontend/build/_app/immutable/chunks/De6rLmuB.js b/frontend/build/_app/immutable/chunks/De6rLmuB.js new file mode 100644 index 0000000..329ae47 --- /dev/null +++ b/frontend/build/_app/immutable/chunks/De6rLmuB.js @@ -0,0 +1 @@ +import{B as g,C as d,D as c,F as m,G as i,I as b,g as p,J as v,K as h,L as k}from"./Ym0WvvUy.js";function x(n=!1){const s=g,e=s.l.u;if(!e)return;let f=()=>v(s.s);if(n){let a=0,t={};const _=h(()=>{let l=!1;const r=s.s;for(const o in r)r[o]!==t[o]&&(t[o]=r[o],l=!0);return l&&a++,a});f=()=>p(_)}e.b.length&&d(()=>{u(s,f),i(e.b)}),c(()=>{const a=m(()=>e.m.map(b));return()=>{for(const t of a)typeof t=="function"&&t()}}),e.a.length&&c(()=>{u(s,f),i(e.a)})}function u(n,s){if(n.l.s)for(const e of n.l.s)p(e);s()}k();export{x as i}; diff --git a/frontend/build/_app/immutable/chunks/Ym0WvvUy.js b/frontend/build/_app/immutable/chunks/Ym0WvvUy.js new file mode 100644 index 0000000..d07c00b --- /dev/null +++ b/frontend/build/_app/immutable/chunks/Ym0WvvUy.js @@ -0,0 +1 @@ +var it=Object.defineProperty;var yn=e=>{throw TypeError(e)};var lt=(e,n,t)=>n in e?it(e,n,{enumerable:!0,configurable:!0,writable:!0,value:t}):e[n]=t;var ve=(e,n,t)=>lt(e,typeof n!="symbol"?n+"":n,t),Ke=(e,n,t)=>n.has(e)||yn("Cannot "+t);var _=(e,n,t)=>(Ke(e,n,"read from private field"),t?t.call(e):n.get(e)),F=(e,n,t)=>n.has(e)?yn("Cannot add the same private member more than once"):n instanceof WeakSet?n.add(e):n.set(e,t),G=(e,n,t,r)=>(Ke(e,n,"write to private field"),r?r.call(e,t):n.set(e,t),t),B=(e,n,t)=>(Ke(e,n,"access private method"),t);var at=Array.isArray,ot=Array.prototype.indexOf,Ee=Array.prototype.includes,nr=Array.from,tr=Object.defineProperty,xe=Object.getOwnPropertyDescriptor,ut=Object.getOwnPropertyDescriptors,ct=Object.prototype,_t=Array.prototype,Sn=Object.getPrototypeOf,En=Object.isExtensible;const vt=()=>{};function rr(e){return e()}function dt(e){for(var n=0;n{e=r,n=s});return{promise:t,resolve:e,reject:n}}const b=2,Se=4,ge=8,Nn=1<<24,ee=16,H=32,_e=64,ht=128,C=512,m=1024,S=2048,q=4096,Y=8192,Z=16384,ke=32768,Ye=65536,gn=1<<17,pt=1<<18,Pe=1<<19,On=1<<20,sr=1<<25,ae=65536,Xe=1<<21,fn=1<<22,W=1<<23,De=Symbol("$state"),fr=Symbol("legacy props"),re=new class extends Error{constructor(){super(...arguments);ve(this,"name","StaleReactionError");ve(this,"message","The reaction that called `getAbortSignal()` was re-run or destroyed")}},Ue=3,xn=8;function wt(){throw new Error("https://svelte.dev/e/async_derived_orphan")}function lr(e,n,t){throw new Error("https://svelte.dev/e/each_key_duplicate")}function yt(e){throw new Error("https://svelte.dev/e/effect_in_teardown")}function Et(){throw new Error("https://svelte.dev/e/effect_in_unowned_derived")}function gt(e){throw new Error("https://svelte.dev/e/effect_orphan")}function mt(){throw new Error("https://svelte.dev/e/effect_update_depth_exceeded")}function ar(){throw new Error("https://svelte.dev/e/hydration_failed")}function or(e){throw new Error("https://svelte.dev/e/props_invalid_value")}function Tt(){throw new Error("https://svelte.dev/e/state_descriptors_fixed")}function At(){throw new Error("https://svelte.dev/e/state_prototype_fixed")}function bt(){throw new Error("https://svelte.dev/e/state_unsafe_mutation")}function ur(){throw new Error("https://svelte.dev/e/svelte_boundary_reset_onerror")}const cr=1,_r=2,vr=4,dr=8,hr=16,pr=1,wr=2,yr=4,Er=8,gr=16,mr=1,Tr=2,Rt="[",St="[!",Ar="[?",kt="]",ln={},T=Symbol(),Nt="http://www.w3.org/1999/xhtml";function an(e){console.warn("https://svelte.dev/e/hydration_mismatch")}function br(){console.warn("https://svelte.dev/e/svelte_boundary_reset_noop")}let oe=!1;function Rr(e){oe=e}let g;function me(e){if(e===null)throw an(),ln;return g=e}function Sr(){return me(ne(g))}function kr(e){if(oe){if(ne(g)!==null)throw an(),ln;g=e}}function Nr(e=1){if(oe){for(var n=e,t=g;n--;)t=ne(t);g=t}}function Or(e=!0){for(var n=0,t=g;;){if(t.nodeType===xn){var r=t.data;if(r===kt){if(n===0)return t;n-=1}else(r===Rt||r===St||r[0]==="["&&!isNaN(Number(r.slice(1))))&&(n+=1)}var s=ne(t);e&&t.remove(),t=s}}function xr(e){if(!e||e.nodeType!==xn)throw an(),ln;return e.data}function Dn(e){return e===this.v}function Ot(e,n){return e!=e?n==n:e!==n||e!==null&&typeof e=="object"||typeof e=="function"}function In(e){return!Ot(e,this.v)}let Be=!1;function Dr(){Be=!0}let R=null;function qe(e){R=e}function Ir(e,n=!1,t){R={p:R,i:!1,c:null,e:null,s:e,x:null,l:Be&&!n?{s:null,u:null,$:[]}:null}}function Cr(e){var n=R,t=n.e;if(t!==null){n.e=null;for(var r of t)$n(r)}return n.i=!0,R=n.p,{}}function Fe(){return!Be||R!==null&&R.l===null}let se=[];function Cn(){var e=se;se=[],dt(e)}function mn(e){if(se.length===0&&!Ie){var n=se;queueMicrotask(()=>{n===se&&Cn()})}se.push(e)}function xt(){for(;se.length>0;)Cn()}function Dt(e){var n=w;if(n===null)return v.f|=W,e;if((n.f&ke)===0&&(n.f&Se)===0)throw e;He(e,n)}function He(e,n){for(;n!==null;){if((n.f&ht)!==0){if((n.f&ke)===0)throw e;try{n.b.error(e);return}catch(t){e=t}}n=n.parent}throw e}const It=-7169;function E(e,n){e.f=e.f&It|n}function on(e){(e.f&C)!==0||e.deps===null?E(e,m):E(e,q)}function Pn(e){if(e!==null)for(const n of e)(n.f&b)===0||(n.f&ae)===0||(n.f^=ae,Pn(n.deps))}function Ct(e,n,t){(e.f&S)!==0?n.add(e):(e.f&q)!==0&&t.add(e),Pn(e.deps),E(e,m)}const je=new Set;let h=null,A=null,N=[],ze=null,Ie=!1,Te=null;var $,de,ie,he,pe,we,X,L,ye,x,Ze,We,Je,Qe;const hn=class hn{constructor(){F(this,x);ve(this,"current",new Map);ve(this,"previous",new Map);F(this,$,new Set);F(this,de,new Set);F(this,ie,0);F(this,he,0);F(this,pe,null);F(this,we,new Set);F(this,X,new Set);F(this,L,new Map);ve(this,"is_fork",!1);F(this,ye,!1)}skip_effect(n){_(this,L).has(n)||_(this,L).set(n,{d:[],m:[]})}unskip_effect(n){var t=_(this,L).get(n);if(t){_(this,L).delete(n);for(var r of t.d)E(r,S),z(r);for(r of t.m)E(r,q),z(r)}}process(n){var s;N=[],this.apply();var t=Te=[],r=[];for(const f of n)B(this,x,We).call(this,f,t,r);if(Te=null,B(this,x,Ze).call(this)){B(this,x,Je).call(this,r),B(this,x,Je).call(this,t);for(const[f,l]of _(this,L))Ln(f,l)}else{h=null;for(const f of _(this,$))f(this);_(this,$).clear(),_(this,ie)===0&&B(this,x,Qe).call(this),Tn(r),Tn(t),_(this,we).clear(),_(this,X).clear(),(s=_(this,pe))==null||s.resolve()}A=null}capture(n,t){t!==T&&!this.previous.has(n)&&this.previous.set(n,t),(n.f&W)===0&&(this.current.set(n,n.v),A==null||A.set(n,n.v))}activate(){h=this,this.apply()}deactivate(){h===this&&(h=null,A=null)}flush(){var n;if(N.length>0)h=this,Fn();else if(_(this,ie)===0&&!this.is_fork){for(const t of _(this,$))t(this);_(this,$).clear(),B(this,x,Qe).call(this),(n=_(this,pe))==null||n.resolve()}this.deactivate()}discard(){for(const n of _(this,de))n(this);_(this,de).clear()}increment(n){G(this,ie,_(this,ie)+1),n&&G(this,he,_(this,he)+1)}decrement(n){G(this,ie,_(this,ie)-1),n&&G(this,he,_(this,he)-1),!_(this,ye)&&(G(this,ye,!0),mn(()=>{G(this,ye,!1),B(this,x,Ze).call(this)?N.length>0&&this.flush():this.revive()}))}revive(){for(const n of _(this,we))_(this,X).delete(n),E(n,S),z(n);for(const n of _(this,X))E(n,q),z(n);this.flush()}oncommit(n){_(this,$).add(n)}ondiscard(n){_(this,de).add(n)}settled(){return(_(this,pe)??G(this,pe,kn())).promise}static ensure(){if(h===null){const n=h=new hn;je.add(h),Ie||mn(()=>{h===n&&n.flush()})}return h}apply(){}};$=new WeakMap,de=new WeakMap,ie=new WeakMap,he=new WeakMap,pe=new WeakMap,we=new WeakMap,X=new WeakMap,L=new WeakMap,ye=new WeakMap,x=new WeakSet,Ze=function(){return this.is_fork||_(this,he)>0},We=function(n,t,r){n.f^=m;for(var s=n.first;s!==null;){var f=s.f,l=(f&(H|_e))!==0,o=l&&(f&m)!==0,i=o||(f&Y)!==0||_(this,L).has(s);if(!i&&s.fn!==null){l?s.f^=m:(f&Se)!==0?t.push(s):Me(s)&&((f&ee)!==0&&_(this,X).add(s),Re(s));var a=s.first;if(a!==null){s=a;continue}}for(;s!==null;){var c=s.next;if(c!==null){s=c;break}s=s.parent}}},Je=function(n){for(var t=0;t1){this.previous.clear();var n=h,t=A,r=!0;for(const l of je){if(l===this){r=!1;continue}const o=[];for(const[a,c]of this.current){if(l.current.has(a))if(r&&c!==l.current.get(a))l.current.set(a,c);else continue;o.push(a)}if(o.length===0)continue;const i=[...l.current.keys()].filter(a=>!this.current.has(a));if(i.length>0){var s=N;N=[];const a=new Set,c=new Map;for(const u of o)Mn(u,i,a,c);if(N.length>0){h=l,l.apply();for(const u of N)B(f=l,x,We).call(f,u,[],[]);l.deactivate()}N=s}}h=n,A=t}_(this,L).clear(),je.delete(this)};let Ae=hn;function Pt(e){var n=Ie;Ie=!0;try{for(var t;;){if(xt(),N.length===0&&(h==null||h.flush(),N.length===0))return ze=null,t;Fn()}}finally{Ie=n}}function Fn(){var e=null;try{for(var n=0;N.length>0;){var t=Ae.ensure();if(n++>1e3){var r,s;Ft()}t.process(N),J.clear()}}finally{N=[],ze=null,Te=null}}function Ft(){try{mt()}catch(e){He(e,ze)}}let M=null;function Tn(e){var n=e.length;if(n!==0){for(var t=0;t0)){J.clear();for(const s of M){if((s.f&(Z|Y))!==0)continue;const f=[s];let l=s.parent;for(;l!==null;)M.has(l)&&(M.delete(l),f.push(l)),l=l.parent;for(let o=f.length-1;o>=0;o--){const i=f[o];(i.f&(Z|Y))===0&&Re(i)}}M.clear()}}M=null}}function Mn(e,n,t,r){if(!t.has(e)&&(t.add(e),e.reactions!==null))for(const s of e.reactions){const f=s.f;(f&b)!==0?Mn(s,n,t,r):(f&(fn|ee))!==0&&(f&S)===0&&jn(s,n,r)&&(E(s,S),z(s))}}function jn(e,n,t){const r=t.get(e);if(r!==void 0)return r;if(e.deps!==null)for(const s of e.deps){if(Ee.call(n,s))return!0;if((s.f&b)!==0&&jn(s,n,t))return t.set(s,!0),!0}return t.set(e,!1),!1}function z(e){var n=ze=e,t=n.b;if(t!=null&&t.is_pending&&(e.f&(Se|ge|Nn))!==0&&(e.f&ke)===0){t.defer_effect(e);return}for(;n.parent!==null;){n=n.parent;var r=n.f;if(Te!==null&&n===w&&(e.f&ge)===0)return;if((r&(_e|H))!==0){if((r&m)===0)return;n.f^=m}}N.push(n)}function Ln(e,n){if(!((e.f&H)!==0&&(e.f&m)!==0)){(e.f&S)!==0?n.d.push(e):(e.f&q)!==0&&n.m.push(e),E(e,m);for(var t=e.first;t!==null;)Ln(t,n),t=t.next}}function Mt(e,n,t,r){const s=Fe()?un:qt;var f=e.filter(u=>!u.settled);if(t.length===0&&f.length===0){r(n.map(s));return}var l=w,o=jt(),i=f.length===1?f[0].promise:f.length>1?Promise.all(f.map(u=>u.promise)):null;function a(u){o();try{r(u)}catch(d){(l.f&Z)===0&&He(d,l)}en()}if(t.length===0){i.then(()=>a(n.map(s)));return}function c(){o(),Promise.all(t.map(u=>Yt(u))).then(u=>a([...n.map(s),...u])).catch(u=>He(u,l))}i?i.then(c):c()}function jt(){var e=w,n=v,t=R,r=h;return function(f=!0){be(e),Q(n),qe(t),f&&(r==null||r.activate())}}function en(e=!0){be(null),Q(null),qe(null),e&&(h==null||h.deactivate())}function Lt(){var e=w.b,n=h,t=e.is_rendered();return e.update_pending_count(1),n.increment(t),()=>{e.update_pending_count(-1),n.decrement(t)}}function un(e){var n=b|S,t=v!==null&&(v.f&b)!==0?v:null;return w!==null&&(w.f|=Pe),{ctx:R,deps:null,effects:null,equals:Dn,f:n,fn:e,reactions:null,rv:0,v:T,wv:0,parent:t??w,ac:null}}function Yt(e,n,t){w===null&&wt();var s=void 0,f=_n(T),l=!v,o=new Map;return $t(()=>{var d;var i=kn();s=i.promise;try{Promise.resolve(e()).then(i.resolve,i.reject).finally(en)}catch(y){i.reject(y),en()}var a=h;if(l){var c=Lt();(d=o.get(a))==null||d.reject(re),o.delete(a),o.set(a,i)}const u=(y,p=void 0)=>{if(a.activate(),p)p!==re&&(f.f|=W,tn(f,p));else{(f.f&W)!==0&&(f.f^=W),tn(f,y);for(const[U,k]of o){if(o.delete(U),U===a)break;k.reject(re)}}c&&c()};i.promise.then(u,y=>u(null,y||"unknown"))}),Kt(()=>{for(const i of o.values())i.reject(re)}),new Promise(i=>{function a(c){function u(){c===s?i(f):a(s)}c.then(u,u)}a(s)})}function Pr(e){const n=un(e);return Qn(n),n}function qt(e){const n=un(e);return n.equals=In,n}function Ht(e){var n=e.effects;if(n!==null){e.effects=null;for(var t=0;t0&&!Hn&&Bt()}return n}function Bt(){Hn=!1;for(const e of nn)(e.f&m)!==0&&E(e,q),Me(e)&&Re(e);nn.clear()}function $e(e){te(e,e.v+1)}function Vn(e,n){var t=e.reactions;if(t!==null)for(var r=Fe(),s=t.length,f=0;f{if(le===f)return o();var i=v,a=le;Q(null),Rn(f);var c=o();return Q(i),Rn(a),c};return r&&t.set("length",K(e.length)),new Proxy(e,{defineProperty(o,i,a){(!("value"in a)||a.configurable===!1||a.enumerable===!1||a.writable===!1)&&Tt();var c=t.get(i);return c===void 0?l(()=>{var u=K(a.value);return t.set(i,u),u}):te(c,a.value,!0),!0},deleteProperty(o,i){var a=t.get(i);if(a===void 0){if(i in o){const c=l(()=>K(T));t.set(i,c),$e(s)}}else te(a,T),$e(s);return!0},get(o,i,a){var y;if(i===De)return e;var c=t.get(i),u=i in o;if(c===void 0&&(!u||(y=xe(o,i))!=null&&y.writable)&&(c=l(()=>{var p=Ne(u?o[i]:T),U=K(p);return U}),t.set(i,c)),c!==void 0){var d=Oe(c);return d===T?void 0:d}return Reflect.get(o,i,a)},getOwnPropertyDescriptor(o,i){var a=Reflect.getOwnPropertyDescriptor(o,i);if(a&&"value"in a){var c=t.get(i);c&&(a.value=Oe(c))}else if(a===void 0){var u=t.get(i),d=u==null?void 0:u.v;if(u!==void 0&&d!==T)return{enumerable:!0,configurable:!0,value:d,writable:!0}}return a},has(o,i){var d;if(i===De)return!0;var a=t.get(i),c=a!==void 0&&a.v!==T||Reflect.has(o,i);if(a!==void 0||w!==null&&(!c||(d=xe(o,i))!=null&&d.writable)){a===void 0&&(a=l(()=>{var y=c?Ne(o[i]):T,p=K(y);return p}),t.set(i,a));var u=Oe(a);if(u===T)return!1}return c},set(o,i,a,c){var wn;var u=t.get(i),d=i in o;if(r&&i==="length")for(var y=a;yK(T)),t.set(y+"",p))}if(u===void 0)(!d||(wn=xe(o,i))!=null&&wn.writable)&&(u=l(()=>K(void 0)),te(u,Ne(a)),t.set(i,u));else{d=u.v!==T;var U=l(()=>Ne(a));te(u,U)}var k=Reflect.getOwnPropertyDescriptor(o,i);if(k!=null&&k.set&&k.set.call(c,a),!d){if(r&&typeof i=="string"){var pn=t.get("length"),Ge=Number(i);Number.isInteger(Ge)&&Ge>=pn.v&&te(pn,Ge+1)}$e(s)}return!0},ownKeys(o){Oe(s);var i=Reflect.ownKeys(o).filter(u=>{var d=t.get(u);return d===void 0||d.v!==T});for(var[a,c]of t)c.v!==T&&!(a in o)&&i.push(a);return i},setPrototypeOf(){At()}})}var An,zt,Un,Bn;function Mr(){if(An===void 0){An=window,zt=/Firefox/.test(navigator.userAgent);var e=Element.prototype,n=Node.prototype,t=Text.prototype;Un=xe(n,"firstChild").get,Bn=xe(n,"nextSibling").get,En(e)&&(e.__click=void 0,e.__className=void 0,e.__attributes=null,e.__style=void 0,e.__e=void 0),En(t)&&(t.__t=void 0)}}function Ve(e=""){return document.createTextNode(e)}function rn(e){return Un.call(e)}function ne(e){return Bn.call(e)}function jr(e,n){if(!oe)return rn(e);var t=rn(g);if(t===null)t=g.appendChild(Ve());else if(n&&t.nodeType!==Ue){var r=Ve();return t==null||t.before(r),me(r),r}return n&&vn(t),me(t),t}function Lr(e,n=!1){if(!oe){var t=rn(e);return t instanceof Comment&&t.data===""?ne(t):t}if(n){if((g==null?void 0:g.nodeType)!==Ue){var r=Ve();return g==null||g.before(r),me(r),r}vn(g)}return g}function Yr(e,n=1,t=!1){let r=oe?g:e;for(var s;n--;)s=r,r=ne(r);if(!oe)return r;if(t){if((r==null?void 0:r.nodeType)!==Ue){var f=Ve();return r===null?s==null||s.after(f):r.before(f),me(f),f}vn(r)}return me(r),r}function qr(e){e.textContent=""}function Hr(){return!1}function Vr(e,n,t){return document.createElementNS(Nt,e,void 0)}function vn(e){if(e.nodeValue.length<65536)return;let n=e.nextSibling;for(;n!==null&&n.nodeType===Ue;)n.remove(),e.nodeValue+=n.nodeValue,n=e.nextSibling}function zn(e){var n=v,t=w;Q(null),be(null);try{return e()}finally{Q(n),be(t)}}function Gn(e){w===null&&(v===null&>(),Et()),ce&&yt()}function Gt(e,n){var t=n.last;t===null?n.last=n.first=e:(t.next=e,e.prev=t,n.last=e)}function V(e,n){var t=w;t!==null&&(t.f&Y)!==0&&(e|=Y);var r={ctx:R,deps:null,nodes:null,f:e|S|C,first:null,fn:n,last:null,next:null,parent:t,b:t&&t.b,prev:null,teardown:null,wv:0,ac:null},s=r;if((e&Se)!==0)Te!==null?Te.push(r):z(r);else if(n!==null){try{Re(r)}catch(l){throw ue(r),l}s.deps===null&&s.teardown===null&&s.nodes===null&&s.first===s.last&&(s.f&Pe)===0&&(s=s.first,(e&ee)!==0&&(e&Ye)!==0&&s!==null&&(s.f|=Ye))}if(s!==null&&(s.parent=t,t!==null&&Gt(s,t),v!==null&&(v.f&b)!==0&&(e&_e)===0)){var f=v;(f.effects??(f.effects=[])).push(s)}return r}function Kn(){return v!==null&&!j}function Kt(e){const n=V(ge,null);return E(n,m),n.teardown=e,n}function Ur(e){Gn();var n=w.f,t=!v&&(n&H)!==0&&(n&ke)===0;if(t){var r=R;(r.e??(r.e=[])).push(e)}else return $n(e)}function $n(e){return V(Se|On,e)}function Br(e){return Gn(),V(ge|On,e)}function zr(e){Ae.ensure();const n=V(_e|Pe,e);return(t={})=>new Promise(r=>{t.outro?Wt(n,()=>{ue(n),r(void 0)}):(ue(n),r(void 0))})}function Gr(e){return V(Se,e)}function $t(e){return V(fn|Pe,e)}function Kr(e,n=0){return V(ge|n,e)}function $r(e,n=[],t=[],r=[]){Mt(r,n,t,s=>{V(ge,()=>e(...s.map(Oe)))})}function Xr(e,n=0){var t=V(ee|n,e);return t}function Zr(e){return V(H|Pe,e)}function Xn(e){var n=e.teardown;if(n!==null){const t=ce,r=v;bn(!0),Q(null);try{n.call(null)}finally{bn(t),Q(r)}}}function dn(e,n=!1){var t=e.first;for(e.first=e.last=null;t!==null;){const s=t.ac;s!==null&&zn(()=>{s.abort(re)});var r=t.next;(t.f&_e)!==0?t.parent=null:ue(t,n),t=r}}function Xt(e){for(var n=e.first;n!==null;){var t=n.next;(n.f&H)===0&&ue(n),n=t}}function ue(e,n=!0){var t=!1;(n||(e.f&pt)!==0)&&e.nodes!==null&&e.nodes.end!==null&&(Zt(e.nodes.start,e.nodes.end),t=!0),dn(e,n&&!t),Ce(e,0),E(e,Z);var r=e.nodes&&e.nodes.t;if(r!==null)for(const f of r)f.stop();Xn(e);var s=e.parent;s!==null&&s.first!==null&&Zn(e),e.next=e.prev=e.teardown=e.ctx=e.deps=e.fn=e.nodes=e.ac=null}function Zt(e,n){for(;e!==null;){var t=e===n?null:ne(e);e.remove(),e=t}}function Zn(e){var n=e.parent,t=e.prev,r=e.next;t!==null&&(t.next=r),r!==null&&(r.prev=t),n!==null&&(n.first===e&&(n.first=r),n.last===e&&(n.last=t))}function Wt(e,n,t=!0){var r=[];Wn(e,r,!0);var s=()=>{t&&ue(e),n&&n()},f=r.length;if(f>0){var l=()=>--f||s();for(var o of r)o.out(l)}else s()}function Wn(e,n,t){if((e.f&Y)===0){e.f^=Y;var r=e.nodes&&e.nodes.t;if(r!==null)for(const o of r)(o.is_global||t)&&n.push(o);for(var s=e.first;s!==null;){var f=s.next,l=(s.f&Ye)!==0||(s.f&H)!==0&&(e.f&ee)!==0;Wn(s,n,l?t:!1),s=f}}}function Wr(e){Jn(e,!0)}function Jn(e,n){if((e.f&Y)!==0){e.f^=Y,(e.f&m)===0&&(E(e,S),z(e));for(var t=e.first;t!==null;){var r=t.next,s=(t.f&Ye)!==0||(t.f&H)!==0;Jn(t,s?n:!1),t=r}var f=e.nodes&&e.nodes.t;if(f!==null)for(const l of f)(l.is_global||n)&&l.in()}}function Jr(e,n){if(e.nodes)for(var t=e.nodes.start,r=e.nodes.end;t!==null;){var s=t===r?null:ne(t);n.append(t),t=s}}let Le=!1,ce=!1;function bn(e){ce=e}let v=null,j=!1;function Q(e){v=e}let w=null;function be(e){w=e}let P=null;function Qn(e){v!==null&&(P===null?P=[e]:P.push(e))}let O=null,D=0,I=null;function Jt(e){I=e}let et=1,fe=0,le=fe;function Rn(e){le=e}function nt(){return++et}function Me(e){var n=e.f;if((n&S)!==0)return!0;if(n&b&&(e.f&=~ae),(n&q)!==0){for(var t=e.deps,r=t.length,s=0;se.wv)return!0}(n&C)!==0&&A===null&&E(e,m)}return!1}function tt(e,n,t=!0){var r=e.reactions;if(r!==null&&!(P!==null&&Ee.call(P,e)))for(var s=0;s{e.ac.abort(re)}),e.ac=null);try{e.f|=Xe;var c=e.fn,u=c();e.f|=ke;var d=e.deps,y=h==null?void 0:h.is_fork;if(O!==null){var p;if(y||Ce(e,D),d!==null&&D>0)for(d.length=D+O.length,p=0;p{throw TypeError(t)};var Ie=(t,e,r)=>e in t?Ye(t,e,{enumerable:!0,configurable:!0,writable:!0,value:r}):t[e]=r;var j=(t,e,r)=>Ie(t,typeof e!="symbol"?e+"":e,r),re=(t,e,r)=>e.has(t)||ue("Cannot "+r);var s=(t,e,r)=>(re(t,e,"read from private field"),r?r.call(t):e.get(t)),c=(t,e,r)=>e.has(t)?ue("Cannot add the same private member more than once"):e instanceof WeakSet?e.add(t):e.set(t,r),n=(t,e,r,a)=>(re(t,e,"write to private field"),a?a.call(t,r):e.set(t,r),r),p=(t,e,r)=>(re(t,e,"access private method"),r);import{W as Me,g as me,X as Le,Y as we,F as Be,Z as _e,_ as V,j as Y,h as I,O as C,$ as pe,b as He,c as Ce,d as Pe,a0 as ge,n as k,m as Te,a1 as se,p as ie,q as We,a2 as ve,a3 as qe,a4 as ye,a5 as xe,a6 as Ve,a7 as G,a8 as K,a9 as be,aa as $e,ab as Re,B as Se,ac as je,l as ae,f as Q,ad as ze,e as Je,ae as z,E as Ue,af as Xe,ag as Ze,ah as Ge,ai as Ke,aj as Qe,ak as et,al as ne,P as tt,am as De,H as rt,an as st,ao as fe,i as J,ap as it,aq as at,ar as nt,as as ft,u as ht,at as ot,au as lt,w as ct}from"./Ym0WvvUy.js";import{b as dt}from"./B6M6q2Zo.js";function ut(t){let e=0,r=we(0),a;return()=>{Me()&&(me(r),Le(()=>(e===0&&(a=Be(()=>t(()=>_e(r)))),e+=1,()=>{V(()=>{e-=1,e===0&&(a==null||a(),a=void 0,_e(r))})})))}}var _t=Ue|Xe;function pt(t,e,r,a){new gt(t,e,r,a)}var E,$,T,L,g,R,m,w,S,B,A,P,W,q,D,ee,o,Ne,Ae,Oe,he,X,Z,oe;class gt{constructor(e,r,a,h){c(this,o);j(this,"parent");j(this,"is_pending",!1);j(this,"transform_error");c(this,E);c(this,$,I?Y:null);c(this,T);c(this,L);c(this,g);c(this,R,null);c(this,m,null);c(this,w,null);c(this,S,null);c(this,B,0);c(this,A,0);c(this,P,!1);c(this,W,new Set);c(this,q,new Set);c(this,D,null);c(this,ee,ut(()=>(n(this,D,we(s(this,B))),()=>{n(this,D,null)})));var i;n(this,E,e),n(this,T,r),n(this,L,f=>{var u=C;u.b=this,u.f|=pe,a(f)}),this.parent=C.b,this.transform_error=h??((i=this.parent)==null?void 0:i.transform_error)??(f=>f),n(this,g,He(()=>{if(I){const f=s(this,$);Ce();const u=f.data===Pe;if(f.data.startsWith(ge)){const d=JSON.parse(f.data.slice(ge.length));p(this,o,Ae).call(this,d)}else u?p(this,o,Oe).call(this):p(this,o,Ne).call(this)}else p(this,o,he).call(this)},_t)),I&&n(this,E,Y)}defer_effect(e){Ve(e,s(this,W),s(this,q))}is_rendered(){return!this.is_pending&&(!this.parent||this.parent.is_rendered())}has_pending_snippet(){return!!s(this,T).pending}update_pending_count(e){p(this,o,oe).call(this,e),n(this,B,s(this,B)+e),!(!s(this,D)||s(this,P))&&(n(this,P,!0),V(()=>{n(this,P,!1),s(this,D)&&je(s(this,D),s(this,B))}))}get_effect_pending(){return s(this,ee).call(this),me(s(this,D))}error(e){var r=s(this,T).onerror;let a=s(this,T).failed;if(!r&&!a)throw e;s(this,R)&&(ae(s(this,R)),n(this,R,null)),s(this,m)&&(ae(s(this,m)),n(this,m,null)),s(this,w)&&(ae(s(this,w)),n(this,w,null)),I&&(Q(s(this,$)),ze(),Q(Je()));var h=!1,i=!1;const f=()=>{if(h){Ge();return}h=!0,i&&Ze(),s(this,w)!==null&&ie(s(this,w),()=>{n(this,w,null)}),p(this,o,Z).call(this,()=>{se.ensure(),p(this,o,he).call(this)})},u=l=>{try{i=!0,r==null||r(l,f),i=!1}catch(d){z(d,s(this,g)&&s(this,g).parent)}a&&n(this,w,p(this,o,Z).call(this,()=>{se.ensure();try{return k(()=>{var d=C;d.b=this,d.f|=pe,a(s(this,E),()=>l,()=>f)})}catch(d){return z(d,s(this,g).parent),null}}))};V(()=>{var l;try{l=this.transform_error(e)}catch(d){z(d,s(this,g)&&s(this,g).parent);return}l!==null&&typeof l=="object"&&typeof l.then=="function"?l.then(u,d=>z(d,s(this,g)&&s(this,g).parent)):u(l)})}}E=new WeakMap,$=new WeakMap,T=new WeakMap,L=new WeakMap,g=new WeakMap,R=new WeakMap,m=new WeakMap,w=new WeakMap,S=new WeakMap,B=new WeakMap,A=new WeakMap,P=new WeakMap,W=new WeakMap,q=new WeakMap,D=new WeakMap,ee=new WeakMap,o=new WeakSet,Ne=function(){try{n(this,R,k(()=>s(this,L).call(this,s(this,E))))}catch(e){this.error(e)}},Ae=function(e){const r=s(this,T).failed;r&&n(this,w,k(()=>{r(s(this,E),()=>e,()=>()=>{})}))},Oe=function(){const e=s(this,T).pending;e&&(this.is_pending=!0,n(this,m,k(()=>e(s(this,E)))),V(()=>{var r=n(this,S,document.createDocumentFragment()),a=Te();r.append(a),n(this,R,p(this,o,Z).call(this,()=>(se.ensure(),k(()=>s(this,L).call(this,a))))),s(this,A)===0&&(s(this,E).before(r),n(this,S,null),ie(s(this,m),()=>{n(this,m,null)}),p(this,o,X).call(this))}))},he=function(){try{if(this.is_pending=this.has_pending_snippet(),n(this,A,0),n(this,B,0),n(this,R,k(()=>{s(this,L).call(this,s(this,E))})),s(this,A)>0){var e=n(this,S,document.createDocumentFragment());We(s(this,R),e);const r=s(this,T).pending;n(this,m,k(()=>r(s(this,E))))}else p(this,o,X).call(this)}catch(r){this.error(r)}},X=function(){this.is_pending=!1;for(const e of s(this,W))ve(e,qe),ye(e);for(const e of s(this,q))ve(e,xe),ye(e);s(this,W).clear(),s(this,q).clear()},Z=function(e){var r=C,a=Re,h=Se;G(s(this,g)),K(s(this,g)),be(s(this,g).ctx);try{return e()}catch(i){return $e(i),null}finally{G(r),K(a),be(h)}},oe=function(e){var r;if(!this.has_pending_snippet()){this.parent&&p(r=this.parent,o,oe).call(r,e);return}n(this,A,s(this,A)+e),s(this,A)===0&&(p(this,o,X).call(this),s(this,m)&&ie(s(this,m),()=>{n(this,m,null)}),s(this,S)&&(s(this,E).before(s(this,S)),n(this,S,null)))};const vt=["touchstart","touchmove"];function yt(t){return vt.includes(t)}const M=Symbol("events"),Fe=new Set,le=new Set;function bt(t,e,r,a={}){function h(i){if(a.capture||ce.call(e,i),!i.cancelBubble)return Qe(()=>r==null?void 0:r.call(this,i))}return t.startsWith("pointer")||t.startsWith("touch")||t==="wheel"?V(()=>{e.addEventListener(t,h,a)}):e.addEventListener(t,h,a),h}function Rt(t,e,r,a,h){var i={capture:a,passive:h},f=bt(t,e,r,i);(e===document.body||e===window||e===document||e instanceof HTMLMediaElement)&&Ke(()=>{e.removeEventListener(t,f,i)})}function St(t,e,r){(e[M]??(e[M]={}))[t]=r}function Dt(t){for(var e=0;e{throw F});throw N}}finally{t[M]=e,delete t.currentTarget,K(H),G(x)}}}function Nt(t,e){var r=e==null?"":typeof e=="object"?`${e}`:e;r!==(t.__t??(t.__t=t.nodeValue))&&(t.__t=r,t.nodeValue=`${r}`)}function Et(t,e){return ke(t,e)}function At(t,e){ne(),e.intro=e.intro??!1;const r=e.target,a=I,h=Y;try{for(var i=tt(r);i&&(i.nodeType!==De||i.data!==rt);)i=st(i);if(!i)throw fe;J(!0),Q(i);const f=ke(t,{...e,anchor:i});return J(!1),f}catch(f){if(f instanceof Error&&f.message.split(` +`).some(u=>u.startsWith("https://svelte.dev/e/")))throw f;return f!==fe&&console.warn("Failed to hydrate: ",f),e.recover===!1&&it(),ne(),at(r),J(!1),Et(t,e)}finally{J(a),Q(h)}}const U=new Map;function ke(t,{target:e,anchor:r,props:a={},events:h,context:i,intro:f=!0,transformError:u}){ne();var l=void 0,d=nt(()=>{var H=r??e.appendChild(Te());pt(H,{pending:()=>{}},v=>{ht({});var _=Se;if(i&&(_.c=i),h&&(a.$$events=h),I&&dt(v,null),l=t(v,a)||{},I&&(C.nodes.end=Y,Y===null||Y.nodeType!==De||Y.data!==ot))throw lt(),fe;ct()},u);var x=new Set,N=v=>{for(var _=0;_{var O;for(var v of x)for(const b of[e,document]){var _=U.get(b),y=_.get(v);--y==0?(b.removeEventListener(v,ce),_.delete(v),_.size===0&&U.delete(b)):_.set(v,y)}le.delete(N),H!==r&&((O=H.parentNode)==null||O.removeChild(H))}});return de.set(l,d),l}let de=new WeakMap;function Ot(t,e){const r=de.get(t);return r?(de.delete(t),r(e)):Promise.resolve()}export{St as a,Dt as d,Rt as e,At as h,Et as m,Nt as s,Ot as u}; diff --git a/frontend/build/_app/immutable/chunks/giww_vF6.js b/frontend/build/_app/immutable/chunks/giww_vF6.js new file mode 100644 index 0000000..e2bacc2 --- /dev/null +++ b/frontend/build/_app/immutable/chunks/giww_vF6.js @@ -0,0 +1 @@ +var Qt=t=>{throw TypeError(t)};var Oe=(t,e,n)=>e.has(t)||Qt("Cannot "+n);var w=(t,e,n)=>(Oe(t,e,"read from private field"),n?n.call(t):e.get(t)),A=(t,e,n)=>e.has(t)?Qt("Cannot add the same private member more than once"):e instanceof WeakSet?e.add(t):e.set(t,n);import{a$ as Ut,b0 as Ce,s as T,g as I,a as P,aZ as gt,b1 as je}from"./Ym0WvvUy.js";import{o as te}from"./Bfwrz3i4.js";const M=[];function qt(t,e=Ut){let n=null;const r=new Set;function a(s){if(Ce(t,s)&&(t=s,n)){const l=!M.length;for(const c of r)c[1](),M.push(c,t);if(l){for(let c=0;c{r.delete(c),r.size===0&&n&&(n(),n=null)}}return{set:a,update:i,subscribe:o}}class Dt{constructor(e,n){this.status=e,typeof n=="string"?this.body={message:n}:n?this.body=n:this.body={message:`Error: ${e}`}}toString(){return JSON.stringify(this.body)}}class Vt{constructor(e,n){this.status=e,this.location=n}}class Bt extends Error{constructor(e,n,r){super(r),this.status=e,this.text=n}}new URL("sveltekit-internal://");function Ne(t,e){return t==="/"||e==="ignore"?t:e==="never"?t.endsWith("/")?t.slice(0,-1):t:e==="always"&&!t.endsWith("/")?t+"/":t}function qe(t){return t.split("%25").map(decodeURI).join("%25")}function De(t){for(const e in t)t[e]=decodeURIComponent(t[e]);return t}function At({href:t}){return t.split("#")[0]}function Ve(...t){let e=5381;for(const n of t)if(typeof n=="string"){let r=n.length;for(;r;)e=e*33^n.charCodeAt(--r)}else if(ArrayBuffer.isView(n)){const r=new Uint8Array(n.buffer,n.byteOffset,n.byteLength);let a=r.length;for(;a;)e=e*33^r[--a]}else throw new TypeError("value must be a string or TypedArray");return(e>>>0).toString(36)}new TextEncoder;new TextDecoder;function Be(t){const e=atob(t),n=new Uint8Array(e.length);for(let r=0;r((t instanceof Request?t.method:(e==null?void 0:e.method)||"GET")!=="GET"&&Y.delete(Kt(t)),Ke(t,e));const Y=new Map;function Me(t,e){const n=Kt(t,e),r=document.querySelector(n);if(r!=null&&r.textContent){r.remove();let{body:a,...i}=JSON.parse(r.textContent);const o=r.getAttribute("data-ttl");return o&&Y.set(n,{body:a,init:i,ttl:1e3*Number(o)}),r.getAttribute("data-b64")!==null&&(a=Be(a)),Promise.resolve(new Response(a,i))}return window.fetch(t,e)}function ze(t,e,n){if(Y.size>0){const r=Kt(t,n),a=Y.get(r);if(a){if(performance.now(){const a=/^\[\.\.\.(\w+)(?:=(\w+))?\]$/.exec(r);if(a)return e.push({name:a[1],matcher:a[2],optional:!1,rest:!0,chained:!0}),"(?:/([^]*))?";const i=/^\[\[(\w+)(?:=(\w+))?\]\]$/.exec(r);if(i)return e.push({name:i[1],matcher:i[2],optional:!0,rest:!1,chained:!0}),"(?:/([^/]+))?";if(!r)return;const o=r.split(/\[(.+?)\](?!\])/);return"/"+o.map((l,c)=>{if(c%2){if(l.startsWith("x+"))return Tt(String.fromCharCode(parseInt(l.slice(2),16)));if(l.startsWith("u+"))return Tt(String.fromCharCode(...l.slice(2).split("-").map(_=>parseInt(_,16))));const d=Fe.exec(l),[,u,v,f,h]=d;return e.push({name:f,matcher:h,optional:!!u,rest:!!v,chained:v?c===1&&o[0]==="":!1}),v?"([^]*?)":u?"([^/]*)?":"([^/]+?)"}return Tt(l)}).join("")}).join("")}/?$`),params:e}}function We(t){return t!==""&&!/^\([^)]+\)$/.test(t)}function Ye(t){return t.slice(1).split("/").filter(We)}function He(t,e,n){const r={},a=t.slice(1),i=a.filter(s=>s!==void 0);let o=0;for(let s=0;sd).join("/"),o=0),c===void 0)if(l.rest)c="";else continue;if(!l.matcher||n[l.matcher](c)){r[l.name]=c;const d=e[s+1],u=a[s+1];d&&!d.rest&&d.optional&&u&&l.chained&&(o=0),!d&&!u&&Object.keys(r).length===i.length&&(o=0);continue}if(l.optional&&l.chained){o++;continue}return}if(!o)return r}function Tt(t){return t.normalize().replace(/[[\]]/g,"\\$&").replace(/%/g,"%25").replace(/\//g,"%2[Ff]").replace(/\?/g,"%3[Ff]").replace(/#/g,"%23").replace(/[.*+?^${}()|\\]/g,"\\$&")}function Je({nodes:t,server_loads:e,dictionary:n,matchers:r}){const a=new Set(e);return Object.entries(n).map(([s,[l,c,d]])=>{const{pattern:u,params:v}=Ge(s),f={id:s,exec:h=>{const _=u.exec(h);if(_)return He(_,v,r)},errors:[1,...d||[]].map(h=>t[h]),layouts:[0,...c||[]].map(o),leaf:i(l)};return f.errors.length=f.layouts.length=Math.max(f.errors.length,f.layouts.length),f});function i(s){const l=s<0;return l&&(s=~s),[l,t[s]]}function o(s){return s===void 0?s:[a.has(s),t[s]]}}function he(t,e=JSON.parse){try{return e(sessionStorage[t])}catch{}}function ee(t,e,n=JSON.stringify){const r=n(e);try{sessionStorage[t]=r}catch{}}var le;const U=((le=globalThis.__sveltekit_1rgg0vt)==null?void 0:le.base)??"";var ce;const Xe=((ce=globalThis.__sveltekit_1rgg0vt)==null?void 0:ce.assets)??U??"",Ze="1772333625386",pe="sveltekit:snapshot",ge="sveltekit:scroll",me="sveltekit:states",Qe="sveltekit:pageurl",F="sveltekit:history",J="sveltekit:navigation",q={tap:1,hover:2,viewport:3,eager:4,off:-1,false:-1},Et=location.origin;function Mt(t){if(t instanceof URL)return t;let e=document.baseURI;if(!e){const n=document.getElementsByTagName("base");e=n.length?n[0].href:document.URL}return new URL(t,e)}function V(){return{x:pageXOffset,y:pageYOffset}}function z(t,e){return t.getAttribute(`data-sveltekit-${e}`)}const ne={...q,"":q.hover};function _e(t){let e=t.assignedSlot??t.parentNode;return(e==null?void 0:e.nodeType)===11&&(e=e.host),e}function we(t,e){for(;t&&t!==e;){if(t.nodeName.toUpperCase()==="A"&&t.hasAttribute("href"))return t;t=_e(t)}}function $t(t,e,n){let r;try{if(r=new URL(t instanceof SVGAElement?t.href.baseVal:t.href,document.baseURI),n&&r.hash.match(/^#[^/]/)){const s=location.hash.split("#")[1]||"/";r.hash=`#${s}${r.hash}`}}catch{}const a=t instanceof SVGAElement?t.target.baseVal:t.target,i=!r||!!a||Rt(r,e,n)||(t.getAttribute("rel")||"").split(/\s+/).includes("external"),o=(r==null?void 0:r.origin)===Et&&t.hasAttribute("download");return{url:r,external:i,target:a,download:o}}function mt(t){let e=null,n=null,r=null,a=null,i=null,o=null,s=t;for(;s&&s!==document.documentElement;)r===null&&(r=z(s,"preload-code")),a===null&&(a=z(s,"preload-data")),e===null&&(e=z(s,"keepfocus")),n===null&&(n=z(s,"noscroll")),i===null&&(i=z(s,"reload")),o===null&&(o=z(s,"replacestate")),s=_e(s);function l(c){switch(c){case"":case"true":return!0;case"off":case"false":return!1;default:return}}return{preload_code:ne[r??"off"],preload_data:ne[a??"off"],keepfocus:l(e),noscroll:l(n),reload:l(i),replace_state:l(o)}}function ae(t){const e=qt(t);let n=!0;function r(){n=!0,e.update(o=>o)}function a(o){n=!1,e.set(o)}function i(o){let s;return e.subscribe(l=>{(s===void 0||n&&l!==s)&&o(s=l)})}return{notify:r,set:a,subscribe:i}}const ve={v:()=>{}};function tn(){const{set:t,subscribe:e}=qt(!1);let n;async function r(){clearTimeout(n);try{const a=await fetch(`${Xe}/_app/version.json`,{headers:{pragma:"no-cache","cache-control":"no-cache"}});if(!a.ok)return!1;const o=(await a.json()).version!==Ze;return o&&(t(!0),ve.v(),clearTimeout(n)),o}catch{return!1}}return{subscribe:e,check:r}}function Rt(t,e,n){return t.origin!==Et||!t.pathname.startsWith(e)?!0:n?t.pathname!==location.pathname:!1}function An(t){}const ye=new Set(["load","prerender","csr","ssr","trailingSlash","config"]);[...ye];const en=new Set([...ye]);[...en];function nn(t){return t.filter(e=>e!=null)}function zt(t){return t instanceof Dt||t instanceof Bt?t.status:500}function an(t){return t instanceof Bt?t.text:"Internal Error"}let R,X,It;const rn=te.toString().includes("$$")||/function \w+\(\) \{\}/.test(te.toString());var nt,at,rt,ot,st,it,lt,ct,fe,ft,ue,ut,de;rn?(R={data:{},form:null,error:null,params:{},route:{id:null},state:{},status:-1,url:new URL("https://example.com")},X={current:null},It={current:!1}):(R=new(fe=class{constructor(){A(this,nt,T({}));A(this,at,T(null));A(this,rt,T(null));A(this,ot,T({}));A(this,st,T({id:null}));A(this,it,T({}));A(this,lt,T(-1));A(this,ct,T(new URL("https://example.com")))}get data(){return I(w(this,nt))}set data(e){P(w(this,nt),e)}get form(){return I(w(this,at))}set form(e){P(w(this,at),e)}get error(){return I(w(this,rt))}set error(e){P(w(this,rt),e)}get params(){return I(w(this,ot))}set params(e){P(w(this,ot),e)}get route(){return I(w(this,st))}set route(e){P(w(this,st),e)}get state(){return I(w(this,it))}set state(e){P(w(this,it),e)}get status(){return I(w(this,lt))}set status(e){P(w(this,lt),e)}get url(){return I(w(this,ct))}set url(e){P(w(this,ct),e)}},nt=new WeakMap,at=new WeakMap,rt=new WeakMap,ot=new WeakMap,st=new WeakMap,it=new WeakMap,lt=new WeakMap,ct=new WeakMap,fe),X=new(ue=class{constructor(){A(this,ft,T(null))}get current(){return I(w(this,ft))}set current(e){P(w(this,ft),e)}},ft=new WeakMap,ue),It=new(de=class{constructor(){A(this,ut,T(!1))}get current(){return I(w(this,ut))}set current(e){P(w(this,ut),e)}},ut=new WeakMap,de),ve.v=()=>It.current=!0);function on(t){Object.assign(R,t)}const sn=new Set(["icon","shortcut icon","apple-touch-icon"]),j=he(ge)??{},Z=he(pe)??{},C={url:ae({}),page:ae({}),navigating:qt(null),updated:tn()};function Ft(t){j[t]=V()}function ln(t,e){let n=t+1;for(;j[n];)delete j[n],n+=1;for(n=e+1;Z[n];)delete Z[n],n+=1}function Q(t,e=!1){return e?location.replace(t.href):location.href=t.href,new Promise(()=>{})}async function be(){if("serviceWorker"in navigator){const t=await navigator.serviceWorker.getRegistration(U||"/");t&&await t.update()}}function re(){}let Gt,Ot,_t,$,Ct,S;const wt=[],vt=[];let y=null;function jt(){var t;(t=y==null?void 0:y.fork)==null||t.then(e=>e==null?void 0:e.discard()),y=null}const pt=new Map,ke=new Set,cn=new Set,H=new Set;let m={branch:[],error:null,url:null},Se=!1,yt=!1,oe=!0,tt=!1,W=!1,Ee=!1,Wt=!1,Re,k,L,D;const bt=new Set,se=new Map;async function $n(t,e,n){var i,o,s,l,c;(i=globalThis.__sveltekit_1rgg0vt)!=null&&i.data&&globalThis.__sveltekit_1rgg0vt.data,document.URL!==location.href&&(location.href=location.href),S=t,await((s=(o=t.hooks).init)==null?void 0:s.call(o)),Gt=Je(t),$=document.documentElement,Ct=e,Ot=t.nodes[0],_t=t.nodes[1],Ot(),_t(),k=(l=history.state)==null?void 0:l[F],L=(c=history.state)==null?void 0:c[J],k||(k=L=Date.now(),history.replaceState({...history.state,[F]:k,[J]:L},""));const r=j[k];function a(){r&&(history.scrollRestoration="manual",scrollTo(r.x,r.y))}n?(a(),await kn(Ct,n)):(await G({type:"enter",url:Mt(S.hash?Rn(new URL(location.href)):location.href),replace_state:!0}),a()),bn()}function fn(){wt.length=0,Wt=!1}function xe(t){vt.some(e=>e==null?void 0:e.snapshot)&&(Z[t]=vt.map(e=>{var n;return(n=e==null?void 0:e.snapshot)==null?void 0:n.capture()}))}function Le(t){var e;(e=Z[t])==null||e.forEach((n,r)=>{var a,i;(i=(a=vt[r])==null?void 0:a.snapshot)==null||i.restore(n)})}function ie(){Ft(k),ee(ge,j),xe(L),ee(pe,Z)}async function Ue(t,e,n,r){let a;e.invalidateAll&&jt(),await G({type:"goto",url:Mt(t),keepfocus:e.keepFocus,noscroll:e.noScroll,replace_state:e.replaceState,state:e.state,redirect_count:n,nav_token:r,accept:()=>{e.invalidateAll&&(Wt=!0,a=[...se.keys()]),e.invalidate&&e.invalidate.forEach(yn)}}),e.invalidateAll&>().then(gt).then(()=>{se.forEach(({resource:i},o)=>{var s;a!=null&&a.includes(o)&&((s=i.refresh)==null||s.call(i))})})}async function un(t){if(t.id!==(y==null?void 0:y.id)){jt();const e={};bt.add(e),y={id:t.id,token:e,promise:Te({...t,preload:e}).then(n=>(bt.delete(e),n.type==="loaded"&&n.state.error&&jt(),n)),fork:null}}return y.promise}async function Pt(t){var n;const e=(n=await xt(t,!1))==null?void 0:n.route;e&&await Promise.all([...e.layouts,e.leaf].filter(Boolean).map(r=>r[1]()))}async function Ae(t,e,n){var a;m=t.state;const r=document.querySelector("style[data-sveltekit]");if(r&&r.remove(),Object.assign(R,t.props.page),Re=new S.root({target:e,props:{...t.props,stores:C,components:vt},hydrate:n,sync:!1}),await Promise.resolve(),Le(L),n){const i={from:null,to:{params:m.params,route:{id:((a=m.route)==null?void 0:a.id)??null},url:new URL(location.href),scroll:j[k]??V()},willUnload:!1,type:"enter",complete:Promise.resolve()};H.forEach(o=>o(i))}yt=!0}function kt({url:t,params:e,branch:n,status:r,error:a,route:i,form:o}){let s="never";if(U&&(t.pathname===U||t.pathname===U+"/"))s="always";else for(const f of n)(f==null?void 0:f.slash)!==void 0&&(s=f.slash);t.pathname=Ne(t.pathname,s),t.search=t.search;const l={type:"loaded",state:{url:t,params:e,branch:n,error:a,route:i},props:{constructors:nn(n).map(f=>f.node.component),page:Zt(R)}};o!==void 0&&(l.props.form=o);let c={},d=!R,u=0;for(let f=0;fs(new URL(o))))return!0;return!1}function Ht(t,e){return(t==null?void 0:t.type)==="data"?t:(t==null?void 0:t.type)==="skip"?e??null:null}function pn(t,e){if(!t)return new Set(e.searchParams.keys());const n=new Set([...t.searchParams.keys(),...e.searchParams.keys()]);for(const r of n){const a=t.searchParams.getAll(r),i=e.searchParams.getAll(r);a.every(o=>i.includes(o))&&i.every(o=>a.includes(o))&&n.delete(r)}return n}function gn({error:t,url:e,route:n,params:r}){return{type:"loaded",state:{error:t,url:e,route:n,params:r,branch:[]},props:{page:Zt(R),constructors:[]}}}async function Te({id:t,invalidating:e,url:n,params:r,route:a,preload:i}){if((y==null?void 0:y.id)===t)return bt.delete(y.token),y.promise;const{errors:o,layouts:s,leaf:l}=a,c=[...s,l];o.forEach(g=>g==null?void 0:g().catch(()=>{})),c.forEach(g=>g==null?void 0:g[1]().catch(()=>{}));const d=m.url?t!==St(m.url):!1,u=m.route?a.id!==m.route.id:!1,v=pn(m.url,n);let f=!1;const h=c.map(async(g,p)=>{var O;if(!g)return;const b=m.branch[p];return g[1]===(b==null?void 0:b.loader)&&!hn(f,u,d,v,(O=b.universal)==null?void 0:O.uses,r)?b:(f=!0,Yt({loader:g[1],url:n,params:r,route:a,parent:async()=>{var dt;const N={};for(let B=0;B{});const _=[];for(let g=0;gPromise.resolve({}),server_data_node:Ht(i)}),s={node:await _t(),loader:_t,universal:null,server:null,data:null};return kt({url:n,params:a,branch:[o,s],status:t,error:e,route:null})}catch(o){if(o instanceof Vt)return Ue(new URL(o.location,location.href),{},0);throw o}}async function _n(t){const e=t.href;if(pt.has(e))return pt.get(e);let n;try{const r=(async()=>{let a=await S.hooks.reroute({url:new URL(t),fetch:async(i,o)=>dn(i,o,t).promise})??t;if(typeof a=="string"){const i=new URL(t);S.hash?i.hash=a:i.pathname=a,a=i}return a})();pt.set(e,r),n=await r}catch{pt.delete(e);return}return n}async function xt(t,e){if(t&&!Rt(t,U,S.hash)){const n=await _n(t);if(!n)return;const r=wn(n);for(const a of Gt){const i=a.exec(r);if(i)return{id:St(t),invalidating:e,route:a,params:De(i),url:t}}}}function wn(t){return qe(S.hash?t.hash.replace(/^#/,"").replace(/[?#].+/,""):t.pathname.slice(U.length))||"/"}function St(t){return(S.hash?t.hash.replace(/^#/,""):t.pathname)+t.search}function Ie({url:t,type:e,intent:n,delta:r,event:a,scroll:i}){let o=!1;const s=Xt(m,n,t,e,i??null);r!==void 0&&(s.navigation.delta=r),a!==void 0&&(s.navigation.event=a);const l={...s.navigation,cancel:()=>{o=!0,s.reject(new Error("navigation cancelled"))}};return tt||ke.forEach(c=>c(l)),o?null:s}async function G({type:t,url:e,popped:n,keepfocus:r,noscroll:a,replace_state:i,state:o={},redirect_count:s=0,nav_token:l={},accept:c=re,block:d=re,event:u}){var B;const v=D;D=l;const f=await xt(e,!1),h=t==="enter"?Xt(m,f,e,t):Ie({url:e,type:t,delta:n==null?void 0:n.delta,intent:f,scroll:n==null?void 0:n.scroll,event:u});if(!h){d(),D===l&&(D=v);return}const _=k,g=L;c(),tt=!0,yt&&h.navigation.type!=="enter"&&C.navigating.set(X.current=h.navigation);let p=f&&await Te(f);if(!p){if(Rt(e,U,S.hash))return await Q(e,i);p=await Pe(e,{id:null},await et(new Bt(404,"Not Found",`Not found: ${e.pathname}`),{url:e,params:{},route:{id:null}}),404,i)}if(e=(f==null?void 0:f.url)||e,D!==l)return h.reject(new Error("navigation aborted")),!1;if(p.type==="redirect"){if(s<20){await G({type:t,url:new URL(p.location,e),popped:n,keepfocus:r,noscroll:a,replace_state:i,state:o,redirect_count:s+1,nav_token:l}),h.fulfil(void 0);return}p=await Jt({status:500,error:await et(new Error("Redirect loop"),{url:e,params:{},route:{id:null}}),url:e,route:{id:null}})}else p.props.page.status>=400&&await C.updated.check()&&(await be(),await Q(e,i));if(fn(),Ft(_),xe(g),p.props.page.url.pathname!==e.pathname&&(e.pathname=p.props.page.url.pathname),o=n?n.state:o,!n){const E=i?0:1,ht={[F]:k+=E,[J]:L+=E,[me]:o};(i?history.replaceState:history.pushState).call(history,ht,"",e),i||ln(k,L)}const b=f&&(y==null?void 0:y.id)===f.id?y.fork:null;y=null,p.props.page.state=o;let x;if(yt){const E=(await Promise.all(Array.from(cn,K=>K(h.navigation)))).filter(K=>typeof K=="function");if(E.length>0){let K=function(){E.forEach(Lt=>{H.delete(Lt)})};E.push(K),E.forEach(Lt=>{H.add(Lt)})}m=p.state,p.props.page&&(p.props.page.url=e);const ht=b&&await b;ht?x=ht.commit():(Re.$set(p.props),on(p.props.page),x=(B=je)==null?void 0:B()),Ee=!0}else await Ae(p,Ct,!1);const{activeElement:O}=document;await x,await gt(),await gt();let N=null;if(oe){const E=n?n.scroll:a?V():null;E?scrollTo(E.x,E.y):(N=e.hash&&document.getElementById($e(e)))?N.scrollIntoView():scrollTo(0,0)}const dt=document.activeElement!==O&&document.activeElement!==document.body;!r&&!dt&&En(e,!N),oe=!0,p.props.page&&Object.assign(R,p.props.page),tt=!1,t==="popstate"&&Le(L),h.fulfil(void 0),h.navigation.to&&(h.navigation.to.scroll=V()),H.forEach(E=>E(h.navigation)),C.navigating.set(X.current=null)}async function Pe(t,e,n,r,a){return t.origin===Et&&t.pathname===location.pathname&&!Se?await Jt({status:r,error:n,url:t,route:e}):await Q(t,a)}function vn(){let t,e={element:void 0,href:void 0},n;$.addEventListener("mousemove",s=>{const l=s.target;clearTimeout(t),t=setTimeout(()=>{i(l,q.hover)},20)});function r(s){s.defaultPrevented||i(s.composedPath()[0],q.tap)}$.addEventListener("mousedown",r),$.addEventListener("touchstart",r,{passive:!0});const a=new IntersectionObserver(s=>{for(const l of s)l.isIntersecting&&(Pt(new URL(l.target.href)),a.unobserve(l.target))},{threshold:0});async function i(s,l){const c=we(s,$),d=c===e.element&&(c==null?void 0:c.href)===e.href&&l>=n;if(!c||d)return;const{url:u,external:v,download:f}=$t(c,U,S.hash);if(v||f)return;const h=mt(c),_=u&&St(m.url)===St(u);if(!(h.reload||_))if(l<=h.preload_data){e={element:c,href:c.href},n=q.tap;const g=await xt(u,!1);if(!g)return;un(g)}else l<=h.preload_code&&(e={element:c,href:c.href},n=l,Pt(u))}function o(){a.disconnect();for(const s of $.querySelectorAll("a")){const{url:l,external:c,download:d}=$t(s,U,S.hash);if(c||d)continue;const u=mt(s);u.reload||(u.preload_code===q.viewport&&a.observe(s),u.preload_code===q.eager&&Pt(l))}}H.add(o),o()}function et(t,e){if(t instanceof Dt)return t.body;const n=zt(t),r=an(t);return S.hooks.handleError({error:t,event:e,status:n,message:r})??{message:r}}function On(t,e={}){return t=new URL(Mt(t)),t.origin!==Et?Promise.reject(new Error("goto: invalid URL")):Ue(t,e,0)}function yn(t){if(typeof t=="function")wt.push(t);else{const{href:e}=new URL(t,location.href);wt.push(n=>n.href===e)}}function bn(){var e;history.scrollRestoration="manual",addEventListener("beforeunload",n=>{let r=!1;if(ie(),!tt){const a=Xt(m,void 0,null,"leave"),i={...a.navigation,cancel:()=>{r=!0,a.reject(new Error("navigation cancelled"))}};ke.forEach(o=>o(i))}r?(n.preventDefault(),n.returnValue=""):history.scrollRestoration="auto"}),addEventListener("visibilitychange",()=>{document.visibilityState==="hidden"&&ie()}),(e=navigator.connection)!=null&&e.saveData||vn(),$.addEventListener("click",async n=>{if(n.button||n.which!==1||n.metaKey||n.ctrlKey||n.shiftKey||n.altKey||n.defaultPrevented)return;const r=we(n.composedPath()[0],$);if(!r)return;const{url:a,external:i,target:o,download:s}=$t(r,U,S.hash);if(!a)return;if(o==="_parent"||o==="_top"){if(window.parent!==window)return}else if(o&&o!=="_self")return;const l=mt(r);if(!(r instanceof SVGAElement)&&a.protocol!==location.protocol&&!(a.protocol==="https:"||a.protocol==="http:")||s)return;const[d,u]=(S.hash?a.hash.replace(/^#/,""):a.href).split("#"),v=d===At(location);if(i||l.reload&&(!v||!u)){Ie({url:a,type:"link",event:n})?tt=!0:n.preventDefault();return}if(u!==void 0&&v){const[,f]=m.url.href.split("#");if(f===u){if(n.preventDefault(),u===""||u==="top"&&r.ownerDocument.getElementById("top")===null)scrollTo({top:0});else{const h=r.ownerDocument.getElementById(decodeURIComponent(u));h&&(h.scrollIntoView(),h.focus())}return}if(W=!0,Ft(k),t(a),!l.replace_state)return;W=!1}n.preventDefault(),await new Promise(f=>{requestAnimationFrame(()=>{setTimeout(f,0)}),setTimeout(f,100)}),await G({type:"link",url:a,keepfocus:l.keepfocus,noscroll:l.noscroll,replace_state:l.replace_state??a.href===location.href,event:n})}),$.addEventListener("submit",n=>{if(n.defaultPrevented)return;const r=HTMLFormElement.prototype.cloneNode.call(n.target),a=n.submitter;if(((a==null?void 0:a.formTarget)||r.target)==="_blank"||((a==null?void 0:a.formMethod)||r.method)!=="get")return;const s=new URL((a==null?void 0:a.hasAttribute("formaction"))&&(a==null?void 0:a.formAction)||r.action);if(Rt(s,U,!1))return;const l=n.target,c=mt(l);if(c.reload)return;n.preventDefault(),n.stopPropagation();const d=new FormData(l,a);s.search=new URLSearchParams(d).toString(),G({type:"form",url:s,keepfocus:c.keepfocus,noscroll:c.noscroll,replace_state:c.replace_state??s.href===location.href,event:n})}),addEventListener("popstate",async n=>{var r;if(!Nt){if((r=n.state)!=null&&r[F]){const a=n.state[F];if(D={},a===k)return;const i=j[a],o=n.state[me]??{},s=new URL(n.state[Qe]??location.href),l=n.state[J],c=m.url?At(location)===At(m.url):!1;if(l===L&&(Ee||c)){o!==R.state&&(R.state=o),t(s),j[k]=V(),i&&scrollTo(i.x,i.y),k=a;return}const u=a-k;await G({type:"popstate",url:s,popped:{state:o,scroll:i,delta:u},accept:()=>{k=a,L=l},block:()=>{history.go(-u)},nav_token:D,event:n})}else if(!W){const a=new URL(location.href);t(a),S.hash&&location.reload()}}}),addEventListener("hashchange",()=>{W&&(W=!1,history.replaceState({...history.state,[F]:++k,[J]:L},"",location.href))});for(const n of document.querySelectorAll("link"))sn.has(n.rel)&&(n.href=n.href);addEventListener("pageshow",n=>{n.persisted&&C.navigating.set(X.current=null)});function t(n){m.url=R.url=n,C.page.set(Zt(R)),C.page.notify()}}async function kn(t,{status:e=200,error:n,node_ids:r,params:a,route:i,server_route:o,data:s,form:l}){Se=!0;const c=new URL(location.href);let d;({params:a={},route:i={id:null}}=await xt(c,!1)||{}),d=Gt.find(({id:f})=>f===i.id);let u,v=!0;try{const f=r.map(async(_,g)=>{const p=s[g];return p!=null&&p.uses&&(p.uses=Sn(p.uses)),Yt({loader:S.nodes[_],url:c,params:a,route:i,parent:async()=>{const b={};for(let x=0;x{const s=history.state;Nt=!0,location.replace(new URL(`#${r}`,location.href)),history.replaceState(s,"",t),e&&scrollTo(i,o),Nt=!1})}else{const i=document.body,o=i.getAttribute("tabindex");i.tabIndex=-1,i.focus({preventScroll:!0,focusVisible:!1}),o!==null?i.setAttribute("tabindex",o):i.removeAttribute("tabindex")}const a=getSelection();if(a&&a.type!=="None"){const i=[];for(let o=0;o{if(a.rangeCount===i.length){for(let o=0;o{i=u,o=v});return s.catch(()=>{}),{navigation:{from:{params:t.params,route:{id:((c=t.route)==null?void 0:c.id)??null},url:t.url,scroll:V()},to:n&&{params:(e==null?void 0:e.params)??null,route:{id:((d=e==null?void 0:e.route)==null?void 0:d.id)??null},url:n,scroll:a},willUnload:!e,type:r,complete:s},fulfil:i,reject:o}}function Zt(t){return{data:t.data,error:t.error,form:t.form,params:t.params,route:t.route,state:t.state,status:t.status,url:t.url}}function Rn(t){const e=new URL(t);return e.hash=decodeURIComponent(t.hash),e}function $e(t){let e;if(S.hash){const[,,n]=t.hash.split("#",3);e=n??""}else e=t.hash.slice(1);return decodeURIComponent(e)}export{$n as a,On as g,An as l,R as p,C as s}; diff --git a/frontend/build/_app/immutable/entry/app.DWnDWHgs.js b/frontend/build/_app/immutable/entry/app.DWnDWHgs.js new file mode 100644 index 0000000..e959077 --- /dev/null +++ b/frontend/build/_app/immutable/entry/app.DWnDWHgs.js @@ -0,0 +1,2 @@ +const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["../nodes/0.CNxjQThJ.js","../chunks/B6M6q2Zo.js","../chunks/Ym0WvvUy.js","../chunks/Da6yQRl8.js","../assets/0.LvVNMuLM.css","../nodes/1.DQmxvu2E.js","../chunks/De6rLmuB.js","../chunks/dTRRgeF-.js","../chunks/giww_vF6.js","../chunks/Bfwrz3i4.js","../nodes/2.CwK2tdGg.js","../chunks/B9dvBo0E.js","../chunks/DMqvp7vx.js","../assets/2.lCQ6RyE1.css","../nodes/3.BjUxkFGX.js","../assets/3.C7Q2VT44.css"])))=>i.map(i=>d[i]); +var z=t=>{throw TypeError(t)};var H=(t,e,r)=>e.has(t)||z("Cannot "+r);var v=(t,e,r)=>(H(t,e,"read from private field"),r?r.call(t):e.get(t)),C=(t,e,r)=>e.has(t)?z("Cannot add the same private member more than once"):e instanceof WeakSet?e.add(t):e.set(t,r),j=(t,e,r,o)=>(H(t,e,"write to private field"),o?o.call(t,r):e.set(t,r),r);import{h as W,c as ae,b as se,E as ne,r as ie,e as oe,f as ce,i as X,H as ue,j as fe,aL as le,X as de,F as K,_ as _e,aM as Q,aN as me,aO as ve,aP as he,g as E,aQ as ge,a as w,aR as ye,O as Ee,aS as Pe,aT as Re,M as be,aU as Se,aV as Oe,K as Ae,ay as Te,aW as we,aX as J,aY as Ie,ak as Le,aC as xe,u as De,C as ke,D as Ce,aZ as je,v as L,x as Be,w as Ne,s as B,y as Ue,z as Ye,A as Me,a_ as N}from"../chunks/Ym0WvvUy.js";import{h as Ve,m as qe,u as Fe,s as ze}from"../chunks/dTRRgeF-.js";import{a as A,c as U,f as p,t as He}from"../chunks/B6M6q2Zo.js";import{o as We}from"../chunks/Bfwrz3i4.js";import{i as Y}from"../chunks/B9dvBo0E.js";import{B as Xe}from"../chunks/Da6yQRl8.js";function M(t,e,r){var o;W&&(o=fe,ae());var i=new Xe(t);se(()=>{var n=e()??null;if(W){var s=ie(o),a=s===ue,f=n!==null;if(a!==f){var P=oe();ce(P),i.anchor=P,X(!1),i.ensure(n,n&&(c=>r(c,n))),X(!0);return}}i.ensure(n,n&&(c=>r(c,n)))},ne)}function Z(t,e){return t===e||(t==null?void 0:t[Q])===e}function V(t={},e,r,o){return le(()=>{var i,n;return de(()=>{i=n,n=[],K(()=>{t!==r(...n)&&(e(t,...n),i&&Z(r(...i),t)&&e(null,...i))})}),()=>{_e(()=>{n&&Z(r(...n),t)&&e(null,...n)})}}),t}let x=!1;function Ze(t){var e=x;try{return x=!1,[t(),x]}finally{x=e}}function q(t,e,r,o){var b;var i=!be||(r&Se)!==0,n=(r&Re)!==0,s=(r&we)!==0,a=o,f=!0,P=()=>(f&&(f=!1,a=s?K(o):o),a),c;if(n){var R=Q in t||J in t;c=((b=me(t,e))==null?void 0:b.set)??(R&&e in t?u=>t[e]=u:void 0)}var h,T=!1;n?[h,T]=Ze(()=>t[e]):h=t[e],h===void 0&&o!==void 0&&(h=P(),c&&(i&&ve(),c(h)));var d;if(i?d=()=>{var u=t[e];return u===void 0?P():(f=!0,u)}:d=()=>{var u=t[e];return u!==void 0&&(a=void 0),u===void 0?a:u},i&&(r&he)===0)return d;if(c){var l=t.$$legacy;return(function(u,m){return arguments.length>0?((!i||!m||l||T)&&c(m?d():u),u):d()})}var _=!1,g=((r&Oe)!==0?Ae:Te)(()=>(_=!1,d()));n&&E(g);var O=Ee;return(function(u,m){if(arguments.length>0){const k=m?E(g):i&&n?ge(u):u;return w(g,k),_=!0,a!==void 0&&(a=k),u}return ye&&_||(O.f&Pe)!==0?g.v:E(g)})}function Ge(t){return class extends Ke{constructor(e){super({component:t,...e})}}}var S,y;class Ke{constructor(e){C(this,S);C(this,y);var n;var r=new Map,o=(s,a)=>{var f=xe(a,!1,!1);return r.set(s,f),f};const i=new Proxy({...e.props||{},$$events:{}},{get(s,a){return E(r.get(a)??o(a,Reflect.get(s,a)))},has(s,a){return a===J?!0:(E(r.get(a)??o(a,Reflect.get(s,a))),Reflect.has(s,a))},set(s,a,f){return w(r.get(a)??o(a,f),f),Reflect.set(s,a,f)}});j(this,y,(e.hydrate?Ve:qe)(e.component,{target:e.target,anchor:e.anchor,props:i,context:e.context,intro:e.intro??!1,recover:e.recover,transformError:e.transformError})),(!((n=e==null?void 0:e.props)!=null&&n.$$host)||e.sync===!1)&&Ie(),j(this,S,i.$$events);for(const s of Object.keys(v(this,y)))s==="$set"||s==="$destroy"||s==="$on"||Le(this,s,{get(){return v(this,y)[s]},set(a){v(this,y)[s]=a},enumerable:!0});v(this,y).$set=s=>{Object.assign(i,s)},v(this,y).$destroy=()=>{Fe(v(this,y))}}$set(e){v(this,y).$set(e)}$on(e,r){v(this,S)[e]=v(this,S)[e]||[];const o=(...i)=>r.call(this,...i);return v(this,S)[e].push(o),()=>{v(this,S)[e]=v(this,S)[e].filter(i=>i!==o)}}$destroy(){v(this,y).$destroy()}}S=new WeakMap,y=new WeakMap;const Qe="modulepreload",Je=function(t,e){return new URL(t,e).href},G={},D=function(e,r,o){let i=Promise.resolve();if(r&&r.length>0){let s=function(c){return Promise.all(c.map(R=>Promise.resolve(R).then(h=>({status:"fulfilled",value:h}),h=>({status:"rejected",reason:h}))))};const a=document.getElementsByTagName("link"),f=document.querySelector("meta[property=csp-nonce]"),P=(f==null?void 0:f.nonce)||(f==null?void 0:f.getAttribute("nonce"));i=s(r.map(c=>{if(c=Je(c,o),c in G)return;G[c]=!0;const R=c.endsWith(".css"),h=R?'[rel="stylesheet"]':"";if(!!o)for(let l=a.length-1;l>=0;l--){const _=a[l];if(_.href===c&&(!R||_.rel==="stylesheet"))return}else if(document.querySelector(`link[href="${c}"]${h}`))return;const d=document.createElement("link");if(d.rel=R?"stylesheet":Qe,R||(d.as="script"),d.crossOrigin="",d.href=c,P&&d.setAttribute("nonce",P),document.head.appendChild(d),R)return new Promise((l,_)=>{d.addEventListener("load",l),d.addEventListener("error",()=>_(new Error(`Unable to preload CSS for ${c}`)))})}))}function n(s){const a=new Event("vite:preloadError",{cancelable:!0});if(a.payload=s,window.dispatchEvent(a),!a.defaultPrevented)throw s}return i.then(s=>{for(const a of s||[])a.status==="rejected"&&n(a.reason);return e().catch(n)})},ut={};var pe=p('
'),$e=p(" ",1);function et(t,e){De(e,!0);let r=q(e,"components",23,()=>[]),o=q(e,"data_0",3,null),i=q(e,"data_1",3,null);ke(()=>e.stores.page.set(e.page)),Ce(()=>{e.stores,e.page,e.constructors,r(),e.form,o(),i(),e.stores.page.notify()});let n=B(!1),s=B(!1),a=B(null);We(()=>{const l=e.stores.page.subscribe(()=>{E(n)&&(w(s,!0),je().then(()=>{w(a,document.title||"untitled page",!0)}))});return w(n,!0),l});const f=N(()=>e.constructors[1]);var P=$e(),c=L(P);{var R=l=>{const _=N(()=>e.constructors[0]);var g=U(),O=L(g);M(O,()=>E(_),(b,u)=>{V(u(b,{get data(){return o()},get form(){return e.form},get params(){return e.page.params},children:(m,k)=>{var F=U(),ee=L(F);M(ee,()=>E(f),(te,re)=>{V(re(te,{get data(){return i()},get form(){return e.form},get params(){return e.page.params}}),I=>r()[1]=I,()=>{var I;return(I=r())==null?void 0:I[1]})}),A(m,F)},$$slots:{default:!0}}),m=>r()[0]=m,()=>{var m;return(m=r())==null?void 0:m[0]})}),A(l,g)},h=l=>{const _=N(()=>e.constructors[0]);var g=U(),O=L(g);M(O,()=>E(_),(b,u)=>{V(u(b,{get data(){return o()},get form(){return e.form},get params(){return e.page.params}}),m=>r()[0]=m,()=>{var m;return(m=r())==null?void 0:m[0]})}),A(l,g)};Y(c,l=>{e.constructors[1]?l(R):l(h,!1)})}var T=Be(c,2);{var d=l=>{var _=pe(),g=Ue(_);{var O=b=>{var u=He();Me(()=>ze(u,E(a))),A(b,u)};Y(g,b=>{E(s)&&b(O)})}Ye(_),A(l,_)};Y(T,l=>{E(n)&&l(d)})}A(t,P),Ne()}const ft=Ge(et),lt=[()=>D(()=>import("../nodes/0.CNxjQThJ.js"),__vite__mapDeps([0,1,2,3,4]),import.meta.url),()=>D(()=>import("../nodes/1.DQmxvu2E.js"),__vite__mapDeps([5,1,2,6,7,8,9]),import.meta.url),()=>D(()=>import("../nodes/2.CwK2tdGg.js"),__vite__mapDeps([10,1,2,6,9,7,11,3,12,8,13]),import.meta.url),()=>D(()=>import("../nodes/3.BjUxkFGX.js"),__vite__mapDeps([14,1,2,9,7,11,3,12,8,15]),import.meta.url)],dt=[],_t={"/":[2],"/login":[3]},$={handleError:(({error:t})=>{console.error(t)}),reroute:(()=>{}),transport:{}},tt=Object.fromEntries(Object.entries($.transport).map(([t,e])=>[t,e.decode])),mt=Object.fromEntries(Object.entries($.transport).map(([t,e])=>[t,e.encode])),vt=!1,ht=(t,e)=>tt[t](e);export{ht as decode,tt as decoders,_t as dictionary,mt as encoders,vt as hash,$ as hooks,ut as matchers,lt as nodes,ft as root,dt as server_loads}; diff --git a/frontend/build/_app/immutable/entry/start.Cw5np0_P.js b/frontend/build/_app/immutable/entry/start.Cw5np0_P.js new file mode 100644 index 0000000..798389d --- /dev/null +++ b/frontend/build/_app/immutable/entry/start.Cw5np0_P.js @@ -0,0 +1 @@ +import{l as o,a as r}from"../chunks/giww_vF6.js";export{o as load_css,r as start}; diff --git a/frontend/build/_app/immutable/nodes/0.CNxjQThJ.js b/frontend/build/_app/immutable/nodes/0.CNxjQThJ.js new file mode 100644 index 0000000..a659a79 --- /dev/null +++ b/frontend/build/_app/immutable/nodes/0.CNxjQThJ.js @@ -0,0 +1 @@ +import{c as s,a as c}from"../chunks/B6M6q2Zo.js";import{b as l,E as p,v as i}from"../chunks/Ym0WvvUy.js";import{B as m}from"../chunks/Da6yQRl8.js";function u(n,r,...e){var o=new m(n);l(()=>{const t=r()??null;o.ensure(t,t&&(a=>t(a,...e)))},p)}const f=!0,_=!1,g=Object.freeze(Object.defineProperty({__proto__:null,prerender:f,ssr:_},Symbol.toStringTag,{value:"Module"}));function h(n,r){var e=s(),o=i(e);u(o,()=>r.children),c(n,e)}export{h as component,g as universal}; diff --git a/frontend/build/_app/immutable/nodes/1.DQmxvu2E.js b/frontend/build/_app/immutable/nodes/1.DQmxvu2E.js new file mode 100644 index 0000000..925aaef --- /dev/null +++ b/frontend/build/_app/immutable/nodes/1.DQmxvu2E.js @@ -0,0 +1 @@ +import{a as h,f as g}from"../chunks/B6M6q2Zo.js";import{i as v}from"../chunks/De6rLmuB.js";import{u as l,v as d,A as x,w as _,y as e,z as o,x as $}from"../chunks/Ym0WvvUy.js";import{s as p}from"../chunks/dTRRgeF-.js";import{s as k,p as m}from"../chunks/giww_vF6.js";const b={get error(){return m.error},get status(){return m.status}};k.updated.check;const i=b;var w=g("

",1);function q(f,n){l(n,!1),v();var t=w(),r=d(t),c=e(r,!0);o(r);var s=$(r,2),u=e(s,!0);o(s),x(()=>{var a;p(c,i.status),p(u,(a=i.error)==null?void 0:a.message)}),h(f,t),_()}export{q as component}; diff --git a/frontend/build/_app/immutable/nodes/2.CwK2tdGg.js b/frontend/build/_app/immutable/nodes/2.CwK2tdGg.js new file mode 100644 index 0000000..026a664 --- /dev/null +++ b/frontend/build/_app/immutable/nodes/2.CwK2tdGg.js @@ -0,0 +1 @@ +import{c as u,a as e,f as p}from"../chunks/B6M6q2Zo.js";import{i as _}from"../chunks/De6rLmuB.js";import{o as d}from"../chunks/Bfwrz3i4.js";import{u as x,v as y,w as A,x as b,y as m,z as n,A as k}from"../chunks/Ym0WvvUy.js";import{s as w}from"../chunks/dTRRgeF-.js";import{i as z}from"../chunks/B9dvBo0E.js";import{a as o}from"../chunks/DMqvp7vx.js";import{g as F}from"../chunks/giww_vF6.js";var M=p('

Felt

Tournament management system

'),O=p('

Redirecting to login...

');function E(l,f){x(f,!1),d(()=>{o.isAuthenticated||F("/login")}),_();var s=u(),c=y(s);{var v=a=>{var t=M(),r=b(m(t),4),h=m(r);n(r),n(t),k(()=>{var i;return w(h,`Welcome, ${((i=o.operator)==null?void 0:i.name)??"Operator"??""}`)}),e(a,t)},g=a=>{var t=O();e(a,t)};z(c,a=>{o.isAuthenticated?a(v):a(g,!1)})}e(l,s),A()}export{E as component}; diff --git a/frontend/build/_app/immutable/nodes/3.BjUxkFGX.js b/frontend/build/_app/immutable/nodes/3.BjUxkFGX.js new file mode 100644 index 0000000..0e801bd --- /dev/null +++ b/frontend/build/_app/immutable/nodes/3.BjUxkFGX.js @@ -0,0 +1,2 @@ +import{a as P,f as K,t as ue}from"../chunks/B6M6q2Zo.js";import{o as ke}from"../chunks/Bfwrz3i4.js";import{m as V,b as Ne,av as we,h as I,f as X,P as ze,c as Ce,g as h,r as Se,d as Ie,e as ce,i as j,j as G,am as ye,at as Me,ac as de,o as De,aw as y,n as Z,ax as He,t as Le,ay as Oe,az as Pe,as as ae,aA as Re,aB as Fe,aC as Be,Y as ve,aD as Ue,k as Ae,p as Te,aE as Q,_ as $e,aF as qe,aG as Ge,aq as Ye,l as Je,an as Ke,aH as Ve,aI as Xe,aJ as je,u as Qe,A as Y,w as We,aK as Ze,y as R,x as L,z as O,s as W,a as w}from"../chunks/Ym0WvvUy.js";import{d as er,e as rr,a as B,s as pe}from"../chunks/dTRRgeF-.js";import{i as ge}from"../chunks/B9dvBo0E.js";import{a as J}from"../chunks/DMqvp7vx.js";import{g as ee}from"../chunks/giww_vF6.js";function he(e,t){return t}function tr(e,t,r){for(var a=[],i=t.length,l,s=t.length,d=0;d{if(l){if(l.pending.delete(m),l.done.add(m),l.pending.size===0){var g=e.outrogroups;re(ae(l.done)),g.delete(l),g.size===0&&(e.outrogroups=null)}}else s-=1},!1)}if(s===0){var f=a.length===0&&r!==null;if(f){var p=r,c=p.parentNode;Ye(c),c.append(p),e.items.clear()}re(t,!f)}else l={pending:new Set(t),done:new Set},(e.outrogroups??(e.outrogroups=new Set)).add(l)}function re(e,t=!0){for(var r=0;r{var u=r();return Pe(u)?u:u==null?[]:ae(u)}),g,_=!0;function T(){n.fallback=c,ar(n,g,s,t,a),c!==null&&(g.length===0?(c.f&y)===0?Ae(c):(c.f^=y,q(c,null,s)):Te(c,()=>{c=null}))}var M=Ne(()=>{g=h(m);var u=g.length;let k=!1;if(I){var N=Se(s)===Ie;N!==(u===0)&&(s=ce(),X(s),j(!1),k=!0)}for(var b=new Set,A=De,D=Le(),E=0;El(s)):(c=Z(()=>l(_e??(_e=V()))),c.f|=y)),u>b.size&&He(),I&&u>0&&X(ce()),!_)if(D){for(const[x,C]of d)b.has(x)||A.skip_effect(C.e);A.oncommit(T),A.ondiscard(()=>{})}else T();k&&j(!0),h(m)}),n={effect:M,items:d,outrogroups:null,fallback:c};_=!1,I&&(s=G)}function U(e){for(;e!==null&&(e.f&qe)===0;)e=e.next;return e}function ar(e,t,r,a,i){var v,x,C,F,ne,ie,se,oe,le;var l=(a&Ge)!==0,s=t.length,d=e.items,f=U(e.effect.first),p,c=null,m,g=[],_=[],T,M,n,u;if(l)for(u=0;u0){var o=(a&we)!==0&&s===0?r:null;if(l){for(u=0;u{var S,fe;if(m!==void 0)for(n of m)(fe=(S=n.nodes)==null?void 0:S.a)==null||fe.apply()})}function nr(e,t,r,a,i,l,s,d){var f=(s&Re)!==0?(s&Fe)===0?Be(r,!1,!1):ve(r):null,p=(s&Ue)!==0?ve(i):null;return{v:f,i:p,e:Z(()=>(l(t,f??r,p??i,d),()=>{e.delete(a)}))}}function q(e,t,r){if(e.nodes)for(var a=e.nodes.start,i=e.nodes.end,l=t&&(t.f&y)===0?t.nodes.start:r;a!==null;){var s=Ke(a);if(l.before(a),a===i)return;a=s}}function H(e,t,r){t===null?e.effect.first=r:t.next=r,r===null?e.effect.last=t:r.prev=t}const be=[...` +\r\f \v\uFEFF`];function ir(e,t,r){var a=""+e;if(r){for(var i of Object.keys(r))if(r[i])a=a?a+" "+i:i;else if(a.length)for(var l=i.length,s=0;(s=a.indexOf(i,s))>=0;){var d=s+l;(s===0||be.includes(a[s-1]))&&(d===a.length||be.includes(a[d]))?a=(s===0?"":a.substring(0,s))+a.substring(d+1):s=d}}return a===""?null:a}function sr(e,t,r,a,i,l){var s=e.__className;if(I||s!==r||s===void 0){var d=ir(r,a,l);(!I||d!==e.getAttribute("class"))&&(d==null?e.removeAttribute("class"):e.className=d),e.__className=r}else if(l&&i!==l)for(var f in l){var p=!!l[f];(i==null||p!==!!i[f])&&e.classList.toggle(f,p)}return l}const or=Symbol("is custom element"),lr=Symbol("is html");function Ee(e,t,r,a){var i=fr(e);I&&(i[t]=e.getAttribute(t)),i[t]!==(i[t]=r)&&(r==null?e.removeAttribute(t):typeof r!="string"&&ur(e).includes(t)?e[t]=r:e.setAttribute(t,r))}function fr(e){return e.__attributes??(e.__attributes={[or]:e.nodeName.includes("-"),[lr]:e.namespaceURI===Ve})}var xe=new Map;function ur(e){var t=e.getAttribute("is")||e.nodeName,r=xe.get(t);if(r)return r;xe.set(t,r=[]);for(var a,i=e,l=Element.prototype;l!==i;){a=je(i);for(var s in a)a[s].set&&r.push(s);i=Xe(i)}return r}class te extends Error{constructor(t,r,a){const i=typeof a=="object"&&a!==null&&"error"in a?a.error:r;super(i),this.status=t,this.statusText=r,this.body=a,this.name="ApiError"}}function cr(){return`${window.location.origin}/api/v1`}function dr(e){const t={Accept:"application/json"};e&&(t["Content-Type"]="application/json");const r=J.token;return r&&(t.Authorization=`Bearer ${r}`),t}async function vr(e){if(e.status===401)throw J.logout(),await ee("/login"),new te(401,"Unauthorized",{error:"Session expired"});if(!e.ok){let t;try{t=await e.json()}catch{t={error:e.statusText}}throw new te(e.status,e.statusText,t)}if(e.status!==204)return e.json()}async function $(e,t,r){const a=`${cr()}${t}`,i={method:e,headers:dr(r!==void 0),credentials:"same-origin"};r!==void 0&&(i.body=JSON.stringify(r));const l=await fetch(a,i);return vr(l)}const pr={get(e){return $("GET",e)},post(e,t){return $("POST",e,t)},put(e,t){return $("PUT",e,t)},patch(e,t){return $("PATCH",e,t)},delete(e){return $("DELETE",e)}};var gr=K("
"),hr=K(''),_r=K(''),mr=K('
');function Nr(e,t){Qe(t,!0);let r=W(""),a=W(""),i=W(!1);const l=6;ke(()=>{J.isAuthenticated&&ee("/")});function s(o){h(r).length>=l||(w(r,h(r)+o),w(a,""))}function d(){w(r,h(r).slice(0,-1),!0),w(a,"")}function f(){w(r,""),w(a,"")}async function p(){if(!(h(r).length<4||h(i))){w(i,!0),w(a,"");try{const o=await pr.post("/auth/login",{pin:h(r)});J.login(o.token,{id:o.operator.id,name:o.operator.name,role:o.operator.role}),await ee("/")}catch(o){o instanceof te?o.status===429?w(a,"Too many attempts. Please wait."):o.status===401?w(a,"Invalid PIN. Try again."):w(a,o.message,!0):w(a,"Connection error. Check your network."),w(r,"")}finally{w(i,!1)}}}function c(o){o.key>="0"&&o.key<="9"?s(o.key):o.key==="Backspace"?d():o.key==="Enter"?p():o.key==="Escape"&&f()}var m=mr();rr("keydown",Ze,c);var g=R(m),_=L(R(g),2);me(_,21,()=>Array(l),he,(o,v,x)=>{var C=gr();let F;Y(()=>F=sr(C,1,"pin-dot svelte-1x05zx6",null,F,{filled:x{var v=hr(),x=R(v,!0);O(v),Y(()=>pe(x,h(a))),P(o,v)};ge(T,o=>{h(a)&&o(M)})}var n=L(T,2),u=R(n);me(u,16,()=>["1","2","3","4","5","6","7","8","9"],he,(o,v)=>{var x=_r(),C=R(x,!0);O(x),Y(()=>{x.disabled=h(i)||h(r).length>=l,Ee(x,"aria-label",`Digit ${v??""}`),pe(C,v)}),B("click",x,()=>s(v)),P(o,x)});var k=L(u,2),N=L(k,2),b=L(N,2);O(n);var A=L(n,2),D=R(A);{var E=o=>{var v=ue("Signing in...");P(o,v)},z=o=>{var v=ue("Sign In");P(o,v)};ge(D,o=>{h(i)?o(E):o(z,!1)})}O(A),O(g),O(m),Y(()=>{Ee(_,"aria-label",`PIN entered: ${h(r).length??""} digits`),k.disabled=h(i),N.disabled=h(i)||h(r).length>=l,b.disabled=h(i)||h(r).length===0,A.disabled=h(r).length<4||h(i)}),B("click",k,f),B("click",N,()=>s("0")),B("click",b,d),B("click",A,p),P(e,m),We()}er(["click"]);export{Nr as component}; diff --git a/frontend/build/_app/version.json b/frontend/build/_app/version.json new file mode 100644 index 0000000..f2bd3d6 --- /dev/null +++ b/frontend/build/_app/version.json @@ -0,0 +1 @@ +{"version":"1772333625386"} \ No newline at end of file diff --git a/frontend/build/favicon.png b/frontend/build/favicon.png new file mode 100644 index 0000000000000000000000000000000000000000..7cf2b36ba2d0b120b4487943b2bc6d33fca28007 GIT binary patch literal 70 zcmeAS@N?(olHy`uVBq!ia0vp^j3CUx1|;Q0k92}1TpU9x<|Mzk^Xauc1G@#Y`A&KM Q2S5o1Pgg&ebxsLQ0L{-3CjbBd literal 0 HcmV?d00001 diff --git a/frontend/build/index.html b/frontend/build/index.html index ff8a382..d8ab952 100644 --- a/frontend/build/index.html +++ b/frontend/build/index.html @@ -1,38 +1,39 @@ - - - - - - Felt - - - -
-

Felt

-

Loading...

-
- + + + + + + + Felt + + + + + + + + + + + + +
+ +
+ diff --git a/frontend/build/login.html b/frontend/build/login.html new file mode 100644 index 0000000..a141a19 --- /dev/null +++ b/frontend/build/login.html @@ -0,0 +1,39 @@ + + + + + + + Felt + + + + + + + + + + + + +
+ +
+ + diff --git a/frontend/package-lock.json b/frontend/package-lock.json new file mode 100644 index 0000000..e5a2fa0 --- /dev/null +++ b/frontend/package-lock.json @@ -0,0 +1,1627 @@ +{ + "name": "felt-frontend", + "version": "0.1.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "felt-frontend", + "version": "0.1.0", + "devDependencies": { + "@sveltejs/adapter-static": "^3.0.8", + "@sveltejs/kit": "^2.16.0", + "@sveltejs/vite-plugin-svelte": "^5.0.0", + "svelte": "^5.0.0", + "svelte-check": "^4.0.0", + "typescript": "^5.0.0", + "vite": "^6.0.0" + } + }, + "node_modules/@esbuild/aix-ppc64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.25.12.tgz", + "integrity": "sha512-Hhmwd6CInZ3dwpuGTF8fJG6yoWmsToE+vYgD4nytZVxcu1ulHpUQRAB1UJ8+N1Am3Mz4+xOByoQoSZf4D+CpkA==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "aix" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-arm": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.25.12.tgz", + "integrity": "sha512-VJ+sKvNA/GE7Ccacc9Cha7bpS8nyzVv0jdVgwNDaR4gDMC/2TTRc33Ip8qrNYUcpkOHUT5OZ0bUcNNVZQ9RLlg==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-arm64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.25.12.tgz", + "integrity": "sha512-6AAmLG7zwD1Z159jCKPvAxZd4y/VTO0VkprYy+3N2FtJ8+BQWFXU+OxARIwA46c5tdD9SsKGZ/1ocqBS/gAKHg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-x64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.25.12.tgz", + "integrity": "sha512-5jbb+2hhDHx5phYR2By8GTWEzn6I9UqR11Kwf22iKbNpYrsmRB18aX/9ivc5cabcUiAT/wM+YIZ6SG9QO6a8kg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/darwin-arm64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.25.12.tgz", + "integrity": "sha512-N3zl+lxHCifgIlcMUP5016ESkeQjLj/959RxxNYIthIg+CQHInujFuXeWbWMgnTo4cp5XVHqFPmpyu9J65C1Yg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/darwin-x64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.25.12.tgz", + "integrity": "sha512-HQ9ka4Kx21qHXwtlTUVbKJOAnmG1ipXhdWTmNXiPzPfWKpXqASVcWdnf2bnL73wgjNrFXAa3yYvBSd9pzfEIpA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/freebsd-arm64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.25.12.tgz", + "integrity": "sha512-gA0Bx759+7Jve03K1S0vkOu5Lg/85dou3EseOGUes8flVOGxbhDDh/iZaoek11Y8mtyKPGF3vP8XhnkDEAmzeg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/freebsd-x64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.25.12.tgz", + "integrity": "sha512-TGbO26Yw2xsHzxtbVFGEXBFH0FRAP7gtcPE7P5yP7wGy7cXK2oO7RyOhL5NLiqTlBh47XhmIUXuGciXEqYFfBQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-arm": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.25.12.tgz", + "integrity": "sha512-lPDGyC1JPDou8kGcywY0YILzWlhhnRjdof3UlcoqYmS9El818LLfJJc3PXXgZHrHCAKs/Z2SeZtDJr5MrkxtOw==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-arm64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.25.12.tgz", + "integrity": "sha512-8bwX7a8FghIgrupcxb4aUmYDLp8pX06rGh5HqDT7bB+8Rdells6mHvrFHHW2JAOPZUbnjUpKTLg6ECyzvas2AQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-ia32": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.25.12.tgz", + "integrity": "sha512-0y9KrdVnbMM2/vG8KfU0byhUN+EFCny9+8g202gYqSSVMonbsCfLjUO+rCci7pM0WBEtz+oK/PIwHkzxkyharA==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-loong64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.25.12.tgz", + "integrity": "sha512-h///Lr5a9rib/v1GGqXVGzjL4TMvVTv+s1DPoxQdz7l/AYv6LDSxdIwzxkrPW438oUXiDtwM10o9PmwS/6Z0Ng==", + "cpu": [ + "loong64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-mips64el": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.25.12.tgz", + "integrity": "sha512-iyRrM1Pzy9GFMDLsXn1iHUm18nhKnNMWscjmp4+hpafcZjrr2WbT//d20xaGljXDBYHqRcl8HnxbX6uaA/eGVw==", + "cpu": [ + "mips64el" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-ppc64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.25.12.tgz", + "integrity": "sha512-9meM/lRXxMi5PSUqEXRCtVjEZBGwB7P/D4yT8UG/mwIdze2aV4Vo6U5gD3+RsoHXKkHCfSxZKzmDssVlRj1QQA==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-riscv64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.25.12.tgz", + "integrity": "sha512-Zr7KR4hgKUpWAwb1f3o5ygT04MzqVrGEGXGLnj15YQDJErYu/BGg+wmFlIDOdJp0PmB0lLvxFIOXZgFRrdjR0w==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-s390x": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.25.12.tgz", + "integrity": "sha512-MsKncOcgTNvdtiISc/jZs/Zf8d0cl/t3gYWX8J9ubBnVOwlk65UIEEvgBORTiljloIWnBzLs4qhzPkJcitIzIg==", + "cpu": [ + "s390x" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-x64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.25.12.tgz", + "integrity": "sha512-uqZMTLr/zR/ed4jIGnwSLkaHmPjOjJvnm6TVVitAa08SLS9Z0VM8wIRx7gWbJB5/J54YuIMInDquWyYvQLZkgw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/netbsd-arm64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.25.12.tgz", + "integrity": "sha512-xXwcTq4GhRM7J9A8Gv5boanHhRa/Q9KLVmcyXHCTaM4wKfIpWkdXiMog/KsnxzJ0A1+nD+zoecuzqPmCRyBGjg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/netbsd-x64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.25.12.tgz", + "integrity": "sha512-Ld5pTlzPy3YwGec4OuHh1aCVCRvOXdH8DgRjfDy/oumVovmuSzWfnSJg+VtakB9Cm0gxNO9BzWkj6mtO1FMXkQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openbsd-arm64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.25.12.tgz", + "integrity": "sha512-fF96T6KsBo/pkQI950FARU9apGNTSlZGsv1jZBAlcLL1MLjLNIWPBkj5NlSz8aAzYKg+eNqknrUJ24QBybeR5A==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openbsd-x64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.25.12.tgz", + "integrity": "sha512-MZyXUkZHjQxUvzK7rN8DJ3SRmrVrke8ZyRusHlP+kuwqTcfWLyqMOE3sScPPyeIXN/mDJIfGXvcMqCgYKekoQw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openharmony-arm64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.25.12.tgz", + "integrity": "sha512-rm0YWsqUSRrjncSXGA7Zv78Nbnw4XL6/dzr20cyrQf7ZmRcsovpcRBdhD43Nuk3y7XIoW2OxMVvwuRvk9XdASg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openharmony" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/sunos-x64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.25.12.tgz", + "integrity": "sha512-3wGSCDyuTHQUzt0nV7bocDy72r2lI33QL3gkDNGkod22EsYl04sMf0qLb8luNKTOmgF/eDEDP5BFNwoBKH441w==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "sunos" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-arm64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.25.12.tgz", + "integrity": "sha512-rMmLrur64A7+DKlnSuwqUdRKyd3UE7oPJZmnljqEptesKM8wx9J8gx5u0+9Pq0fQQW8vqeKebwNXdfOyP+8Bsg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-ia32": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.25.12.tgz", + "integrity": "sha512-HkqnmmBoCbCwxUKKNPBixiWDGCpQGVsrQfJoVGYLPT41XWF8lHuE5N6WhVia2n4o5QK5M4tYr21827fNhi4byQ==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-x64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.25.12.tgz", + "integrity": "sha512-alJC0uCZpTFrSL0CCDjcgleBXPnCrEAhTBILpeAp7M/OFgoqtAetfBzX0xM00MUsVVPpVjlPuMbREqnZCXaTnA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@jridgewell/gen-mapping": { + "version": "0.3.13", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.13.tgz", + "integrity": "sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.5.0", + "@jridgewell/trace-mapping": "^0.3.24" + } + }, + "node_modules/@jridgewell/remapping": { + "version": "2.3.5", + "resolved": "https://registry.npmjs.org/@jridgewell/remapping/-/remapping-2.3.5.tgz", + "integrity": "sha512-LI9u/+laYG4Ds1TDKSJW2YPrIlcVYOwi2fUC6xB43lueCjgxV4lffOCZCtYFiH6TNOX+tQKXx97T4IKHbhyHEQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.24" + } + }, + "node_modules/@jridgewell/resolve-uri": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", + "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.5.5", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz", + "integrity": "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==", + "dev": true, + "license": "MIT" + }, + "node_modules/@jridgewell/trace-mapping": { + "version": "0.3.31", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.31.tgz", + "integrity": "sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/resolve-uri": "^3.1.0", + "@jridgewell/sourcemap-codec": "^1.4.14" + } + }, + "node_modules/@polka/url": { + "version": "1.0.0-next.29", + "resolved": "https://registry.npmjs.org/@polka/url/-/url-1.0.0-next.29.tgz", + "integrity": "sha512-wwQAWhWSuHaag8c4q/KN/vCoeOJYshAIvMQwD4GpSb3OiZklFfvAgmj0VCBBImRpuF/aFgIRzllXlVX93Jevww==", + "dev": true, + "license": "MIT" + }, + "node_modules/@rollup/rollup-android-arm-eabi": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.59.0.tgz", + "integrity": "sha512-upnNBkA6ZH2VKGcBj9Fyl9IGNPULcjXRlg0LLeaioQWueH30p6IXtJEbKAgvyv+mJaMxSm1l6xwDXYjpEMiLMg==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@rollup/rollup-android-arm64": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.59.0.tgz", + "integrity": "sha512-hZ+Zxj3SySm4A/DylsDKZAeVg0mvi++0PYVceVyX7hemkw7OreKdCvW2oQ3T1FMZvCaQXqOTHb8qmBShoqk69Q==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@rollup/rollup-darwin-arm64": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.59.0.tgz", + "integrity": "sha512-W2Psnbh1J8ZJw0xKAd8zdNgF9HRLkdWwwdWqubSVk0pUuQkoHnv7rx4GiF9rT4t5DIZGAsConRE3AxCdJ4m8rg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@rollup/rollup-darwin-x64": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.59.0.tgz", + "integrity": "sha512-ZW2KkwlS4lwTv7ZVsYDiARfFCnSGhzYPdiOU4IM2fDbL+QGlyAbjgSFuqNRbSthybLbIJ915UtZBtmuLrQAT/w==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@rollup/rollup-freebsd-arm64": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.59.0.tgz", + "integrity": "sha512-EsKaJ5ytAu9jI3lonzn3BgG8iRBjV4LxZexygcQbpiU0wU0ATxhNVEpXKfUa0pS05gTcSDMKpn3Sx+QB9RlTTA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ] + }, + "node_modules/@rollup/rollup-freebsd-x64": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.59.0.tgz", + "integrity": "sha512-d3DuZi2KzTMjImrxoHIAODUZYoUUMsuUiY4SRRcJy6NJoZ6iIqWnJu9IScV9jXysyGMVuW+KNzZvBLOcpdl3Vg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ] + }, + "node_modules/@rollup/rollup-linux-arm-gnueabihf": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.59.0.tgz", + "integrity": "sha512-t4ONHboXi/3E0rT6OZl1pKbl2Vgxf9vJfWgmUoCEVQVxhW6Cw/c8I6hbbu7DAvgp82RKiH7TpLwxnJeKv2pbsw==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm-musleabihf": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.59.0.tgz", + "integrity": "sha512-CikFT7aYPA2ufMD086cVORBYGHffBo4K8MQ4uPS/ZnY54GKj36i196u8U+aDVT2LX4eSMbyHtyOh7D7Zvk2VvA==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm64-gnu": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.59.0.tgz", + "integrity": "sha512-jYgUGk5aLd1nUb1CtQ8E+t5JhLc9x5WdBKew9ZgAXg7DBk0ZHErLHdXM24rfX+bKrFe+Xp5YuJo54I5HFjGDAA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm64-musl": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.59.0.tgz", + "integrity": "sha512-peZRVEdnFWZ5Bh2KeumKG9ty7aCXzzEsHShOZEFiCQlDEepP1dpUl/SrUNXNg13UmZl+gzVDPsiCwnV1uI0RUA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-loong64-gnu": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-gnu/-/rollup-linux-loong64-gnu-4.59.0.tgz", + "integrity": "sha512-gbUSW/97f7+r4gHy3Jlup8zDG190AuodsWnNiXErp9mT90iCy9NKKU0Xwx5k8VlRAIV2uU9CsMnEFg/xXaOfXg==", + "cpu": [ + "loong64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-loong64-musl": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-musl/-/rollup-linux-loong64-musl-4.59.0.tgz", + "integrity": "sha512-yTRONe79E+o0FWFijasoTjtzG9EBedFXJMl888NBEDCDV9I2wGbFFfJQQe63OijbFCUZqxpHz1GzpbtSFikJ4Q==", + "cpu": [ + "loong64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-ppc64-gnu": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-gnu/-/rollup-linux-ppc64-gnu-4.59.0.tgz", + "integrity": "sha512-sw1o3tfyk12k3OEpRddF68a1unZ5VCN7zoTNtSn2KndUE+ea3m3ROOKRCZxEpmT9nsGnogpFP9x6mnLTCaoLkA==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-ppc64-musl": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-musl/-/rollup-linux-ppc64-musl-4.59.0.tgz", + "integrity": "sha512-+2kLtQ4xT3AiIxkzFVFXfsmlZiG5FXYW7ZyIIvGA7Bdeuh9Z0aN4hVyXS/G1E9bTP/vqszNIN/pUKCk/BTHsKA==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-riscv64-gnu": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.59.0.tgz", + "integrity": "sha512-NDYMpsXYJJaj+I7UdwIuHHNxXZ/b/N2hR15NyH3m2qAtb/hHPA4g4SuuvrdxetTdndfj9b1WOmy73kcPRoERUg==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-riscv64-musl": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.59.0.tgz", + "integrity": "sha512-nLckB8WOqHIf1bhymk+oHxvM9D3tyPndZH8i8+35p/1YiVoVswPid2yLzgX7ZJP0KQvnkhM4H6QZ5m0LzbyIAg==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-s390x-gnu": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.59.0.tgz", + "integrity": "sha512-oF87Ie3uAIvORFBpwnCvUzdeYUqi2wY6jRFWJAy1qus/udHFYIkplYRW+wo+GRUP4sKzYdmE1Y3+rY5Gc4ZO+w==", + "cpu": [ + "s390x" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-x64-gnu": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.59.0.tgz", + "integrity": "sha512-3AHmtQq/ppNuUspKAlvA8HtLybkDflkMuLK4DPo77DfthRb71V84/c4MlWJXixZz4uruIH4uaa07IqoAkG64fg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-x64-musl": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.59.0.tgz", + "integrity": "sha512-2UdiwS/9cTAx7qIUZB/fWtToJwvt0Vbo0zmnYt7ED35KPg13Q0ym1g442THLC7VyI6JfYTP4PiSOWyoMdV2/xg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-openbsd-x64": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-openbsd-x64/-/rollup-openbsd-x64-4.59.0.tgz", + "integrity": "sha512-M3bLRAVk6GOwFlPTIxVBSYKUaqfLrn8l0psKinkCFxl4lQvOSz8ZrKDz2gxcBwHFpci0B6rttydI4IpS4IS/jQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ] + }, + "node_modules/@rollup/rollup-openharmony-arm64": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-openharmony-arm64/-/rollup-openharmony-arm64-4.59.0.tgz", + "integrity": "sha512-tt9KBJqaqp5i5HUZzoafHZX8b5Q2Fe7UjYERADll83O4fGqJ49O1FsL6LpdzVFQcpwvnyd0i+K/VSwu/o/nWlA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openharmony" + ] + }, + "node_modules/@rollup/rollup-win32-arm64-msvc": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.59.0.tgz", + "integrity": "sha512-V5B6mG7OrGTwnxaNUzZTDTjDS7F75PO1ae6MJYdiMu60sq0CqN5CVeVsbhPxalupvTX8gXVSU9gq+Rx1/hvu6A==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-ia32-msvc": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.59.0.tgz", + "integrity": "sha512-UKFMHPuM9R0iBegwzKF4y0C4J9u8C6MEJgFuXTBerMk7EJ92GFVFYBfOZaSGLu6COf7FxpQNqhNS4c4icUPqxA==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-x64-gnu": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-gnu/-/rollup-win32-x64-gnu-4.59.0.tgz", + "integrity": "sha512-laBkYlSS1n2L8fSo1thDNGrCTQMmxjYY5G0WFWjFFYZkKPjsMBsgJfGf4TLxXrF6RyhI60L8TMOjBMvXiTcxeA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-x64-msvc": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.59.0.tgz", + "integrity": "sha512-2HRCml6OztYXyJXAvdDXPKcawukWY2GpR5/nxKp4iBgiO3wcoEGkAaqctIbZcNB6KlUQBIqt8VYkNSj2397EfA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@standard-schema/spec": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@standard-schema/spec/-/spec-1.1.0.tgz", + "integrity": "sha512-l2aFy5jALhniG5HgqrD6jXLi/rUWrKvqN/qJx6yoJsgKhblVd+iqqU4RCXavm/jPityDo5TCvKMnpjKnOriy0w==", + "dev": true, + "license": "MIT" + }, + "node_modules/@sveltejs/acorn-typescript": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/@sveltejs/acorn-typescript/-/acorn-typescript-1.0.9.tgz", + "integrity": "sha512-lVJX6qEgs/4DOcRTpo56tmKzVPtoWAaVbL4hfO7t7NVwl9AAXzQR6cihesW1BmNMPl+bK6dreu2sOKBP2Q9CIA==", + "dev": true, + "license": "MIT", + "peerDependencies": { + "acorn": "^8.9.0" + } + }, + "node_modules/@sveltejs/adapter-static": { + "version": "3.0.10", + "resolved": "https://registry.npmjs.org/@sveltejs/adapter-static/-/adapter-static-3.0.10.tgz", + "integrity": "sha512-7D9lYFWJmB7zxZyTE/qxjksvMqzMuYrrsyh1f4AlZqeZeACPRySjbC3aFiY55wb1tWUaKOQG9PVbm74JcN2Iew==", + "dev": true, + "license": "MIT", + "peerDependencies": { + "@sveltejs/kit": "^2.0.0" + } + }, + "node_modules/@sveltejs/kit": { + "version": "2.53.4", + "resolved": "https://registry.npmjs.org/@sveltejs/kit/-/kit-2.53.4.tgz", + "integrity": "sha512-iAIPEahFgDJJyvz8g0jP08KvqnM6JvdW8YfsygZ+pMeMvyM2zssWMltcsotETvjSZ82G3VlitgDtBIvpQSZrTA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@standard-schema/spec": "^1.0.0", + "@sveltejs/acorn-typescript": "^1.0.5", + "@types/cookie": "^0.6.0", + "acorn": "^8.14.1", + "cookie": "^0.6.0", + "devalue": "^5.6.3", + "esm-env": "^1.2.2", + "kleur": "^4.1.5", + "magic-string": "^0.30.5", + "mrmime": "^2.0.0", + "set-cookie-parser": "^3.0.0", + "sirv": "^3.0.0" + }, + "bin": { + "svelte-kit": "svelte-kit.js" + }, + "engines": { + "node": ">=18.13" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.0.0", + "@sveltejs/vite-plugin-svelte": "^3.0.0 || ^4.0.0-next.1 || ^5.0.0 || ^6.0.0-next.0 || ^7.0.0", + "svelte": "^4.0.0 || ^5.0.0-next.0", + "typescript": "^5.3.3", + "vite": "^5.0.3 || ^6.0.0 || ^7.0.0-beta.0 || ^8.0.0" + }, + "peerDependenciesMeta": { + "@opentelemetry/api": { + "optional": true + }, + "typescript": { + "optional": true + } + } + }, + "node_modules/@sveltejs/vite-plugin-svelte": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/@sveltejs/vite-plugin-svelte/-/vite-plugin-svelte-5.1.1.tgz", + "integrity": "sha512-Y1Cs7hhTc+a5E9Va/xwKlAJoariQyHY+5zBgCZg4PFWNYQ1nMN9sjK1zhw1gK69DuqVP++sht/1GZg1aRwmAXQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@sveltejs/vite-plugin-svelte-inspector": "^4.0.1", + "debug": "^4.4.1", + "deepmerge": "^4.3.1", + "kleur": "^4.1.5", + "magic-string": "^0.30.17", + "vitefu": "^1.0.6" + }, + "engines": { + "node": "^18.0.0 || ^20.0.0 || >=22" + }, + "peerDependencies": { + "svelte": "^5.0.0", + "vite": "^6.0.0" + } + }, + "node_modules/@sveltejs/vite-plugin-svelte-inspector": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/@sveltejs/vite-plugin-svelte-inspector/-/vite-plugin-svelte-inspector-4.0.1.tgz", + "integrity": "sha512-J/Nmb2Q2y7mck2hyCX4ckVHcR5tu2J+MtBEQqpDrrgELZ2uvraQcK/ioCV61AqkdXFgriksOKIceDcQmqnGhVw==", + "dev": true, + "license": "MIT", + "dependencies": { + "debug": "^4.3.7" + }, + "engines": { + "node": "^18.0.0 || ^20.0.0 || >=22" + }, + "peerDependencies": { + "@sveltejs/vite-plugin-svelte": "^5.0.0", + "svelte": "^5.0.0", + "vite": "^6.0.0" + } + }, + "node_modules/@types/cookie": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/@types/cookie/-/cookie-0.6.0.tgz", + "integrity": "sha512-4Kh9a6B2bQciAhf7FSuMRRkUWecJgJu9nPnx3yzpsfXX/c50REIqpHY4C82bXP90qrLtXtkDxTZosYO3UpOwlA==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/estree": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.8.tgz", + "integrity": "sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/trusted-types": { + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/@types/trusted-types/-/trusted-types-2.0.7.tgz", + "integrity": "sha512-ScaPdn1dQczgbl0QFTeTOmVHFULt394XJgOQNoyVhZ6r2vLnMLJfBPd53SB52T/3G36VI1/g2MZaX0cwDuXsfw==", + "dev": true, + "license": "MIT" + }, + "node_modules/acorn": { + "version": "8.16.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.16.0.tgz", + "integrity": "sha512-UVJyE9MttOsBQIDKw1skb9nAwQuR5wuGD3+82K6JgJlm/Y+KI92oNsMNGZCYdDsVtRHSak0pcV5Dno5+4jh9sw==", + "dev": true, + "license": "MIT", + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/aria-query": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-5.3.1.tgz", + "integrity": "sha512-Z/ZeOgVl7bcSYZ/u/rh0fOpvEpq//LZmdbkXyc7syVzjPAhfOa9ebsdTSjEBDU4vs5nC98Kfduj1uFo0qyET3g==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/axobject-query": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/axobject-query/-/axobject-query-4.1.0.tgz", + "integrity": "sha512-qIj0G9wZbMGNLjLmg1PT6v2mE9AH2zlnADJD/2tC6E00hgmhUOfEB6greHPAfLRSufHqROIUTkw6E+M3lH0PTQ==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/chokidar": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-4.0.3.tgz", + "integrity": "sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==", + "dev": true, + "license": "MIT", + "dependencies": { + "readdirp": "^4.0.1" + }, + "engines": { + "node": ">= 14.16.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/clsx": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/clsx/-/clsx-2.1.1.tgz", + "integrity": "sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/cookie": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.6.0.tgz", + "integrity": "sha512-U71cyTamuh1CRNCfpGY6to28lxvNwPG4Guz/EVjgf3Jmzv0vlDp1atT9eS5dDjMYHucpHbWns6Lwf3BKz6svdw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/debug": { + "version": "4.4.3", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", + "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/deepmerge": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.3.1.tgz", + "integrity": "sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/devalue": { + "version": "5.6.3", + "resolved": "https://registry.npmjs.org/devalue/-/devalue-5.6.3.tgz", + "integrity": "sha512-nc7XjUU/2Lb+SvEFVGcWLiKkzfw8+qHI7zn8WYXKkLMgfGSHbgCEaR6bJpev8Cm6Rmrb19Gfd/tZvGqx9is3wg==", + "dev": true, + "license": "MIT" + }, + "node_modules/esbuild": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.25.12.tgz", + "integrity": "sha512-bbPBYYrtZbkt6Os6FiTLCTFxvq4tt3JKall1vRwshA3fdVztsLAatFaZobhkBC8/BrPetoa0oksYoKXoG4ryJg==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=18" + }, + "optionalDependencies": { + "@esbuild/aix-ppc64": "0.25.12", + "@esbuild/android-arm": "0.25.12", + "@esbuild/android-arm64": "0.25.12", + "@esbuild/android-x64": "0.25.12", + "@esbuild/darwin-arm64": "0.25.12", + "@esbuild/darwin-x64": "0.25.12", + "@esbuild/freebsd-arm64": "0.25.12", + "@esbuild/freebsd-x64": "0.25.12", + "@esbuild/linux-arm": "0.25.12", + "@esbuild/linux-arm64": "0.25.12", + "@esbuild/linux-ia32": "0.25.12", + "@esbuild/linux-loong64": "0.25.12", + "@esbuild/linux-mips64el": "0.25.12", + "@esbuild/linux-ppc64": "0.25.12", + "@esbuild/linux-riscv64": "0.25.12", + "@esbuild/linux-s390x": "0.25.12", + "@esbuild/linux-x64": "0.25.12", + "@esbuild/netbsd-arm64": "0.25.12", + "@esbuild/netbsd-x64": "0.25.12", + "@esbuild/openbsd-arm64": "0.25.12", + "@esbuild/openbsd-x64": "0.25.12", + "@esbuild/openharmony-arm64": "0.25.12", + "@esbuild/sunos-x64": "0.25.12", + "@esbuild/win32-arm64": "0.25.12", + "@esbuild/win32-ia32": "0.25.12", + "@esbuild/win32-x64": "0.25.12" + } + }, + "node_modules/esm-env": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/esm-env/-/esm-env-1.2.2.tgz", + "integrity": "sha512-Epxrv+Nr/CaL4ZcFGPJIYLWFom+YeV1DqMLHJoEd9SYRxNbaFruBwfEX/kkHUJf55j2+TUbmDcmuilbP1TmXHA==", + "dev": true, + "license": "MIT" + }, + "node_modules/esrap": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/esrap/-/esrap-2.2.3.tgz", + "integrity": "sha512-8fOS+GIGCQZl/ZIlhl59htOlms6U8NvX6ZYgYHpRU/b6tVSh3uHkOHZikl3D4cMbYM0JlpBe+p/BkZEi8J9XIQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.4.15" + } + }, + "node_modules/fdir": { + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz", + "integrity": "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12.0.0" + }, + "peerDependencies": { + "picomatch": "^3 || ^4" + }, + "peerDependenciesMeta": { + "picomatch": { + "optional": true + } + } + }, + "node_modules/fsevents": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/is-reference": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/is-reference/-/is-reference-3.0.3.tgz", + "integrity": "sha512-ixkJoqQvAP88E6wLydLGGqCJsrFUnqoH6HnaczB8XmDH1oaWU+xxdptvikTgaEhtZ53Ky6YXiBuUI2WXLMCwjw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/estree": "^1.0.6" + } + }, + "node_modules/kleur": { + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/kleur/-/kleur-4.1.5.tgz", + "integrity": "sha512-o+NO+8WrRiQEE4/7nwRJhN1HWpVmJm511pBHUxPLtp0BUISzlBplORYSmTclCnJvQq2tKu/sgl3xVpkc7ZWuQQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/locate-character": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/locate-character/-/locate-character-3.0.0.tgz", + "integrity": "sha512-SW13ws7BjaeJ6p7Q6CO2nchbYEc3X3J6WrmTTDto7yMPqVSZTUyY5Tjbid+Ab8gLnATtygYtiDIJGQRRn2ZOiA==", + "dev": true, + "license": "MIT" + }, + "node_modules/magic-string": { + "version": "0.30.21", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.21.tgz", + "integrity": "sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.5.5" + } + }, + "node_modules/mri": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/mri/-/mri-1.2.0.tgz", + "integrity": "sha512-tzzskb3bG8LvYGFF/mDTpq3jpI6Q9wc3LEmBaghu+DdCssd1FakN7Bc0hVNmEyGq1bq3RgfkCb3cmQLpNPOroA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/mrmime": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/mrmime/-/mrmime-2.0.1.tgz", + "integrity": "sha512-Y3wQdFg2Va6etvQ5I82yUhGdsKrcYox6p7FfL1LbK2J4V01F9TGlepTIhnK24t7koZibmg82KGglhA1XK5IsLQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + } + }, + "node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "dev": true, + "license": "MIT" + }, + "node_modules/nanoid": { + "version": "3.3.11", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.11.tgz", + "integrity": "sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "bin": { + "nanoid": "bin/nanoid.cjs" + }, + "engines": { + "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" + } + }, + "node_modules/picocolors": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", + "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", + "dev": true, + "license": "ISC" + }, + "node_modules/picomatch": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz", + "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/postcss": { + "version": "8.5.6", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.6.tgz", + "integrity": "sha512-3Ybi1tAuwAP9s0r1UQ2J4n5Y0G05bJkpUIO0/bI9MhwmD70S5aTWbXGBwxHrelT+XM1k6dM0pk+SwNkpTRN7Pg==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/postcss" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "nanoid": "^3.3.11", + "picocolors": "^1.1.1", + "source-map-js": "^1.2.1" + }, + "engines": { + "node": "^10 || ^12 || >=14" + } + }, + "node_modules/readdirp": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-4.1.2.tgz", + "integrity": "sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 14.18.0" + }, + "funding": { + "type": "individual", + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/rollup": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.59.0.tgz", + "integrity": "sha512-2oMpl67a3zCH9H79LeMcbDhXW/UmWG/y2zuqnF2jQq5uq9TbM9TVyXvA4+t+ne2IIkBdrLpAaRQAvo7YI/Yyeg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/estree": "1.0.8" + }, + "bin": { + "rollup": "dist/bin/rollup" + }, + "engines": { + "node": ">=18.0.0", + "npm": ">=8.0.0" + }, + "optionalDependencies": { + "@rollup/rollup-android-arm-eabi": "4.59.0", + "@rollup/rollup-android-arm64": "4.59.0", + "@rollup/rollup-darwin-arm64": "4.59.0", + "@rollup/rollup-darwin-x64": "4.59.0", + "@rollup/rollup-freebsd-arm64": "4.59.0", + "@rollup/rollup-freebsd-x64": "4.59.0", + "@rollup/rollup-linux-arm-gnueabihf": "4.59.0", + "@rollup/rollup-linux-arm-musleabihf": "4.59.0", + "@rollup/rollup-linux-arm64-gnu": "4.59.0", + "@rollup/rollup-linux-arm64-musl": "4.59.0", + "@rollup/rollup-linux-loong64-gnu": "4.59.0", + "@rollup/rollup-linux-loong64-musl": "4.59.0", + "@rollup/rollup-linux-ppc64-gnu": "4.59.0", + "@rollup/rollup-linux-ppc64-musl": "4.59.0", + "@rollup/rollup-linux-riscv64-gnu": "4.59.0", + "@rollup/rollup-linux-riscv64-musl": "4.59.0", + "@rollup/rollup-linux-s390x-gnu": "4.59.0", + "@rollup/rollup-linux-x64-gnu": "4.59.0", + "@rollup/rollup-linux-x64-musl": "4.59.0", + "@rollup/rollup-openbsd-x64": "4.59.0", + "@rollup/rollup-openharmony-arm64": "4.59.0", + "@rollup/rollup-win32-arm64-msvc": "4.59.0", + "@rollup/rollup-win32-ia32-msvc": "4.59.0", + "@rollup/rollup-win32-x64-gnu": "4.59.0", + "@rollup/rollup-win32-x64-msvc": "4.59.0", + "fsevents": "~2.3.2" + } + }, + "node_modules/sade": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/sade/-/sade-1.8.1.tgz", + "integrity": "sha512-xal3CZX1Xlo/k4ApwCFrHVACi9fBqJ7V+mwhBsuf/1IOKbBy098Fex+Wa/5QMubw09pSZ/u8EY8PWgevJsXp1A==", + "dev": true, + "license": "MIT", + "dependencies": { + "mri": "^1.1.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/set-cookie-parser": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/set-cookie-parser/-/set-cookie-parser-3.0.1.tgz", + "integrity": "sha512-n7Z7dXZhJbwuAHhNzkTti6Aw9QDDjZtm3JTpTGATIdNzdQz5GuFs22w90BcvF4INfnrL5xrX3oGsuqO5Dx3A1Q==", + "dev": true, + "license": "MIT" + }, + "node_modules/sirv": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/sirv/-/sirv-3.0.2.tgz", + "integrity": "sha512-2wcC/oGxHis/BoHkkPwldgiPSYcpZK3JU28WoMVv55yHJgcZ8rlXvuG9iZggz+sU1d4bRgIGASwyWqjxu3FM0g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@polka/url": "^1.0.0-next.24", + "mrmime": "^2.0.0", + "totalist": "^3.0.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/source-map-js": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz", + "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/svelte": { + "version": "5.53.6", + "resolved": "https://registry.npmjs.org/svelte/-/svelte-5.53.6.tgz", + "integrity": "sha512-lP5DGF3oDDI9fhHcSpaBiJEkFLuS16h92DhM1L5K1lFm0WjOmUh1i2sNkBBk8rkxJRpob0dBE75jRfUzGZUOGA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/remapping": "^2.3.4", + "@jridgewell/sourcemap-codec": "^1.5.0", + "@sveltejs/acorn-typescript": "^1.0.5", + "@types/estree": "^1.0.5", + "@types/trusted-types": "^2.0.7", + "acorn": "^8.12.1", + "aria-query": "5.3.1", + "axobject-query": "^4.1.0", + "clsx": "^2.1.1", + "devalue": "^5.6.3", + "esm-env": "^1.2.1", + "esrap": "^2.2.2", + "is-reference": "^3.0.3", + "locate-character": "^3.0.0", + "magic-string": "^0.30.11", + "zimmerframe": "^1.1.2" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/svelte-check": { + "version": "4.4.4", + "resolved": "https://registry.npmjs.org/svelte-check/-/svelte-check-4.4.4.tgz", + "integrity": "sha512-F1pGqXc710Oi/wTI4d/x7d6lgPwwfx1U6w3Q35n4xsC2e8C/yN2sM1+mWxjlMcpAfWucjlq4vPi+P4FZ8a14sQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/trace-mapping": "^0.3.25", + "chokidar": "^4.0.1", + "fdir": "^6.2.0", + "picocolors": "^1.0.0", + "sade": "^1.7.4" + }, + "bin": { + "svelte-check": "bin/svelte-check" + }, + "engines": { + "node": ">= 18.0.0" + }, + "peerDependencies": { + "svelte": "^4.0.0 || ^5.0.0-next.0", + "typescript": ">=5.0.0" + } + }, + "node_modules/tinyglobby": { + "version": "0.2.15", + "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.15.tgz", + "integrity": "sha512-j2Zq4NyQYG5XMST4cbs02Ak8iJUdxRM0XI5QyxXuZOzKOINmWurp3smXu3y5wDcJrptwpSjgXHzIQxR0omXljQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "fdir": "^6.5.0", + "picomatch": "^4.0.3" + }, + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/SuperchupuDev" + } + }, + "node_modules/totalist": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/totalist/-/totalist-3.0.1.tgz", + "integrity": "sha512-sf4i37nQ2LBx4m3wB74y+ubopq6W/dIzXg0FDGjsYnZHVa1Da8FH853wlL2gtUhg+xJXjfk3kUZS3BRoQeoQBQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/typescript": { + "version": "5.9.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.3.tgz", + "integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==", + "dev": true, + "license": "Apache-2.0", + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" + } + }, + "node_modules/vite": { + "version": "6.4.1", + "resolved": "https://registry.npmjs.org/vite/-/vite-6.4.1.tgz", + "integrity": "sha512-+Oxm7q9hDoLMyJOYfUYBuHQo+dkAloi33apOPP56pzj+vsdJDzr+j1NISE5pyaAuKL4A3UD34qd0lx5+kfKp2g==", + "dev": true, + "license": "MIT", + "dependencies": { + "esbuild": "^0.25.0", + "fdir": "^6.4.4", + "picomatch": "^4.0.2", + "postcss": "^8.5.3", + "rollup": "^4.34.9", + "tinyglobby": "^0.2.13" + }, + "bin": { + "vite": "bin/vite.js" + }, + "engines": { + "node": "^18.0.0 || ^20.0.0 || >=22.0.0" + }, + "funding": { + "url": "https://github.com/vitejs/vite?sponsor=1" + }, + "optionalDependencies": { + "fsevents": "~2.3.3" + }, + "peerDependencies": { + "@types/node": "^18.0.0 || ^20.0.0 || >=22.0.0", + "jiti": ">=1.21.0", + "less": "*", + "lightningcss": "^1.21.0", + "sass": "*", + "sass-embedded": "*", + "stylus": "*", + "sugarss": "*", + "terser": "^5.16.0", + "tsx": "^4.8.1", + "yaml": "^2.4.2" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + }, + "jiti": { + "optional": true + }, + "less": { + "optional": true + }, + "lightningcss": { + "optional": true + }, + "sass": { + "optional": true + }, + "sass-embedded": { + "optional": true + }, + "stylus": { + "optional": true + }, + "sugarss": { + "optional": true + }, + "terser": { + "optional": true + }, + "tsx": { + "optional": true + }, + "yaml": { + "optional": true + } + } + }, + "node_modules/vitefu": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/vitefu/-/vitefu-1.1.2.tgz", + "integrity": "sha512-zpKATdUbzbsycPFBN71nS2uzBUQiVnFoOrr2rvqv34S1lcAgMKKkjWleLGeiJlZ8lwCXvtWaRn7R3ZC16SYRuw==", + "dev": true, + "license": "MIT", + "workspaces": [ + "tests/deps/*", + "tests/projects/*", + "tests/projects/workspace/packages/*" + ], + "peerDependencies": { + "vite": "^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0-beta.0" + }, + "peerDependenciesMeta": { + "vite": { + "optional": true + } + } + }, + "node_modules/zimmerframe": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/zimmerframe/-/zimmerframe-1.1.4.tgz", + "integrity": "sha512-B58NGBEoc8Y9MWWCQGl/gq9xBCe4IiKM0a2x7GZdQKOW5Exr8S1W24J6OgM1njK8xCRGvAJIL/MxXHf6SkmQKQ==", + "dev": true, + "license": "MIT" + } + } +} diff --git a/frontend/package.json b/frontend/package.json new file mode 100644 index 0000000..3414338 --- /dev/null +++ b/frontend/package.json @@ -0,0 +1,22 @@ +{ + "name": "felt-frontend", + "version": "0.1.0", + "private": true, + "type": "module", + "scripts": { + "dev": "vite dev", + "build": "vite build", + "preview": "vite preview", + "check": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json", + "check:watch": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json --watch" + }, + "devDependencies": { + "@sveltejs/adapter-static": "^3.0.8", + "@sveltejs/kit": "^2.16.0", + "@sveltejs/vite-plugin-svelte": "^5.0.0", + "svelte": "^5.0.0", + "svelte-check": "^4.0.0", + "typescript": "^5.0.0", + "vite": "^6.0.0" + } +} diff --git a/frontend/src/app.css b/frontend/src/app.css new file mode 100644 index 0000000..dd0fcd9 --- /dev/null +++ b/frontend/src/app.css @@ -0,0 +1,138 @@ +@import '$lib/theme/catppuccin.css'; + +/* ============================================ + Reset + ============================================ */ +*, +*::before, +*::after { + box-sizing: border-box; + margin: 0; + padding: 0; +} + +/* ============================================ + Base styles + ============================================ */ +html { + font-family: var(--font-body); + font-size: 16px; + line-height: var(--leading-normal); + color: var(--color-text); + background-color: var(--color-bg); + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; + /* Prevent layout shift from scrollbar */ + scrollbar-gutter: stable; +} + +body { + min-height: 100dvh; + color: var(--color-text); + background-color: var(--color-bg); +} + +/* ============================================ + Touch targets & interaction + Poker room: TD using phone with one hand + ============================================ */ +button, +a, +input, +select, +textarea, +[role='button'], +[role='tab'], +[role='menuitem'] { + /* Prevent double-tap zoom on mobile */ + touch-action: manipulation; +} + +/* Minimum 48px touch target for all interactive elements */ +.touch-target, +button, +[role='button'], +[role='tab'] { + min-height: var(--touch-target); + min-width: var(--touch-target); +} + +/* Active/pressed state for tactile feedback */ +button:active, +[role='button']:active, +[role='tab']:active, +.touch-target:active { + transform: scale(0.97); + opacity: 0.9; + transition: transform var(--transition-fast), opacity var(--transition-fast); +} + +/* Focus visible for keyboard accessibility */ +:focus-visible { + outline: 2px solid var(--color-primary); + outline-offset: 2px; +} + +/* Remove default focus ring for mouse/touch users */ +:focus:not(:focus-visible) { + outline: none; +} + +/* ============================================ + Scrollbar styling (dark theme) + ============================================ */ +::-webkit-scrollbar { + width: 8px; + height: 8px; +} + +::-webkit-scrollbar-track { + background: var(--color-bg); +} + +::-webkit-scrollbar-thumb { + background: var(--color-surface-active); + border-radius: var(--radius-full); +} + +::-webkit-scrollbar-thumb:hover { + background: var(--color-overlay); +} + +/* Firefox */ +* { + scrollbar-width: thin; + scrollbar-color: var(--color-surface-active) var(--color-bg); +} + +/* ============================================ + Typography helpers + ============================================ */ +.font-mono { + font-family: var(--font-mono); +} + +/* Timer/number display — always monospace */ +.timer, +.number, +.blinds, +.chips, +.currency { + font-family: var(--font-mono); + font-variant-numeric: tabular-nums; +} + +/* ============================================ + Common utility classes + ============================================ */ +.visually-hidden { + position: absolute; + width: 1px; + height: 1px; + padding: 0; + margin: -1px; + overflow: hidden; + clip: rect(0, 0, 0, 0); + white-space: nowrap; + border: 0; +} diff --git a/frontend/src/app.d.ts b/frontend/src/app.d.ts new file mode 100644 index 0000000..da08e6d --- /dev/null +++ b/frontend/src/app.d.ts @@ -0,0 +1,13 @@ +// See https://svelte.dev/docs/kit/types#app.d.ts +// for information about these interfaces +declare global { + namespace App { + // interface Error {} + // interface Locals {} + // interface PageData {} + // interface PageState {} + // interface Platform {} + } +} + +export {}; diff --git a/frontend/src/app.html b/frontend/src/app.html new file mode 100644 index 0000000..03453cf --- /dev/null +++ b/frontend/src/app.html @@ -0,0 +1,13 @@ + + + + + + + Felt + %sveltekit.head% + + +
%sveltekit.body%
+ + diff --git a/frontend/src/lib/api.ts b/frontend/src/lib/api.ts new file mode 100644 index 0000000..f8d657b --- /dev/null +++ b/frontend/src/lib/api.ts @@ -0,0 +1,124 @@ +/** + * HTTP API client for the Felt backend. + * + * Auto-detects base URL from current host, attaches JWT from auth store, + * handles 401 responses by clearing auth state and redirecting to login. + */ + +import { auth } from '$lib/stores/auth.svelte'; +import { goto } from '$app/navigation'; + +/** Typed API error with status code and message. */ +export class ApiError extends Error { + constructor( + public readonly status: number, + public readonly statusText: string, + public readonly body: unknown + ) { + const msg = typeof body === 'object' && body !== null && 'error' in body + ? (body as { error: string }).error + : statusText; + super(msg); + this.name = 'ApiError'; + } +} + +/** Base URL for API requests — auto-detected from current host. */ +function getBaseUrl(): string { + return `${window.location.origin}/api/v1`; +} + +/** Build headers with JWT auth and content type. */ +function buildHeaders(hasBody: boolean): HeadersInit { + const headers: Record = { + 'Accept': 'application/json' + }; + + if (hasBody) { + headers['Content-Type'] = 'application/json'; + } + + const token = auth.token; + if (token) { + headers['Authorization'] = `Bearer ${token}`; + } + + return headers; +} + +/** Handle API response — parse JSON, handle errors. */ +async function handleResponse(response: Response): Promise { + if (response.status === 401) { + // Token expired or invalid — clear auth and redirect to login + auth.logout(); + await goto('/login'); + throw new ApiError(401, 'Unauthorized', { error: 'Session expired' }); + } + + if (!response.ok) { + let body: unknown; + try { + body = await response.json(); + } catch { + body = { error: response.statusText }; + } + throw new ApiError(response.status, response.statusText, body); + } + + // Handle 204 No Content + if (response.status === 204) { + return undefined as T; + } + + return response.json() as Promise; +} + +/** Perform an API request. */ +async function request(method: string, path: string, body?: unknown): Promise { + const url = `${getBaseUrl()}${path}`; + + const init: RequestInit = { + method, + headers: buildHeaders(body !== undefined), + credentials: 'same-origin' + }; + + if (body !== undefined) { + init.body = JSON.stringify(body); + } + + const response = await fetch(url, init); + return handleResponse(response); +} + +/** + * HTTP API client. + * + * All methods auto-attach JWT from auth store and handle 401 responses. + */ +export const api = { + /** GET request. */ + get(path: string): Promise { + return request('GET', path); + }, + + /** POST request with JSON body. */ + post(path: string, body?: unknown): Promise { + return request('POST', path, body); + }, + + /** PUT request with JSON body. */ + put(path: string, body?: unknown): Promise { + return request('PUT', path, body); + }, + + /** PATCH request with JSON body. */ + patch(path: string, body?: unknown): Promise { + return request('PATCH', path, body); + }, + + /** DELETE request. */ + delete(path: string): Promise { + return request('DELETE', path); + } +}; diff --git a/frontend/src/lib/stores/auth.svelte.ts b/frontend/src/lib/stores/auth.svelte.ts new file mode 100644 index 0000000..c39c291 --- /dev/null +++ b/frontend/src/lib/stores/auth.svelte.ts @@ -0,0 +1,109 @@ +/** + * Authentication state using Svelte 5 runes. + * + * Manages JWT token and operator info with localStorage persistence. + * Token is stored in localStorage (acceptable while Leaf is local-network only). + * + * TODO Phase 7: Migrate token storage from localStorage to HttpOnly cookies + * for XSS protection when Netbird reverse proxy is in place. + */ + +const TOKEN_KEY = 'felt_token'; +const OPERATOR_KEY = 'felt_operator'; + +/** Operator role type. */ +export type OperatorRole = 'admin' | 'floor' | 'viewer'; + +/** Operator information from JWT claims. */ +export interface Operator { + id: string; + name: string; + role: OperatorRole; +} + +class AuthState { + token = $state(null); + operator = $state(null); + + constructor() { + // Load persisted state on initialization + if (typeof window !== 'undefined') { + this.loadFromStorage(); + } + } + + /** Whether the user is authenticated. */ + get isAuthenticated(): boolean { + return this.token !== null; + } + + /** Whether the user has admin role. */ + get isAdmin(): boolean { + return this.operator?.role === 'admin'; + } + + /** Whether the user has floor or admin role. */ + get isFloor(): boolean { + return ['admin', 'floor'].includes(this.operator?.role ?? ''); + } + + /** + * Set authentication state after successful login. + * + * @param token - JWT token string + * @param operator - Operator info from token claims + */ + login(token: string, operator: Operator): void { + this.token = token; + this.operator = operator; + this.saveToStorage(); + } + + /** Clear authentication state (logout or 401). */ + logout(): void { + this.token = null; + this.operator = null; + this.clearStorage(); + } + + /** Load persisted auth from localStorage. */ + private loadFromStorage(): void { + try { + const token = localStorage.getItem(TOKEN_KEY); + const operatorJson = localStorage.getItem(OPERATOR_KEY); + + if (token && operatorJson) { + this.token = token; + this.operator = JSON.parse(operatorJson) as Operator; + } + } catch (err) { + console.warn('auth: failed to load from storage:', err); + this.clearStorage(); + } + } + + /** Save auth state to localStorage. */ + private saveToStorage(): void { + try { + if (this.token && this.operator) { + localStorage.setItem(TOKEN_KEY, this.token); + localStorage.setItem(OPERATOR_KEY, JSON.stringify(this.operator)); + } + } catch (err) { + console.warn('auth: failed to save to storage:', err); + } + } + + /** Clear auth from localStorage. */ + private clearStorage(): void { + try { + localStorage.removeItem(TOKEN_KEY); + localStorage.removeItem(OPERATOR_KEY); + } catch (err) { + console.warn('auth: failed to clear storage:', err); + } + } +} + +/** Singleton auth state instance. */ +export const auth = new AuthState(); diff --git a/frontend/src/lib/stores/tournament.svelte.ts b/frontend/src/lib/stores/tournament.svelte.ts new file mode 100644 index 0000000..a12d7bd --- /dev/null +++ b/frontend/src/lib/stores/tournament.svelte.ts @@ -0,0 +1,326 @@ +/** + * Tournament state using Svelte 5 runes. + * + * Handles real-time WebSocket messages from the backend and maintains + * reactive state for all tournament data: clock, players, tables, + * financials, activity feed, rankings, and table balance status. + */ + +// ============================================ +// Types +// ============================================ + +export interface ClockSnapshot { + level: number; + name: string; + small_blind: number; + big_blind: number; + ante: number; + elapsed_seconds: number; + remaining_seconds: number; + is_break: boolean; + is_paused: boolean; + next_break_in_seconds: number | null; +} + +export type PlayerStatus = 'registered' | 'active' | 'eliminated' | 'away'; + +export interface Player { + id: string; + name: string; + status: PlayerStatus; + table_id: string | null; + seat: number | null; + chips: number; + rebuys: number; + addons: number; + bounty: number; + finish_position: number | null; + eliminated_by: string | null; +} + +export interface Table { + id: string; + number: number; + seats: number; + players: string[]; // player IDs + is_final_table: boolean; + is_break_table: boolean; +} + +export interface FinancialSummary { + total_buyin: number; + total_rebuys: number; + total_addons: number; + total_collected: number; + prize_pool: number; + house_fee: number; + paid_positions: number; + payouts: PayoutEntry[]; +} + +export interface PayoutEntry { + position: number; + amount: number; + player_id: string | null; + player_name: string | null; +} + +export interface ActivityEntry { + id: string; + type: string; + message: string; + player_id: string | null; + player_name: string | null; + timestamp: number; +} + +export interface PlayerRanking { + position: number; + player_id: string; + player_name: string; + chips: number; + bounties: number; +} + +export interface BalanceStatus { + is_balanced: boolean; + moves_needed: BalanceMove[]; + max_diff: number; +} + +export interface BalanceMove { + player_id: string; + player_name: string; + from_table: number; + to_table: number; + to_seat: number; +} + +export interface WSMessage { + type: string; + tournament_id?: string; + data: unknown; + timestamp: number; +} + +// ============================================ +// State +// ============================================ + +class TournamentState { + /** Current tournament ID. */ + id = $state(null); + + /** Clock/timer state. */ + clock = $state(null); + + /** All players. */ + players = $state([]); + + /** All tables. */ + tables = $state([]); + + /** Financial summary. */ + financials = $state(null); + + /** Activity feed (most recent first). */ + activity = $state([]); + + /** Player rankings by chip count. */ + rankings = $state([]); + + /** Table balance status. */ + balanceStatus = $state(null); + + /** Maximum activity feed entries to keep. */ + private maxActivityEntries = 100; + + // ============================================ + // Derived state + // ============================================ + + /** Count of active (not eliminated) players. */ + get remainingPlayers(): number { + return this.players.filter((p) => p.status === 'active').length; + } + + /** Total registered players. */ + get totalPlayers(): number { + return this.players.length; + } + + /** Active tables count. */ + get activeTables(): number { + return this.tables.filter((t) => t.players.length > 0).length; + } + + /** Whether tables are balanced. */ + get isBalanced(): boolean { + return this.balanceStatus?.is_balanced ?? true; + } + + // ============================================ + // WebSocket message handler + // ============================================ + + /** + * Handle an incoming WebSocket message and update state. + * + * Message types match the Go backend's broadcast types: + * - clock.tick: Timer update every second + * - state.snapshot: Full state load (on connect or refresh) + * - player.*: Player-related events + * - table.*: Table-related events + * - financial.*: Financial updates + * - balance.*: Table balance events + */ + handleMessage(msg: WSMessage): void { + switch (msg.type) { + // Clock + case 'clock.tick': + this.clock = msg.data as ClockSnapshot; + break; + case 'clock.level_change': + this.clock = msg.data as ClockSnapshot; + break; + case 'clock.paused': + if (this.clock) this.clock.is_paused = true; + break; + case 'clock.resumed': + if (this.clock) this.clock.is_paused = false; + break; + + // Full state snapshot + case 'state.snapshot': + this.loadFullState(msg.data as FullSnapshot); + break; + + // Players + case 'player.registered': + this.addOrUpdatePlayer(msg.data as Player); + break; + case 'player.seated': + this.addOrUpdatePlayer(msg.data as Player); + break; + case 'player.bust': + case 'player.eliminated': + this.addOrUpdatePlayer(msg.data as Player); + break; + case 'player.rebuy': + case 'player.addon': + this.addOrUpdatePlayer(msg.data as Player); + break; + case 'player.moved': + this.addOrUpdatePlayer(msg.data as Player); + break; + + // Tables + case 'table.created': + this.addOrUpdateTable(msg.data as Table); + break; + case 'table.broken': + this.removeTable((msg.data as { id: string }).id); + break; + case 'table.updated': + this.addOrUpdateTable(msg.data as Table); + break; + + // Financials + case 'financial.updated': + this.financials = msg.data as FinancialSummary; + break; + + // Rankings + case 'rankings.updated': + this.rankings = msg.data as PlayerRanking[]; + break; + + // Balance + case 'balance.updated': + this.balanceStatus = msg.data as BalanceStatus; + break; + + // Activity + case 'activity.new': + this.addActivity(msg.data as ActivityEntry); + break; + + // Connection + case 'connected': + console.log('tournament: connected to server'); + break; + + default: + console.warn(`tournament: unknown message type: ${msg.type}`); + } + } + + /** Reset all state. */ + reset(): void { + this.id = null; + this.clock = null; + this.players = []; + this.tables = []; + this.financials = null; + this.activity = []; + this.rankings = []; + this.balanceStatus = null; + } + + // ============================================ + // Private helpers + // ============================================ + + private loadFullState(snapshot: FullSnapshot): void { + this.id = snapshot.id ?? this.id; + this.clock = snapshot.clock ?? null; + this.players = snapshot.players ?? []; + this.tables = snapshot.tables ?? []; + this.financials = snapshot.financials ?? null; + this.activity = snapshot.activity ?? []; + this.rankings = snapshot.rankings ?? []; + this.balanceStatus = snapshot.balance_status ?? null; + } + + private addOrUpdatePlayer(player: Player): void { + const idx = this.players.findIndex((p) => p.id === player.id); + if (idx >= 0) { + this.players[idx] = player; + } else { + this.players.push(player); + } + } + + private addOrUpdateTable(table: Table): void { + const idx = this.tables.findIndex((t) => t.id === table.id); + if (idx >= 0) { + this.tables[idx] = table; + } else { + this.tables.push(table); + } + } + + private removeTable(tableId: string): void { + this.tables = this.tables.filter((t) => t.id !== tableId); + } + + private addActivity(entry: ActivityEntry): void { + this.activity = [entry, ...this.activity].slice(0, this.maxActivityEntries); + } +} + +/** Full state snapshot received on WebSocket connect. */ +interface FullSnapshot { + id?: string; + clock?: ClockSnapshot; + players?: Player[]; + tables?: Table[]; + financials?: FinancialSummary; + activity?: ActivityEntry[]; + rankings?: PlayerRanking[]; + balance_status?: BalanceStatus; +} + +/** Singleton tournament state instance. */ +export const tournament = new TournamentState(); diff --git a/frontend/src/lib/theme/catppuccin.css b/frontend/src/lib/theme/catppuccin.css new file mode 100644 index 0000000..2137762 --- /dev/null +++ b/frontend/src/lib/theme/catppuccin.css @@ -0,0 +1,163 @@ +/* + * Catppuccin Theme for Felt + * https://catppuccin.com/ + * + * Mocha (dark) — default + * Latte (light) — alternate + * + * All 26 base colors + semantic mappings + poker-specific tokens + */ + +/* ============================================ + Mocha (dark theme) — default + ============================================ */ +[data-theme='mocha'], +:root { + /* Base colors */ + --ctp-rosewater: #f5e0dc; + --ctp-flamingo: #f2cdcd; + --ctp-pink: #f5c2e7; + --ctp-mauve: #cba6f7; + --ctp-red: #f38ba8; + --ctp-maroon: #eba0ac; + --ctp-peach: #fab387; + --ctp-yellow: #f9e2af; + --ctp-green: #a6e3a1; + --ctp-teal: #94e2d5; + --ctp-sky: #89dceb; + --ctp-sapphire: #74c7ec; + --ctp-blue: #89b4fa; + --ctp-lavender: #b4befe; + + /* Surface colors */ + --ctp-text: #cdd6f4; + --ctp-subtext1: #bac2de; + --ctp-subtext0: #a6adc8; + --ctp-overlay2: #9399b2; + --ctp-overlay1: #7f849c; + --ctp-overlay0: #6c7086; + --ctp-surface2: #585b70; + --ctp-surface1: #45475a; + --ctp-surface0: #313244; + --ctp-base: #1e1e2e; + --ctp-mantle: #181825; + --ctp-crust: #11111b; + + /* Semantic color mappings */ + --color-bg: var(--ctp-base); + --color-bg-elevated: var(--ctp-mantle); + --color-bg-sunken: var(--ctp-crust); + --color-surface: var(--ctp-surface0); + --color-surface-hover: var(--ctp-surface1); + --color-surface-active: var(--ctp-surface2); + --color-text: var(--ctp-text); + --color-text-secondary: var(--ctp-subtext1); + --color-text-muted: var(--ctp-subtext0); + --color-primary: var(--ctp-blue); + --color-success: var(--ctp-green); + --color-warning: var(--ctp-yellow); + --color-error: var(--ctp-red); + --color-accent: var(--ctp-mauve); + --color-border: var(--ctp-surface1); + --color-overlay: var(--ctp-overlay0); + + /* Poker-specific semantic tokens */ + --color-felt: var(--ctp-green); + --color-card: var(--ctp-text); + --color-bounty: var(--ctp-pink); + --color-prize: var(--ctp-yellow); + --color-chip: var(--ctp-peach); + --color-clock: var(--ctp-sapphire); + --color-break: var(--ctp-teal); + --color-elimination: var(--ctp-red); +} + +/* ============================================ + Latte (light theme) — alternate + ============================================ */ +[data-theme='latte'] { + /* Base colors */ + --ctp-rosewater: #dc8a78; + --ctp-flamingo: #dd7878; + --ctp-pink: #ea76cb; + --ctp-mauve: #8839ef; + --ctp-red: #d20f39; + --ctp-maroon: #e64553; + --ctp-peach: #fe640b; + --ctp-yellow: #df8e1d; + --ctp-green: #40a02b; + --ctp-teal: #179299; + --ctp-sky: #04a5e5; + --ctp-sapphire: #209fb5; + --ctp-blue: #1e66f5; + --ctp-lavender: #7287fd; + + /* Surface colors */ + --ctp-text: #4c4f69; + --ctp-subtext1: #5c5f77; + --ctp-subtext0: #6c6f85; + --ctp-overlay2: #7c7f93; + --ctp-overlay1: #8c8fa1; + --ctp-overlay0: #9ca0b0; + --ctp-surface2: #acb0be; + --ctp-surface1: #bcc0cc; + --ctp-surface0: #ccd0da; + --ctp-base: #eff1f5; + --ctp-mantle: #e6e9ef; + --ctp-crust: #dce0e8; + + /* Semantic mappings auto-inherit from --ctp-* variables */ +} + +/* ============================================ + Typography + ============================================ */ +:root { + /* Font stacks */ + --font-body: system-ui, -apple-system, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif; + --font-mono: 'JetBrains Mono', 'Fira Code', ui-monospace, 'Cascadia Code', 'Source Code Pro', Menlo, Consolas, 'DejaVu Sans Mono', monospace; + + /* Font sizes */ + --text-xs: 0.75rem; + --text-sm: 0.875rem; + --text-base: 1rem; + --text-lg: 1.125rem; + --text-xl: 1.25rem; + --text-2xl: 1.5rem; + --text-3xl: 1.875rem; + --text-4xl: 2.25rem; + + /* Line heights */ + --leading-tight: 1.25; + --leading-normal: 1.5; + --leading-relaxed: 1.75; + + /* Spacing */ + --space-1: 0.25rem; + --space-2: 0.5rem; + --space-3: 0.75rem; + --space-4: 1rem; + --space-6: 1.5rem; + --space-8: 2rem; + --space-12: 3rem; + + /* Border radius */ + --radius-sm: 0.25rem; + --radius-md: 0.5rem; + --radius-lg: 0.75rem; + --radius-xl: 1rem; + --radius-full: 9999px; + + /* Shadows */ + --shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.3); + --shadow-md: 0 4px 6px rgba(0, 0, 0, 0.3); + --shadow-lg: 0 10px 15px rgba(0, 0, 0, 0.3); + + /* Transitions */ + --transition-fast: 100ms ease; + --transition-normal: 200ms ease; + --transition-slow: 300ms ease; + + /* Touch target minimum */ + --touch-target: 48px; +} diff --git a/frontend/src/lib/ws.ts b/frontend/src/lib/ws.ts new file mode 100644 index 0000000..52db426 --- /dev/null +++ b/frontend/src/lib/ws.ts @@ -0,0 +1,199 @@ +/** + * WebSocket client with auto-reconnect and exponential backoff. + * + * Connects to the Go backend's /ws endpoint with JWT authentication + * via query parameter (browser WebSocket API limitation). + */ + +export type ConnectionState = 'connecting' | 'connected' | 'disconnected' | 'reconnecting'; + +export interface WSMessage { + type: string; + tournament_id?: string; + data: unknown; + timestamp: number; +} + +type MessageHandler = (msg: WSMessage) => void; +type StateHandler = (state: ConnectionState) => void; + +const MIN_RECONNECT_DELAY = 1000; // 1s +const MAX_RECONNECT_DELAY = 30000; // 30s +const BACKOFF_MULTIPLIER = 2; + +export class WebSocketClient { + private ws: WebSocket | null = null; + private url: string = ''; + private token: string = ''; + private tournamentID: string = ''; + private reconnectDelay: number = MIN_RECONNECT_DELAY; + private reconnectTimer: ReturnType | null = null; + private intentionalClose: boolean = false; + private messageHandlers: MessageHandler[] = []; + private stateHandlers: StateHandler[] = []; + private _state: ConnectionState = 'disconnected'; + + /** Current connection state. */ + get state(): ConnectionState { + return this._state; + } + + /** + * Connect to the WebSocket server. + * + * @param token - JWT token for authentication + * @param tournamentID - Optional tournament scope + */ + connect(token: string, tournamentID?: string): void { + this.token = token; + this.tournamentID = tournamentID ?? ''; + this.intentionalClose = false; + + // Auto-detect protocol: http -> ws, https -> wss + const protocol = window.location.protocol === 'https:' ? 'wss:' : 'ws:'; + const host = window.location.host; + + let wsUrl = `${protocol}//${host}/ws?token=${encodeURIComponent(token)}`; + if (this.tournamentID) { + wsUrl += `&tournament=${encodeURIComponent(this.tournamentID)}`; + } + this.url = wsUrl; + + this.doConnect(); + } + + /** + * Subscribe to a specific tournament's updates. + * Reconnects with the new tournament scope. + */ + subscribe(tournamentID: string): void { + const wasConnected = this._state === 'connected'; + this.tournamentID = tournamentID; + + if (wasConnected && this.token) { + this.disconnect(); + this.connect(this.token, tournamentID); + } + } + + /** Disconnect from the WebSocket server. */ + disconnect(): void { + this.intentionalClose = true; + this.clearReconnectTimer(); + + if (this.ws) { + this.ws.close(1000, 'client disconnect'); + this.ws = null; + } + + this.setState('disconnected'); + } + + /** Send a JSON message to the server. */ + send(message: Record): void { + if (this.ws && this.ws.readyState === WebSocket.OPEN) { + this.ws.send(JSON.stringify(message)); + } else { + console.warn('ws: cannot send, not connected'); + } + } + + /** Register a message handler. Returns unsubscribe function. */ + onMessage(handler: MessageHandler): () => void { + this.messageHandlers.push(handler); + return () => { + this.messageHandlers = this.messageHandlers.filter((h) => h !== handler); + }; + } + + /** Register a connection state change handler. Returns unsubscribe function. */ + onStateChange(handler: StateHandler): () => void { + this.stateHandlers.push(handler); + return () => { + this.stateHandlers = this.stateHandlers.filter((h) => h !== handler); + }; + } + + private doConnect(): void { + if (this.ws) { + this.ws.close(); + this.ws = null; + } + + this.setState('connecting'); + + try { + this.ws = new WebSocket(this.url); + } catch (err) { + console.error('ws: failed to create WebSocket:', err); + this.scheduleReconnect(); + return; + } + + this.ws.onopen = () => { + console.log('ws: connected'); + this.setState('connected'); + this.reconnectDelay = MIN_RECONNECT_DELAY; // Reset backoff on success + }; + + this.ws.onmessage = (event: MessageEvent) => { + try { + const msg: WSMessage = JSON.parse(event.data as string); + for (const handler of this.messageHandlers) { + handler(msg); + } + } catch (err) { + console.error('ws: failed to parse message:', err); + } + }; + + this.ws.onclose = (event: CloseEvent) => { + console.log(`ws: closed (code=${event.code}, reason=${event.reason})`); + this.ws = null; + + if (!this.intentionalClose) { + this.scheduleReconnect(); + } else { + this.setState('disconnected'); + } + }; + + this.ws.onerror = (event: Event) => { + console.error('ws: error:', event); + // onclose will fire after onerror, which handles reconnect + }; + } + + private scheduleReconnect(): void { + this.setState('reconnecting'); + + this.clearReconnectTimer(); + + console.log(`ws: reconnecting in ${this.reconnectDelay}ms`); + this.reconnectTimer = setTimeout(() => { + this.doConnect(); + }, this.reconnectDelay); + + // Exponential backoff with cap + this.reconnectDelay = Math.min(this.reconnectDelay * BACKOFF_MULTIPLIER, MAX_RECONNECT_DELAY); + } + + private clearReconnectTimer(): void { + if (this.reconnectTimer !== null) { + clearTimeout(this.reconnectTimer); + this.reconnectTimer = null; + } + } + + private setState(state: ConnectionState): void { + if (this._state !== state) { + this._state = state; + for (const handler of this.stateHandlers) { + handler(state); + } + } + } +} + +/** Singleton WebSocket client instance. */ +export const wsClient = new WebSocketClient(); diff --git a/frontend/src/routes/+layout.svelte b/frontend/src/routes/+layout.svelte new file mode 100644 index 0000000..b93e9ba --- /dev/null +++ b/frontend/src/routes/+layout.svelte @@ -0,0 +1,7 @@ + + +{@render children()} diff --git a/frontend/src/routes/+layout.ts b/frontend/src/routes/+layout.ts new file mode 100644 index 0000000..c533800 --- /dev/null +++ b/frontend/src/routes/+layout.ts @@ -0,0 +1,2 @@ +export const prerender = true; +export const ssr = false; // SPA mode, no SSR diff --git a/frontend/src/routes/+page.svelte b/frontend/src/routes/+page.svelte new file mode 100644 index 0000000..50067a9 --- /dev/null +++ b/frontend/src/routes/+page.svelte @@ -0,0 +1,45 @@ + + +{#if auth.isAuthenticated} +
+

Felt

+

Tournament management system

+

Welcome, {auth.operator?.name ?? 'Operator'}

+
+{:else} +
+

Redirecting to login...

+
+{/if} + + diff --git a/frontend/src/routes/login/+page.svelte b/frontend/src/routes/login/+page.svelte new file mode 100644 index 0000000..885f8d8 --- /dev/null +++ b/frontend/src/routes/login/+page.svelte @@ -0,0 +1,302 @@ + + + + +
+ +
+ + diff --git a/frontend/static/favicon.png b/frontend/static/favicon.png new file mode 100644 index 0000000000000000000000000000000000000000..7cf2b36ba2d0b120b4487943b2bc6d33fca28007 GIT binary patch literal 70 zcmeAS@N?(olHy`uVBq!ia0vp^j3CUx1|;Q0k92}1TpU9x<|Mzk^Xauc1G@#Y`A&KM Q2S5o1Pgg&ebxsLQ0L{-3CjbBd literal 0 HcmV?d00001 diff --git a/frontend/svelte.config.js b/frontend/svelte.config.js new file mode 100644 index 0000000..df4201f --- /dev/null +++ b/frontend/svelte.config.js @@ -0,0 +1,17 @@ +import adapter from '@sveltejs/adapter-static'; + +/** @type {import('@sveltejs/kit').Config} */ +const config = { + kit: { + adapter: adapter({ + pages: 'build', + assets: 'build', + fallback: 'index.html', // SPA fallback + precompress: false, + strict: true + }), + paths: { base: '' } + } +}; + +export default config; diff --git a/frontend/tsconfig.json b/frontend/tsconfig.json new file mode 100644 index 0000000..a8f10c8 --- /dev/null +++ b/frontend/tsconfig.json @@ -0,0 +1,14 @@ +{ + "extends": "./.svelte-kit/tsconfig.json", + "compilerOptions": { + "allowJs": true, + "checkJs": true, + "esModuleInterop": true, + "forceConsistentCasingInFileNames": true, + "resolveJsonModule": true, + "skipLibCheck": true, + "sourceMap": true, + "strict": true, + "moduleResolution": "bundler" + } +} diff --git a/frontend/vite.config.ts b/frontend/vite.config.ts new file mode 100644 index 0000000..bbf8c7d --- /dev/null +++ b/frontend/vite.config.ts @@ -0,0 +1,6 @@ +import { sveltekit } from '@sveltejs/kit/vite'; +import { defineConfig } from 'vite'; + +export default defineConfig({ + plugins: [sveltekit()] +});