+ {title} +
+{desc}
+From 82e78ba217d10df5e5f5ac0c9064d3315b0bf65a Mon Sep 17 00:00:00 2001 From: Benno <57860196+bennoinbeta@users.noreply.github.com> Date: Tue, 10 Mar 2026 07:18:23 +0100 Subject: [PATCH 01/51] #7 init tanstack start --- apps/midimarble/.cta.json | 18 ++ apps/midimarble/.gitignore | 13 + apps/midimarble/.prettierignore | 3 + apps/midimarble/README.md | 204 ++++++++++++++ apps/midimarble/eslint.config.js | 20 ++ apps/midimarble/package.json | 54 ++++ apps/midimarble/public/favicon.ico | Bin 0 -> 3870 bytes apps/midimarble/public/logo192.png | Bin 0 -> 5347 bytes apps/midimarble/public/logo512.png | Bin 0 -> 9664 bytes apps/midimarble/public/manifest.json | 25 ++ apps/midimarble/public/robots.txt | 3 + apps/midimarble/src/components/Footer.tsx | 44 +++ apps/midimarble/src/components/Header.tsx | 78 ++++++ .../midimarble/src/components/ThemeToggle.tsx | 81 ++++++ apps/midimarble/src/router.tsx | 20 ++ apps/midimarble/src/routes/__root.tsx | 61 +++++ apps/midimarble/src/routes/about.tsx | 23 ++ apps/midimarble/src/routes/index.tsx | 87 ++++++ apps/midimarble/src/styles.css | 259 ++++++++++++++++++ apps/midimarble/tsconfig.json | 30 ++ apps/midimarble/vite.config.ts | 22 ++ 21 files changed, 1045 insertions(+) create mode 100644 apps/midimarble/.cta.json create mode 100644 apps/midimarble/.gitignore create mode 100644 apps/midimarble/.prettierignore create mode 100644 apps/midimarble/README.md create mode 100644 apps/midimarble/eslint.config.js create mode 100644 apps/midimarble/package.json create mode 100644 apps/midimarble/public/favicon.ico create mode 100644 apps/midimarble/public/logo192.png create mode 100644 apps/midimarble/public/logo512.png create mode 100644 apps/midimarble/public/manifest.json create mode 100644 apps/midimarble/public/robots.txt create mode 100644 apps/midimarble/src/components/Footer.tsx create mode 100644 apps/midimarble/src/components/Header.tsx create mode 100644 apps/midimarble/src/components/ThemeToggle.tsx create mode 100644 apps/midimarble/src/router.tsx create mode 100644 apps/midimarble/src/routes/__root.tsx create mode 100644 apps/midimarble/src/routes/about.tsx create mode 100644 apps/midimarble/src/routes/index.tsx create mode 100644 apps/midimarble/src/styles.css create mode 100644 apps/midimarble/tsconfig.json create mode 100644 apps/midimarble/vite.config.ts diff --git a/apps/midimarble/.cta.json b/apps/midimarble/.cta.json new file mode 100644 index 0000000..0f7df96 --- /dev/null +++ b/apps/midimarble/.cta.json @@ -0,0 +1,18 @@ +{ + "projectName": "midimarble", + "mode": "file-router", + "typescript": true, + "packageManager": "pnpm", + "includeExamples": false, + "tailwind": true, + "addOnOptions": {}, + "envVarValues": {}, + "git": false, + "routerOnly": false, + "version": 1, + "framework": "react", + "chosenAddOns": [ + "eslint", + "nitro" + ] +} \ No newline at end of file diff --git a/apps/midimarble/.gitignore b/apps/midimarble/.gitignore new file mode 100644 index 0000000..8b25bb5 --- /dev/null +++ b/apps/midimarble/.gitignore @@ -0,0 +1,13 @@ +node_modules +.DS_Store +dist +dist-ssr +*.local +.env +.nitro +.tanstack +.wrangler +.output +.vinxi +__unconfig* +todos.json diff --git a/apps/midimarble/.prettierignore b/apps/midimarble/.prettierignore new file mode 100644 index 0000000..5322d7f --- /dev/null +++ b/apps/midimarble/.prettierignore @@ -0,0 +1,3 @@ +package-lock.json +pnpm-lock.yaml +yarn.lock \ No newline at end of file diff --git a/apps/midimarble/README.md b/apps/midimarble/README.md new file mode 100644 index 0000000..811f171 --- /dev/null +++ b/apps/midimarble/README.md @@ -0,0 +1,204 @@ +Welcome to your new TanStack Start app! + +# Getting Started + +To run this application: + +```bash +pnpm install +pnpm dev +``` + +# Building For Production + +To build this application for production: + +```bash +pnpm build +``` + +## Testing + +This project uses [Vitest](https://vitest.dev/) for testing. You can run the tests with: + +```bash +pnpm test +``` + +## Styling + +This project uses [Tailwind CSS](https://tailwindcss.com/) for styling. + +### Removing Tailwind CSS + +If you prefer not to use Tailwind CSS: + +1. Remove the demo pages in `src/routes/demo/` +2. Replace the Tailwind import in `src/styles.css` with your own styles +3. Remove `tailwindcss()` from the plugins array in `vite.config.ts` +4. Uninstall the packages: `pnpm add @tailwindcss/vite tailwindcss --dev` + +## Linting & Formatting + + +This project uses [eslint](https://eslint.org/) and [prettier](https://prettier.io/) for linting and formatting. Eslint is configured using [tanstack/eslint-config](https://tanstack.com/config/latest/docs/eslint). The following scripts are available: + +```bash +pnpm lint +pnpm format +pnpm check +``` + + + +## Routing + +This project uses [TanStack Router](https://tanstack.com/router) with file-based routing. Routes are managed as files in `src/routes`. + +### Adding A Route + +To add a new route to your application just add a new file in the `./src/routes` directory. + +TanStack will automatically generate the content of the route file for you. + +Now that you have two routes you can use a `Link` component to navigate between them. + +### Adding Links + +To use SPA (Single Page Application) navigation you will need to import the `Link` component from `@tanstack/react-router`. + +```tsx +import { Link } from "@tanstack/react-router"; +``` + +Then anywhere in your JSX you can use it like so: + +```tsx +About +``` + +This will create a link that will navigate to the `/about` route. + +More information on the `Link` component can be found in the [Link documentation](https://tanstack.com/router/v1/docs/framework/react/api/router/linkComponent). + +### Using A Layout + +In the File Based Routing setup the layout is located in `src/routes/__root.tsx`. Anything you add to the root route will appear in all the routes. The route content will appear in the JSX where you render `{children}` in the `shellComponent`. + +Here is an example layout that includes a header: + +```tsx +import { HeadContent, Scripts, createRootRoute } from '@tanstack/react-router' + +export const Route = createRootRoute({ + head: () => ({ + meta: [ + { charSet: 'utf-8' }, + { name: 'viewport', content: 'width=device-width, initial-scale=1' }, + { title: 'My App' }, + ], + }), + shellComponent: ({ children }) => ( + +
+&*j;=u%25ay-%>3@81tGe^_z*C7pb9y*Ed^H3t$BIKH2o+olp#$q;)_ zfpjCb_^VFg5fU~K)nf*d*r@BCC>UZ!0&b?AGk_jTPXaSnCuW110wjHPPe^9R^;jo3 zwvzTl)C`Zl5}O2}3lec=hZ*$JnkW#7enKKc)(pM${_$9Hc=Sr_A9Biwe*Y=T?~1CK z6eZ9uPICjy-sMGbZl$yQmpB&`ouS8v{58__t0$JP%i3R&%QR3ianbZqDs<2#5FdN@n5bCn^ZtH992~5k(eA|8|@G9u`wdn7bnpg|@{m z^d6Y`*$Zf2Xr&|g%sai#5}Syvv(>Jnx&EM7-|Jr7!M~zdAyjt*xl;OLhvW-a%H1m0 z*x5*nb=R5u><7lyVpN AR?q@1U59 zO+)QW wL8t zyip?u_nI+K$uh{ y)~}qj?(w0&=SE^8`_WMM zTybjG=999h38Yes7}-4*LJ7H)UE8{mE(6;8voE+TYY%33A>S6`G_95^5QHNTo_;Ao ztIQIZ_}49%{8|=O;isBZ?=7kfdF8_@azfoTd+hEJKWE!)$)N%HIe2cplaK`ry#=pV z0q{9w-`i0h@!R8K3GC{ivt{70IWG`EP |(1g7i_Q<>aEAT{5( yD z=!O?kq61VegV+st@XCw475j6vS)_z@efuqQgHQR1T4;|-#OLZNQJPV4k$AX1Uk8Lm z{N*b*ia=I+MB}kWpupJ~>!C@xEN#Wa7V+7{m4j8c?)ChV=D?o~sjT?0C_AQ 7B-vxqX30s0I_`2$in86#`mAsT-w?j{&AL@B3$;P z31G4(lV|b}uSD CIrjk+M1R!X7s 4Aabn<)zpgT}#gE|mIvV38^ODy@<&yflpCwS#fRf9ZX3lPV_?8@C5)A;T zqmouFLFk;qIs4rA=hh=GL~sCFsXHsqO6_y~*AFt93 9UYVBSx1s(=Kb&5;j7cSowdE;7()CC2|-i9Zz+_BIw8#ll~-tyH?F3{%`QCsYa*b#s*9iCc`1P1oC26?`g<9))EJ3%xz+O!B3 zZ7$j~To)C@PquR>a1+Dh>-a%IvH_Y7^ys|4o?E%3`I&ADXfC8++hAdZfzIT#%C+Jz z1lU~K_vAm0m8Qk}K$F>| >RPK%<1SI0(G+8q~H zAsjezyP+u!Se4q3GW)`h`NPSRlMoBjCzNPesWJwVTY!o@G8=(6I%4XHGaSiS3MEBK zhgGFv6Jc>L$4jVE!I?TQuwvz_%CyO!bLh94nqK11C2W$*aa2ueGopG8DnBICVUORP zgytv#)49fVXDaR$SukloYC3u7#5H)}1K21=?DKj^U)8G;MS)&Op)g^zR2($<>C*zW z;X7`hLxiIO#J`ANdyAOJle4V%ppa*(+0i3w;8i*BA_;u8gOO6)MY`ueq7stBMJTB; z-a0R>hT*}>z|Gg}@^zDL1MrH+2hsR8 zHc}*9IvuQC^Ju)^#Y{fOr(96rQNPNhxc;mH@W*m206>Lo<*SaaH?~8zg&f&%YiOEG zGiz?*CP>Bci}!WiS=zj#K5I}>DtpregpP_tfZtPa(N<%vo^#WCQ5BTv0vr%Z{)0q+ z)RbfHktUm|lg&U3YM%lMUM(f u}i#kjX9h>GYctkx9Mt_8{@s%!K_EI zScgwy6%_fR?CG JQtmgNAj^h9B#zma MDWgH55pGuY1Gv7D z;8Psm(vEPiwn#MgJYu4Ty9D|h!?Rj0ddE|&L3S{IP%H4^N!m`60ZwZw^;eg4sk6K{ ziA^`Sbl_4~f&Oo%n;8Ye(tiAdlZKI!Z=|j$5hS|D$bDJ}p{gh$KN&JZYLUjv4h{NY zBJ>X9z !xfDGY z+oh_Z&_e#Q(-}>ssZfm=j$D&4W4FNy&-kAO1~#3Im;F)Nwe{(*75(p=P^VI?X 0GFakfh+X-px4a%Uw@fSbmp9hM1_~R>?Z8+ ziy|e9>8V*`OP}4x5JjdWp}7eX;lVxp5qS} 0YZek;SNmm7tEeSF*-dI)6U-A%m6YvCgM(}_=k#a6o^%-K4{`B1+}O4x zztDT%hVb;v#?j`lTvlFQ3aV#zkX=7 ;YFLS$uIzb0E3lozs5`Xy zi~vF+%{z9uLjKvKPhP%x5f ~7-Gj+%5N`%^=yk*Qn{`> z;xj&ROY6g`iy2a@{O)V(jk&8#hHACVDXey5a+KDod_Z&}kHM}xt7}Md@pil{2x7E~ zL$k^d2@Ec2XskjrN+IILw;#7((abu;OJii&v3?60x>d_Ma(onIPtcVnX@ELF0aL?T zSmWiL3(dOFkt!x=1O!_0n(cAzZW+3nHJ{2S>tgSK?~cF ha^y(l@-Mr2W$%MN{#af8J;V*>hdq!gx=d0h$T7l}>91Wh07)9CTX zh2_ZdQCyFOQ)l(}gft0UZ G`Sh2`x-w`5vC2UD}lZs*5 zG76$akzn}Xi))L3oGJ75#pcN=cX3!=57$Ha=hQ2^lwdyU#a}4JJOz6ddR%zae%#4& za)bFj)z=YQela(F#Y|Q#dp}PJghITwXouVaMq$BM?K%cXn9^Y@g43$=O)F&ZlOUom zJiad#dea;-eywBA@e&D6Pdso1?2^(pXiN91?jvcaUyYoKUmvl5G9e$W!okWe*@a<^ z8cQQ6cNSf+UPDx%?_G4a IiybZHHagF{ ;IcD(dPO!#=u zWfqLcPc^+7Uu#l(B pxft{*4lv#*u7X9AOzDO z1D9?^jIo}?%iz(_dwLa{ex#T}76ZfN_Z-hwpus9y+4xaUu9cX}&P{XrZVWE{1^0yw zO;YhLEW!pJcbCt3L8~a7>jsaN{V3>tz6_7`&pi%GxZ=V3?3K^ U+*ryLSb)8^IblJ0 zSRLNDvIxt)S}g30?s_3NX>F?NKIGrG_zB9@Z>uSW3k2es_H2kU;Rnn%j5qP)!XHKE zPB2mHP~tLCg4K_vH$xv`HbRsJwbZMUV(t=ez;Ec(vyHH)FbfLg`c61I$W_uBB>i^r z&{_P;369-&>23R%qNIULe=1~T$(DA`ev*EWZ6j(B$(te}x1WvmIll21zvygkS%vwG zzkR6Z#RKA2!z!C%M!O>!=Gr0(J0FP=-MN=5t-Ir)of50y10W}j`GtRCsXBakrKtG& zazmITDJMA0C51&BnLY)SY9r)NVTMs);1<=oosS9g31l{4ztjD3#+2H7u_|66b|_*O z;Qk6nalpqdHOjx|K&vUS_6ITgGll;TdaN*ta=M_YtyC)I9Tmr~VaPrH2q b6sd~=AcIxV+%z{E&0@y=DPArw zdV7z(G1hBx7hd{>(cr43^WF%4Y@PXZ?wPpj{OQ#tvc$pABJbvPGvdR`cAtHn)cSEV zrpu}1tJwQ3y!mSmH*uz*x0o|CS<^w%&KJzsj~DU0cLQUxk5B!hWE>aBkjJle8z~;s z-!A=($+}Jq_BTK5^B!`R>!MulZN)F=iXXeUd0w5lUsE5VP*H*oCy( ;?S$p*TVvTxwAeWFB$jHyb0593)$zqalVlDX=GcCN1gU0 zlgU)I$LcXZ8Oyc2TZYTPu@-;7<4YYB-``Qa;IDcvydIA$%kHhJKV^m*- zxcvU4viy &Kr5GVM{IT>WRywKQ9;>SEiQD*NqplK-KK4YR`p0@JW)n_{TU3bt0 zim%;(m1=#v2}zTps=?fU5w^(*y)xT%1vtQH&}50ZF!9YxW=&7*W($2kgKyz1mUgfs zfV<*XVVIFnohW=|j+@Kfo!#liQR^x>2yQdrG;2o8WZR+XzU_nG=Ed2rK?ntA;K5B{ z>M8+*A4 !Jm^Bg}aW?R?6;@QG@uQ8&oJ{hFixcfEnJ4QH?A4>P=q29oDGW;L;= z9-a0;g%c`C+Ai!UmK$NC*4#;Jp<1=TioL=t^YM)<<%u#hnnfSS`nq63QKGO1L8RzX z@MFDq s1z ztYmxDl@LU)5acvHk)~Z`RW7=aJ_nGD!mOSYD>5Odjn@TK#LY{jf?+piB5AM-CAoT_ z?S-*q7}wyLJzK>N%eMPuFgN)Q_otKP;aqy=D5f! 7<=n(lNkYRXVpkB{TAYLYg{|(jtRqYmg$xH zjmq ?B(RE4 zQx^~Pt}gxC2~l=K$$-sYy_r$CO(d=+b3H1MB*y_5g6WLaWTXn+TKQ|hNY^>Mp6k*$ zwkovomhu776vQATqT4blf~g;TY(MWCrf^^yfWJvSAB$p5l;jm@o#=!lqw+Lqfq>X= z$6~kxfm7`3q4zUEB;u4qa#BdJxO!;xGm)wwuisj{0y2x{R(IGMrsIzDY9LW>m!Y`= z04sx3IjnYvL<4JqxQ8f7qYd0s2Ig%`ytYPEMKI)s(LD}D@EY>x`VFtqvnADNBdeao zC96X+MxnwKmjpg{U&gP3HE}1=s!lv&D{6(g_lzyF3A`7Jn*&d_kL<;dAFx!UZ>hB8 z5A*%LsAn;VLp>3${0>M?PSQ)9s3}|h2e?TG4_F{}{Cs>#3Q*t$(CUc}M)I}8cPF6% z=+h(Kh^8)}gj(0}#e7O^FQ6`~fd1#8#!}LMuo3A0bN`o}PYsm!Y}sdOz$+Tegc=qT z8x`PH$7lvnhJp{kHWb22l;@7B7|4yL4UOOVM0MP_>P%S1Lnid)+k9{+3D+JFa#Pyf zhVc#&df87APl4W9X)F3pGS>@etfl=_E5tBcVoOfrD4hmVeTY-cj((pkn%n@EgN{0f zwb_^Rk0I#i ZuHK!l*lN`ceJn(sI{$Fq6nN& zE<-=0_2WN}m+*ivmIOxB@#~Q-cZ>l136w{#TIJe478`KE7@=a{>SzPHsKLzYAyBQO zAtuuF$-JSDy_S@6GW0MOE~R)b;+0f%_NMrW(+V#c_d&U8Z9+ec4=HmOHw?gdjF(Lu zzra 83M_BoO-1b3;9`%&DHfuUY)6YDV21P$C!Rc?mv&{lx#f8oc6?0?x zK08{WP65?#>(vPfA-c=MCY| %*1_<3D4NX zeVTi-JGl2uP_2@0F{G({pxQOXt_d{g_CV6b?jNpfUG9;8yle-^4KHRvZs-_2siata zt+d_T@U$&t*xaD22(fH(W1r$Mo?3dc%Tncm=C6{V9y{v&VT#^1L04vDrLM9qBoZ4@ z6DBN#m57hX7$C(=#$Y5$bJmwA$T8jKD8+6A!-IJwA{WOfs%s}yxUw^?MRZjF$n_KN z6`_bGXcmE#5e4Ym)aQJ)xg3Pg0@k`iGuHe?f(5LtuzSq=nS^5z>vqU0EuZ&75V%Z{ zYyhRLN^)$c6Ds{f7*FBpE;n5iglx5PkHfWrj3`x^j^t z7ntuV`g!9Xg#^3!x)l*}IW=(Tz3>Y5l4uGaB&lz{GDjm2D5S$CExLT`I1#n^lBH7Y zDgpMag@`iETKAI=p<5E#LTkw zVR@=yY|uBVI1HG|8h+d;G-qfuj}-ZR6fN>EfCCW z9~wRQoAPEa#aO?3h?x{YvV*d+NtPkf&4V0k4|L=uj!U{L+oLa(z#&iuhJr3-PjO3R z5s?=nn_5^*^Rawr>>Nr@K(jwkB#JK-=+HqwfdO<+P5byeim)wvqGlP-P|~Nse8=XF zz`?RYB|D6SwS}C+YQv+;}k6$-%D(@+t14BL@vM z2q%q?f6D-A5s$_WY3{^G0F131bbh|g!}#BKw=HQ7mx;Dzg4Z*bTLQSfo{ed{4}NZW zfrRm^Ca$rlE{Ue~uYv>R9{3s mwATcdM_6+yWIO z*ZRH~uXE@#p$XTbCt5j7j2=86e{9>HIB6xDzV+vAo&B?KUiMP|ttOElepnl%|DPqL b{|{}U^kRn2wo}j7|0ATu<;8xA7zX}7|B6mN literal 0 HcmV?d00001 diff --git a/apps/midimarble/public/manifest.json b/apps/midimarble/public/manifest.json new file mode 100644 index 0000000..078ef50 --- /dev/null +++ b/apps/midimarble/public/manifest.json @@ -0,0 +1,25 @@ +{ + "short_name": "TanStack App", + "name": "Create TanStack App Sample", + "icons": [ + { + "src": "favicon.ico", + "sizes": "64x64 32x32 24x24 16x16", + "type": "image/x-icon" + }, + { + "src": "logo192.png", + "type": "image/png", + "sizes": "192x192" + }, + { + "src": "logo512.png", + "type": "image/png", + "sizes": "512x512" + } + ], + "start_url": ".", + "display": "standalone", + "theme_color": "#000000", + "background_color": "#ffffff" +} diff --git a/apps/midimarble/public/robots.txt b/apps/midimarble/public/robots.txt new file mode 100644 index 0000000..e9e57dc --- /dev/null +++ b/apps/midimarble/public/robots.txt @@ -0,0 +1,3 @@ +# https://www.robotstxt.org/robotstxt.html +User-agent: * +Disallow: diff --git a/apps/midimarble/src/components/Footer.tsx b/apps/midimarble/src/components/Footer.tsx new file mode 100644 index 0000000..c8bfd17 --- /dev/null +++ b/apps/midimarble/src/components/Footer.tsx @@ -0,0 +1,44 @@ +export default function Footer() { + const year = new Date().getFullYear() + + return ( + + ) +} diff --git a/apps/midimarble/src/components/Header.tsx b/apps/midimarble/src/components/Header.tsx new file mode 100644 index 0000000..fa196d6 --- /dev/null +++ b/apps/midimarble/src/components/Header.tsx @@ -0,0 +1,78 @@ +import { Link } from '@tanstack/react-router' +import ThemeToggle from './ThemeToggle' + +export default function Header() { + return ( + + + + ) +} diff --git a/apps/midimarble/src/components/ThemeToggle.tsx b/apps/midimarble/src/components/ThemeToggle.tsx new file mode 100644 index 0000000..081ebe2 --- /dev/null +++ b/apps/midimarble/src/components/ThemeToggle.tsx @@ -0,0 +1,81 @@ +import { useEffect, useState } from 'react' + +type ThemeMode = 'light' | 'dark' | 'auto' + +function getInitialMode(): ThemeMode { + if (typeof window === 'undefined') { + return 'auto' + } + + const stored = window.localStorage.getItem('theme') + if (stored === 'light' || stored === 'dark' || stored === 'auto') { + return stored + } + + return 'auto' +} + +function applyThemeMode(mode: ThemeMode) { + const prefersDark = window.matchMedia('(prefers-color-scheme: dark)').matches + const resolved = mode === 'auto' ? (prefersDark ? 'dark' : 'light') : mode + + document.documentElement.classList.remove('light', 'dark') + document.documentElement.classList.add(resolved) + + if (mode === 'auto') { + document.documentElement.removeAttribute('data-theme') + } else { + document.documentElement.setAttribute('data-theme', mode) + } + + document.documentElement.style.colorScheme = resolved +} + +export default function ThemeToggle() { + const [mode, setMode] = useState('auto') + + useEffect(() => { + const initialMode = getInitialMode() + setMode(initialMode) + applyThemeMode(initialMode) + }, []) + + useEffect(() => { + if (mode !== 'auto') { + return + } + + const media = window.matchMedia('(prefers-color-scheme: dark)') + const onChange = () => applyThemeMode('auto') + + media.addEventListener('change', onChange) + return () => { + media.removeEventListener('change', onChange) + } + }, [mode]) + + function toggleMode() { + const nextMode: ThemeMode = + mode === 'light' ? 'dark' : mode === 'dark' ? 'auto' : 'light' + setMode(nextMode) + applyThemeMode(nextMode) + window.localStorage.setItem('theme', nextMode) + } + + const label = + mode === 'auto' + ? 'Theme mode: auto (system). Click to switch to light mode.' + : `Theme mode: ${mode}. Click to switch mode.` + + return ( + + ) +} diff --git a/apps/midimarble/src/router.tsx b/apps/midimarble/src/router.tsx new file mode 100644 index 0000000..dfab11b --- /dev/null +++ b/apps/midimarble/src/router.tsx @@ -0,0 +1,20 @@ +import { createRouter as createTanStackRouter } from '@tanstack/react-router' +import { routeTree } from './routeTree.gen' + +export function getRouter() { + const router = createTanStackRouter({ + routeTree, + + scrollRestoration: true, + defaultPreload: 'intent', + defaultPreloadStaleTime: 0, + }) + + return router +} + +declare module '@tanstack/react-router' { + interface Register { + router: ReturnType + } +} diff --git a/apps/midimarble/src/routes/__root.tsx b/apps/midimarble/src/routes/__root.tsx new file mode 100644 index 0000000..3f7f8c2 --- /dev/null +++ b/apps/midimarble/src/routes/__root.tsx @@ -0,0 +1,61 @@ +import { HeadContent, Scripts, createRootRoute } from '@tanstack/react-router' +import { TanStackRouterDevtoolsPanel } from '@tanstack/react-router-devtools' +import { TanStackDevtools } from '@tanstack/react-devtools' +import Footer from '../components/Footer' +import Header from '../components/Header' + +import appCss from '../styles.css?url' + +const THEME_INIT_SCRIPT = `(function(){try{var stored=window.localStorage.getItem('theme');var mode=(stored==='light'||stored==='dark'||stored==='auto')?stored:'auto';var prefersDark=window.matchMedia('(prefers-color-scheme: dark)').matches;var resolved=mode==='auto'?(prefersDark?'dark':'light'):mode;var root=document.documentElement;root.classList.remove('light','dark');root.classList.add(resolved);if(mode==='auto'){root.removeAttribute('data-theme')}else{root.setAttribute('data-theme',mode)}root.style.colorScheme=resolved;}catch(e){}})();` + +export const Route = createRootRoute({ + head: () => ({ + meta: [ + { + charSet: 'utf-8', + }, + { + name: 'viewport', + content: 'width=device-width, initial-scale=1', + }, + { + title: 'TanStack Start Starter', + }, + ], + links: [ + { + rel: 'stylesheet', + href: appCss, + }, + ], + }), + shellComponent: RootDocument, +}) + +function RootDocument({ children }: { children: React.ReactNode }) { + return ( + + + + + + + + {children} + + , + }, + ]} + /> + + + + ) +} diff --git a/apps/midimarble/src/routes/about.tsx b/apps/midimarble/src/routes/about.tsx new file mode 100644 index 0000000..e5bc399 --- /dev/null +++ b/apps/midimarble/src/routes/about.tsx @@ -0,0 +1,23 @@ +import { createFileRoute } from '@tanstack/react-router' + +export const Route = createFileRoute('/about')({ + component: About, +}) + +function About() { + return ( + + + ) +} diff --git a/apps/midimarble/src/routes/index.tsx b/apps/midimarble/src/routes/index.tsx new file mode 100644 index 0000000..f732d82 --- /dev/null +++ b/apps/midimarble/src/routes/index.tsx @@ -0,0 +1,87 @@ +import { createFileRoute } from '@tanstack/react-router' + +export const Route = createFileRoute('/')({ component: App }) + +function App() { + return ( ++ +About
++ A small starter with room to grow. +
++ TanStack Start gives you type-safe routing, server functions, and + modern SSR defaults. Use this as a clean foundation, then layer in + your own routes, styling, and add-ons. +
++ + ) +} diff --git a/apps/midimarble/src/styles.css b/apps/midimarble/src/styles.css new file mode 100644 index 0000000..498b4c5 --- /dev/null +++ b/apps/midimarble/src/styles.css @@ -0,0 +1,259 @@ +@import url("https://fonts.googleapis.com/css2?family=Fraunces:opsz,wght@9..144,500;9..144,700&family=Manrope:wght@400;500;600;700;800&display=swap"); +@import "tailwindcss"; +@plugin "@tailwindcss/typography"; + +@theme { + --font-sans: "Manrope", ui-sans-serif, system-ui, sans-serif; +} + +:root { + --sea-ink: #173a40; + --sea-ink-soft: #416166; + --lagoon: #4fb8b2; + --lagoon-deep: #328f97; + --palm: #2f6a4a; + --sand: #e7f0e8; + --foam: #f3faf5; + --surface: rgba(255, 255, 255, 0.74); + --surface-strong: rgba(255, 255, 255, 0.9); + --line: rgba(23, 58, 64, 0.14); + --inset-glint: rgba(255, 255, 255, 0.82); + --kicker: rgba(47, 106, 74, 0.9); + --bg-base: #e7f3ec; + --header-bg: rgba(251, 255, 248, 0.84); + --chip-bg: rgba(255, 255, 255, 0.8); + --chip-line: rgba(47, 106, 74, 0.18); + --link-bg-hover: rgba(255, 255, 255, 0.9); + --hero-a: rgba(79, 184, 178, 0.36); + --hero-b: rgba(47, 106, 74, 0.2); +} + +:root[data-theme="dark"] { + --sea-ink: #d7ece8; + --sea-ink-soft: #afcdc8; + --lagoon: #60d7cf; + --lagoon-deep: #8de5db; + --palm: #6ec89a; + --sand: #0f1a1e; + --foam: #101d22; + --surface: rgba(16, 30, 34, 0.8); + --surface-strong: rgba(15, 27, 31, 0.92); + --line: rgba(141, 229, 219, 0.18); + --inset-glint: rgba(194, 247, 238, 0.14); + --kicker: #b8efe5; + --bg-base: #0a1418; + --header-bg: rgba(10, 20, 24, 0.8); + --chip-bg: rgba(13, 28, 32, 0.9); + --chip-line: rgba(141, 229, 219, 0.24); + --link-bg-hover: rgba(24, 44, 49, 0.8); + --hero-a: rgba(96, 215, 207, 0.18); + --hero-b: rgba(110, 200, 154, 0.12); +} + +@media (prefers-color-scheme: dark) { + :root:not([data-theme="light"]) { + --sea-ink: #d7ece8; + --sea-ink-soft: #afcdc8; + --lagoon: #60d7cf; + --lagoon-deep: #8de5db; + --palm: #6ec89a; + --sand: #0f1a1e; + --foam: #101d22; + --surface: rgba(16, 30, 34, 0.8); + --surface-strong: rgba(15, 27, 31, 0.92); + --line: rgba(141, 229, 219, 0.18); + --inset-glint: rgba(194, 247, 238, 0.14); + --kicker: #b8efe5; + --bg-base: #0a1418; + --header-bg: rgba(10, 20, 24, 0.8); + --chip-bg: rgba(13, 28, 32, 0.9); + --chip-line: rgba(141, 229, 219, 0.24); + --link-bg-hover: rgba(24, 44, 49, 0.8); + --hero-a: rgba(96, 215, 207, 0.18); + --hero-b: rgba(110, 200, 154, 0.12); + } +} + +* { + box-sizing: border-box; +} + +html, +body, +#app { + min-height: 100%; +} + +body { + margin: 0; + color: var(--sea-ink); + font-family: var(--font-sans); + background-color: var(--bg-base); + background: + radial-gradient(1100px 620px at -8% -10%, var(--hero-a), transparent 58%), + radial-gradient(1050px 620px at 112% -12%, var(--hero-b), transparent 62%), + radial-gradient(720px 380px at 50% 115%, rgba(79, 184, 178, 0.1), transparent 68%), + linear-gradient(180deg, color-mix(in oklab, var(--sand) 68%, white) 0%, var(--foam) 44%, var(--bg-base) 100%); + overflow-x: hidden; + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; +} + +body::before { + content: ""; + position: fixed; + inset: 0; + pointer-events: none; + z-index: -1; + opacity: 0.28; + background: + radial-gradient(circle at 20% 15%, rgba(255, 255, 255, 0.8), transparent 34%), + radial-gradient(circle at 78% 26%, rgba(79, 184, 178, 0.2), transparent 42%), + radial-gradient(circle at 42% 82%, rgba(47, 106, 74, 0.14), transparent 36%); +} + +body::after { + content: ""; + position: fixed; + inset: 0; + pointer-events: none; + z-index: -1; + opacity: 0.14; + background-image: + linear-gradient(rgba(255, 255, 255, 0.07) 1px, transparent 1px), + linear-gradient(90deg, rgba(255, 255, 255, 0.06) 1px, transparent 1px); + background-size: 28px 28px; + mask-image: radial-gradient(circle at 50% 30%, black, transparent 78%); +} + +a { + color: var(--lagoon-deep); + text-decoration-color: rgba(50, 143, 151, 0.4); + text-decoration-thickness: 1px; + text-underline-offset: 2px; +} + +a:hover { + color: #246f76; +} + +code { + font-size: 0.9em; + border: 1px solid var(--line); + background: color-mix(in oklab, var(--surface-strong) 82%, white 18%); + border-radius: 7px; + padding: 2px 7px; +} + +pre code { + border: 0; + background: transparent; + padding: 0; + border-radius: 0; + font-size: inherit; + color: inherit; +} + +.page-wrap { + width: min(1080px, calc(100% - 2rem)); + margin-inline: auto; +} + +.display-title { + font-family: "Fraunces", Georgia, serif; +} + +.island-shell { + border: 1px solid var(--line); + background: linear-gradient(165deg, var(--surface-strong), var(--surface)); + box-shadow: + 0 1px 0 var(--inset-glint) inset, + 0 22px 44px rgba(30, 90, 72, 0.1), + 0 6px 18px rgba(23, 58, 64, 0.08); + backdrop-filter: blur(4px); +} + +.feature-card { + background: linear-gradient(165deg, color-mix(in oklab, var(--surface-strong) 93%, white 7%), var(--surface)); + box-shadow: + 0 1px 0 var(--inset-glint) inset, + 0 18px 34px rgba(30, 90, 72, 0.1), + 0 4px 14px rgba(23, 58, 64, 0.06); +} + +.feature-card:hover { + transform: translateY(-2px); + border-color: color-mix(in oklab, var(--lagoon-deep) 35%, var(--line)); +} + +button, +.island-shell, +a { + transition: background-color 180ms ease, color 180ms ease, border-color 180ms ease, + transform 180ms ease; +} + +.island-kicker { + letter-spacing: 0.16em; + text-transform: uppercase; + font-weight: 700; + font-size: 0.69rem; + color: var(--kicker); +} + +.nav-link { + position: relative; + display: inline-flex; + align-items: center; + text-decoration: none; + color: var(--sea-ink-soft); +} + +.nav-link::after { + content: ""; + position: absolute; + left: 0; + bottom: -6px; + width: 100%; + height: 2px; + transform: scaleX(0); + transform-origin: left; + background: linear-gradient(90deg, var(--lagoon), #7ed3bf); + transition: transform 170ms ease; +} + +.nav-link:hover, +.nav-link.is-active { + color: var(--sea-ink); +} + +.nav-link:hover::after, +.nav-link.is-active::after { + transform: scaleX(1); +} + +@media (max-width: 640px) { + .nav-link::after { + bottom: -4px; + } +} + +.site-footer { + border-top: 1px solid var(--line); + background: color-mix(in oklab, var(--header-bg) 84%, transparent 16%); +} + +.rise-in { + animation: rise-in 700ms cubic-bezier(0.16, 1, 0.3, 1) both; +} + +@keyframes rise-in { + from { + opacity: 0; + transform: translateY(12px); + } + to { + opacity: 1; + transform: translateY(0); + } +} diff --git a/apps/midimarble/tsconfig.json b/apps/midimarble/tsconfig.json new file mode 100644 index 0000000..2377168 --- /dev/null +++ b/apps/midimarble/tsconfig.json @@ -0,0 +1,30 @@ +{ + "include": ["**/*.ts", "**/*.tsx", "eslint.config.js", "prettier.config.js", "vite.config.js"], + + "compilerOptions": { + "target": "ES2022", + "jsx": "react-jsx", + "module": "ESNext", + "baseUrl": ".", + "paths": { + "#/*": ["./src/*"], + "@/*": ["./src/*"] + }, + "lib": ["ES2022", "DOM", "DOM.Iterable"], + "types": ["vite/client"], + + /* Bundler mode */ + "moduleResolution": "bundler", + "allowImportingTsExtensions": true, + "verbatimModuleSyntax": true, + "noEmit": true, + + /* Linting */ + "skipLibCheck": true, + "strict": true, + "noUnusedLocals": true, + "noUnusedParameters": true, + "noFallthroughCasesInSwitch": true, + "noUncheckedSideEffectImports": true + } +} diff --git a/apps/midimarble/vite.config.ts b/apps/midimarble/vite.config.ts new file mode 100644 index 0000000..bbf795a --- /dev/null +++ b/apps/midimarble/vite.config.ts @@ -0,0 +1,22 @@ +import { defineConfig } from 'vite' +import { devtools } from '@tanstack/devtools-vite' +import tsconfigPaths from 'vite-tsconfig-paths' + +import { tanstackStart } from '@tanstack/react-start/plugin/vite' + +import viteReact from '@vitejs/plugin-react' +import tailwindcss from '@tailwindcss/vite' +import { nitro } from 'nitro/vite' + +const config = defineConfig({ + plugins: [ + devtools(), + nitro({ rollupConfig: { external: [/^@sentry\//] } }), + tsconfigPaths({ projects: ['./tsconfig.json'] }), + tailwindcss(), + tanstackStart(), + viteReact(), + ], +}) + +export default config From cc4fd82dbd238e880c5e8d3c3b3b8ba86354234a Mon Sep 17 00:00:00 2001 From: Benno <57860196+bennoinbeta@users.noreply.github.com> Date: Tue, 10 Mar 2026 07:25:53 +0100 Subject: [PATCH 02/51] #7 cleanup --- apps/midimarble/.gitignore | 13 +- apps/midimarble/.prettierignore | 3 - apps/midimarble/README.md | 205 +- apps/midimarble/{ => docs}/project-spec.md | 0 apps/midimarble/eslint.config.js | 28 +- apps/midimarble/package.json | 101 +- apps/midimarble/src/routeTree.gen.ts | 86 + apps/midimarble/tsconfig.json | 40 +- apps/midimarble/vite.config.ts | 41 +- pnpm-lock.yaml | 2283 +++++++++++++++++++- 10 files changed, 2368 insertions(+), 432 deletions(-) delete mode 100644 apps/midimarble/.prettierignore rename apps/midimarble/{ => docs}/project-spec.md (100%) create mode 100644 apps/midimarble/src/routeTree.gen.ts diff --git a/apps/midimarble/.gitignore b/apps/midimarble/.gitignore index 8b25bb5..7e6ced4 100644 --- a/apps/midimarble/.gitignore +++ b/apps/midimarble/.gitignore @@ -1,13 +1,2 @@ -node_modules -.DS_Store -dist -dist-ssr -*.local -.env -.nitro .tanstack -.wrangler -.output -.vinxi -__unconfig* -todos.json +.output \ No newline at end of file diff --git a/apps/midimarble/.prettierignore b/apps/midimarble/.prettierignore deleted file mode 100644 index 5322d7f..0000000 --- a/apps/midimarble/.prettierignore +++ /dev/null @@ -1,3 +0,0 @@ -package-lock.json -pnpm-lock.yaml -yarn.lock \ No newline at end of file diff --git a/apps/midimarble/README.md b/apps/midimarble/README.md index 811f171..109a6cd 100644 --- a/apps/midimarble/README.md +++ b/apps/midimarble/README.md @@ -1,204 +1 @@ -Welcome to your new TanStack Start app! - -# Getting Started - -To run this application: - -```bash -pnpm install -pnpm dev -``` - -# Building For Production - -To build this application for production: - -```bash -pnpm build -``` - -## Testing - -This project uses [Vitest](https://vitest.dev/) for testing. You can run the tests with: - -```bash -pnpm test -``` - -## Styling - -This project uses [Tailwind CSS](https://tailwindcss.com/) for styling. - -### Removing Tailwind CSS - -If you prefer not to use Tailwind CSS: - -1. Remove the demo pages in `src/routes/demo/` -2. Replace the Tailwind import in `src/styles.css` with your own styles -3. Remove `tailwindcss()` from the plugins array in `vite.config.ts` -4. Uninstall the packages: `pnpm add @tailwindcss/vite tailwindcss --dev` - -## Linting & Formatting - - -This project uses [eslint](https://eslint.org/) and [prettier](https://prettier.io/) for linting and formatting. Eslint is configured using [tanstack/eslint-config](https://tanstack.com/config/latest/docs/eslint). The following scripts are available: - -```bash -pnpm lint -pnpm format -pnpm check -``` - - - -## Routing - -This project uses [TanStack Router](https://tanstack.com/router) with file-based routing. Routes are managed as files in `src/routes`. - -### Adding A Route - -To add a new route to your application just add a new file in the `./src/routes` directory. - -TanStack will automatically generate the content of the route file for you. - -Now that you have two routes you can use a `Link` component to navigate between them. - -### Adding Links - -To use SPA (Single Page Application) navigation you will need to import the `Link` component from `@tanstack/react-router`. - -```tsx -import { Link } from "@tanstack/react-router"; -``` - -Then anywhere in your JSX you can use it like so: - -```tsx -About -``` - -This will create a link that will navigate to the `/about` route. - -More information on the `Link` component can be found in the [Link documentation](https://tanstack.com/router/v1/docs/framework/react/api/router/linkComponent). - -### Using A Layout - -In the File Based Routing setup the layout is located in `src/routes/__root.tsx`. Anything you add to the root route will appear in all the routes. The route content will appear in the JSX where you render `{children}` in the `shellComponent`. - -Here is an example layout that includes a header: - -```tsx -import { HeadContent, Scripts, createRootRoute } from '@tanstack/react-router' - -export const Route = createRootRoute({ - head: () => ({ - meta: [ - { charSet: 'utf-8' }, - { name: 'viewport', content: 'width=device-width, initial-scale=1' }, - { title: 'My App' }, - ], - }), - shellComponent: ({ children }) => ( - - -+ + + + +TanStack Start Base Template
++ Start simple, ship quickly. +
++ This base starter intentionally keeps things light: two routes, clean + structure, and the essentials you need to build from scratch. +
+ ++ {[ + [ + 'Type-Safe Routing', + 'Routes and links stay in sync across every page.', + ], + [ + 'Server Functions', + 'Call server code from your UI without creating API boilerplate.', + ], + [ + 'Streaming by Default', + 'Ship progressively rendered responses for faster experiences.', + ], + [ + 'Tailwind Native', + 'Design quickly with utility-first styling and reusable tokens.', + ], + ].map(([title, desc], index) => ( + + ++ + ))} ++ {title} +
+{desc}
++ +Quick Start
++
+- + Edit
+src/routes/index.tsxto customize the home page. +- + Update
+src/components/Header.tsxand{' '} +src/components/Footer.tsxfor brand links. +- + Add routes in
+src/routesand tweak visual tokens in{' '} +src/styles.css. +- - - - - - {children} -- - - ), -}) -``` - -More information on layouts can be found in the [Layouts documentation](https://tanstack.com/router/latest/docs/framework/react/guide/routing-concepts#layouts). - -## Server Functions - -TanStack Start provides server functions that allow you to write server-side code that seamlessly integrates with your client components. - -```tsx -import { createServerFn } from '@tanstack/react-start' - -const getServerTime = createServerFn({ - method: 'GET', -}).handler(async () => { - return new Date().toISOString() -}) - -// Use in a component -function MyComponent() { - const [time, setTime] = useState('') - - useEffect(() => { - getServerTime().then(setTime) - }, []) - - return Server time: {time}-} -``` - -## API Routes - -You can create API routes by using the `server` property in your route definitions: - -```tsx -import { createFileRoute } from '@tanstack/react-router' -import { json } from '@tanstack/react-start' - -export const Route = createFileRoute('/api/hello')({ - server: { - handlers: { - GET: () => json({ message: 'Hello, World!' }), - }, - }, -}) -``` - -## Data Fetching - -There are multiple ways to fetch data in your application. You can use TanStack Query to fetch data from a server. But you can also use the `loader` functionality built into TanStack Router to load the data for a route before it's rendered. - -For example: - -```tsx -import { createFileRoute } from '@tanstack/react-router' - -export const Route = createFileRoute('/people')({ - loader: async () => { - const response = await fetch('https://swapi.dev/api/people') - return response.json() - }, - component: PeopleComponent, -}) - -function PeopleComponent() { - const data = Route.useLoaderData() - return ( -- {data.results.map((person) => ( -
- ) -} -``` - -Loaders simplify your data fetching logic dramatically. Check out more information in the [Loader documentation](https://tanstack.com/router/latest/docs/framework/react/guide/data-loading#loader-parameters). - -# Demo files - -Files prefixed with `demo` can be safely deleted. They are there to provide a starting point for you to play around with the features you've installed. - -# Learn More - -You can learn more about all of the offerings from TanStack in the [TanStack documentation](https://tanstack.com). - -For TanStack Start specific documentation, visit [TanStack Start](https://tanstack.com/start). +# `@repo/midimarble` \ No newline at end of file diff --git a/apps/midimarble/project-spec.md b/apps/midimarble/docs/project-spec.md similarity index 100% rename from apps/midimarble/project-spec.md rename to apps/midimarble/docs/project-spec.md diff --git a/apps/midimarble/eslint.config.js b/apps/midimarble/eslint.config.js index 3f272c0..5970b21 100644 --- a/apps/midimarble/eslint.config.js +++ b/apps/midimarble/eslint.config.js @@ -1,20 +1,12 @@ -// @ts-check - -import { tanstackConfig } from '@tanstack/eslint-config' +import reactInternal from '@blgc/config/eslint/react-internal'; +/** + * @see https://eslint.org/docs/latest/use/configure/configuration-files + * @type {import("eslint").Linter.Config} + */ export default [ - ...tanstackConfig, - { - rules: { - 'import/no-cycle': 'off', - 'import/order': 'off', - 'sort-imports': 'off', - '@typescript-eslint/array-type': 'off', - '@typescript-eslint/require-await': 'off', - 'pnpm/json-enforce-catalog': 'off', - }, - }, - { - ignores: ['eslint.config.js', 'prettier.config.js'], - }, -] + ...reactInternal, + { + ignores: ['build/**', 'dist/**', 'node_modules/**'] + } +]; diff --git a/apps/midimarble/package.json b/apps/midimarble/package.json index ea47d82..2220d7d 100644 --- a/apps/midimarble/package.json +++ b/apps/midimarble/package.json @@ -1,54 +1,49 @@ { - "name": "midimarble", - "private": true, - "type": "module", - "imports": { - "#/*": "./src/*" - }, - "scripts": { - "dev": "vite dev --port 3000", - "build": "vite build", - "preview": "vite preview", - "test": "vitest run", - "lint": "eslint", - "format": "prettier --check .", - "check": "prettier --write . && eslint --fix" - }, - "dependencies": { - "@tailwindcss/vite": "^4.1.18", - "@tanstack/react-devtools": "latest", - "@tanstack/react-router": "latest", - "@tanstack/react-router-devtools": "latest", - "@tanstack/react-router-ssr-query": "latest", - "@tanstack/react-start": "latest", - "@tanstack/router-plugin": "^1.132.0", - "lucide-react": "^0.545.0", - "nitro": "npm:nitro-nightly@latest", - "react": "^19.2.0", - "react-dom": "^19.2.0", - "tailwindcss": "^4.1.18" - }, - "devDependencies": { - "@tailwindcss/typography": "^0.5.16", - "@tanstack/devtools-vite": "latest", - "@tanstack/eslint-config": "latest", - "@testing-library/dom": "^10.4.1", - "@testing-library/react": "^16.3.0", - "@types/node": "^22.10.2", - "@types/react": "^19.2.0", - "@types/react-dom": "^19.2.0", - "@vitejs/plugin-react": "^5.1.4", - "jsdom": "^28.1.0", - "prettier": "^3.8.1", - "typescript": "^5.7.2", - "vite": "^7.3.1", - "vite-tsconfig-paths": "^5.1.4", - "vitest": "^3.0.5" - }, - "pnpm": { - "onlyBuiltDependencies": [ - "esbuild", - "lightningcss" - ] - } -} \ No newline at end of file + "name": "@repo/midimarble", + "version": "0.0.1", + "private": true, + "description": "", + "keywords": [], + "bugs": { + "url": "https://github.com/builder-group/lab/issues" + }, + "repository": { + "type": "git", + "url": "https://github.com/builder-group/lab.git" + }, + "license": "AGPL-3.0-or-later", + "author": "@bennobuilder", + "type": "module", + "scripts": { + "build": "pnpm typecheck && vite build", + "clean": "shx rm -rf dist && shx rm -rf .tanstack && shx rm -rf .turbo && shx rm -rf node_modules", + "format": "prettier --write \"**/*.{ts,tsx,md,json,js,jsx}\"", + "install:clean": "pnpm run clean && pnpm install", + "lint": "eslint . --fix", + "start:dev": "vite dev", + "test": "echo \"🧪 No tests defined yet.\"", + "typecheck": "tsc --noEmit", + "update:latest": "pnpm update --latest" + }, + "dependencies": { + "@tanstack/react-devtools": "^0.9.10", + "@tanstack/react-router": "^1.166.6", + "@tanstack/react-router-devtools": "^1.166.6", + "@tanstack/react-start": "^1.166.6", + "lucide-react": "^0.577.0", + "react": "19.2.4", + "react-dom": "19.2.4" + }, + "devDependencies": { + "@tailwindcss/typography": "^0.5.19", + "@tailwindcss/vite": "^4.2.1", + "@tanstack/devtools-vite": "^0.5.3", + "@types/node": "^25.4.0", + "@types/react": "^19.2.14", + "@types/react-dom": "^19.2.3", + "@vitejs/plugin-react": "^5.1.4", + "nitro": "3.0.1-alpha.2", + "tailwindcss": "^4.2.1", + "vite-tsconfig-paths": "^6.1.1" + } +} diff --git a/apps/midimarble/src/routeTree.gen.ts b/apps/midimarble/src/routeTree.gen.ts new file mode 100644 index 0000000..421daf2 --- /dev/null +++ b/apps/midimarble/src/routeTree.gen.ts @@ -0,0 +1,86 @@ +/* eslint-disable */ + +// @ts-nocheck + +// noinspection JSUnusedGlobalSymbols + +// This file was automatically generated by TanStack Router. +// You should NOT make any changes in this file as it will be overwritten. +// Additionally, you should also exclude this file from your linter and/or formatter to prevent it from being checked or modified. + +import { Route as rootRouteImport } from './routes/__root' +import { Route as AboutRouteImport } from './routes/about' +import { Route as IndexRouteImport } from './routes/index' + +const AboutRoute = AboutRouteImport.update({ + id: '/about', + path: '/about', + getParentRoute: () => rootRouteImport, +} as any) +const IndexRoute = IndexRouteImport.update({ + id: '/', + path: '/', + getParentRoute: () => rootRouteImport, +} as any) + +export interface FileRoutesByFullPath { + '/': typeof IndexRoute + '/about': typeof AboutRoute +} +export interface FileRoutesByTo { + '/': typeof IndexRoute + '/about': typeof AboutRoute +} +export interface FileRoutesById { + __root__: typeof rootRouteImport + '/': typeof IndexRoute + '/about': typeof AboutRoute +} +export interface FileRouteTypes { + fileRoutesByFullPath: FileRoutesByFullPath + fullPaths: '/' | '/about' + fileRoutesByTo: FileRoutesByTo + to: '/' | '/about' + id: '__root__' | '/' | '/about' + fileRoutesById: FileRoutesById +} +export interface RootRouteChildren { + IndexRoute: typeof IndexRoute + AboutRoute: typeof AboutRoute +} + +declare module '@tanstack/react-router' { + interface FileRoutesByPath { + '/about': { + id: '/about' + path: '/about' + fullPath: '/about' + preLoaderRoute: typeof AboutRouteImport + parentRoute: typeof rootRouteImport + } + '/': { + id: '/' + path: '/' + fullPath: '/' + preLoaderRoute: typeof IndexRouteImport + parentRoute: typeof rootRouteImport + } + } +} + +const rootRouteChildren: RootRouteChildren = { + IndexRoute: IndexRoute, + AboutRoute: AboutRoute, +} +export const routeTree = rootRouteImport + ._addFileChildren(rootRouteChildren) + ._addFileTypes- {person.name}
- ))} -() + +import type { getRouter } from './router.tsx' +import type { createStart } from '@tanstack/react-start' +declare module '@tanstack/react-start' { + interface Register { + ssr: true + router: Awaited > + } +} diff --git a/apps/midimarble/tsconfig.json b/apps/midimarble/tsconfig.json index 2377168..bb7f8c9 100644 --- a/apps/midimarble/tsconfig.json +++ b/apps/midimarble/tsconfig.json @@ -1,30 +1,14 @@ { - "include": ["**/*.ts", "**/*.tsx", "eslint.config.js", "prettier.config.js", "vite.config.js"], - - "compilerOptions": { - "target": "ES2022", - "jsx": "react-jsx", - "module": "ESNext", - "baseUrl": ".", - "paths": { - "#/*": ["./src/*"], - "@/*": ["./src/*"] - }, - "lib": ["ES2022", "DOM", "DOM.Iterable"], - "types": ["vite/client"], - - /* Bundler mode */ - "moduleResolution": "bundler", - "allowImportingTsExtensions": true, - "verbatimModuleSyntax": true, - "noEmit": true, - - /* Linting */ - "skipLibCheck": true, - "strict": true, - "noUnusedLocals": true, - "noUnusedParameters": true, - "noFallthroughCasesInSwitch": true, - "noUncheckedSideEffectImports": true - } + "extends": "@blgc/config/typescript/react-internal", + "compilerOptions": { + "target": "ES2022", + "lib": ["ES2022", "dom", "dom.iterable"], + "baseUrl": ".", + "paths": { + "@/*": ["./src/*"] + } + }, + "include": ["env.d.ts", "**/*.ts", "**/*.tsx"], + "exclude": ["node_modules"], + "noEmit": true } diff --git a/apps/midimarble/vite.config.ts b/apps/midimarble/vite.config.ts index bbf795a..4eed3d6 100644 --- a/apps/midimarble/vite.config.ts +++ b/apps/midimarble/vite.config.ts @@ -1,22 +1,25 @@ -import { defineConfig } from 'vite' -import { devtools } from '@tanstack/devtools-vite' -import tsconfigPaths from 'vite-tsconfig-paths' - -import { tanstackStart } from '@tanstack/react-start/plugin/vite' - -import viteReact from '@vitejs/plugin-react' -import tailwindcss from '@tailwindcss/vite' -import { nitro } from 'nitro/vite' +import tailwindcss from '@tailwindcss/vite'; +import { devtools } from '@tanstack/devtools-vite'; +import { tanstackStart } from '@tanstack/react-start/plugin/vite'; +import viteReact from '@vitejs/plugin-react'; +import { nitro } from 'nitro/vite'; +import { defineConfig } from 'vite'; +import tsconfigPaths from 'vite-tsconfig-paths'; const config = defineConfig({ - plugins: [ - devtools(), - nitro({ rollupConfig: { external: [/^@sentry\//] } }), - tsconfigPaths({ projects: ['./tsconfig.json'] }), - tailwindcss(), - tanstackStart(), - viteReact(), - ], -}) + server: { + port: 3000 + }, + plugins: [ + devtools(), + nitro(), + tsconfigPaths({ projects: ['./tsconfig.json'] }), + tailwindcss(), + tanstackStart({ + srcDirectory: 'src' + }), + viteReact() + ] +}); -export default config +export default config; diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index bfeb62f..569482e 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -15,7 +15,7 @@ importers: devDependencies: '@blgc/config': specifier: ^0.0.40 - version: 0.0.40(eslint@9.39.3(jiti@2.6.1))(postcss@8.5.6)(prettier@3.8.1)(turbo@2.8.11)(typescript@5.9.3)(vite@7.3.1(@types/node@25.3.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)) + version: 0.0.40(eslint@9.39.3(jiti@2.6.1))(postcss@8.5.6)(prettier@3.8.1)(turbo@2.8.11)(typescript@5.9.3)(vite@7.3.1(@types/node@25.4.0)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)) eslint: specifier: ^9.39.2 version: 9.39.3(jiti@2.6.1) @@ -42,10 +42,10 @@ importers: version: 5.9.3 vite: specifier: ^7.3.1 - version: 7.3.1(@types/node@25.3.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2) + version: 7.3.1(@types/node@25.4.0)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2) vitest: specifier: ^4.0.18 - version: 4.0.18(@types/node@25.3.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2) + version: 4.0.18(@types/node@25.4.0)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2) apps/gazegames: dependencies: @@ -275,10 +275,10 @@ importers: version: 19.2.14 eas-cli: specifier: ^18.0.6 - version: 18.0.6(@types/node@25.3.2)(typescript@5.9.3) + version: 18.0.6(@types/node@25.4.0)(typescript@5.9.3) eslint-config-expo: specifier: ~55.0.0 - version: 55.0.0(eslint@9.39.3(jiti@2.6.1))(typescript@5.9.3) + version: 55.0.0(eslint-plugin-import-x@4.16.1(@typescript-eslint/utils@8.57.0(eslint@9.39.3(jiti@2.6.1))(typescript@5.9.3))(eslint-import-resolver-node@0.3.9)(eslint@9.39.3(jiti@2.6.1)))(eslint@9.39.3(jiti@2.6.1))(typescript@5.9.3) postcss: specifier: ^8.5.6 version: 8.5.6 @@ -290,7 +290,7 @@ importers: dependencies: '@react-router/fs-routes': specifier: ^7.13.0 - version: 7.13.1(@react-router/dev@7.13.1(@react-router/serve@7.13.1(react-router@7.13.1(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(typescript@5.9.3))(@types/node@25.3.2)(jiti@2.6.1)(lightningcss@1.30.1)(react-router@7.13.1(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(terser@5.46.0)(tsx@4.21.0)(typescript@5.9.3)(vite@7.3.1(@types/node@25.3.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2))(yaml@2.8.2))(typescript@5.9.3) + version: 7.13.1(@react-router/dev@7.13.1(@react-router/serve@7.13.1(react-router@7.13.1(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(typescript@5.9.3))(@types/node@25.4.0)(jiti@2.6.1)(lightningcss@1.30.1)(react-router@7.13.1(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(terser@5.46.0)(tsx@4.21.0)(typescript@5.9.3)(vite@7.3.1(@types/node@25.4.0)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2))(yaml@2.8.2))(typescript@5.9.3) '@react-router/node': specifier: ^7.13.0 version: 7.13.1(react-router@7.13.1(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(typescript@5.9.3) @@ -302,7 +302,7 @@ importers: version: 1.6.1(react@19.2.4) '@vercel/react-router': specifier: ^1.2.5 - version: 1.2.5(@react-router/dev@7.13.1(@react-router/serve@7.13.1(react-router@7.13.1(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(typescript@5.9.3))(@types/node@25.3.2)(jiti@2.6.1)(lightningcss@1.30.1)(react-router@7.13.1(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(terser@5.46.0)(tsx@4.21.0)(typescript@5.9.3)(vite@7.3.1(@types/node@25.3.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2))(yaml@2.8.2))(@react-router/node@7.13.1(react-router@7.13.1(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(typescript@5.9.3))(isbot@5.1.35)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + version: 1.2.5(@react-router/dev@7.13.1(@react-router/serve@7.13.1(react-router@7.13.1(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(typescript@5.9.3))(@types/node@25.4.0)(jiti@2.6.1)(lightningcss@1.30.1)(react-router@7.13.1(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(terser@5.46.0)(tsx@4.21.0)(typescript@5.9.3)(vite@7.3.1(@types/node@25.4.0)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2))(yaml@2.8.2))(@react-router/node@7.13.1(react-router@7.13.1(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(typescript@5.9.3))(isbot@5.1.35)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) clsx: specifier: ^2.1.1 version: 2.1.1 @@ -336,13 +336,13 @@ importers: version: 3.1.1(rollup@4.59.0) '@react-router/dev': specifier: ^7.13.0 - version: 7.13.1(@react-router/serve@7.13.1(react-router@7.13.1(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(typescript@5.9.3))(@types/node@25.3.2)(jiti@2.6.1)(lightningcss@1.30.1)(react-router@7.13.1(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(terser@5.46.0)(tsx@4.21.0)(typescript@5.9.3)(vite@7.3.1(@types/node@25.3.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2))(yaml@2.8.2) + version: 7.13.1(@react-router/serve@7.13.1(react-router@7.13.1(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(typescript@5.9.3))(@types/node@25.4.0)(jiti@2.6.1)(lightningcss@1.30.1)(react-router@7.13.1(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(terser@5.46.0)(tsx@4.21.0)(typescript@5.9.3)(vite@7.3.1(@types/node@25.4.0)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2))(yaml@2.8.2) '@tailwindcss/typography': specifier: ^0.5.19 version: 0.5.19(tailwindcss@4.2.1) '@tailwindcss/vite': specifier: ^4.1.18 - version: 4.2.1(vite@7.3.1(@types/node@25.3.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)) + version: 4.2.1(vite@7.3.1(@types/node@25.4.0)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)) '@types/mdx': specifier: ^2.0.13 version: 2.0.13 @@ -360,7 +360,62 @@ importers: version: 4.2.1 vite-tsconfig-paths: specifier: ^6.0.5 - version: 6.1.1(typescript@5.9.3)(vite@7.3.1(@types/node@25.3.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)) + version: 6.1.1(typescript@5.9.3)(vite@7.3.1(@types/node@25.4.0)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)) + + apps/midimarble: + dependencies: + '@tanstack/react-devtools': + specifier: ^0.9.10 + version: 0.9.10(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(csstype@3.2.3)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(solid-js@1.9.11) + '@tanstack/react-router': + specifier: ^1.166.6 + version: 1.166.6(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@tanstack/react-router-devtools': + specifier: ^1.166.6 + version: 1.166.6(@tanstack/react-router@1.166.6(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(@tanstack/router-core@1.166.6)(csstype@3.2.3)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@tanstack/react-start': + specifier: ^1.166.6 + version: 1.166.6(crossws@0.4.4(srvx@0.10.1))(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(vite@7.3.1(@types/node@25.4.0)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)) + lucide-react: + specifier: ^0.577.0 + version: 0.577.0(react@19.2.4) + react: + specifier: 19.2.4 + version: 19.2.4 + react-dom: + specifier: 19.2.4 + version: 19.2.4(react@19.2.4) + devDependencies: + '@tailwindcss/typography': + specifier: ^0.5.19 + version: 0.5.19(tailwindcss@4.2.1) + '@tailwindcss/vite': + specifier: ^4.2.1 + version: 4.2.1(vite@7.3.1(@types/node@25.4.0)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)) + '@tanstack/devtools-vite': + specifier: ^0.5.3 + version: 0.5.3(vite@7.3.1(@types/node@25.4.0)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)) + '@types/node': + specifier: ^25.4.0 + version: 25.4.0 + '@types/react': + specifier: ^19.2.14 + version: 19.2.14 + '@types/react-dom': + specifier: ^19.2.3 + version: 19.2.3(@types/react@19.2.14) + '@vitejs/plugin-react': + specifier: ^5.1.4 + version: 5.1.4(vite@7.3.1(@types/node@25.4.0)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)) + nitro: + specifier: 3.0.1-alpha.2 + version: 3.0.1-alpha.2(chokidar@4.0.3)(lru-cache@11.2.6)(rolldown@1.0.0-rc.8)(rollup@4.59.0)(vite@7.3.1(@types/node@25.4.0)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)) + tailwindcss: + specifier: ^4.2.1 + version: 4.2.1 + vite-tsconfig-paths: + specifier: ^6.1.1 + version: 6.1.1(typescript@5.9.3)(vite@7.3.1(@types/node@25.4.0)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)) packages: @@ -383,6 +438,10 @@ packages: resolution: {integrity: sha512-CgH3s1a96LipHCmSUmYFPwY7MNx8C3avkq7i4Wl3cfa662ldtUe4VM1TPXX70pfmrlWTb6jLqTYrZyT2ZTJBgA==} engines: {node: '>=6.9.0'} + '@babel/code-frame@7.27.1': + resolution: {integrity: sha512-cjQ7ZlQ0Mv3b47hABuTevyTuYN4i+loJKGeV9flcCgIK37cCXRh+L1bd3iBHlynerhQ7BhCkn2BPbQUL+rGqFg==} + engines: {node: '>=6.9.0'} + '@babel/code-frame@7.29.0': resolution: {integrity: sha512-9NhCeYjq9+3uxgdtp20LSiJXJvN0FeCtNGpJxuMFZ1Kv3cWUNb6DOhJwUvcVCzKGR66cw4njwM6hrJLqgOwbcw==} engines: {node: '>=6.9.0'} @@ -1697,6 +1756,9 @@ packages: '@napi-rs/wasm-runtime@0.2.12': resolution: {integrity: sha512-ZVWUcfwY4E/yPitQJl481FjFo3K22D6qF0DuFH6Y/nbnE11GY5uguDxZMGXPQ8WQ0128MXQD7TnfHyK4oWoIJQ==} + '@napi-rs/wasm-runtime@1.1.1': + resolution: {integrity: sha512-p64ah1M1ld8xjWv3qbvFwHiFVWrq1yFvV4f7w+mzaqiR4IlSgkqhcRdHwsGgomwzBH51sRY4NEowLxnaBjcW/A==} + '@next/eslint-plugin-next@16.1.6': resolution: {integrity: sha512-/Qq3PTagA6+nYVfryAtQ7/9FEr/6YVyvOtl6rZnGsbReGLf0jZU6gkpr1FuChAQpvV46a78p4cmHOVP8mbfSMQ==} @@ -1736,6 +1798,279 @@ packages: engines: {node: '>=12.0.0'} deprecated: Package no longer supported. Contact Support at https://www.npmjs.com/support for more info. + '@oozcitak/dom@2.0.2': + resolution: {integrity: sha512-GjpKhkSYC3Mj4+lfwEyI1dqnsKTgwGy48ytZEhm4A/xnH/8z9M3ZVXKr/YGQi3uCLs1AEBS+x5T2JPiueEDW8w==} + engines: {node: '>=20.0'} + + '@oozcitak/infra@2.0.2': + resolution: {integrity: sha512-2g+E7hoE2dgCz/APPOEK5s3rMhJvNxSMBrP+U+j1OWsIbtSpWxxlUjq1lU8RIsFJNYv7NMlnVsCuHcUzJW+8vA==} + engines: {node: '>=20.0'} + + '@oozcitak/url@3.0.0': + resolution: {integrity: sha512-ZKfET8Ak1wsLAiLWNfFkZc/BraDccuTJKR6svTYc7sVjbR+Iu0vtXdiDMY4o6jaFl5TW2TlS7jbLl4VovtAJWQ==} + engines: {node: '>=20.0'} + + '@oozcitak/util@10.0.0': + resolution: {integrity: sha512-hAX0pT/73190NLqBPPWSdBVGtbY6VOhWYK3qqHqtXQ1gK7kS2yz4+ivsN07hpJ6I3aeMtKP6J6npsEKOAzuTLA==} + engines: {node: '>=20.0'} + + '@oxc-minify/binding-android-arm-eabi@0.110.0': + resolution: {integrity: sha512-43fMTO8/5bMlqfOiNSZNKUzIqeLIYuB9Hr1Ohyf58B1wU11S2dPGibTXOGNaWsfgHy99eeZ1bSgeIHy/fEYqbw==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm] + os: [android] + + '@oxc-minify/binding-android-arm64@0.110.0': + resolution: {integrity: sha512-5oQrnn9eK/ccOp80PTrNj0Vq893NPNNRryjGpOIVsYNgWFuoGCfpnKg68oEFcN8bArizYAqw4nvgHljEnar69w==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [android] + + '@oxc-minify/binding-darwin-arm64@0.110.0': + resolution: {integrity: sha512-dqBDgTG9tF2z2lrZp9E8wU+Godz1i8gCGSei2eFKS2hRploBOD5dmOLp1j4IMornkPvSQmbwB3uSjPq7fjx4EA==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [darwin] + + '@oxc-minify/binding-darwin-x64@0.110.0': + resolution: {integrity: sha512-U0AqabqaooDOpYmeeOye8wClv8PSScELXgOfYqyqgrwH9J9KrpCE1jL8Rlqgz68QbL4mPw3V6sKiiHssI4CLeQ==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [darwin] + + '@oxc-minify/binding-freebsd-x64@0.110.0': + resolution: {integrity: sha512-H0w8o/Wo1072WSdLfhwwrpFpwZnPpjQODlHuRYkTfsSSSJbTxQtjJd4uxk7YJsRv5RQp69y0I7zvdH6f8Xueyw==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [freebsd] + + '@oxc-minify/binding-linux-arm-gnueabihf@0.110.0': + resolution: {integrity: sha512-qd6sW0AvEVYZhbVVMGtmKZw3b1zDYGIW+54Uh42moWRAj6i4Jhk/LGr6r9YNZpOINeuvZfkFuEeDD/jbu7xPUA==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm] + os: [linux] + + '@oxc-minify/binding-linux-arm-musleabihf@0.110.0': + resolution: {integrity: sha512-7WXP0aXMrWSn0ScppUBi3jf68ebfBG0eri8kxLmBOVSBj6jw1repzkHMITJMBeLr5d0tT/51qFEptiAk2EP2iA==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm] + os: [linux] + + '@oxc-minify/binding-linux-arm64-gnu@0.110.0': + resolution: {integrity: sha512-LYfADrq5x1W5gs+u9OIbMbDQNYkAECTXX0ufnAuf3oGmO51rF98kGFR5qJqC/6/csokDyT3wwTpxhE0TkcF/Og==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [linux] + libc: [glibc] + + '@oxc-minify/binding-linux-arm64-musl@0.110.0': + resolution: {integrity: sha512-53GjCVY8kvymk9P6qNDh6zyblcehF5QHstq9QgCjv13ONGRnSHjeds0PxIwiihD7h295bxsWs84DN39syLPH4Q==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [linux] + libc: [musl] + + '@oxc-minify/binding-linux-ppc64-gnu@0.110.0': + resolution: {integrity: sha512-li8XcN81dxbJDMBESnTgGhoiAQ+CNIdM0QGscZ4duVPjCry1RpX+5FJySFbGqG3pk4s9ZzlL/vtQtbRzZIZOzg==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [ppc64] + os: [linux] + libc: [glibc] + + '@oxc-minify/binding-linux-riscv64-gnu@0.110.0': + resolution: {integrity: sha512-SweKfsnLKShu6UFV8mwuj1d1wmlNoL/FlAxPUzwjEBgwiT2HQkY24KnjBH+TIA+//1O83kzmWKvvs4OuEhdIEQ==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [riscv64] + os: [linux] + libc: [glibc] + + '@oxc-minify/binding-linux-riscv64-musl@0.110.0': + resolution: {integrity: sha512-oH8G4aFMP8XyTsEpdANC5PQyHgSeGlopHZuW1rpyYcaErg5YaK0vXjQ4EM5HVvPm+feBV24JjxgakTnZoF3aOQ==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [riscv64] + os: [linux] + libc: [musl] + + '@oxc-minify/binding-linux-s390x-gnu@0.110.0': + resolution: {integrity: sha512-W9na+Vza7XVUlpf8wMt4QBfH35KeTENEmnpPUq3NSlbQHz8lSlSvhAafvo43NcKvHAXV3ckD/mUf2VkqSdbklg==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [s390x] + os: [linux] + libc: [glibc] + + '@oxc-minify/binding-linux-x64-gnu@0.110.0': + resolution: {integrity: sha512-XJdA4mmmXOjJxSRgNJXsDP7Xe8h3gQhmb56hUcCrvq5d+h5UcEi2pR8rxsdIrS8QmkLuBA3eHkGK8E27D7DTgQ==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [linux] + libc: [glibc] + + '@oxc-minify/binding-linux-x64-musl@0.110.0': + resolution: {integrity: sha512-QqzvALuOTtSckI8x467R4GNArzYDb/yEh6aNzLoeaY1O7vfT7SPDwlOEcchaTznutpeS9Dy8gUS/AfqtUHaufw==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [linux] + libc: [musl] + + '@oxc-minify/binding-openharmony-arm64@0.110.0': + resolution: {integrity: sha512-gAMssLs2Q3+uhLZxanh1DF+27Kaug3cf4PXb9AB7XK81DR+LVcKySXaoGYoOs20Co0fFSphd6rRzKge2qDK3dA==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [openharmony] + + '@oxc-minify/binding-wasm32-wasi@0.110.0': + resolution: {integrity: sha512-7Wqi5Zjl022bs2zXq+ICdalDPeDuCH/Nhbi8q2isLihAonMVIT0YH2hqqnNEylRNGYck+FJ6gRZwMpGCgrNxPg==} + engines: {node: '>=14.0.0'} + cpu: [wasm32] + + '@oxc-minify/binding-win32-arm64-msvc@0.110.0': + resolution: {integrity: sha512-ZPx+0Tj4dqn41ecyoGotlvekQKy6JxJCixn9Rw7h/dafZ3eDuBcEVh3c2ZoldXXsyMIt5ywI8IWzFZsjNedd5Q==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [win32] + + '@oxc-minify/binding-win32-ia32-msvc@0.110.0': + resolution: {integrity: sha512-H0Oyd3RWBfpEyvJIrFK94RYiY7KKSQl11Ym7LMDwLEagelIAfRCkt1amHZhFa/S3ZRoaOJFXzEw4YKeSsjVFsg==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [ia32] + os: [win32] + + '@oxc-minify/binding-win32-x64-msvc@0.110.0': + resolution: {integrity: sha512-Hr3nK90+qXKJ2kepXwFIcNfQQIOBecB4FFCyaMMypthoEEhVP08heRynj4eSXZ8NL9hLjs3fQzH8PJXfpznRnQ==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [win32] + + '@oxc-project/types@0.115.0': + resolution: {integrity: sha512-4n91DKnebUS4yjUHl2g3/b2T+IUdCfmoZGhmwsovZCDaJSs+QkVAM+0AqqTxHSsHfeiMuueT75cZaZcT/m0pSw==} + + '@oxc-transform/binding-android-arm-eabi@0.110.0': + resolution: {integrity: sha512-sE9dxvqqAax1YYJ3t7j+h5ZSI9jl6dYuDfngl6ieZUrIy5P89/8JKVgAzgp8o3wQSo7ndpJvYsi1K4ZqrmbP7w==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm] + os: [android] + + '@oxc-transform/binding-android-arm64@0.110.0': + resolution: {integrity: sha512-nqtbP4aMCtsCZ6qpHlHaQoWVHSBtlKzwaAgwEOvR+9DWqHjk31BHvpGiDXlMeed6CVNpl3lCbWgygb3RcSjcfw==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [android] + + '@oxc-transform/binding-darwin-arm64@0.110.0': + resolution: {integrity: sha512-oeSeHnL4Z4cMXtc8V0/rwoVn0dgwlS9q0j6LcHn9dIhtFEdp3W0iSBF8YmMQA+E7sILeLDjsHmHE4Kp0sOScXw==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [darwin] + + '@oxc-transform/binding-darwin-x64@0.110.0': + resolution: {integrity: sha512-nL9K5x7OuZydobAGPylsEW9d4APs2qEkIBLMgQPA+kY8dtVD3IR87QsTbs4l4DBQYyun/+ay6qVCDlxqxdX2Jg==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [darwin] + + '@oxc-transform/binding-freebsd-x64@0.110.0': + resolution: {integrity: sha512-GS29zXXirDQhZEUq8xKJ1azAWMuUy3Ih3W5Bc5ddk12LRthO5wRLFcKIyeHpAXCoXymQ+LmxbMtbPf84GPxouw==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [freebsd] + + '@oxc-transform/binding-linux-arm-gnueabihf@0.110.0': + resolution: {integrity: sha512-glzDHak8ISyZJemCUi7RCvzNSl+MQ1ly9RceT2qRufhUsvNZ4C/2QLJ1HJwd2N6E88bO4laYn+RofdRzNnGGEA==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm] + os: [linux] + + '@oxc-transform/binding-linux-arm-musleabihf@0.110.0': + resolution: {integrity: sha512-8JThvgJ2FRoTVfbp7e4wqeZqCZbtudM06SfZmNzND9kPNu/LVYygIR+72RWs+xm4bWkuYHg/islo/boNPtMT5Q==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm] + os: [linux] + + '@oxc-transform/binding-linux-arm64-gnu@0.110.0': + resolution: {integrity: sha512-IRh21Ub/g4bkHoErZ0AUWMlWfoZaS0A6EaOVtbcY70RSYIMlrsbjiFwJCzM+b/1DD1rXbH5tsGcH7GweTbfRqg==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [linux] + libc: [glibc] + + '@oxc-transform/binding-linux-arm64-musl@0.110.0': + resolution: {integrity: sha512-e5JN94/oy+wevk76q+LMr+2klTTcO60uXa+Wkq558Ms7mdF2TvkKFI++d/JeiuIwJLTi/BxQ4qdT5FWcsHM/ug==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [linux] + libc: [musl] + + '@oxc-transform/binding-linux-ppc64-gnu@0.110.0': + resolution: {integrity: sha512-Y3/Tnnz1GvDpmv8FXBIKtdZPsdZklOEPdrL6NHrN5i2u54BOkybFaDSptgWF53wOrJlTrcmAVSE6fRKK9XCM2Q==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [ppc64] + os: [linux] + libc: [glibc] + + '@oxc-transform/binding-linux-riscv64-gnu@0.110.0': + resolution: {integrity: sha512-Y0E35iA9/v9jlkNcP6tMJ+ZFOS0rLsWDqG6rU9z+X2R3fBFJBO9UARIK6ngx8upxk81y1TFR2CmBFhupfYdH6Q==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [riscv64] + os: [linux] + libc: [glibc] + + '@oxc-transform/binding-linux-riscv64-musl@0.110.0': + resolution: {integrity: sha512-JOUSYFfHjBUs7xp2FHmZHb8eTYD/oEu0NklS6JgUauqnoXZHiTLPLVW2o2uVCqldnabYHcomuwI2iqVFYJNhTw==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [riscv64] + os: [linux] + libc: [musl] + + '@oxc-transform/binding-linux-s390x-gnu@0.110.0': + resolution: {integrity: sha512-7blgoXF9D3Ngzb7eun23pNrHJpoV/TtE6LObwlZ3Nmb4oZ6Z+yMvBVaoW68NarbmvNGfZ95zrOjgm6cVETLYBA==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [s390x] + os: [linux] + libc: [glibc] + + '@oxc-transform/binding-linux-x64-gnu@0.110.0': + resolution: {integrity: sha512-YQ2joGWCVDZVEU2cD/r/w49hVjDm/Qu1BvC/7zs8LvprzdLS/HyMXGF2oA0puw0b+AqgYaz3bhwKB2xexHyITQ==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [linux] + libc: [glibc] + + '@oxc-transform/binding-linux-x64-musl@0.110.0': + resolution: {integrity: sha512-fkjr5qE632ULmNgvFXWDR/8668WxERz3tU7TQFp6JebPBneColitjSkdx6VKNVXEoMmQnOvBIGeP5tUNT384oA==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [linux] + libc: [musl] + + '@oxc-transform/binding-openharmony-arm64@0.110.0': + resolution: {integrity: sha512-HWH9Zj+lMrdSTqFRCZsvDWMz7OnMjbdGsm3xURXWfRZpuaz0bVvyuZNDQXc4FyyhRDsemICaJbU1bgeIpUJDGw==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [openharmony] + + '@oxc-transform/binding-wasm32-wasi@0.110.0': + resolution: {integrity: sha512-ejdxHmYfIcHDPhZUe3WklViLt9mDEJE5BzcW7+R1vc5i/5JFA8D0l7NUSsHBJ7FB8Bu9gF+5iMDm6cXGAgaghw==} + engines: {node: '>=14.0.0'} + cpu: [wasm32] + + '@oxc-transform/binding-win32-arm64-msvc@0.110.0': + resolution: {integrity: sha512-9VTwpXCZs7xkV+mKhQ62dVk7KLnLXtEUxNS2T4nLz3iMl1IJbA4h5oltK0JoobtiUAnbkV53QmMVGW8+Nh3bDQ==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [win32] + + '@oxc-transform/binding-win32-ia32-msvc@0.110.0': + resolution: {integrity: sha512-5y0fzuNON7/F2hh2P94vANFaRPJ/3DI1hVl5rseCT8VUVqOGIjWaza0YS/D1g6t1WwycW2LWDMi2raOKoWU5GQ==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [ia32] + os: [win32] + + '@oxc-transform/binding-win32-x64-msvc@0.110.0': + resolution: {integrity: sha512-QROrowwlrApI1fEScMknGWKM6GTM/Z2xwMnDqvSaEmzNazBsDUlE08Jasw610hFEsYAVU2K5sp/YaCa9ORdP4A==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [win32] + '@pkgjs/parseargs@0.11.0': resolution: {integrity: sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==} engines: {node: '>=14'} @@ -2155,62 +2490,166 @@ packages: '@remix-run/node-fetch-server@0.13.0': resolution: {integrity: sha512-1EsNo0ZpgXu/90AWoRZf/oE3RVTUS80tiTUpt+hv5pjtAkw7icN4WskDwz/KdAw5ARbJLMhZBrO1NqThmy/McA==} - '@rollup/plugin-commonjs@29.0.0': - resolution: {integrity: sha512-U2YHaxR2cU/yAiwKJtJRhnyLk7cifnQw0zUpISsocBDoHDJn+HTV74ABqnwr5bEgWUwFZC9oFL6wLe21lHu5eQ==} - engines: {node: '>=16.0.0 || 14 >= 14.17'} - peerDependencies: - rollup: ^2.68.0||^3.0.0||^4.0.0 - peerDependenciesMeta: - rollup: - optional: true - - '@rollup/pluginutils@5.3.0': - resolution: {integrity: sha512-5EdhGZtnu3V88ces7s53hhfK5KSASnJZv8Lulpc04cWO3REESroJXg73DFsOmgbU2BhwV0E20bu2IDZb3VKW4Q==} - engines: {node: '>=14.0.0'} - peerDependencies: - rollup: ^1.20.0||^2.0.0||^3.0.0||^4.0.0 - peerDependenciesMeta: - rollup: - optional: true - - '@rollup/rollup-android-arm-eabi@4.59.0': - resolution: {integrity: sha512-upnNBkA6ZH2VKGcBj9Fyl9IGNPULcjXRlg0LLeaioQWueH30p6IXtJEbKAgvyv+mJaMxSm1l6xwDXYjpEMiLMg==} - cpu: [arm] - os: [android] - - '@rollup/rollup-android-arm64@4.59.0': - resolution: {integrity: sha512-hZ+Zxj3SySm4A/DylsDKZAeVg0mvi++0PYVceVyX7hemkw7OreKdCvW2oQ3T1FMZvCaQXqOTHb8qmBShoqk69Q==} + '@rolldown/binding-android-arm64@1.0.0-rc.8': + resolution: {integrity: sha512-5bcmMQDWEfWUq3m79Mcf/kbO6e5Jr6YjKSsA1RnpXR6k73hQ9z1B17+4h93jXpzHvS18p7bQHM1HN/fSd+9zog==} + engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [android] - '@rollup/rollup-darwin-arm64@4.59.0': - resolution: {integrity: sha512-W2Psnbh1J8ZJw0xKAd8zdNgF9HRLkdWwwdWqubSVk0pUuQkoHnv7rx4GiF9rT4t5DIZGAsConRE3AxCdJ4m8rg==} + '@rolldown/binding-darwin-arm64@1.0.0-rc.8': + resolution: {integrity: sha512-dcHPd5N4g9w2iiPRJmAvO0fsIWzF2JPr9oSuTjxLL56qu+oML5aMbBMNwWbk58Mt3pc7vYs9CCScwLxdXPdRsg==} + engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [darwin] - '@rollup/rollup-darwin-x64@4.59.0': - resolution: {integrity: sha512-ZW2KkwlS4lwTv7ZVsYDiARfFCnSGhzYPdiOU4IM2fDbL+QGlyAbjgSFuqNRbSthybLbIJ915UtZBtmuLrQAT/w==} + '@rolldown/binding-darwin-x64@1.0.0-rc.8': + resolution: {integrity: sha512-mw0VzDvoj8AuR761QwpdCFN0sc/jspuc7eRYJetpLWd+XyansUrH3C7IgNw6swBOgQT9zBHNKsVCjzpfGJlhUA==} + engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [darwin] - '@rollup/rollup-freebsd-arm64@4.59.0': - resolution: {integrity: sha512-EsKaJ5ytAu9jI3lonzn3BgG8iRBjV4LxZexygcQbpiU0wU0ATxhNVEpXKfUa0pS05gTcSDMKpn3Sx+QB9RlTTA==} - cpu: [arm64] - os: [freebsd] - - '@rollup/rollup-freebsd-x64@4.59.0': - resolution: {integrity: sha512-d3DuZi2KzTMjImrxoHIAODUZYoUUMsuUiY4SRRcJy6NJoZ6iIqWnJu9IScV9jXysyGMVuW+KNzZvBLOcpdl3Vg==} + '@rolldown/binding-freebsd-x64@1.0.0-rc.8': + resolution: {integrity: sha512-xNrRa6mQ9NmMIJBdJtPMPG8Mso0OhM526pDzc/EKnRrIrrkHD1E0Z6tONZRmUeJElfsQ6h44lQQCcDilSNIvSQ==} + engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [freebsd] - '@rollup/rollup-linux-arm-gnueabihf@4.59.0': - resolution: {integrity: sha512-t4ONHboXi/3E0rT6OZl1pKbl2Vgxf9vJfWgmUoCEVQVxhW6Cw/c8I6hbbu7DAvgp82RKiH7TpLwxnJeKv2pbsw==} + '@rolldown/binding-linux-arm-gnueabihf@1.0.0-rc.8': + resolution: {integrity: sha512-WgCKoO6O/rRUwimWfEJDeztwJJmuuX0N2bYLLRxmXDTtCwjToTOqk7Pashl/QpQn3H/jHjx0b5yCMbcTVYVpNg==} + engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm] os: [linux] - libc: [glibc] - '@rollup/rollup-linux-arm-musleabihf@4.59.0': - resolution: {integrity: sha512-CikFT7aYPA2ufMD086cVORBYGHffBo4K8MQ4uPS/ZnY54GKj36i196u8U+aDVT2LX4eSMbyHtyOh7D7Zvk2VvA==} + '@rolldown/binding-linux-arm64-gnu@1.0.0-rc.8': + resolution: {integrity: sha512-tOHgTOQa8G4Z3ULj4G3NYOGGJEsqPHR91dT72u63OtVsZ7B6wFJKOx+ZKv+pvwzxWz92/I2ycaqi2/Ll4l+rlg==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [linux] + libc: [glibc] + + '@rolldown/binding-linux-arm64-musl@1.0.0-rc.8': + resolution: {integrity: sha512-oRbxcgDujCi2Yp1GTxoUFsIFlZsuPHU4OV4AzNc3/6aUmR4lfm9FK0uwQu82PJsuUwnF2jFdop3Ep5c1uK7Uxg==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [linux] + libc: [musl] + + '@rolldown/binding-linux-ppc64-gnu@1.0.0-rc.8': + resolution: {integrity: sha512-oaLRyUHw8kQE5M89RqrDJZ10GdmGJcMeCo8tvaE4ukOofqgjV84AbqBSH6tTPjeT2BHv+xlKj678GBuIb47lKA==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [ppc64] + os: [linux] + libc: [glibc] + + '@rolldown/binding-linux-s390x-gnu@1.0.0-rc.8': + resolution: {integrity: sha512-1hjSKFrod5MwBBdLOOA0zpUuSfSDkYIY+QqcMcIU1WOtswZtZdUkcFcZza9b2HcAb0bnpmmyo0LZcaxLb2ov1g==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [s390x] + os: [linux] + libc: [glibc] + + '@rolldown/binding-linux-x64-gnu@1.0.0-rc.8': + resolution: {integrity: sha512-a1+F0aV4Wy9tT3o+cHl3XhOy6aFV+B8Ll+/JFj98oGkb6lGk3BNgrxd+80RwYRVd23oLGvj3LwluKYzlv1PEuw==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [linux] + libc: [glibc] + + '@rolldown/binding-linux-x64-musl@1.0.0-rc.8': + resolution: {integrity: sha512-bGyXCFU11seFrf7z8PcHSwGEiFVkZ9vs+auLacVOQrVsI8PFHJzzJROF3P6b0ODDmXr0m6Tj5FlDhcXVk0Jp8w==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [linux] + libc: [musl] + + '@rolldown/binding-openharmony-arm64@1.0.0-rc.8': + resolution: {integrity: sha512-n8d+L2bKgf9G3+AM0bhHFWdlz9vYKNim39ujRTieukdRek0RAo2TfG2uEnV9spa4r4oHUfL9IjcY3M9SlqN1gw==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [openharmony] + + '@rolldown/binding-wasm32-wasi@1.0.0-rc.8': + resolution: {integrity: sha512-4R4iJDIk7BrJdteAbEAICXPoA7vZoY/M0OBfcRlQxzQvUYMcEp2GbC/C8UOgQJhu2TjGTpX1H8vVO1xHWcRqQA==} + engines: {node: '>=14.0.0'} + cpu: [wasm32] + + '@rolldown/binding-win32-arm64-msvc@1.0.0-rc.8': + resolution: {integrity: sha512-3lwnklba9qQOpFnQ7EW+A1m4bZTWXZE4jtehsZ0YOl2ivW1FQqp5gY7X2DLuKITggesyuLwcmqS11fA7NtrmrA==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [win32] + + '@rolldown/binding-win32-x64-msvc@1.0.0-rc.8': + resolution: {integrity: sha512-VGjCx9Ha1P/r3tXGDZyG0Fcq7Q0Afnk64aaKzr1m40vbn1FL8R3W0V1ELDvPgzLXaaqK/9PnsqSaLWXfn6JtGQ==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [win32] + + '@rolldown/pluginutils@1.0.0-beta.40': + resolution: {integrity: sha512-s3GeJKSQOwBlzdUrj4ISjJj5SfSh+aqn0wjOar4Bx95iV1ETI7F6S/5hLcfAxZ9kXDcyrAkxPlqmd1ZITttf+w==} + + '@rolldown/pluginutils@1.0.0-rc.3': + resolution: {integrity: sha512-eybk3TjzzzV97Dlj5c+XrBFW57eTNhzod66y9HrBlzJ6NsCrWCp/2kaPS3K9wJmurBC0Tdw4yPjXKZqlznim3Q==} + + '@rolldown/pluginutils@1.0.0-rc.8': + resolution: {integrity: sha512-wzJwL82/arVfeSP3BLr1oTy40XddjtEdrdgtJ4lLRBu06mP3q/8HGM6K0JRlQuTA3XB0pNJx2so/nmpY4xyOew==} + + '@rollup/plugin-commonjs@29.0.0': + resolution: {integrity: sha512-U2YHaxR2cU/yAiwKJtJRhnyLk7cifnQw0zUpISsocBDoHDJn+HTV74ABqnwr5bEgWUwFZC9oFL6wLe21lHu5eQ==} + engines: {node: '>=16.0.0 || 14 >= 14.17'} + peerDependencies: + rollup: ^2.68.0||^3.0.0||^4.0.0 + peerDependenciesMeta: + rollup: + optional: true + + '@rollup/pluginutils@5.3.0': + resolution: {integrity: sha512-5EdhGZtnu3V88ces7s53hhfK5KSASnJZv8Lulpc04cWO3REESroJXg73DFsOmgbU2BhwV0E20bu2IDZb3VKW4Q==} + engines: {node: '>=14.0.0'} + peerDependencies: + rollup: ^1.20.0||^2.0.0||^3.0.0||^4.0.0 + peerDependenciesMeta: + rollup: + optional: true + + '@rollup/rollup-android-arm-eabi@4.59.0': + resolution: {integrity: sha512-upnNBkA6ZH2VKGcBj9Fyl9IGNPULcjXRlg0LLeaioQWueH30p6IXtJEbKAgvyv+mJaMxSm1l6xwDXYjpEMiLMg==} + cpu: [arm] + os: [android] + + '@rollup/rollup-android-arm64@4.59.0': + resolution: {integrity: sha512-hZ+Zxj3SySm4A/DylsDKZAeVg0mvi++0PYVceVyX7hemkw7OreKdCvW2oQ3T1FMZvCaQXqOTHb8qmBShoqk69Q==} + cpu: [arm64] + os: [android] + + '@rollup/rollup-darwin-arm64@4.59.0': + resolution: {integrity: sha512-W2Psnbh1J8ZJw0xKAd8zdNgF9HRLkdWwwdWqubSVk0pUuQkoHnv7rx4GiF9rT4t5DIZGAsConRE3AxCdJ4m8rg==} + cpu: [arm64] + os: [darwin] + + '@rollup/rollup-darwin-x64@4.59.0': + resolution: {integrity: sha512-ZW2KkwlS4lwTv7ZVsYDiARfFCnSGhzYPdiOU4IM2fDbL+QGlyAbjgSFuqNRbSthybLbIJ915UtZBtmuLrQAT/w==} + cpu: [x64] + os: [darwin] + + '@rollup/rollup-freebsd-arm64@4.59.0': + resolution: {integrity: sha512-EsKaJ5ytAu9jI3lonzn3BgG8iRBjV4LxZexygcQbpiU0wU0ATxhNVEpXKfUa0pS05gTcSDMKpn3Sx+QB9RlTTA==} + cpu: [arm64] + os: [freebsd] + + '@rollup/rollup-freebsd-x64@4.59.0': + resolution: {integrity: sha512-d3DuZi2KzTMjImrxoHIAODUZYoUUMsuUiY4SRRcJy6NJoZ6iIqWnJu9IScV9jXysyGMVuW+KNzZvBLOcpdl3Vg==} + cpu: [x64] + os: [freebsd] + + '@rollup/rollup-linux-arm-gnueabihf@4.59.0': + resolution: {integrity: sha512-t4ONHboXi/3E0rT6OZl1pKbl2Vgxf9vJfWgmUoCEVQVxhW6Cw/c8I6hbbu7DAvgp82RKiH7TpLwxnJeKv2pbsw==} + cpu: [arm] + os: [linux] + libc: [glibc] + + '@rollup/rollup-linux-arm-musleabihf@4.59.0': + resolution: {integrity: sha512-CikFT7aYPA2ufMD086cVORBYGHffBo4K8MQ4uPS/ZnY54GKj36i196u8U+aDVT2LX4eSMbyHtyOh7D7Zvk2VvA==} cpu: [arm] os: [linux] libc: [musl] @@ -2347,6 +2786,36 @@ packages: '@sinonjs/fake-timers@10.3.0': resolution: {integrity: sha512-V4BG07kuYSUkTCSBHG8G8TNhM+F19jXFWnQtzj+we8DrkpSBCee9Z3Ms8yiGer/dlmhe35/Xdgyo3/0rQKg7YA==} + '@solid-primitives/event-listener@2.4.5': + resolution: {integrity: sha512-nwRV558mIabl4yVAhZKY8cb6G+O1F0M6Z75ttTu5hk+SxdOnKSGj+eetDIu7Oax1P138ZdUU01qnBPR8rnxaEA==} + peerDependencies: + solid-js: ^1.6.12 + + '@solid-primitives/keyboard@1.3.5': + resolution: {integrity: sha512-sav+l+PL+74z3yaftVs7qd8c2SXkqzuxPOVibUe5wYMt+U5Hxp3V3XCPgBPN2I6cANjvoFtz0NiU8uHVLdi9FQ==} + peerDependencies: + solid-js: ^1.6.12 + + '@solid-primitives/resize-observer@2.1.5': + resolution: {integrity: sha512-AiyTknKcNBaKHbcSMuxtSNM8FjIuiSuFyFghdD0TcCMU9hKi9EmsC5pjfjDwxE+5EueB1a+T/34PLRI5vbBbKw==} + peerDependencies: + solid-js: ^1.6.12 + + '@solid-primitives/rootless@1.5.3': + resolution: {integrity: sha512-N8cIDAHbWcLahNRLr0knAAQvXyEdEMoAZvIMZKmhNb1mlx9e2UOv9BRD5YNwQUJwbNoYVhhLwFOEOcVXFx0HqA==} + peerDependencies: + solid-js: ^1.6.12 + + '@solid-primitives/static-store@0.1.3': + resolution: {integrity: sha512-uxez7SXnr5GiRnzqO2IEDjOJRIXaG+0LZLBizmUA1FwSi+hrpuMzVBwyk70m4prcl8X6FDDXUl9O8hSq8wHbBQ==} + peerDependencies: + solid-js: ^1.6.12 + + '@solid-primitives/utils@6.4.0': + resolution: {integrity: sha512-AeGTBg8Wtkh/0s+evyLtP8piQoS4wyqqQaAFs2HJcFMMjYAtUgo+ZPduRXLjPlqKVc2ejeR544oeqpbn8Egn8A==} + peerDependencies: + solid-js: ^1.6.12 + '@standard-schema/spec@1.1.0': resolution: {integrity: sha512-l2aFy5jALhniG5HgqrD6jXLi/rUWrKvqN/qJx6yoJsgKhblVd+iqqU4RCXavm/jPityDo5TCvKMnpjKnOriy0w==} @@ -2452,6 +2921,168 @@ packages: peerDependencies: vite: ^5.2.0 || ^6 || ^7 + '@tanstack/devtools-client@0.0.6': + resolution: {integrity: sha512-f85ZJXJnDIFOoykG/BFIixuAevJovCvJF391LPs6YjBAPhGYC50NWlx1y4iF/UmK5/cCMx+/JqI5SBOz7FanQQ==} + engines: {node: '>=18'} + + '@tanstack/devtools-event-bus@0.4.1': + resolution: {integrity: sha512-cNnJ89Q021Zf883rlbBTfsaxTfi2r73/qejGtyTa7ksErF3hyDyAq1aTbo5crK9dAL7zSHh9viKY1BtMls1QOA==} + engines: {node: '>=18'} + + '@tanstack/devtools-event-client@0.4.1': + resolution: {integrity: sha512-GRxmPw4OHZ2oZeIEUkEwt/NDvuEqzEYRAjzUVMs+I0pd4C7k1ySOiuJK2CqF+K/yEAR3YZNkW3ExrpDarh9Vwg==} + engines: {node: '>=18'} + + '@tanstack/devtools-ui@0.5.0': + resolution: {integrity: sha512-nNZ14054n31fWB61jtWhZYLRdQ3yceCE3G/RINoINUB0RqIGZAIm9DnEDwOTAOfqt4/a/D8vNk8pJu6RQUp74g==} + engines: {node: '>=18'} + peerDependencies: + solid-js: '>=1.9.7' + + '@tanstack/devtools-vite@0.5.3': + resolution: {integrity: sha512-S7VK2GthBrEkto0UVODx31IAvxTFUK0RGH6aZEZixsohYTytTdrwcLmPKEREwFrRN8Qc2mIqfBhENPbRG1RFXA==} + engines: {node: '>=18'} + peerDependencies: + vite: ^6.0.0 || ^7.0.0 + + '@tanstack/devtools@0.10.11': + resolution: {integrity: sha512-Nk1rHsv6S/5Krzz+uL5jldW9gKb3s6rkkVl1L9oVYHNClKthbrk2hGef4Di6yj449QIOqVExTdDujjQ4roq1dg==} + engines: {node: '>=18'} + peerDependencies: + solid-js: '>=1.9.7' + + '@tanstack/history@1.161.4': + resolution: {integrity: sha512-Kp/WSt411ZWYvgXy6uiv5RmhHrz9cAml05AQPrtdAp7eUqvIDbMGPnML25OKbzR3RJ1q4wgENxDTvlGPa9+Mww==} + engines: {node: '>=20.19'} + + '@tanstack/react-devtools@0.9.10': + resolution: {integrity: sha512-WKFU8SXN7DLM7EyD2aUAhmk7JGNeONWhQozAH2qDCeOjyc3Yzxs4BxeoyKMYyEiX/eCp8ZkMTf/pJX6vm2LGeA==} + engines: {node: '>=18'} + peerDependencies: + '@types/react': '>=16.8' + '@types/react-dom': '>=16.8' + react: 19.2.4 + react-dom: 19.2.4 + + '@tanstack/react-router-devtools@1.166.6': + resolution: {integrity: sha512-TheVyOgo8ljD8wHHLceFsnKrX7nhTIQv9WokSrPjNTP4H3synUMADxh8yZafVYdr6lS2CBvldd5s7JI8DcwBUg==} + engines: {node: '>=20.19'} + peerDependencies: + '@tanstack/react-router': ^1.166.6 + '@tanstack/router-core': ^1.166.6 + react: 19.2.4 + react-dom: 19.2.4 + peerDependenciesMeta: + '@tanstack/router-core': + optional: true + + '@tanstack/react-router@1.166.6': + resolution: {integrity: sha512-lfymPCfTkLQaNj/KIPElt+6B9REwPw2/Of3KtMwhNINs7h2xFQMSAOYk+ItCv8i93lBczlg89BRHtRS99qmzyA==} + engines: {node: '>=20.19'} + peerDependencies: + react: 19.2.4 + react-dom: 19.2.4 + + '@tanstack/react-start-client@1.166.6': + resolution: {integrity: sha512-RG+aFN/JdJXArcTBbsJUCrCMzxqMA1YDkdm50Qg2P7H2e3T7Tmqf7mzopXP0b8oMCxbdvjY0leer4t4/KndnjQ==} + engines: {node: '>=22.12.0'} + peerDependencies: + react: 19.2.4 + react-dom: 19.2.4 + + '@tanstack/react-start-server@1.166.6': + resolution: {integrity: sha512-L1aUZW1Q6NU08/MDbQTUJw9yIKr5l3Kg8XWZvB2bpFahN3N+yy2KJehWRMZHTUfnIcV2IjGk3FMEwbLiI20DtA==} + engines: {node: '>=22.12.0'} + peerDependencies: + react: 19.2.4 + react-dom: 19.2.4 + + '@tanstack/react-start@1.166.6': + resolution: {integrity: sha512-nJXyan9KzxUuNYjvuYT6PlPY/SIoAQ9Cobn1lp2mtXM0/J3JwnOvASkuquglVSbKfrVwspVuk3lB5DTbOgiAlw==} + engines: {node: '>=22.12.0'} + peerDependencies: + react: 19.2.4 + react-dom: 19.2.4 + vite: '>=7.0.0' + + '@tanstack/react-store@0.9.2': + resolution: {integrity: sha512-Vt5usJE5sHG/cMechQfmwvwne6ktGCELe89Lmvoxe3LKRoFrhPa8OCKWs0NliG8HTJElEIj7PLtaBQIcux5pAQ==} + peerDependencies: + react: 19.2.4 + react-dom: 19.2.4 + + '@tanstack/router-core@1.166.6': + resolution: {integrity: sha512-SwVPMQxjoY4jwiNgD9u5kDFp/iSaf3wgf1t93xRCC6qDHmv/xLaawhvwEPNIJaPepWuSYRpywpJWH9hGlBqVbw==} + engines: {node: '>=20.19'} + + '@tanstack/router-devtools-core@1.166.6': + resolution: {integrity: sha512-ndPnCDeSGW3bd33u3EMe3+EJGLiFOHZaIKRJRLdZClOB6J6pvzKMELJgizBtjaR6X56FdCsC/STgjPkOeR9paA==} + engines: {node: '>=20.19'} + peerDependencies: + '@tanstack/router-core': ^1.166.6 + csstype: ^3.0.10 + peerDependenciesMeta: + csstype: + optional: true + + '@tanstack/router-generator@1.166.6': + resolution: {integrity: sha512-D7Z6oLP2IfflXUzOOxIgeCD8v3/SXU//cgBon0pbF13HkKdf9Zlt97kQqcaOkbnruJJ6i5xtUIsoAQbMmj+EsQ==} + engines: {node: '>=20.19'} + + '@tanstack/router-plugin@1.166.6': + resolution: {integrity: sha512-07ZwOMNDlKIoaRtrfP5zO3VfqXNg2Zm7qvqZOBaTbbqgMvaKclW0ylqakweXtDwiNs9GPf/+lH/xyc+CgLGUyg==} + engines: {node: '>=20.19'} + peerDependencies: + '@rsbuild/core': '>=1.0.2' + '@tanstack/react-router': ^1.166.6 + vite: '>=5.0.0 || >=6.0.0 || >=7.0.0' + vite-plugin-solid: ^2.11.10 + webpack: '>=5.92.0' + peerDependenciesMeta: + '@rsbuild/core': + optional: true + '@tanstack/react-router': + optional: true + vite: + optional: true + vite-plugin-solid: + optional: true + webpack: + optional: true + + '@tanstack/router-utils@1.161.4': + resolution: {integrity: sha512-r8TpjyIZoqrXXaf2DDyjd44gjGBoyE+/oEaaH68yLI9ySPO1gUWmQENZ1MZnmBnpUGN24NOZxdjDLc8npK0SAw==} + engines: {node: '>=20.19'} + + '@tanstack/start-client-core@1.166.6': + resolution: {integrity: sha512-fnSkRaL6pI3RRdWSeJFg5Vg88Cn9GuuOvmOBP0IgWTNHqywjFm/b1dPGemphD5cmJLhMPAkqGwbK4oPzzdnB9A==} + engines: {node: '>=22.12.0'} + + '@tanstack/start-fn-stubs@1.161.4': + resolution: {integrity: sha512-b8s6iSQ+ny0P4lGK0n3DKaL6EI7SECG0/89svDeYieVw2+MaFOJVcQo3rU3BUvmuOcIkgkE5IhdzkmzPXH6yfA==} + engines: {node: '>=22.12.0'} + + '@tanstack/start-plugin-core@1.166.6': + resolution: {integrity: sha512-/VlfJYOnVyzGlyEATCFxhgPC2AF5pt5MEO+cjvguu9q9+hE/zceSY33Y9gmg7keybVGOz+cmRrSbUaBPMQ+aNw==} + engines: {node: '>=22.12.0'} + peerDependencies: + vite: '>=7.0.0' + + '@tanstack/start-server-core@1.166.6': + resolution: {integrity: sha512-nekpa3zFx1SFBURwVbqNunJlLcxvx8vu+Mbnv/nYw4JLfeBmhNNGMZjxmB2K5PRBwIzcKRpLIwgtzyWWzaHKPw==} + engines: {node: '>=22.12.0'} + + '@tanstack/start-storage-context@1.166.6': + resolution: {integrity: sha512-FLu+bHWS0VFz/KTOPEQnhDxzxToca4giVoUZ3DYfYcQNky+FrIeKYvlwurFNVuLkSCY1Jqr1O2xVnD9dEqBAag==} + engines: {node: '>=22.12.0'} + + '@tanstack/store@0.9.2': + resolution: {integrity: sha512-K013lUJEFJK2ofFQ/hZKJUmCnpcV00ebLyOyFOWQvyQHUOZp/iYO84BM6aOGiV81JzwbX0APTVmW8YI7yiG5oA==} + + '@tanstack/virtual-file-routes@1.161.4': + resolution: {integrity: sha512-42WoRePf8v690qG8yGRe/YOh+oHni9vUaUUfoqlS91U2scd3a5rkLtVsc6b7z60w3RogH0I00vdrC5AaeiZ18w==} + engines: {node: '>=20.19'} + '@ts-morph/common@0.11.1': resolution: {integrity: sha512-7hWZS0NRpEsNV8vWJzg7FEz6V8MaLNeJOmwmghqUXTpzk16V1LLZhdo+4QvE/+zv4cVci0OviuJFnqhEfoV3+g==} @@ -2539,6 +3170,9 @@ packages: '@types/node@25.3.2': resolution: {integrity: sha512-RpV6r/ij22zRRdyBPcxDeKAzH43phWVKEjL2iksqo1Vz3CuBUrgmPpPhALKiRfU7OMCmeeO9vECBMsV0hMTG8Q==} + '@types/node@25.4.0': + resolution: {integrity: sha512-9wLpoeWuBlcbBpOY3XmzSTG3oscB6xjBEEtn+pYXTfhyXhIxC5FsBer2KTopBlvKEiW9l13po9fq+SJY/5lkhw==} + '@types/react-dom@19.2.3': resolution: {integrity: sha512-jp2L/eY6fn+KgVVQAOqYItbF0VY/YApe5Mz2F0aykSO8gx31bYCZyvSeYxCHKvzHG5eZjc+zyaS5BrBWya2+kQ==} peerDependencies: @@ -2583,16 +3217,32 @@ packages: peerDependencies: typescript: '>=4.8.4 <6.0.0' + '@typescript-eslint/project-service@8.57.0': + resolution: {integrity: sha512-pR+dK0BlxCLxtWfaKQWtYr7MhKmzqZxuii+ZjuFlZlIGRZm22HnXFqa2eY+90MUz8/i80YJmzFGDUsi8dMOV5w==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + typescript: '>=4.8.4 <6.0.0' + '@typescript-eslint/scope-manager@8.56.1': resolution: {integrity: sha512-YAi4VDKcIZp0O4tz/haYKhmIDZFEUPOreKbfdAN3SzUDMcPhJ8QI99xQXqX+HoUVq8cs85eRKnD+rne2UAnj2w==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + '@typescript-eslint/scope-manager@8.57.0': + resolution: {integrity: sha512-nvExQqAHF01lUM66MskSaZulpPL5pgy5hI5RfrxviLgzZVffB5yYzw27uK/ft8QnKXI2X0LBrHJFr1TaZtAibw==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + '@typescript-eslint/tsconfig-utils@8.56.1': resolution: {integrity: sha512-qOtCYzKEeyr3aR9f28mPJqBty7+DBqsdd63eO0yyDwc6vgThj2UjWfJIcsFeSucYydqcuudMOprZ+x1SpF3ZuQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: typescript: '>=4.8.4 <6.0.0' + '@typescript-eslint/tsconfig-utils@8.57.0': + resolution: {integrity: sha512-LtXRihc5ytjJIQEH+xqjB0+YgsV4/tW35XKX3GTZHpWtcC8SPkT/d4tqdf1cKtesryHm2bgp6l555NYcT2NLvA==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + typescript: '>=4.8.4 <6.0.0' + '@typescript-eslint/type-utils@8.56.1': resolution: {integrity: sha512-yB/7dxi7MgTtGhZdaHCemf7PuwrHMenHjmzgUW1aJpO+bBU43OycnM3Wn+DdvDO/8zzA9HlhaJ0AUGuvri4oGg==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} @@ -2604,12 +3254,22 @@ packages: resolution: {integrity: sha512-dbMkdIUkIkchgGDIv7KLUpa0Mda4IYjo4IAMJUZ+3xNoUXxMsk9YtKpTHSChRS85o+H9ftm51gsK1dZReY9CVw==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + '@typescript-eslint/types@8.57.0': + resolution: {integrity: sha512-dTLI8PEXhjUC7B9Kre+u0XznO696BhXcTlOn0/6kf1fHaQW8+VjJAVHJ3eTI14ZapTxdkOmc80HblPQLaEeJdg==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + '@typescript-eslint/typescript-estree@8.56.1': resolution: {integrity: sha512-qzUL1qgalIvKWAf9C1HpvBjif+Vm6rcT5wZd4VoMb9+Km3iS3Cv9DY6dMRMDtPnwRAFyAi7YXJpTIEXLvdfPxg==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: typescript: '>=4.8.4 <6.0.0' + '@typescript-eslint/typescript-estree@8.57.0': + resolution: {integrity: sha512-m7faHcyVg0BT3VdYTlX8GdJEM7COexXxS6KqGopxdtkQRvBanK377QDHr4W/vIPAR+ah9+B/RclSW5ldVniO1Q==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + typescript: '>=4.8.4 <6.0.0' + '@typescript-eslint/utils@8.56.1': resolution: {integrity: sha512-HPAVNIME3tABJ61siYlHzSWCGtOoeP2RTIaHXFMPqjrQKCGB9OgUVdiNgH7TJS2JNIQ5qQ4RsAUDuGaGme/KOA==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} @@ -2617,10 +3277,21 @@ packages: eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 typescript: '>=4.8.4 <6.0.0' + '@typescript-eslint/utils@8.57.0': + resolution: {integrity: sha512-5iIHvpD3CZe06riAsbNxxreP+MuYgVUsV0n4bwLH//VJmgtt54sQeY2GszntJ4BjYCpMzrfVh2SBnUQTtys2lQ==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 + typescript: '>=4.8.4 <6.0.0' + '@typescript-eslint/visitor-keys@8.56.1': resolution: {integrity: sha512-KiROIzYdEV85YygXw6BI/Dx4fnBlFQu6Mq4QE4MOH9fFnhohw6wX/OAvDY2/C+ut0I3RSPKenvZJIVYqJNkhEw==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + '@typescript-eslint/visitor-keys@8.57.0': + resolution: {integrity: sha512-zm6xx8UT/Xy2oSr2ZXD0pZo7Jx2XsCoID2IUh9YSTFRu7z+WdwYTRk6LhUftm1crwqbuoF6I8zAFeCMw0YjwDg==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + '@ungap/structured-clone@1.3.0': resolution: {integrity: sha512-WmoN8qaIAo7WTYWbAZuG8PYEhn5fkz7dZrqTBZ7dtt//lL2Gwms1IcnQ5yHqjDfX8Ft5j4YzDM23f87zBfDe9g==} @@ -2771,6 +3442,12 @@ packages: '@vercel/static-config@3.1.2': resolution: {integrity: sha512-2d+TXr6K30w86a+WbMbGm2W91O0UzO5VeemZYBBUJbCjk/5FLLGIi8aV6RS2+WmaRvtcqNTn2pUA7nCOK3bGcQ==} + '@vitejs/plugin-react@5.1.4': + resolution: {integrity: sha512-VIcFLdRi/VYRU8OL/puL7QXMYafHmqOnwTZY50U1JPlCNj30PxCMx65c494b1K9be9hX83KVt0+gTEwTWLqToA==} + engines: {node: ^20.19.0 || >=22.12.0} + peerDependencies: + vite: ^4.2.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 + '@vitest/expect@4.0.18': resolution: {integrity: sha512-8sCWUyckXXYvx4opfzVY03EOiYVxyNrHS5QxX3DAIi5dpJAAkyJezHCP77VMX4HKA2LDT/Jpfo8i2r5BE3GnQQ==} @@ -2898,6 +3575,10 @@ packages: ansicolors@0.3.2: resolution: {integrity: sha512-QXu7BPrP29VllRxH8GwB7x5iX5qWKAAMLqKQGWTeLWVlNHNOpVMJ91dsxQAIWXpjuW5wqvxu3Jd/nRjrJ+0pqg==} + ansis@4.2.0: + resolution: {integrity: sha512-HqZ5rWlFjGiV0tDm3UxxgNRqsOTniqoKZu0pIAfh7TZQMGuZK+hH0drySty0si0QXj1ieop4+SkSfPZBPPkHig==} + engines: {node: '>=14'} + any-promise@1.3.0: resolution: {integrity: sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A==} @@ -2973,6 +3654,10 @@ packages: resolution: {integrity: sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA==} engines: {node: '>=12'} + ast-types@0.16.1: + resolution: {integrity: sha512-6t10qk83GOG8p0vKmaCr8eiilZwO171AvbROMtvvNiwrTly62t+7XkA8RdIIVbpMhCASAsxgAzdRSwh6nw/5Dg==} + engines: {node: '>=4'} + astral-regex@2.0.0: resolution: {integrity: sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==} engines: {node: '>=8'} @@ -3121,6 +3806,10 @@ packages: resolution: {integrity: sha512-QxD8cf2eVqJOOz63z6JIN9BzvVs/dlySa5HGSBH5xtR8dPteIRQnBxxKqkNTiT6jbDTF6jAfrd4oMcND9RGbQg==} engines: {node: '>=0.6'} + binary-extensions@2.3.0: + resolution: {integrity: sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==} + engines: {node: '>=8'} + body-parser@1.20.4: resolution: {integrity: sha512-ZTgYYLMOXY9qKU/57FAo8F+HA2dGX7bqGc71txDRC1rS4frdFI5R7NhluHxH6M0YItAP0sHB4uqAOcYKxO6uGA==} engines: {node: '>= 0.8', npm: 1.2.8000 || >= 1.4.16} @@ -3226,6 +3915,10 @@ packages: resolution: {integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==} engines: {node: '>=10'} + chalk@5.6.2: + resolution: {integrity: sha512-7NzBL0rN6fMUW+f7A6Io4h40qQlG+xGmtMxfbnH/K7TAtt8JQWVQK+6g0UXKMeVJoyV5EkkNsErQ8pVD3bLHbA==} + engines: {node: ^12.17.0 || ^14.13 || >=16.0.0} + character-entities-html4@2.1.0: resolution: {integrity: sha512-1v7fgQRj6hnSwFpq1Eu0ynr/CDEw0rXo2B61qXrLNdHZmPKgb7fqS1a2JwF0rISo9q77jDI8VMEHoApn8qDoZA==} @@ -3241,6 +3934,17 @@ packages: charenc@0.0.2: resolution: {integrity: sha512-yrLQ/yVUFXkzg7EDQsPieE/53+0RlaWTs+wBrvW36cyilJ2SaDWfl4Yj7MtLTXleV9uEKefbAGUPv2/iWSooRA==} + cheerio-select@2.1.0: + resolution: {integrity: sha512-9v9kG0LvzrlcungtnJtpGNxY+fzECQKhK4EGJX2vByejiMX84MFNQw4UxPJl3bFbTMw+Dfs37XaIkCwTZfLh4g==} + + cheerio@1.2.0: + resolution: {integrity: sha512-WDrybc/gKFpTYQutKIK6UvfcuxijIZfMfXaYm8NMsPQxSYvf+13fXUJ4rztGGbJcBQ/GF55gvrZ0Bc0bj/mqvg==} + engines: {node: '>=20.18.1'} + + chokidar@3.6.0: + resolution: {integrity: sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==} + engines: {node: '>= 8.10.0'} + chokidar@4.0.3: resolution: {integrity: sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==} engines: {node: '>= 14.16.0'} @@ -3354,6 +4058,10 @@ packages: resolution: {integrity: sha512-taEtr3ozUmOB7it68Jll7s0Pwm+aoiHyXKrEC8SEodL4rNpdfDLqa7PfBlrgFoCNNdR8ImL+muti5IGvktJAAg==} engines: {node: '>= 6'} + comment-parser@1.4.5: + resolution: {integrity: sha512-aRDkn3uyIlCFfk5NUA+VdwMmMsh8JGhc4hapfV4yxymHGQ3BVskMQfoXGpCo5IoBuQ9tS5iiVKhCpTcB4pW4qw==} + engines: {node: '>= 12.0.0'} + commondir@1.0.1: resolution: {integrity: sha512-W9pAhw0ja1Edb5GVdIF1mjZw/ASI0AlShXM83UUGe2DVr5TdAPEA1OA8m/g8zWp9x6On7gqufY+FatDbC3MDQg==} @@ -3378,6 +4086,10 @@ packages: resolution: {integrity: sha512-ZqRXc+tZukToSNmh5C2iWMSoV3X1YUcPbqEM4DkEG5tNQXrQUZCNVGGv3IuicnkMtPfGf3Xtp8WCXs295iQ1pQ==} engines: {node: '>= 0.10.0'} + consola@3.4.2: + resolution: {integrity: sha512-5IKcdX0nnYavi6G7TtOhwkYzyjfJlatbjMjuLSfE2kYT5pMDOilZ4OvMhi637CcDICTmz3wARPoyhqyX1Y+XvA==} + engines: {node: ^14.18.0 || >=16.10.0} + content-disposition@0.5.4: resolution: {integrity: sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==} engines: {node: '>= 0.6'} @@ -3389,6 +4101,9 @@ packages: convert-source-map@2.0.0: resolution: {integrity: sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==} + cookie-es@2.0.0: + resolution: {integrity: sha512-RAj4E421UYRgqokKUmotqAwuplYw15qtdXfY+hGzgCJ/MBjCVZcSoHK/kH9kocfjRjcDME7IiDWR/1WX1TM2Pg==} + cookie-signature@1.0.7: resolution: {integrity: sha512-NXdYc3dLr47pBkpUCHtKSwIOQXLVn8dZEuywboCOJY/osA0wFSLlSawr3KN8qXJEyX66FcONTH8EIlVuK0yyFA==} @@ -3420,6 +4135,14 @@ packages: resolution: {integrity: sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==} engines: {node: '>= 8'} + crossws@0.4.4: + resolution: {integrity: sha512-w6c4OdpRNnudVmcgr7brb/+/HmYjMQvYToO/oTrprTwxRUiom3LYWU1PMWuD006okbUWpII1Ea9/+kwpUfmyRg==} + peerDependencies: + srvx: '>=0.7.1' + peerDependenciesMeta: + srvx: + optional: true + crypt@0.0.2: resolution: {integrity: sha512-mCxBlsHFYh9C+HVpiEacem8FEBnMXgU9gy4zmNC+SXAZNB/1idgp/aulFJ4FgCi7GPEVbfyng092GqL2k2rmow==} @@ -3473,6 +4196,32 @@ packages: dateformat@4.6.3: resolution: {integrity: sha512-2P0p0pFGzHS5EMnhdxQi7aJN+iMheud0UhG4dlE1DLAlvL8JHjJJTX/CSm4JXwV0Ka5nGk3zC5mcb5bUQUxxMA==} + dayjs@1.11.19: + resolution: {integrity: sha512-t5EcLVS6QPBNqM2z8fakk/NKel+Xzshgt8FFKAn+qwlD1pzZWxh0nVCrvFK7ZDb6XucZeF9z8C7CBWTRIVApAw==} + + db0@0.3.4: + resolution: {integrity: sha512-RiXXi4WaNzPTHEOu8UPQKMooIbqOEyqA1t7Z6MsdxSCeb8iUC9ko3LcmsLmeUt2SM5bctfArZKkRQggKZz7JNw==} + peerDependencies: + '@electric-sql/pglite': '*' + '@libsql/client': '*' + better-sqlite3: '*' + drizzle-orm: '*' + mysql2: '*' + sqlite3: '*' + peerDependenciesMeta: + '@electric-sql/pglite': + optional: true + '@libsql/client': + optional: true + better-sqlite3: + optional: true + drizzle-orm: + optional: true + mysql2: + optional: true + sqlite3: + optional: true + debug@2.6.9: resolution: {integrity: sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==} peerDependencies: @@ -3577,6 +4326,10 @@ packages: resolution: {integrity: sha512-PJWHUb1RFevKCwaFA9RlG5tCd+FO5iRh9A8HEtkmBH2Li03iJriB6m6JIN4rGz3K3JLawI7/veA1xzRKP6ISBw==} engines: {node: '>=0.3.1'} + diff@8.0.3: + resolution: {integrity: sha512-qejHi7bcSD4hQAZE0tNAawRK1ZtafHDmMTMkrrIGgSLl7hTnQHmKCeB45xAcbfTqK2zowkM3j3bHt/4b/ARbYQ==} + engines: {node: '>=0.3.1'} + dir-glob@3.0.1: resolution: {integrity: sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==} engines: {node: '>=8'} @@ -3664,6 +4417,9 @@ packages: resolution: {integrity: sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==} engines: {node: '>= 0.8'} + encoding-sniffer@0.2.1: + resolution: {integrity: sha512-5gvq20T6vfpekVtqrYQsSCFZ1wEg5+wW0/QaZMWkFr6BqD3NfKs0rLCx4rrVlSWJeZb5NBJgVLswK/w2MWU+Gw==} + end-of-stream@1.4.5: resolution: {integrity: sha512-ooEGc6HP26xXq/N+GCGOT0JKCLDGrq2bQUZrQ7gyrJiZANJ/8YDTxTpQBXGMn+WbIQXNVpyWymm7KYVICQnyOg==} @@ -3675,8 +4431,16 @@ packages: resolution: {integrity: sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==} engines: {node: '>=0.12'} - env-paths@2.2.0: - resolution: {integrity: sha512-6u0VYSCo/OW6IoD5WCLLy9JUGARbamfSavcNXry/eu8aHVFei6CD3Sw+VGX5alea1i9pgPHW0mbu6Xj0uBh7gA==} + entities@6.0.1: + resolution: {integrity: sha512-aN97NXWF6AWBTahfVOIrB/NShkzi5H7F9r1s9mD3cDj4Ko5f2qhhVoYMibXF7GlLveb/D2ioWay8lxI97Ven3g==} + engines: {node: '>=0.12'} + + entities@7.0.1: + resolution: {integrity: sha512-TWrgLOFUQTH994YUyl1yT4uyavY5nNB5muff+RtWaqNVCAK408b5ZnnbNAUEWLTCpum9w6arT70i1XdQ4UeOPA==} + engines: {node: '>=0.12'} + + env-paths@2.2.0: + resolution: {integrity: sha512-6u0VYSCo/OW6IoD5WCLLy9JUGARbamfSavcNXry/eu8aHVFei6CD3Sw+VGX5alea1i9pgPHW0mbu6Xj0uBh7gA==} engines: {node: '>=6'} env-string@1.0.1: @@ -3772,6 +4536,15 @@ packages: peerDependencies: eslint: '>=7.0.0' + eslint-import-context@0.1.9: + resolution: {integrity: sha512-K9Hb+yRaGAGUbwjhFNHvSmmkZs9+zbuoe3kFQ4V1wYjrepUFYM2dZAfNtjbbj3qsPfUfsA68Bx/ICWQMi+C8Eg==} + engines: {node: ^12.20.0 || ^14.18.0 || >=16.0.0} + peerDependencies: + unrs-resolver: ^1.0.0 + peerDependenciesMeta: + unrs-resolver: + optional: true + eslint-import-resolver-node@0.3.9: resolution: {integrity: sha512-WFj2isz22JahUv+B788TlO3N6zL3nNJGU8CcZbPZvVEkBPaJdCV4vy5wyghty5ROFbCRnm132v8BScu5/1BQ8g==} @@ -3815,6 +4588,19 @@ packages: peerDependencies: eslint: '>=8.10' + eslint-plugin-import-x@4.16.1: + resolution: {integrity: sha512-vPZZsiOKaBAIATpFE2uMI4w5IRwdv/FpQ+qZZMR4E+PeOcM4OeoEbqxRMnywdxP19TyB/3h6QBB0EWon7letSQ==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + '@typescript-eslint/utils': ^8.0.0 + eslint: ^8.57.0 || ^9.0.0 + eslint-import-resolver-node: '*' + peerDependenciesMeta: + '@typescript-eslint/utils': + optional: true + eslint-import-resolver-node: + optional: true + eslint-plugin-import@2.32.0: resolution: {integrity: sha512-whOE1HFo/qJDyX4SnXzP4N6zOWn79WhnCUY/iDR0mPfQZO8wcYE4JClzI2oZrhBnnMUCBCHZhO6VQyoBU95mZA==} engines: {node: '>=4'} @@ -4464,6 +5250,11 @@ packages: golden-fleece@1.0.9: resolution: {integrity: sha512-YSwLaGMOgSBx9roJlNLL12c+FRiw7VECphinc6mGucphc/ZxTHgdEz6gmJqH6NOzYEd/yr64hwjom5pZ+tJVpg==} + goober@2.1.18: + resolution: {integrity: sha512-2vFqsaDVIT9Gz7N6kAL++pLpp41l3PfDuusHcjnGLfR6+huZkl6ziX+zgVC3ZxpqWhzH6pyDdGrCeDhMIvwaxw==} + peerDependencies: + csstype: ^3.0.10 + gopd@1.2.0: resolution: {integrity: sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==} engines: {node: '>= 0.4'} @@ -4485,6 +5276,16 @@ packages: resolution: {integrity: sha512-59LZHPdGZVh695Ud9lRzPBVTtlX9ZCV150Er2W43ro37wVof0ctenSaskPPjN7lVTIN8mSZt8PHUNKZuNQUuxw==} engines: {node: ^12.22.0 || ^14.16.0 || ^16.0.0 || >=17.0.0} + h3@2.0.1-rc.16: + resolution: {integrity: sha512-h+pjvyujdo9way8qj6FUbhaQcHlR8FEq65EhTX9ViT5pK8aLj68uFl4hBkF+hsTJAH+H1END2Yv6hTIsabGfag==} + engines: {node: '>=20.11.1'} + hasBin: true + peerDependencies: + crossws: ^0.4.1 + peerDependenciesMeta: + crossws: + optional: true + has-bigints@1.1.0: resolution: {integrity: sha512-R3pbpkcIqv2Pm3dUwgjclDRVmWpTJW2DcMzcIhEXEx1oh/CEMObMm3KLmRJOdvhM7o4uQBnwr8pzRK2sJWIqfg==} engines: {node: '>= 0.4'} @@ -4563,6 +5364,9 @@ packages: resolution: {integrity: sha512-puUZAUKT5m8Zzvs72XWy3HtvVbTWljRE66cP60bxJzAqf2DgICo7lYTY2IHUmLnNpjYvw5bvmoHvPc0QO2a62w==} engines: {node: ^16.14.0 || >=18.0.0} + htmlparser2@10.1.0: + resolution: {integrity: sha512-VTZkM9GWRAtEpveh7MSF6SjjrpNVNNVJfFup7xTY3UpFtm67foy9HDVXneLtFVt4pMz5kZtgNcvCniNFb1hlEQ==} + http-call@5.3.0: resolution: {integrity: sha512-ahwimsC23ICE4kPl9xTBjKB4inbRaeLyZeRunC/1Jy/Z6X8tv22MEAjK+KBOMSVLaqXPTTmd8638waVIKLGx2w==} engines: {node: '>=8.0.0'} @@ -4594,6 +5398,10 @@ packages: resolution: {integrity: sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==} engines: {node: '>=0.10.0'} + iconv-lite@0.6.3: + resolution: {integrity: sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==} + engines: {node: '>=0.10.0'} + idb@8.0.3: resolution: {integrity: sha512-LtwtVyVYO5BqRvcsKuB2iUMnHwPVByPCXFXOpuU96IZPPoPN6xjOGxZQ74pgSVVLQWtUOYgyeL4GE98BY5D3wg==} @@ -4681,6 +5489,10 @@ packages: resolution: {integrity: sha512-n4ZT37wG78iz03xPRKJrHTdZbe3IicyucEtdRsV5yglwc3GyUfbAfpSeD0FJ41NbUNSt5wbhqfp1fS+BgnvDFQ==} engines: {node: '>= 0.4'} + is-binary-path@2.1.0: + resolution: {integrity: sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==} + engines: {node: '>=8'} + is-boolean-object@1.2.2: resolution: {integrity: sha512-wa56o2/ElJMYqjCjGkXri7it5FbebW5usLw/nPmCMs5DeZ7eziSYZhSmPRn0txqeW4LnAmQQU7FgqLpsEFKM4A==} engines: {node: '>= 0.4'} @@ -4990,6 +5802,9 @@ packages: resolution: {integrity: sha512-EZgbsXMrGS+oK+Ta12mCjzBFse+SIewGdwrSTr5g+MSymnjpox2x05ceI20PQejJOFvOgzcXrfDk/SdY7dSCtw==} hasBin: true + launch-editor@2.13.1: + resolution: {integrity: sha512-lPSddlAAluRKJ7/cjRFoXUFzaX7q/YKI7yPHuEvSJVqoXvFnJov1/Ud87Aa4zULIbA9Nja4mSPK8l0z/7eV2wA==} + leven@3.1.0: resolution: {integrity: sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==} engines: {node: '>=6'} @@ -5133,6 +5948,11 @@ packages: peerDependencies: react: 19.2.4 + lucide-react@0.577.0: + resolution: {integrity: sha512-4LjoFv2eEPwYDPg/CUdBJQSDfPyzXCRrVW1X7jrx/trgxnxkHFjnVZINbzvzxjN70dxychOfg+FTYwBiS3pQ5A==} + peerDependencies: + react: 19.2.4 + magic-string@0.30.21: resolution: {integrity: sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==} @@ -5563,9 +6383,31 @@ packages: resolution: {integrity: sha512-8Ofs/AUQh8MaEcrlq5xOX0CQ9ypTF5dl78mjlMNfOK08fzpgTHQRQPBxcPlEtIw0yRpws+Zo/3r+5WRby7u3Gg==} engines: {node: '>= 0.6'} + nf3@0.3.11: + resolution: {integrity: sha512-ObKp/SA3f1g1f/OMeDlRWaZmqGgk7A0NnDIbeO7c/MV4r/quMlpP/BsqMGuTi3lUlXbC1On8YH7ICM2u2bIAOw==} + nice-try@1.0.5: resolution: {integrity: sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==} + nitro@3.0.1-alpha.2: + resolution: {integrity: sha512-YviDY5J/trS821qQ1fpJtpXWIdPYiOizC/meHavlm1Hfuhx//H+Egd1+4C5SegJRgtWMnRPW9n//6Woaw81cTQ==} + engines: {node: ^20.19.0 || >=22.12.0} + hasBin: true + peerDependencies: + rolldown: '>=1.0.0-beta.0' + rollup: ^4 + vite: ^7 || ^8 || >=8.0.0-0 + xml2js: ^0.6.2 + peerDependenciesMeta: + rolldown: + optional: true + rollup: + optional: true + vite: + optional: true + xml2js: + optional: true + node-exports-info@1.6.0: resolution: {integrity: sha512-pyFS63ptit/P5WqUkt+UUfe+4oevH+bFeIiPPdfb0pFeYEu/1ELnJu5l+5EcTKYL5M7zaAa7S8ddywgXypqKCw==} engines: {node: '>= 0.4'} @@ -5678,6 +6520,12 @@ packages: obug@2.1.1: resolution: {integrity: sha512-uTqF9MuPraAQ+IsnPf366RG4cP9RtUi7MLO1N3KEc+wb0a6yKpeL0lmk2IB1jY5KHPAlTc6T/JRdC/YqxHNwkQ==} + ofetch@2.0.0-alpha.3: + resolution: {integrity: sha512-zpYTCs2byOuft65vI3z43Dd6iSdFbOZZLb9/d21aCpx2rGastVU9dOCv0lu4ykc1Ur1anAYjDi3SUvR0vq50JA==} + + ohash@2.0.11: + resolution: {integrity: sha512-RdR9FQrFwNBNXAr4GixM8YaRZRJ5PUWbKYbE5eOsrwAjJW0q2REGcf79oYPsLyskQCZG1PLN+S/K1V00joZAoQ==} + on-finished@2.3.0: resolution: {integrity: sha512-ikqdkGAAyf/X/gPhXGvfgAytDZtDbr+bkNUJ0N9h5MI/dmdgCs3l6hoHrcUv41sRKew3jIwrp4qQDXiK99Utww==} engines: {node: '>= 0.8'} @@ -5725,6 +6573,14 @@ packages: resolution: {integrity: sha512-qFOyK5PjiWZd+QQIh+1jhdb9LpxTF0qs7Pm8o5QHYZ0M3vKqSqzsZaEB6oWlxZ+q2sJBMI/Ktgd2N5ZwQoRHfg==} engines: {node: '>= 0.4'} + oxc-minify@0.110.0: + resolution: {integrity: sha512-KWGTzPo83QmGrXC4ml83PM9HDwUPtZFfasiclUvTV4i3/0j7xRRqINVkrL77CbQnoWura3CMxkRofjQKVDuhBw==} + engines: {node: ^20.19.0 || >=22.12.0} + + oxc-transform@0.110.0: + resolution: {integrity: sha512-/fymQNzzUoKZweH0nC5yvbI2eR0yWYusT9TEKDYVgOgYrf9Qmdez9lUFyvxKR9ycx+PTHi/reIOzqf3wkShQsw==} + engines: {node: ^20.19.0 || >=22.12.0} + p-finally@1.0.0: resolution: {integrity: sha512-LICb2p9CB7FS+0eR1oqWnHhp0FljGLZCWBE9aix0Uye9W8LTQPwMTYVGWQWIw9RdQiDg4+epXQODwIYJtSJaow==} engines: {node: '>=4'} @@ -5775,6 +6631,15 @@ packages: resolution: {integrity: sha512-Nt/a5SfCLiTnQAjx3fHlqp8hRgTL3z7kTQZzvIMS9uCAepnCyjpdEc6M/sz69WqMBdaDBw9sF1F1UaHROYzGkQ==} engines: {node: '>=10'} + parse5-htmlparser2-tree-adapter@7.1.0: + resolution: {integrity: sha512-ruw5xyKs6lrpo9x9rCZqZZnIUntICjQAd0Wsmp396Ul9lN/h+ifgVV1x1gZHi8euej6wTfpqX8j+BFQxF0NS/g==} + + parse5-parser-stream@7.1.2: + resolution: {integrity: sha512-JyeQc9iwFLn5TbvvqACIF/VXG6abODeB3Fwmv/TGdLk2LfbWkaySGY72at4+Ty7EkPZj854u4CrICqNk2qIbow==} + + parse5@7.3.0: + resolution: {integrity: sha512-IInvU7fabl34qmi9gY8XOVxhYyMyuH2xUNpb2q8/Y+7552KlejkRvqvD19nMoUW/uQGGbqNpA6Tufu5FL5BZgw==} + parseurl@1.3.3: resolution: {integrity: sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==} engines: {node: '>= 0.8'} @@ -6151,6 +7016,10 @@ packages: resolution: {integrity: sha512-jCvmsr+1IUSMUyzOkRcvnVbX3ZYC6g9TDrDbFuFmRDq7PD4yaGbLKNQL6k2jnArV8hjYxh7hVhAZB6s9HDGpZA==} engines: {node: '>=0.10.0'} + react-refresh@0.18.0: + resolution: {integrity: sha512-QgT5//D3jfjJb6Gsjxv0Slpj23ip+HtOpnNgnb2S5zU3CB26G/IDPGoy4RJB42wzFE46DRsstbW6tKHoKbhAxw==} + engines: {node: '>=0.10.0'} + react-remove-scroll-bar@2.3.8: resolution: {integrity: sha512-9r+yi9+mgU33AKcj6IbT9oRCO78WriSj6t/cF8DWBZJ9aOGPOTEDvdUDz1FwKim7QXWwmHqtdHnRJfhAxEG46Q==} engines: {node: '>=10'} @@ -6221,10 +7090,18 @@ packages: resolution: {integrity: sha512-oIGGmcpTLwPga8Bn6/Z75SVaH1z5dUut2ibSyAMVhmUggWpmDn2dapB0n7f8nwaSiRtepAsfJyfXIO5DCVAODg==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + readdirp@3.6.0: + resolution: {integrity: sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==} + engines: {node: '>=8.10.0'} + readdirp@4.1.2: resolution: {integrity: sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg==} engines: {node: '>= 14.18.0'} + recast@0.23.11: + resolution: {integrity: sha512-YTUo+Flmw4ZXiWfQKGcwwc11KnoRAYgzAE2E7mXKCjSviTKShtxBsN6YUUBB2gtaBzKzeKunxhUwNHQuRryhWA==} + engines: {node: '>= 4'} + rechoir@0.6.2: resolution: {integrity: sha512-HFM8rkZ+i3zrV+4LQjwQ0W+ez98pApMGM3HUrN04j3CqzPOzl9nmP15Y8YXNm8QHGv/eacOVEjqhmWpkRV0NAw==} engines: {node: '>= 0.10'} @@ -6356,6 +7233,11 @@ packages: resolution: {integrity: sha512-l0OE8wL34P4nJH/H2ffoaniAokM2qSmrtXHmlpvYr5AVVX8msAyW0l8NVJFDxlSK4u3Uh/f41cQheDVdnYijwQ==} hasBin: true + rolldown@1.0.0-rc.8: + resolution: {integrity: sha512-RGOL7mz/aoQpy/y+/XS9iePBfeNRDUdozrhCEJxdpJyimW8v6yp4c30q6OviUU5AnUJVLRL9GP//HUs6N3ALrQ==} + engines: {node: ^20.19.0 || >=22.12.0} + hasBin: true + rollup-plugin-dts@6.3.0: resolution: {integrity: sha512-d0UrqxYd8KyZ6i3M2Nx7WOMy708qsV/7fTHMHxCMCBOAe3V/U7OMPu5GkX8hC+cmkHhzGnfeYongl1IgiooddA==} engines: {node: '>=16'} @@ -6384,6 +7266,9 @@ packages: engines: {node: '>=18.0.0', npm: '>=8.0.0'} hasBin: true + rou3@0.8.1: + resolution: {integrity: sha512-ePa+XGk00/3HuCqrEnK3LxJW7I0SdNg6EFzKUJG73hMAdDcOUC/i/aSz7LSDwLrGr33kal/rqOGydzwl6U7zBA==} + run-parallel@1.2.0: resolution: {integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==} @@ -6459,6 +7344,16 @@ packages: resolution: {integrity: sha512-ghgmKt5o4Tly5yEG/UJp8qTd0AN7Xalw4XBtDEKP655B699qMEtra1WlXeE6WIvdEG481JvRxULKsInq/iNysw==} engines: {node: '>=0.10.0'} + seroval-plugins@1.5.1: + resolution: {integrity: sha512-4FbuZ/TMl02sqv0RTFexu0SP6V+ywaIe5bAWCCEik0fk17BhALgwvUDVF7e3Uvf9pxmwCEJsRPmlkUE6HdzLAw==} + engines: {node: '>=10'} + peerDependencies: + seroval: ^1.0 + + seroval@1.5.1: + resolution: {integrity: sha512-OwrZRZAfhHww0WEnKHDY8OM0U/Qs8OTfIDWhUD4BLpNJUfXK4cGmjiagGze086m+mhI+V2nD0gfbHEnJjb9STA==} + engines: {node: '>=10'} + serve-static@1.16.3: resolution: {integrity: sha512-x0RTqQel6g5SY7Lg6ZreMmsOzncHFU7nhnRWkKgWuMTu5NN0DR5oruckMqRvacAN9d5w6ARnRBXl9xhDCgfMeA==} engines: {node: '>= 0.8.0'} @@ -6579,6 +7474,9 @@ packages: resolution: {integrity: sha512-h+z7HKHYXj6wJU+AnS/+IH8Uh9fdcX1Lrhg1/VMdf9PwoBQXFcXiAdsy2tSK0P6gKwJLXp02r90ahUCqHk9rrw==} engines: {node: '>=8.0.0'} + solid-js@1.9.11: + resolution: {integrity: sha512-WEJtcc5mkh/BnHA6Yrg4whlF8g6QwpmXXRg4P2ztPmcKeHHlH4+djYecBLhSpecZY2RRECXYUwIc/C2r3yzQ4Q==} + sort-object-keys@2.1.0: resolution: {integrity: sha512-SOiEnthkJKPv2L6ec6HMwhUcN0/lppkeYuN1x63PbyPRrgSPIuBJCiYxYyvWRTtjMlOi14vQUCGUJqS6PLVm8g==} @@ -6616,6 +7514,20 @@ packages: sprintf-js@1.0.3: resolution: {integrity: sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==} + srvx@0.10.1: + resolution: {integrity: sha512-A//xtfak4eESMWWydSRFUVvCTQbSwivnGCEf8YGPe2eHU0+Z6znfUTCPF0a7oV3sObSOcrXHlL6Bs9vVctfXdg==} + engines: {node: '>=20.16.0'} + hasBin: true + + srvx@0.11.9: + resolution: {integrity: sha512-97wWJS6F0KTKAhDlHVmBzMvlBOp5FiNp3XrLoodIgYJpXxgG5tE9rX4Pg7s46n2shI4wtEsMATTS1+rI3/ubzA==} + engines: {node: '>=20.16.0'} + hasBin: true + + stable-hash-x@0.2.0: + resolution: {integrity: sha512-o3yWv49B/o4QZk5ZcsALc6t0+eCelPc44zZsLtCQnZPDwFpDYSWcDnrv2TtMmMbQ7uKo3J0HTURCqckw23czNQ==} + engines: {node: '>=12.0.0'} + stable-hash@0.0.5: resolution: {integrity: sha512-+L3ccpzibovGXFK+Ap/f8LOS0ahMrHTf3xu7mMLSpEGU0EO9ucaysSylKo9eRDFNhWve/y275iPmIZ4z39a9iA==} @@ -6811,6 +7723,12 @@ packages: throat@5.0.0: resolution: {integrity: sha512-fcwX4mndzpLQKBS1DVYhGAcYaYt7vsHNIvQV+WXMvnow5cgjPphq5CaayLaGsjRdSCKZFNGt7/GYAuXaNOiYCA==} + tiny-invariant@1.3.3: + resolution: {integrity: sha512-+FbBPE1o9QAYvviau/qC5SE3caw21q3xkvWKBtja5vgqOWIHHJ3ioaq1VPfn/Szqctz2bU/oYeKd9/z5BL+PVg==} + + tiny-warning@1.0.3: + resolution: {integrity: sha512-lBN9zLN/oAf68o3zNXYrdCt1kP8WsiGW8Oo2ka41b2IM5JL/S1CTyX1rW0mb/zSuJun0ZUrDxx4sqvYS2FWzPA==} + tinybench@2.9.0: resolution: {integrity: sha512-0+DUvqWMValLmha6lr4kD8iAMK1HzV0/aKnCtWb9v9641TnP/MFb7Pc2bxoxQjTXAErryXVgUOfv2YqNllqGeg==} @@ -7008,6 +7926,9 @@ packages: resolution: {integrity: sha512-LbBDqdIC5s8iROCUjMbW1f5dJQTEFB1+KO9ogbvlb3nm9n4YHa5p4KTvFPWvh2Hs8gZMBuiB1/8+pdfe/tDPug==} hasBin: true + ufo@1.6.3: + resolution: {integrity: sha512-yDJTmhydvl5lJzBmy/hyOAA0d+aqCBuwl818haVdYCRrWV84o7YyeVm4QlVHStqNrrJSTb6jKuFAVqAFsr+K3Q==} + unbox-primitive@1.1.0: resolution: {integrity: sha512-nWJ91DjeOkej/TA8pXQ3myruKpKEYgqvpw9lz4OPHj/NWFNluYrjbz9j01CJ8yKQd2g4jFoOkINCTW2I5LEEyw==} engines: {node: '>= 0.4'} @@ -7015,6 +7936,13 @@ packages: undici-types@7.18.2: resolution: {integrity: sha512-AsuCzffGHJybSaRrmr5eHr81mwJU3kjw6M+uprWvCXiNeN9SOGwQ3Jn8jb8m3Z6izVgknn1R0FTCEAP2QrLY/w==} + undici@7.22.0: + resolution: {integrity: sha512-RqslV2Us5BrllB+JeiZnK4peryVTndy9Dnqq62S3yYRRTj0tFQCwEniUy2167skdGOy3vqRzEvl1Dm4sV2ReDg==} + engines: {node: '>=20.18.1'} + + unenv@2.0.0-rc.24: + resolution: {integrity: sha512-i7qRCmY42zmCwnYlh9H2SvLEypEFGye5iRmEMKjcGi7zk9UquigRjFtTLz0TYqr0ZGLZhaMHl/foy1bZR+Cwlw==} + unicode-canonical-property-names-ecmascript@2.0.1: resolution: {integrity: sha512-dA8WbNeb2a6oQzAQ55YlT5vQAWGV9WXOsi3SskE3bcCdM0P4SDd+24zS/OCacdRq5BkdsRj9q3Pg6YyQoxIGqg==} engines: {node: '>=4'} @@ -7076,9 +8004,87 @@ packages: resolution: {integrity: sha512-gwXJnPRewT4rT7sBi/IvxKTjsms7jX7QIDLOClApuZwR49SXbrB1z2NLUZ+vDHyqCj/n58OzRRqaW+B8OZi8vg==} engines: {node: '>=18.12.0'} + unplugin@2.3.11: + resolution: {integrity: sha512-5uKD0nqiYVzlmCRs01Fhs2BdkEgBS3SAVP6ndrBsuK42iC2+JHyxM05Rm9G8+5mkmRtzMZGY8Ct5+mliZxU/Ww==} + engines: {node: '>=18.12.0'} + unrs-resolver@1.11.1: resolution: {integrity: sha512-bSjt9pjaEBnNiGgc9rUiHGKv5l4/TGzDmYw3RhnkJGtLhbnnA/5qJj7x3dNDCRx/PJxu774LlH8lCOlB4hEfKg==} + unstorage@2.0.0-alpha.6: + resolution: {integrity: sha512-w5vLYCJtnSx3OBtDk7cG4c1p3dfAnHA4WSZq9Xsurjbl2wMj7zqfOIjaHQI1Bl7yKzUxXAi+kbMr8iO2RhJmBA==} + peerDependencies: + '@azure/app-configuration': ^1.11.0 + '@azure/cosmos': ^4.9.1 + '@azure/data-tables': ^13.3.2 + '@azure/identity': ^4.13.0 + '@azure/keyvault-secrets': ^4.10.0 + '@azure/storage-blob': ^12.31.0 + '@capacitor/preferences': ^6 || ^7 || ^8 + '@deno/kv': '>=0.13.0' + '@netlify/blobs': ^6.5.0 || ^7.0.0 || ^8.1.0 || ^9.0.0 || ^10.0.0 + '@planetscale/database': ^1.19.0 + '@upstash/redis': ^1.36.2 + '@vercel/blob': '>=0.27.3' + '@vercel/functions': ^2.2.12 || ^3.0.0 + '@vercel/kv': ^1.0.1 + aws4fetch: ^1.0.20 + chokidar: ^4 || ^5 + db0: '>=0.3.4' + idb-keyval: ^6.2.2 + ioredis: ^5.9.3 + lru-cache: ^11.2.6 + mongodb: ^6 || ^7 + ofetch: '*' + uploadthing: ^7.7.4 + peerDependenciesMeta: + '@azure/app-configuration': + optional: true + '@azure/cosmos': + optional: true + '@azure/data-tables': + optional: true + '@azure/identity': + optional: true + '@azure/keyvault-secrets': + optional: true + '@azure/storage-blob': + optional: true + '@capacitor/preferences': + optional: true + '@deno/kv': + optional: true + '@netlify/blobs': + optional: true + '@planetscale/database': + optional: true + '@upstash/redis': + optional: true + '@vercel/blob': + optional: true + '@vercel/functions': + optional: true + '@vercel/kv': + optional: true + aws4fetch: + optional: true + chokidar: + optional: true + db0: + optional: true + idb-keyval: + optional: true + ioredis: + optional: true + lru-cache: + optional: true + mongodb: + optional: true + ofetch: + optional: true + uploadthing: + optional: true + untildify@4.0.0: resolution: {integrity: sha512-KK8xQ1mkzZeg9inewmFVDNkg3l5LUhoq9kN6iWYB/CC9YMG8HA+c1Q8HwDe6dEX7kErrEVNVBO3fWsVq5iDgtw==} engines: {node: '>=8'} @@ -7222,6 +8228,14 @@ packages: yaml: optional: true + vitefu@1.1.2: + resolution: {integrity: sha512-zpKATdUbzbsycPFBN71nS2uzBUQiVnFoOrr2rvqv34S1lcAgMKKkjWleLGeiJlZ8lwCXvtWaRn7R3ZC16SYRuw==} + 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 + vitest@4.0.18: resolution: {integrity: sha512-hOQuK7h0FGKgBAas7v0mSAsnvrIgAvWmRFjmzpJ7SwFHH3g1k2u37JtYwOwmEKhK6ZO3v9ggDBBm0La1LCK4uQ==} engines: {node: ^20.0.0 || ^22.0.0 || >=24.0.0} @@ -7271,9 +8285,21 @@ packages: webidl-conversions@3.0.1: resolution: {integrity: sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==} + webpack-virtual-modules@0.6.2: + resolution: {integrity: sha512-66/V2i5hQanC51vBQKPH4aI8NMAcBW59FVBs+rC7eGHupMyfn34q7rZIE+ETlJ+XTevqfUhVVBgSUNSW2flEUQ==} + + whatwg-encoding@3.1.1: + resolution: {integrity: sha512-6qN4hJdMwfYBtE3YBTTHhoeuUrDBPZmbQaxWAqSALV/MeEnR5z1xd8UKud2RAkFoPkmB+hli1TZSnyi84xz1vQ==} + engines: {node: '>=18'} + deprecated: Use @exodus/bytes instead for a more spec-conformant and faster implementation + whatwg-fetch@3.6.20: resolution: {integrity: sha512-EqhiFU6daOA8kpjOWTL0olhVOF3i7OrFzSYiGsEMB8GcXS+RrzauAERX65xMeNWVqxA6HXH2m69Z9LaKKdisfg==} + whatwg-mimetype@4.0.0: + resolution: {integrity: sha512-QaKxh0eNIi2mE9p2vEdzfagOKHCcj1pJ56EEHGQOVxp8r9/iszLUUV7v89x9O1p/T+NlTM5W7jW6+cz4Fq1YVg==} + engines: {node: '>=18'} + whatwg-url-minimum@0.1.1: resolution: {integrity: sha512-u2FNVjFVFZhdjb502KzXy1gKn1mEisQRJssmSJT8CPhZdZa0AP6VCbWlXERKyGu0l09t0k50FiDiralpGhBxgA==} @@ -7374,6 +8400,10 @@ packages: resolution: {integrity: sha512-eLTh0kA8uHceqesPqSE+VvO1CDDJWMwlQfB6LuN6T8w6MaDJ8Txm8P7s5cHD0miF0V+GGTZrDQfxPZQVsur33w==} engines: {node: '>=4.0.0'} + xmlbuilder2@4.0.3: + resolution: {integrity: sha512-bx8Q1STctnNaaDymWnkfQLKofs0mGNN7rLLapJlGuV3VlvegD7Ls4ggMjE3aUSWItCCzU0PEv45lI87iSigiCA==} + engines: {node: '>=20.0'} + xmlbuilder@11.0.1: resolution: {integrity: sha512-fDlsI/kFEx7gLvbecc0/ohLG50fugQp8ryHzMTuW9vSa1GJ0XYWKnhsUx7oie3G98+r56aTQIUB4kht42R3JvA==} engines: {node: '>=4.0'} @@ -7462,6 +8492,12 @@ snapshots: '@babel/highlight': 7.25.9 chalk: 2.4.2 + '@babel/code-frame@7.27.1': + dependencies: + '@babel/helper-validator-identifier': 7.28.5 + js-tokens: 4.0.0 + picocolors: 1.1.1 + '@babel/code-frame@7.29.0': dependencies: '@babel/helper-validator-identifier': 7.28.5 @@ -8112,7 +9148,7 @@ snapshots: '@babel/helper-string-parser': 7.27.1 '@babel/helper-validator-identifier': 7.28.5 - '@blgc/config@0.0.40(eslint@9.39.3(jiti@2.6.1))(postcss@8.5.6)(prettier@3.8.1)(turbo@2.8.11)(typescript@5.9.3)(vite@7.3.1(@types/node@25.3.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2))': + '@blgc/config@0.0.40(eslint@9.39.3(jiti@2.6.1))(postcss@8.5.6)(prettier@3.8.1)(turbo@2.8.11)(typescript@5.9.3)(vite@7.3.1(@types/node@25.4.0)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2))': dependencies: '@ianvs/prettier-plugin-sort-imports': 4.7.1(prettier@3.8.1) '@next/eslint-plugin-next': 16.1.6 @@ -8127,7 +9163,7 @@ snapshots: prettier-plugin-packagejson: 2.5.22(prettier@3.8.1) prettier-plugin-tailwindcss: 0.7.2(@ianvs/prettier-plugin-sort-imports@4.7.1(prettier@3.8.1))(prettier-plugin-css-order@2.2.0(postcss@8.5.6)(prettier@3.8.1))(prettier@3.8.1) typescript-eslint: 8.56.1(eslint@9.39.3(jiti@2.6.1))(typescript@5.9.3) - vite-tsconfig-paths: 6.1.1(typescript@5.9.3)(vite@7.3.1(@types/node@25.3.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)) + vite-tsconfig-paths: 6.1.1(typescript@5.9.3)(vite@7.3.1(@types/node@25.4.0)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)) transitivePeerDependencies: - '@prettier/plugin-hermes' - '@prettier/plugin-oxc' @@ -8731,18 +9767,18 @@ snapshots: base64-js: 1.5.1 xmlbuilder: 15.1.1 - '@expo/plugin-help@5.1.23(@types/node@25.3.2)(typescript@5.9.3)': + '@expo/plugin-help@5.1.23(@types/node@25.4.0)(typescript@5.9.3)': dependencies: - '@oclif/core': 2.16.0(@types/node@25.3.2)(typescript@5.9.3) + '@oclif/core': 2.16.0(@types/node@25.4.0)(typescript@5.9.3) transitivePeerDependencies: - '@swc/core' - '@swc/wasm' - '@types/node' - typescript - '@expo/plugin-warn-if-update-available@2.5.1(@types/node@25.3.2)(typescript@5.9.3)': + '@expo/plugin-warn-if-update-available@2.5.1(@types/node@25.4.0)(typescript@5.9.3)': dependencies: - '@oclif/core': 2.16.0(@types/node@25.3.2)(typescript@5.9.3) + '@oclif/core': 2.16.0(@types/node@25.4.0)(typescript@5.9.3) chalk: 4.1.2 debug: 4.4.3(supports-color@8.1.1) ejs: 3.1.10 @@ -9052,14 +10088,14 @@ snapshots: dependencies: '@jest/fake-timers': 29.7.0 '@jest/types': 29.6.3 - '@types/node': 25.3.2 + '@types/node': 25.4.0 jest-mock: 29.7.0 '@jest/fake-timers@29.7.0': dependencies: '@jest/types': 29.6.3 '@sinonjs/fake-timers': 10.3.0 - '@types/node': 25.3.2 + '@types/node': 25.4.0 jest-message-util: 29.7.0 jest-mock: 29.7.0 jest-util: 29.7.0 @@ -9093,7 +10129,7 @@ snapshots: '@jest/schemas': 29.6.3 '@types/istanbul-lib-coverage': 2.0.6 '@types/istanbul-reports': 3.0.4 - '@types/node': 25.3.2 + '@types/node': 25.4.0 '@types/yargs': 17.0.35 chalk: 4.1.2 @@ -9175,6 +10211,13 @@ snapshots: '@tybys/wasm-util': 0.10.1 optional: true + '@napi-rs/wasm-runtime@1.1.1': + dependencies: + '@emnapi/core': 1.8.1 + '@emnapi/runtime': 1.8.1 + '@tybys/wasm-util': 0.10.1 + optional: true + '@next/eslint-plugin-next@16.1.6': dependencies: fast-glob: 3.3.1 @@ -9224,7 +10267,7 @@ snapshots: widest-line: 3.1.0 wrap-ansi: 7.0.0 - '@oclif/core@2.16.0(@types/node@25.3.2)(typescript@5.9.3)': + '@oclif/core@2.16.0(@types/node@25.4.0)(typescript@5.9.3)': dependencies: '@types/cli-progress': 3.11.6 ansi-escapes: 4.3.2 @@ -9249,7 +10292,7 @@ snapshots: strip-ansi: 6.0.1 supports-color: 8.1.1 supports-hyperlinks: 2.3.0 - ts-node: 10.9.2(@types/node@25.3.2)(typescript@5.9.3) + ts-node: 10.9.2(@types/node@25.4.0)(typescript@5.9.3) tslib: 2.8.1 widest-line: 3.1.0 wordwrap: 1.0.0 @@ -9262,9 +10305,9 @@ snapshots: '@oclif/linewrap@1.0.0': {} - '@oclif/plugin-autocomplete@2.3.10(@types/node@25.3.2)(typescript@5.9.3)': + '@oclif/plugin-autocomplete@2.3.10(@types/node@25.4.0)(typescript@5.9.3)': dependencies: - '@oclif/core': 2.16.0(@types/node@25.3.2)(typescript@5.9.3) + '@oclif/core': 2.16.0(@types/node@25.4.0)(typescript@5.9.3) chalk: 4.1.2 debug: 4.4.3(supports-color@8.1.1) transitivePeerDependencies: @@ -9276,6 +10319,150 @@ snapshots: '@oclif/screen@3.0.8': {} + '@oozcitak/dom@2.0.2': + dependencies: + '@oozcitak/infra': 2.0.2 + '@oozcitak/url': 3.0.0 + '@oozcitak/util': 10.0.0 + + '@oozcitak/infra@2.0.2': + dependencies: + '@oozcitak/util': 10.0.0 + + '@oozcitak/url@3.0.0': + dependencies: + '@oozcitak/infra': 2.0.2 + '@oozcitak/util': 10.0.0 + + '@oozcitak/util@10.0.0': {} + + '@oxc-minify/binding-android-arm-eabi@0.110.0': + optional: true + + '@oxc-minify/binding-android-arm64@0.110.0': + optional: true + + '@oxc-minify/binding-darwin-arm64@0.110.0': + optional: true + + '@oxc-minify/binding-darwin-x64@0.110.0': + optional: true + + '@oxc-minify/binding-freebsd-x64@0.110.0': + optional: true + + '@oxc-minify/binding-linux-arm-gnueabihf@0.110.0': + optional: true + + '@oxc-minify/binding-linux-arm-musleabihf@0.110.0': + optional: true + + '@oxc-minify/binding-linux-arm64-gnu@0.110.0': + optional: true + + '@oxc-minify/binding-linux-arm64-musl@0.110.0': + optional: true + + '@oxc-minify/binding-linux-ppc64-gnu@0.110.0': + optional: true + + '@oxc-minify/binding-linux-riscv64-gnu@0.110.0': + optional: true + + '@oxc-minify/binding-linux-riscv64-musl@0.110.0': + optional: true + + '@oxc-minify/binding-linux-s390x-gnu@0.110.0': + optional: true + + '@oxc-minify/binding-linux-x64-gnu@0.110.0': + optional: true + + '@oxc-minify/binding-linux-x64-musl@0.110.0': + optional: true + + '@oxc-minify/binding-openharmony-arm64@0.110.0': + optional: true + + '@oxc-minify/binding-wasm32-wasi@0.110.0': + dependencies: + '@napi-rs/wasm-runtime': 1.1.1 + optional: true + + '@oxc-minify/binding-win32-arm64-msvc@0.110.0': + optional: true + + '@oxc-minify/binding-win32-ia32-msvc@0.110.0': + optional: true + + '@oxc-minify/binding-win32-x64-msvc@0.110.0': + optional: true + + '@oxc-project/types@0.115.0': + optional: true + + '@oxc-transform/binding-android-arm-eabi@0.110.0': + optional: true + + '@oxc-transform/binding-android-arm64@0.110.0': + optional: true + + '@oxc-transform/binding-darwin-arm64@0.110.0': + optional: true + + '@oxc-transform/binding-darwin-x64@0.110.0': + optional: true + + '@oxc-transform/binding-freebsd-x64@0.110.0': + optional: true + + '@oxc-transform/binding-linux-arm-gnueabihf@0.110.0': + optional: true + + '@oxc-transform/binding-linux-arm-musleabihf@0.110.0': + optional: true + + '@oxc-transform/binding-linux-arm64-gnu@0.110.0': + optional: true + + '@oxc-transform/binding-linux-arm64-musl@0.110.0': + optional: true + + '@oxc-transform/binding-linux-ppc64-gnu@0.110.0': + optional: true + + '@oxc-transform/binding-linux-riscv64-gnu@0.110.0': + optional: true + + '@oxc-transform/binding-linux-riscv64-musl@0.110.0': + optional: true + + '@oxc-transform/binding-linux-s390x-gnu@0.110.0': + optional: true + + '@oxc-transform/binding-linux-x64-gnu@0.110.0': + optional: true + + '@oxc-transform/binding-linux-x64-musl@0.110.0': + optional: true + + '@oxc-transform/binding-openharmony-arm64@0.110.0': + optional: true + + '@oxc-transform/binding-wasm32-wasi@0.110.0': + dependencies: + '@napi-rs/wasm-runtime': 1.1.1 + optional: true + + '@oxc-transform/binding-win32-arm64-msvc@0.110.0': + optional: true + + '@oxc-transform/binding-win32-ia32-msvc@0.110.0': + optional: true + + '@oxc-transform/binding-win32-x64-msvc@0.110.0': + optional: true + '@pkgjs/parseargs@0.11.0': optional: true @@ -9728,6 +10915,56 @@ snapshots: - tsx - yaml + '@react-router/dev@7.13.1(@react-router/serve@7.13.1(react-router@7.13.1(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(typescript@5.9.3))(@types/node@25.4.0)(jiti@2.6.1)(lightningcss@1.30.1)(react-router@7.13.1(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(terser@5.46.0)(tsx@4.21.0)(typescript@5.9.3)(vite@7.3.1(@types/node@25.4.0)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2))(yaml@2.8.2)': + dependencies: + '@babel/core': 7.29.0 + '@babel/generator': 7.29.1 + '@babel/parser': 7.29.0 + '@babel/plugin-syntax-jsx': 7.28.6(@babel/core@7.29.0) + '@babel/preset-typescript': 7.28.5(@babel/core@7.29.0) + '@babel/traverse': 7.29.0 + '@babel/types': 7.29.0 + '@react-router/node': 7.13.1(react-router@7.13.1(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(typescript@5.9.3) + '@remix-run/node-fetch-server': 0.13.0 + arg: 5.0.2 + babel-dead-code-elimination: 1.0.12 + chokidar: 4.0.3 + dedent: 1.7.1 + es-module-lexer: 1.7.0 + exit-hook: 2.2.1 + isbot: 5.1.35 + jsesc: 3.0.2 + lodash: 4.17.23 + p-map: 7.0.4 + pathe: 1.1.2 + picocolors: 1.1.1 + pkg-types: 2.3.0 + prettier: 3.8.1 + react-refresh: 0.14.2 + react-router: 7.13.1(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + semver: 7.7.4 + tinyglobby: 0.2.15 + valibot: 1.2.0(typescript@5.9.3) + vite: 7.3.1(@types/node@25.4.0)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2) + vite-node: 3.2.4(@types/node@25.4.0)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2) + optionalDependencies: + '@react-router/serve': 7.13.1(react-router@7.13.1(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(typescript@5.9.3) + typescript: 5.9.3 + transitivePeerDependencies: + - '@types/node' + - babel-plugin-macros + - jiti + - less + - lightningcss + - sass + - sass-embedded + - stylus + - sugarss + - supports-color + - terser + - tsx + - yaml + '@react-router/express@7.13.1(express@4.22.1)(react-router@7.13.1(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(typescript@5.9.3)': dependencies: '@react-router/node': 7.13.1(react-router@7.13.1(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(typescript@5.9.3) @@ -9743,6 +10980,13 @@ snapshots: optionalDependencies: typescript: 5.9.3 + '@react-router/fs-routes@7.13.1(@react-router/dev@7.13.1(@react-router/serve@7.13.1(react-router@7.13.1(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(typescript@5.9.3))(@types/node@25.4.0)(jiti@2.6.1)(lightningcss@1.30.1)(react-router@7.13.1(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(terser@5.46.0)(tsx@4.21.0)(typescript@5.9.3)(vite@7.3.1(@types/node@25.4.0)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2))(yaml@2.8.2))(typescript@5.9.3)': + dependencies: + '@react-router/dev': 7.13.1(@react-router/serve@7.13.1(react-router@7.13.1(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(typescript@5.9.3))(@types/node@25.4.0)(jiti@2.6.1)(lightningcss@1.30.1)(react-router@7.13.1(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(terser@5.46.0)(tsx@4.21.0)(typescript@5.9.3)(vite@7.3.1(@types/node@25.4.0)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2))(yaml@2.8.2) + minimatch: 9.0.9 + optionalDependencies: + typescript: 5.9.3 + '@react-router/node@7.13.1(react-router@7.13.1(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(typescript@5.9.3)': dependencies: '@mjackson/node-fetch-server': 0.2.0 @@ -9767,6 +11011,60 @@ snapshots: '@remix-run/node-fetch-server@0.13.0': {} + '@rolldown/binding-android-arm64@1.0.0-rc.8': + optional: true + + '@rolldown/binding-darwin-arm64@1.0.0-rc.8': + optional: true + + '@rolldown/binding-darwin-x64@1.0.0-rc.8': + optional: true + + '@rolldown/binding-freebsd-x64@1.0.0-rc.8': + optional: true + + '@rolldown/binding-linux-arm-gnueabihf@1.0.0-rc.8': + optional: true + + '@rolldown/binding-linux-arm64-gnu@1.0.0-rc.8': + optional: true + + '@rolldown/binding-linux-arm64-musl@1.0.0-rc.8': + optional: true + + '@rolldown/binding-linux-ppc64-gnu@1.0.0-rc.8': + optional: true + + '@rolldown/binding-linux-s390x-gnu@1.0.0-rc.8': + optional: true + + '@rolldown/binding-linux-x64-gnu@1.0.0-rc.8': + optional: true + + '@rolldown/binding-linux-x64-musl@1.0.0-rc.8': + optional: true + + '@rolldown/binding-openharmony-arm64@1.0.0-rc.8': + optional: true + + '@rolldown/binding-wasm32-wasi@1.0.0-rc.8': + dependencies: + '@napi-rs/wasm-runtime': 1.1.1 + optional: true + + '@rolldown/binding-win32-arm64-msvc@1.0.0-rc.8': + optional: true + + '@rolldown/binding-win32-x64-msvc@1.0.0-rc.8': + optional: true + + '@rolldown/pluginutils@1.0.0-beta.40': {} + + '@rolldown/pluginutils@1.0.0-rc.3': {} + + '@rolldown/pluginutils@1.0.0-rc.8': + optional: true + '@rollup/plugin-commonjs@29.0.0(rollup@4.59.0)': dependencies: '@rollup/pluginutils': 5.3.0(rollup@4.59.0) @@ -9895,6 +11193,40 @@ snapshots: dependencies: '@sinonjs/commons': 3.0.1 + '@solid-primitives/event-listener@2.4.5(solid-js@1.9.11)': + dependencies: + '@solid-primitives/utils': 6.4.0(solid-js@1.9.11) + solid-js: 1.9.11 + + '@solid-primitives/keyboard@1.3.5(solid-js@1.9.11)': + dependencies: + '@solid-primitives/event-listener': 2.4.5(solid-js@1.9.11) + '@solid-primitives/rootless': 1.5.3(solid-js@1.9.11) + '@solid-primitives/utils': 6.4.0(solid-js@1.9.11) + solid-js: 1.9.11 + + '@solid-primitives/resize-observer@2.1.5(solid-js@1.9.11)': + dependencies: + '@solid-primitives/event-listener': 2.4.5(solid-js@1.9.11) + '@solid-primitives/rootless': 1.5.3(solid-js@1.9.11) + '@solid-primitives/static-store': 0.1.3(solid-js@1.9.11) + '@solid-primitives/utils': 6.4.0(solid-js@1.9.11) + solid-js: 1.9.11 + + '@solid-primitives/rootless@1.5.3(solid-js@1.9.11)': + dependencies: + '@solid-primitives/utils': 6.4.0(solid-js@1.9.11) + solid-js: 1.9.11 + + '@solid-primitives/static-store@0.1.3(solid-js@1.9.11)': + dependencies: + '@solid-primitives/utils': 6.4.0(solid-js@1.9.11) + solid-js: 1.9.11 + + '@solid-primitives/utils@6.4.0(solid-js@1.9.11)': + dependencies: + solid-js: 1.9.11 + '@standard-schema/spec@1.1.0': {} '@tailwindcss/node@4.2.1': @@ -9978,6 +11310,285 @@ snapshots: tailwindcss: 4.2.1 vite: 7.3.1(@types/node@25.3.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2) + '@tailwindcss/vite@4.2.1(vite@7.3.1(@types/node@25.4.0)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2))': + dependencies: + '@tailwindcss/node': 4.2.1 + '@tailwindcss/oxide': 4.2.1 + tailwindcss: 4.2.1 + vite: 7.3.1(@types/node@25.4.0)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2) + + '@tanstack/devtools-client@0.0.6': + dependencies: + '@tanstack/devtools-event-client': 0.4.1 + + '@tanstack/devtools-event-bus@0.4.1': + dependencies: + ws: 8.19.0 + transitivePeerDependencies: + - bufferutil + - utf-8-validate + + '@tanstack/devtools-event-client@0.4.1': {} + + '@tanstack/devtools-ui@0.5.0(csstype@3.2.3)(solid-js@1.9.11)': + dependencies: + clsx: 2.1.1 + dayjs: 1.11.19 + goober: 2.1.18(csstype@3.2.3) + solid-js: 1.9.11 + transitivePeerDependencies: + - csstype + + '@tanstack/devtools-vite@0.5.3(vite@7.3.1(@types/node@25.4.0)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2))': + dependencies: + '@babel/core': 7.29.0 + '@babel/generator': 7.29.1 + '@babel/parser': 7.29.0 + '@babel/traverse': 7.29.0 + '@babel/types': 7.29.0 + '@tanstack/devtools-client': 0.0.6 + '@tanstack/devtools-event-bus': 0.4.1 + chalk: 5.6.2 + launch-editor: 2.13.1 + picomatch: 4.0.3 + vite: 7.3.1(@types/node@25.4.0)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2) + transitivePeerDependencies: + - bufferutil + - supports-color + - utf-8-validate + + '@tanstack/devtools@0.10.11(csstype@3.2.3)(solid-js@1.9.11)': + dependencies: + '@solid-primitives/event-listener': 2.4.5(solid-js@1.9.11) + '@solid-primitives/keyboard': 1.3.5(solid-js@1.9.11) + '@solid-primitives/resize-observer': 2.1.5(solid-js@1.9.11) + '@tanstack/devtools-client': 0.0.6 + '@tanstack/devtools-event-bus': 0.4.1 + '@tanstack/devtools-ui': 0.5.0(csstype@3.2.3)(solid-js@1.9.11) + clsx: 2.1.1 + goober: 2.1.18(csstype@3.2.3) + solid-js: 1.9.11 + transitivePeerDependencies: + - bufferutil + - csstype + - utf-8-validate + + '@tanstack/history@1.161.4': {} + + '@tanstack/react-devtools@0.9.10(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(csstype@3.2.3)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(solid-js@1.9.11)': + dependencies: + '@tanstack/devtools': 0.10.11(csstype@3.2.3)(solid-js@1.9.11) + '@types/react': 19.2.14 + '@types/react-dom': 19.2.3(@types/react@19.2.14) + react: 19.2.4 + react-dom: 19.2.4(react@19.2.4) + transitivePeerDependencies: + - bufferutil + - csstype + - solid-js + - utf-8-validate + + '@tanstack/react-router-devtools@1.166.6(@tanstack/react-router@1.166.6(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(@tanstack/router-core@1.166.6)(csstype@3.2.3)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': + dependencies: + '@tanstack/react-router': 1.166.6(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@tanstack/router-devtools-core': 1.166.6(@tanstack/router-core@1.166.6)(csstype@3.2.3) + react: 19.2.4 + react-dom: 19.2.4(react@19.2.4) + optionalDependencies: + '@tanstack/router-core': 1.166.6 + transitivePeerDependencies: + - csstype + + '@tanstack/react-router@1.166.6(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': + dependencies: + '@tanstack/history': 1.161.4 + '@tanstack/react-store': 0.9.2(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@tanstack/router-core': 1.166.6 + isbot: 5.1.35 + react: 19.2.4 + react-dom: 19.2.4(react@19.2.4) + tiny-invariant: 1.3.3 + tiny-warning: 1.0.3 + + '@tanstack/react-start-client@1.166.6(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': + dependencies: + '@tanstack/react-router': 1.166.6(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@tanstack/router-core': 1.166.6 + '@tanstack/start-client-core': 1.166.6 + react: 19.2.4 + react-dom: 19.2.4(react@19.2.4) + tiny-invariant: 1.3.3 + tiny-warning: 1.0.3 + + '@tanstack/react-start-server@1.166.6(crossws@0.4.4(srvx@0.10.1))(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': + dependencies: + '@tanstack/history': 1.161.4 + '@tanstack/react-router': 1.166.6(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@tanstack/router-core': 1.166.6 + '@tanstack/start-client-core': 1.166.6 + '@tanstack/start-server-core': 1.166.6(crossws@0.4.4(srvx@0.10.1)) + react: 19.2.4 + react-dom: 19.2.4(react@19.2.4) + transitivePeerDependencies: + - crossws + + '@tanstack/react-start@1.166.6(crossws@0.4.4(srvx@0.10.1))(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(vite@7.3.1(@types/node@25.4.0)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2))': + dependencies: + '@tanstack/react-router': 1.166.6(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@tanstack/react-start-client': 1.166.6(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@tanstack/react-start-server': 1.166.6(crossws@0.4.4(srvx@0.10.1))(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@tanstack/router-utils': 1.161.4 + '@tanstack/start-client-core': 1.166.6 + '@tanstack/start-plugin-core': 1.166.6(@tanstack/react-router@1.166.6(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(crossws@0.4.4(srvx@0.10.1))(vite@7.3.1(@types/node@25.4.0)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)) + '@tanstack/start-server-core': 1.166.6(crossws@0.4.4(srvx@0.10.1)) + pathe: 2.0.3 + react: 19.2.4 + react-dom: 19.2.4(react@19.2.4) + vite: 7.3.1(@types/node@25.4.0)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2) + transitivePeerDependencies: + - '@rsbuild/core' + - crossws + - supports-color + - vite-plugin-solid + - webpack + + '@tanstack/react-store@0.9.2(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': + dependencies: + '@tanstack/store': 0.9.2 + react: 19.2.4 + react-dom: 19.2.4(react@19.2.4) + use-sync-external-store: 1.6.0(react@19.2.4) + + '@tanstack/router-core@1.166.6': + dependencies: + '@tanstack/history': 1.161.4 + '@tanstack/store': 0.9.2 + cookie-es: 2.0.0 + seroval: 1.5.1 + seroval-plugins: 1.5.1(seroval@1.5.1) + tiny-invariant: 1.3.3 + tiny-warning: 1.0.3 + + '@tanstack/router-devtools-core@1.166.6(@tanstack/router-core@1.166.6)(csstype@3.2.3)': + dependencies: + '@tanstack/router-core': 1.166.6 + clsx: 2.1.1 + goober: 2.1.18(csstype@3.2.3) + tiny-invariant: 1.3.3 + optionalDependencies: + csstype: 3.2.3 + + '@tanstack/router-generator@1.166.6': + dependencies: + '@tanstack/router-core': 1.166.6 + '@tanstack/router-utils': 1.161.4 + '@tanstack/virtual-file-routes': 1.161.4 + prettier: 3.8.1 + recast: 0.23.11 + source-map: 0.7.6 + tsx: 4.21.0 + zod: 3.25.76 + transitivePeerDependencies: + - supports-color + + '@tanstack/router-plugin@1.166.6(@tanstack/react-router@1.166.6(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(vite@7.3.1(@types/node@25.4.0)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2))': + dependencies: + '@babel/core': 7.29.0 + '@babel/plugin-syntax-jsx': 7.28.6(@babel/core@7.29.0) + '@babel/plugin-syntax-typescript': 7.28.6(@babel/core@7.29.0) + '@babel/template': 7.28.6 + '@babel/traverse': 7.29.0 + '@babel/types': 7.29.0 + '@tanstack/router-core': 1.166.6 + '@tanstack/router-generator': 1.166.6 + '@tanstack/router-utils': 1.161.4 + '@tanstack/virtual-file-routes': 1.161.4 + chokidar: 3.6.0 + unplugin: 2.3.11 + zod: 3.25.76 + optionalDependencies: + '@tanstack/react-router': 1.166.6(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + vite: 7.3.1(@types/node@25.4.0)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2) + transitivePeerDependencies: + - supports-color + + '@tanstack/router-utils@1.161.4': + dependencies: + '@babel/core': 7.29.0 + '@babel/generator': 7.29.1 + '@babel/parser': 7.29.0 + '@babel/types': 7.29.0 + ansis: 4.2.0 + babel-dead-code-elimination: 1.0.12 + diff: 8.0.3 + pathe: 2.0.3 + tinyglobby: 0.2.15 + transitivePeerDependencies: + - supports-color + + '@tanstack/start-client-core@1.166.6': + dependencies: + '@tanstack/router-core': 1.166.6 + '@tanstack/start-fn-stubs': 1.161.4 + '@tanstack/start-storage-context': 1.166.6 + seroval: 1.5.1 + tiny-invariant: 1.3.3 + tiny-warning: 1.0.3 + + '@tanstack/start-fn-stubs@1.161.4': {} + + '@tanstack/start-plugin-core@1.166.6(@tanstack/react-router@1.166.6(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(crossws@0.4.4(srvx@0.10.1))(vite@7.3.1(@types/node@25.4.0)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2))': + dependencies: + '@babel/code-frame': 7.27.1 + '@babel/core': 7.29.0 + '@babel/types': 7.29.0 + '@rolldown/pluginutils': 1.0.0-beta.40 + '@tanstack/router-core': 1.166.6 + '@tanstack/router-generator': 1.166.6 + '@tanstack/router-plugin': 1.166.6(@tanstack/react-router@1.166.6(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(vite@7.3.1(@types/node@25.4.0)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)) + '@tanstack/router-utils': 1.161.4 + '@tanstack/start-client-core': 1.166.6 + '@tanstack/start-server-core': 1.166.6(crossws@0.4.4(srvx@0.10.1)) + cheerio: 1.2.0 + exsolve: 1.0.8 + pathe: 2.0.3 + picomatch: 4.0.3 + source-map: 0.7.6 + srvx: 0.11.9 + tinyglobby: 0.2.15 + ufo: 1.6.3 + vite: 7.3.1(@types/node@25.4.0)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2) + vitefu: 1.1.2(vite@7.3.1(@types/node@25.4.0)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)) + xmlbuilder2: 4.0.3 + zod: 3.25.76 + transitivePeerDependencies: + - '@rsbuild/core' + - '@tanstack/react-router' + - crossws + - supports-color + - vite-plugin-solid + - webpack + + '@tanstack/start-server-core@1.166.6(crossws@0.4.4(srvx@0.10.1))': + dependencies: + '@tanstack/history': 1.161.4 + '@tanstack/router-core': 1.166.6 + '@tanstack/start-client-core': 1.166.6 + '@tanstack/start-storage-context': 1.166.6 + h3-v2: h3@2.0.1-rc.16(crossws@0.4.4(srvx@0.10.1)) + seroval: 1.5.1 + tiny-invariant: 1.3.3 + transitivePeerDependencies: + - crossws + + '@tanstack/start-storage-context@1.166.6': + dependencies: + '@tanstack/router-core': 1.166.6 + + '@tanstack/store@0.9.2': {} + + '@tanstack/virtual-file-routes@1.161.4': {} + '@ts-morph/common@0.11.1': dependencies: fast-glob: 3.3.3 @@ -10021,7 +11632,7 @@ snapshots: '@types/bunyan@1.8.11': dependencies: - '@types/node': 25.3.2 + '@types/node': 25.4.0 '@types/chai@5.2.3': dependencies: @@ -10030,7 +11641,7 @@ snapshots: '@types/cli-progress@3.11.6': dependencies: - '@types/node': 25.3.2 + '@types/node': 25.4.0 '@types/debug@4.1.12': dependencies: @@ -10046,7 +11657,7 @@ snapshots: '@types/graceful-fs@4.1.9': dependencies: - '@types/node': 25.3.2 + '@types/node': 25.4.0 '@types/hammerjs@2.0.46': {} @@ -10080,6 +11691,10 @@ snapshots: dependencies: undici-types: 7.18.2 + '@types/node@25.4.0': + dependencies: + undici-types: 7.18.2 + '@types/react-dom@19.2.3(@types/react@19.2.14)': dependencies: '@types/react': 19.2.14 @@ -10128,24 +11743,45 @@ snapshots: transitivePeerDependencies: - supports-color - '@typescript-eslint/project-service@8.56.1(typescript@5.9.3)': + '@typescript-eslint/project-service@8.56.1(typescript@5.9.3)': + dependencies: + '@typescript-eslint/tsconfig-utils': 8.56.1(typescript@5.9.3) + '@typescript-eslint/types': 8.56.1 + debug: 4.4.3(supports-color@8.1.1) + typescript: 5.9.3 + transitivePeerDependencies: + - supports-color + + '@typescript-eslint/project-service@8.57.0(typescript@5.9.3)': dependencies: - '@typescript-eslint/tsconfig-utils': 8.56.1(typescript@5.9.3) - '@typescript-eslint/types': 8.56.1 + '@typescript-eslint/tsconfig-utils': 8.57.0(typescript@5.9.3) + '@typescript-eslint/types': 8.57.0 debug: 4.4.3(supports-color@8.1.1) typescript: 5.9.3 transitivePeerDependencies: - supports-color + optional: true '@typescript-eslint/scope-manager@8.56.1': dependencies: '@typescript-eslint/types': 8.56.1 '@typescript-eslint/visitor-keys': 8.56.1 + '@typescript-eslint/scope-manager@8.57.0': + dependencies: + '@typescript-eslint/types': 8.57.0 + '@typescript-eslint/visitor-keys': 8.57.0 + optional: true + '@typescript-eslint/tsconfig-utils@8.56.1(typescript@5.9.3)': dependencies: typescript: 5.9.3 + '@typescript-eslint/tsconfig-utils@8.57.0(typescript@5.9.3)': + dependencies: + typescript: 5.9.3 + optional: true + '@typescript-eslint/type-utils@8.56.1(eslint@9.39.3(jiti@2.6.1))(typescript@5.9.3)': dependencies: '@typescript-eslint/types': 8.56.1 @@ -10160,6 +11796,9 @@ snapshots: '@typescript-eslint/types@8.56.1': {} + '@typescript-eslint/types@8.57.0': + optional: true + '@typescript-eslint/typescript-estree@8.56.1(typescript@5.9.3)': dependencies: '@typescript-eslint/project-service': 8.56.1(typescript@5.9.3) @@ -10175,6 +11814,22 @@ snapshots: transitivePeerDependencies: - supports-color + '@typescript-eslint/typescript-estree@8.57.0(typescript@5.9.3)': + dependencies: + '@typescript-eslint/project-service': 8.57.0(typescript@5.9.3) + '@typescript-eslint/tsconfig-utils': 8.57.0(typescript@5.9.3) + '@typescript-eslint/types': 8.57.0 + '@typescript-eslint/visitor-keys': 8.57.0 + debug: 4.4.3(supports-color@8.1.1) + minimatch: 10.2.4 + semver: 7.7.4 + tinyglobby: 0.2.15 + ts-api-utils: 2.4.0(typescript@5.9.3) + typescript: 5.9.3 + transitivePeerDependencies: + - supports-color + optional: true + '@typescript-eslint/utils@8.56.1(eslint@9.39.3(jiti@2.6.1))(typescript@5.9.3)': dependencies: '@eslint-community/eslint-utils': 4.9.1(eslint@9.39.3(jiti@2.6.1)) @@ -10186,11 +11841,29 @@ snapshots: transitivePeerDependencies: - supports-color + '@typescript-eslint/utils@8.57.0(eslint@9.39.3(jiti@2.6.1))(typescript@5.9.3)': + dependencies: + '@eslint-community/eslint-utils': 4.9.1(eslint@9.39.3(jiti@2.6.1)) + '@typescript-eslint/scope-manager': 8.57.0 + '@typescript-eslint/types': 8.57.0 + '@typescript-eslint/typescript-estree': 8.57.0(typescript@5.9.3) + eslint: 9.39.3(jiti@2.6.1) + typescript: 5.9.3 + transitivePeerDependencies: + - supports-color + optional: true + '@typescript-eslint/visitor-keys@8.56.1': dependencies: '@typescript-eslint/types': 8.56.1 eslint-visitor-keys: 5.0.1 + '@typescript-eslint/visitor-keys@8.57.0': + dependencies: + '@typescript-eslint/types': 8.57.0 + eslint-visitor-keys: 5.0.1 + optional: true + '@ungap/structured-clone@1.3.0': {} '@unrs/resolver-binding-android-arm-eabi@1.11.1': @@ -10280,12 +11953,34 @@ snapshots: react-dom: 19.2.4(react@19.2.4) ts-morph: 12.0.0 + '@vercel/react-router@1.2.5(@react-router/dev@7.13.1(@react-router/serve@7.13.1(react-router@7.13.1(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(typescript@5.9.3))(@types/node@25.4.0)(jiti@2.6.1)(lightningcss@1.30.1)(react-router@7.13.1(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(terser@5.46.0)(tsx@4.21.0)(typescript@5.9.3)(vite@7.3.1(@types/node@25.4.0)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2))(yaml@2.8.2))(@react-router/node@7.13.1(react-router@7.13.1(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(typescript@5.9.3))(isbot@5.1.35)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': + dependencies: + '@react-router/dev': 7.13.1(@react-router/serve@7.13.1(react-router@7.13.1(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(typescript@5.9.3))(@types/node@25.4.0)(jiti@2.6.1)(lightningcss@1.30.1)(react-router@7.13.1(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(terser@5.46.0)(tsx@4.21.0)(typescript@5.9.3)(vite@7.3.1(@types/node@25.4.0)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2))(yaml@2.8.2) + '@react-router/node': 7.13.1(react-router@7.13.1(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(typescript@5.9.3) + '@vercel/static-config': 3.1.2 + isbot: 5.1.35 + react: 19.2.4 + react-dom: 19.2.4(react@19.2.4) + ts-morph: 12.0.0 + '@vercel/static-config@3.1.2': dependencies: ajv: 8.6.3 json-schema-to-ts: 1.6.4 ts-morph: 12.0.0 + '@vitejs/plugin-react@5.1.4(vite@7.3.1(@types/node@25.4.0)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2))': + dependencies: + '@babel/core': 7.29.0 + '@babel/plugin-transform-react-jsx-self': 7.27.1(@babel/core@7.29.0) + '@babel/plugin-transform-react-jsx-source': 7.27.1(@babel/core@7.29.0) + '@rolldown/pluginutils': 1.0.0-rc.3 + '@types/babel__core': 7.20.5 + react-refresh: 0.18.0 + vite: 7.3.1(@types/node@25.4.0)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2) + transitivePeerDependencies: + - supports-color + '@vitest/expect@4.0.18': dependencies: '@standard-schema/spec': 1.1.0 @@ -10295,13 +11990,13 @@ snapshots: chai: 6.2.2 tinyrainbow: 3.0.3 - '@vitest/mocker@4.0.18(vite@7.3.1(@types/node@25.3.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2))': + '@vitest/mocker@4.0.18(vite@7.3.1(@types/node@25.4.0)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2))': dependencies: '@vitest/spy': 4.0.18 estree-walker: 3.0.3 magic-string: 0.30.21 optionalDependencies: - vite: 7.3.1(@types/node@25.3.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2) + vite: 7.3.1(@types/node@25.4.0)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2) '@vitest/pretty-format@4.0.18': dependencies: @@ -10412,6 +12107,8 @@ snapshots: ansicolors@0.3.2: {} + ansis@4.2.0: {} + any-promise@1.3.0: {} anymatch@3.1.3: @@ -10514,6 +12211,10 @@ snapshots: assertion-error@2.0.1: {} + ast-types@0.16.1: + dependencies: + tslib: 2.8.1 + astral-regex@2.0.0: {} astring@1.9.0: {} @@ -10699,6 +12400,8 @@ snapshots: big-integer@1.6.52: {} + binary-extensions@2.3.0: {} + body-parser@1.20.4: dependencies: bytes: 3.1.2 @@ -10823,6 +12526,8 @@ snapshots: ansi-styles: 4.3.0 supports-color: 7.2.0 + chalk@5.6.2: {} + character-entities-html4@2.1.0: {} character-entities-legacy@3.0.0: {} @@ -10833,6 +12538,41 @@ snapshots: charenc@0.0.2: {} + cheerio-select@2.1.0: + dependencies: + boolbase: 1.0.0 + css-select: 5.2.2 + css-what: 6.2.2 + domelementtype: 2.3.0 + domhandler: 5.0.3 + domutils: 3.2.2 + + cheerio@1.2.0: + dependencies: + cheerio-select: 2.1.0 + dom-serializer: 2.0.0 + domhandler: 5.0.3 + domutils: 3.2.2 + encoding-sniffer: 0.2.1 + htmlparser2: 10.1.0 + parse5: 7.3.0 + parse5-htmlparser2-tree-adapter: 7.1.0 + parse5-parser-stream: 7.1.2 + undici: 7.22.0 + whatwg-mimetype: 4.0.0 + + chokidar@3.6.0: + dependencies: + anymatch: 3.1.3 + braces: 3.0.3 + glob-parent: 5.1.2 + is-binary-path: 2.1.0 + is-glob: 4.0.3 + normalize-path: 3.0.0 + readdirp: 3.6.0 + optionalDependencies: + fsevents: 2.3.3 + chokidar@4.0.3: dependencies: readdirp: 4.1.2 @@ -10841,7 +12581,7 @@ snapshots: chrome-launcher@0.15.2: dependencies: - '@types/node': 25.3.2 + '@types/node': 25.4.0 escape-string-regexp: 4.0.0 is-wsl: 2.2.0 lighthouse-logger: 1.4.2 @@ -10850,7 +12590,7 @@ snapshots: chromium-edge-launcher@0.2.0: dependencies: - '@types/node': 25.3.2 + '@types/node': 25.4.0 escape-string-regexp: 4.0.0 is-wsl: 2.2.0 lighthouse-logger: 1.4.2 @@ -10941,6 +12681,9 @@ snapshots: core-util-is: 1.0.3 esprima: 4.0.1 + comment-parser@1.4.5: + optional: true + commondir@1.0.1: {} component-type@1.2.2: {} @@ -10974,6 +12717,8 @@ snapshots: transitivePeerDependencies: - supports-color + consola@3.4.2: {} + content-disposition@0.5.4: dependencies: safe-buffer: 5.2.1 @@ -10982,6 +12727,8 @@ snapshots: convert-source-map@2.0.0: {} + cookie-es@2.0.0: {} + cookie-signature@1.0.7: {} cookie@0.7.2: {} @@ -11016,6 +12763,10 @@ snapshots: shebang-command: 2.0.0 which: 2.0.2 + crossws@0.4.4(srvx@0.10.1): + optionalDependencies: + srvx: 0.10.1 + crypt@0.0.2: {} crypto-random-string@2.0.0: {} @@ -11069,6 +12820,10 @@ snapshots: dateformat@4.6.3: {} + dayjs@1.11.19: {} + + db0@0.3.4: {} + debug@2.6.9: dependencies: ms: 2.0.0 @@ -11137,6 +12892,8 @@ snapshots: diff@7.0.0: {} + diff@8.0.3: {} + dir-glob@3.0.1: dependencies: path-type: 4.0.0 @@ -11188,7 +12945,7 @@ snapshots: es-errors: 1.3.0 gopd: 1.2.0 - eas-cli@18.0.6(@types/node@25.3.2)(typescript@5.9.3): + eas-cli@18.0.6(@types/node@25.4.0)(typescript@5.9.3): dependencies: '@expo/apple-utils': 2.1.13 '@expo/code-signing-certificates': 0.0.5 @@ -11204,8 +12961,8 @@ snapshots: '@expo/package-manager': 1.9.10 '@expo/pkcs12': 0.1.3 '@expo/plist': 0.2.0 - '@expo/plugin-help': 5.1.23(@types/node@25.3.2)(typescript@5.9.3) - '@expo/plugin-warn-if-update-available': 2.5.1(@types/node@25.3.2)(typescript@5.9.3) + '@expo/plugin-help': 5.1.23(@types/node@25.4.0)(typescript@5.9.3) + '@expo/plugin-warn-if-update-available': 2.5.1(@types/node@25.4.0)(typescript@5.9.3) '@expo/prebuild-config': 8.0.17 '@expo/results': 1.0.0 '@expo/rudder-sdk-node': 1.1.1 @@ -11213,7 +12970,7 @@ snapshots: '@expo/steps': 18.0.2 '@expo/timeago.js': 1.0.0 '@oclif/core': 1.26.2 - '@oclif/plugin-autocomplete': 2.3.10(@types/node@25.3.2)(typescript@5.9.3) + '@oclif/plugin-autocomplete': 2.3.10(@types/node@25.4.0)(typescript@5.9.3) '@segment/ajv-human-errors': 2.16.0(ajv@8.11.0) '@urql/core': 4.0.11(graphql@16.8.1) '@urql/exchange-retry': 1.2.0(graphql@16.8.1) @@ -11307,6 +13064,11 @@ snapshots: encodeurl@2.0.0: {} + encoding-sniffer@0.2.1: + dependencies: + iconv-lite: 0.6.3 + whatwg-encoding: 3.1.1 + end-of-stream@1.4.5: dependencies: once: 1.4.0 @@ -11318,6 +13080,10 @@ snapshots: entities@4.5.0: {} + entities@6.0.1: {} + + entities@7.0.1: {} + env-paths@2.2.0: {} env-string@1.0.1: {} @@ -11490,12 +13256,12 @@ snapshots: escape-string-regexp@4.0.0: {} - eslint-config-expo@55.0.0(eslint@9.39.3(jiti@2.6.1))(typescript@5.9.3): + eslint-config-expo@55.0.0(eslint-plugin-import-x@4.16.1(@typescript-eslint/utils@8.57.0(eslint@9.39.3(jiti@2.6.1))(typescript@5.9.3))(eslint-import-resolver-node@0.3.9)(eslint@9.39.3(jiti@2.6.1)))(eslint@9.39.3(jiti@2.6.1))(typescript@5.9.3): dependencies: '@typescript-eslint/eslint-plugin': 8.56.1(@typescript-eslint/parser@8.56.1(eslint@9.39.3(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.3(jiti@2.6.1))(typescript@5.9.3) '@typescript-eslint/parser': 8.56.1(eslint@9.39.3(jiti@2.6.1))(typescript@5.9.3) eslint: 9.39.3(jiti@2.6.1) - eslint-import-resolver-typescript: 3.10.1(eslint-plugin-import@2.32.0)(eslint@9.39.3(jiti@2.6.1)) + eslint-import-resolver-typescript: 3.10.1(eslint-plugin-import-x@4.16.1(@typescript-eslint/utils@8.57.0(eslint@9.39.3(jiti@2.6.1))(typescript@5.9.3))(eslint-import-resolver-node@0.3.9)(eslint@9.39.3(jiti@2.6.1)))(eslint-plugin-import@2.32.0)(eslint@9.39.3(jiti@2.6.1)) eslint-plugin-expo: 1.0.0(eslint@9.39.3(jiti@2.6.1))(typescript@5.9.3) eslint-plugin-import: 2.32.0(@typescript-eslint/parser@8.56.1(eslint@9.39.3(jiti@2.6.1))(typescript@5.9.3))(eslint-import-resolver-typescript@3.10.1)(eslint@9.39.3(jiti@2.6.1)) eslint-plugin-react: 7.37.5(eslint@9.39.3(jiti@2.6.1)) @@ -11511,6 +13277,14 @@ snapshots: dependencies: eslint: 9.39.3(jiti@2.6.1) + eslint-import-context@0.1.9(unrs-resolver@1.11.1): + dependencies: + get-tsconfig: 4.13.6 + stable-hash-x: 0.2.0 + optionalDependencies: + unrs-resolver: 1.11.1 + optional: true + eslint-import-resolver-node@0.3.9: dependencies: debug: 3.2.7 @@ -11519,7 +13293,7 @@ snapshots: transitivePeerDependencies: - supports-color - eslint-import-resolver-typescript@3.10.1(eslint-plugin-import@2.32.0)(eslint@9.39.3(jiti@2.6.1)): + eslint-import-resolver-typescript@3.10.1(eslint-plugin-import-x@4.16.1(@typescript-eslint/utils@8.57.0(eslint@9.39.3(jiti@2.6.1))(typescript@5.9.3))(eslint-import-resolver-node@0.3.9)(eslint@9.39.3(jiti@2.6.1)))(eslint-plugin-import@2.32.0)(eslint@9.39.3(jiti@2.6.1)): dependencies: '@nolyfill/is-core-module': 1.0.39 debug: 4.4.3(supports-color@8.1.1) @@ -11531,6 +13305,7 @@ snapshots: unrs-resolver: 1.11.1 optionalDependencies: eslint-plugin-import: 2.32.0(@typescript-eslint/parser@8.56.1(eslint@9.39.3(jiti@2.6.1))(typescript@5.9.3))(eslint-import-resolver-typescript@3.10.1)(eslint@9.39.3(jiti@2.6.1)) + eslint-plugin-import-x: 4.16.1(@typescript-eslint/utils@8.57.0(eslint@9.39.3(jiti@2.6.1))(typescript@5.9.3))(eslint-import-resolver-node@0.3.9)(eslint@9.39.3(jiti@2.6.1)) transitivePeerDependencies: - supports-color @@ -11541,7 +13316,7 @@ snapshots: '@typescript-eslint/parser': 8.56.1(eslint@9.39.3(jiti@2.6.1))(typescript@5.9.3) eslint: 9.39.3(jiti@2.6.1) eslint-import-resolver-node: 0.3.9 - eslint-import-resolver-typescript: 3.10.1(eslint-plugin-import@2.32.0)(eslint@9.39.3(jiti@2.6.1)) + eslint-import-resolver-typescript: 3.10.1(eslint-plugin-import-x@4.16.1(@typescript-eslint/utils@8.57.0(eslint@9.39.3(jiti@2.6.1))(typescript@5.9.3))(eslint-import-resolver-node@0.3.9)(eslint@9.39.3(jiti@2.6.1)))(eslint-plugin-import@2.32.0)(eslint@9.39.3(jiti@2.6.1)) transitivePeerDependencies: - supports-color @@ -11554,6 +13329,25 @@ snapshots: - supports-color - typescript + eslint-plugin-import-x@4.16.1(@typescript-eslint/utils@8.57.0(eslint@9.39.3(jiti@2.6.1))(typescript@5.9.3))(eslint-import-resolver-node@0.3.9)(eslint@9.39.3(jiti@2.6.1)): + dependencies: + '@typescript-eslint/types': 8.57.0 + comment-parser: 1.4.5 + debug: 4.4.3(supports-color@8.1.1) + eslint: 9.39.3(jiti@2.6.1) + eslint-import-context: 0.1.9(unrs-resolver@1.11.1) + is-glob: 4.0.3 + minimatch: 10.2.4 + semver: 7.7.4 + stable-hash-x: 0.2.0 + unrs-resolver: 1.11.1 + optionalDependencies: + '@typescript-eslint/utils': 8.57.0(eslint@9.39.3(jiti@2.6.1))(typescript@5.9.3) + eslint-import-resolver-node: 0.3.9 + transitivePeerDependencies: + - supports-color + optional: true + eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.56.1(eslint@9.39.3(jiti@2.6.1))(typescript@5.9.3))(eslint-import-resolver-typescript@3.10.1)(eslint@9.39.3(jiti@2.6.1)): dependencies: '@rtsao/scc': 1.1.0 @@ -12423,6 +14217,10 @@ snapshots: golden-fleece@1.0.9: {} + goober@2.1.18(csstype@3.2.3): + dependencies: + csstype: 3.2.3 + gopd@1.2.0: {} graceful-fs@4.2.11: {} @@ -12438,6 +14236,13 @@ snapshots: graphql@16.8.1: {} + h3@2.0.1-rc.16(crossws@0.4.4(srvx@0.10.1)): + dependencies: + rou3: 0.8.1 + srvx: 0.11.9 + optionalDependencies: + crossws: 0.4.4(srvx@0.10.1) + has-bigints@1.1.0: {} has-flag@3.0.0: {} @@ -12543,6 +14348,13 @@ snapshots: dependencies: lru-cache: 10.4.3 + htmlparser2@10.1.0: + dependencies: + domelementtype: 2.3.0 + domhandler: 5.0.3 + domutils: 3.2.2 + entities: 7.0.1 + http-call@5.3.0: dependencies: content-type: 1.0.5 @@ -12586,6 +14398,10 @@ snapshots: dependencies: safer-buffer: 2.1.2 + iconv-lite@0.6.3: + dependencies: + safer-buffer: 2.1.2 + idb@8.0.3: {} ieee754@1.2.1: @@ -12666,6 +14482,10 @@ snapshots: dependencies: has-bigints: 1.1.0 + is-binary-path@2.1.0: + dependencies: + binary-extensions: 2.3.0 + is-boolean-object@1.2.2: dependencies: call-bound: 1.0.4 @@ -12838,7 +14658,7 @@ snapshots: '@jest/environment': 29.7.0 '@jest/fake-timers': 29.7.0 '@jest/types': 29.6.3 - '@types/node': 25.3.2 + '@types/node': 25.4.0 jest-mock: 29.7.0 jest-util: 29.7.0 @@ -12848,7 +14668,7 @@ snapshots: dependencies: '@jest/types': 29.6.3 '@types/graceful-fs': 4.1.9 - '@types/node': 25.3.2 + '@types/node': 25.4.0 anymatch: 3.1.3 fb-watchman: 2.0.2 graceful-fs: 4.2.11 @@ -12875,7 +14695,7 @@ snapshots: jest-mock@29.7.0: dependencies: '@jest/types': 29.6.3 - '@types/node': 25.3.2 + '@types/node': 25.4.0 jest-util: 29.7.0 jest-regex-util@29.6.3: {} @@ -12883,7 +14703,7 @@ snapshots: jest-util@29.7.0: dependencies: '@jest/types': 29.6.3 - '@types/node': 25.3.2 + '@types/node': 25.4.0 chalk: 4.1.2 ci-info: 3.9.0 graceful-fs: 4.2.11 @@ -12900,7 +14720,7 @@ snapshots: jest-worker@29.7.0: dependencies: - '@types/node': 25.3.2 + '@types/node': 25.4.0 jest-util: 29.7.0 merge-stream: 2.0.0 supports-color: 8.1.1 @@ -12996,6 +14816,11 @@ snapshots: lan-network@0.2.0: {} + launch-editor@2.13.1: + dependencies: + picocolors: 1.1.1 + shell-quote: 1.8.3 + leven@3.1.0: {} levn@0.4.1: @@ -13108,6 +14933,10 @@ snapshots: dependencies: react: 19.2.4 + lucide-react@0.577.0(react@19.2.4): + dependencies: + react: 19.2.4 + magic-string@0.30.21: dependencies: '@jridgewell/sourcemap-codec': 1.5.5 @@ -13925,8 +15754,59 @@ snapshots: negotiator@1.0.0: {} + nf3@0.3.11: {} + nice-try@1.0.5: {} + nitro@3.0.1-alpha.2(chokidar@4.0.3)(lru-cache@11.2.6)(rolldown@1.0.0-rc.8)(rollup@4.59.0)(vite@7.3.1(@types/node@25.4.0)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)): + dependencies: + consola: 3.4.2 + crossws: 0.4.4(srvx@0.10.1) + db0: 0.3.4 + h3: 2.0.1-rc.16(crossws@0.4.4(srvx@0.10.1)) + jiti: 2.6.1 + nf3: 0.3.11 + ofetch: 2.0.0-alpha.3 + ohash: 2.0.11 + oxc-minify: 0.110.0 + oxc-transform: 0.110.0 + srvx: 0.10.1 + undici: 7.22.0 + unenv: 2.0.0-rc.24 + unstorage: 2.0.0-alpha.6(chokidar@4.0.3)(db0@0.3.4)(lru-cache@11.2.6)(ofetch@2.0.0-alpha.3) + optionalDependencies: + rolldown: 1.0.0-rc.8 + rollup: 4.59.0 + vite: 7.3.1(@types/node@25.4.0)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2) + transitivePeerDependencies: + - '@azure/app-configuration' + - '@azure/cosmos' + - '@azure/data-tables' + - '@azure/identity' + - '@azure/keyvault-secrets' + - '@azure/storage-blob' + - '@capacitor/preferences' + - '@deno/kv' + - '@electric-sql/pglite' + - '@libsql/client' + - '@netlify/blobs' + - '@planetscale/database' + - '@upstash/redis' + - '@vercel/blob' + - '@vercel/functions' + - '@vercel/kv' + - aws4fetch + - better-sqlite3 + - chokidar + - drizzle-orm + - idb-keyval + - ioredis + - lru-cache + - mongodb + - mysql2 + - sqlite3 + - uploadthing + node-exports-info@1.6.0: dependencies: array.prototype.flatmap: 1.3.3 @@ -14034,6 +15914,10 @@ snapshots: obug@2.1.1: {} + ofetch@2.0.0-alpha.3: {} + + ohash@2.0.11: {} + on-finished@2.3.0: dependencies: ee-first: 1.1.1 @@ -14102,6 +15986,52 @@ snapshots: object-keys: 1.1.1 safe-push-apply: 1.0.0 + oxc-minify@0.110.0: + optionalDependencies: + '@oxc-minify/binding-android-arm-eabi': 0.110.0 + '@oxc-minify/binding-android-arm64': 0.110.0 + '@oxc-minify/binding-darwin-arm64': 0.110.0 + '@oxc-minify/binding-darwin-x64': 0.110.0 + '@oxc-minify/binding-freebsd-x64': 0.110.0 + '@oxc-minify/binding-linux-arm-gnueabihf': 0.110.0 + '@oxc-minify/binding-linux-arm-musleabihf': 0.110.0 + '@oxc-minify/binding-linux-arm64-gnu': 0.110.0 + '@oxc-minify/binding-linux-arm64-musl': 0.110.0 + '@oxc-minify/binding-linux-ppc64-gnu': 0.110.0 + '@oxc-minify/binding-linux-riscv64-gnu': 0.110.0 + '@oxc-minify/binding-linux-riscv64-musl': 0.110.0 + '@oxc-minify/binding-linux-s390x-gnu': 0.110.0 + '@oxc-minify/binding-linux-x64-gnu': 0.110.0 + '@oxc-minify/binding-linux-x64-musl': 0.110.0 + '@oxc-minify/binding-openharmony-arm64': 0.110.0 + '@oxc-minify/binding-wasm32-wasi': 0.110.0 + '@oxc-minify/binding-win32-arm64-msvc': 0.110.0 + '@oxc-minify/binding-win32-ia32-msvc': 0.110.0 + '@oxc-minify/binding-win32-x64-msvc': 0.110.0 + + oxc-transform@0.110.0: + optionalDependencies: + '@oxc-transform/binding-android-arm-eabi': 0.110.0 + '@oxc-transform/binding-android-arm64': 0.110.0 + '@oxc-transform/binding-darwin-arm64': 0.110.0 + '@oxc-transform/binding-darwin-x64': 0.110.0 + '@oxc-transform/binding-freebsd-x64': 0.110.0 + '@oxc-transform/binding-linux-arm-gnueabihf': 0.110.0 + '@oxc-transform/binding-linux-arm-musleabihf': 0.110.0 + '@oxc-transform/binding-linux-arm64-gnu': 0.110.0 + '@oxc-transform/binding-linux-arm64-musl': 0.110.0 + '@oxc-transform/binding-linux-ppc64-gnu': 0.110.0 + '@oxc-transform/binding-linux-riscv64-gnu': 0.110.0 + '@oxc-transform/binding-linux-riscv64-musl': 0.110.0 + '@oxc-transform/binding-linux-s390x-gnu': 0.110.0 + '@oxc-transform/binding-linux-x64-gnu': 0.110.0 + '@oxc-transform/binding-linux-x64-musl': 0.110.0 + '@oxc-transform/binding-openharmony-arm64': 0.110.0 + '@oxc-transform/binding-wasm32-wasi': 0.110.0 + '@oxc-transform/binding-win32-arm64-msvc': 0.110.0 + '@oxc-transform/binding-win32-ia32-msvc': 0.110.0 + '@oxc-transform/binding-win32-x64-msvc': 0.110.0 + p-finally@1.0.0: {} p-limit@2.3.0: @@ -14151,6 +16081,19 @@ snapshots: dependencies: pngjs: 3.4.0 + parse5-htmlparser2-tree-adapter@7.1.0: + dependencies: + domhandler: 5.0.3 + parse5: 7.3.0 + + parse5-parser-stream@7.1.2: + dependencies: + parse5: 7.3.0 + + parse5@7.3.0: + dependencies: + entities: 6.0.1 + parseurl@1.3.3: {} password-prompt@1.1.3: @@ -14521,6 +16464,8 @@ snapshots: react-refresh@0.14.2: {} + react-refresh@0.18.0: {} + react-remove-scroll-bar@2.3.8(@types/react@19.2.14)(react@19.2.4): dependencies: react: 19.2.4 @@ -14582,8 +16527,20 @@ snapshots: string_decoder: 1.3.0 optional: true + readdirp@3.6.0: + dependencies: + picomatch: 2.3.1 + readdirp@4.1.2: {} + recast@0.23.11: + dependencies: + ast-types: 0.16.1 + esprima: 4.0.1 + source-map: 0.6.1 + tiny-invariant: 1.3.3 + tslib: 2.8.1 + rechoir@0.6.2: dependencies: resolve: 1.22.11 @@ -14756,6 +16713,28 @@ snapshots: dependencies: glob: 10.5.0 + rolldown@1.0.0-rc.8: + dependencies: + '@oxc-project/types': 0.115.0 + '@rolldown/pluginutils': 1.0.0-rc.8 + optionalDependencies: + '@rolldown/binding-android-arm64': 1.0.0-rc.8 + '@rolldown/binding-darwin-arm64': 1.0.0-rc.8 + '@rolldown/binding-darwin-x64': 1.0.0-rc.8 + '@rolldown/binding-freebsd-x64': 1.0.0-rc.8 + '@rolldown/binding-linux-arm-gnueabihf': 1.0.0-rc.8 + '@rolldown/binding-linux-arm64-gnu': 1.0.0-rc.8 + '@rolldown/binding-linux-arm64-musl': 1.0.0-rc.8 + '@rolldown/binding-linux-ppc64-gnu': 1.0.0-rc.8 + '@rolldown/binding-linux-s390x-gnu': 1.0.0-rc.8 + '@rolldown/binding-linux-x64-gnu': 1.0.0-rc.8 + '@rolldown/binding-linux-x64-musl': 1.0.0-rc.8 + '@rolldown/binding-openharmony-arm64': 1.0.0-rc.8 + '@rolldown/binding-wasm32-wasi': 1.0.0-rc.8 + '@rolldown/binding-win32-arm64-msvc': 1.0.0-rc.8 + '@rolldown/binding-win32-x64-msvc': 1.0.0-rc.8 + optional: true + rollup-plugin-dts@6.3.0(rollup@4.59.0)(typescript@5.9.3): dependencies: magic-string: 0.30.21 @@ -14824,6 +16803,8 @@ snapshots: '@rollup/rollup-win32-x64-msvc': 4.59.0 fsevents: 2.3.3 + rou3@0.8.1: {} + run-parallel@1.2.0: dependencies: queue-microtask: 1.2.3 @@ -14898,6 +16879,12 @@ snapshots: serialize-error@2.1.0: {} + seroval-plugins@1.5.1(seroval@1.5.1): + dependencies: + seroval: 1.5.1 + + seroval@1.5.1: {} + serve-static@1.16.3: dependencies: encodeurl: 2.0.0 @@ -15056,6 +17043,12 @@ snapshots: slugify@1.6.6: {} + solid-js@1.9.11: + dependencies: + csstype: 3.2.3 + seroval: 1.5.1 + seroval-plugins: 1.5.1(seroval@1.5.1) + sort-object-keys@2.1.0: {} sort-package-json@3.6.0: @@ -15087,6 +17080,13 @@ snapshots: sprintf-js@1.0.3: {} + srvx@0.10.1: {} + + srvx@0.11.9: {} + + stable-hash-x@0.2.0: + optional: true + stable-hash@0.0.5: {} stack-utils@2.0.6: @@ -15315,6 +17315,10 @@ snapshots: throat@5.0.0: {} + tiny-invariant@1.3.3: {} + + tiny-warning@1.0.3: {} + tinybench@2.9.0: {} tinyexec@1.0.2: {} @@ -15355,14 +17359,14 @@ snapshots: '@ts-morph/common': 0.11.1 code-block-writer: 10.1.1 - ts-node@10.9.2(@types/node@25.3.2)(typescript@5.9.3): + ts-node@10.9.2(@types/node@25.4.0)(typescript@5.9.3): dependencies: '@cspotcode/source-map-support': 0.8.1 '@tsconfig/node10': 1.0.12 '@tsconfig/node12': 1.0.11 '@tsconfig/node14': 1.0.3 '@tsconfig/node16': 1.0.4 - '@types/node': 25.3.2 + '@types/node': 25.4.0 acorn: 8.16.0 acorn-walk: 8.3.5 arg: 4.1.3 @@ -15501,6 +17505,8 @@ snapshots: ua-parser-js@1.0.41: {} + ufo@1.6.3: {} + unbox-primitive@1.1.0: dependencies: call-bound: 1.0.4 @@ -15510,6 +17516,12 @@ snapshots: undici-types@7.18.2: {} + undici@7.22.0: {} + + unenv@2.0.0-rc.24: + dependencies: + pathe: 2.0.3 + unicode-canonical-property-names-ecmascript@2.0.1: {} unicode-match-property-ecmascript@2.0.0: @@ -15575,6 +17587,13 @@ snapshots: pathe: 2.0.3 picomatch: 4.0.3 + unplugin@2.3.11: + dependencies: + '@jridgewell/remapping': 2.3.5 + acorn: 8.16.0 + picomatch: 4.0.3 + webpack-virtual-modules: 0.6.2 + unrs-resolver@1.11.1: dependencies: napi-postinstall: 0.3.4 @@ -15599,6 +17618,13 @@ snapshots: '@unrs/resolver-binding-win32-ia32-msvc': 1.11.1 '@unrs/resolver-binding-win32-x64-msvc': 1.11.1 + unstorage@2.0.0-alpha.6(chokidar@4.0.3)(db0@0.3.4)(lru-cache@11.2.6)(ofetch@2.0.0-alpha.3): + optionalDependencies: + chokidar: 4.0.3 + db0: 0.3.4 + lru-cache: 11.2.6 + ofetch: 2.0.0-alpha.3 + untildify@4.0.0: {} update-browserslist-db@1.2.3(browserslist@4.28.1): @@ -15694,6 +17720,27 @@ snapshots: - tsx - yaml + vite-node@3.2.4(@types/node@25.4.0)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2): + dependencies: + cac: 6.7.14 + debug: 4.4.3(supports-color@8.1.1) + es-module-lexer: 1.7.0 + pathe: 2.0.3 + vite: 7.3.1(@types/node@25.4.0)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2) + transitivePeerDependencies: + - '@types/node' + - jiti + - less + - lightningcss + - sass + - sass-embedded + - stylus + - sugarss + - supports-color + - terser + - tsx + - yaml + vite-tsconfig-paths@6.1.1(typescript@5.9.3)(vite@7.3.1(@types/node@25.3.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)): dependencies: debug: 4.4.3(supports-color@8.1.1) @@ -15704,6 +17751,16 @@ snapshots: - supports-color - typescript + vite-tsconfig-paths@6.1.1(typescript@5.9.3)(vite@7.3.1(@types/node@25.4.0)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)): + dependencies: + debug: 4.4.3(supports-color@8.1.1) + globrex: 0.1.2 + tsconfck: 3.1.6(typescript@5.9.3) + vite: 7.3.1(@types/node@25.4.0)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2) + transitivePeerDependencies: + - supports-color + - typescript + vite@7.3.1(@types/node@25.3.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2): dependencies: esbuild: 0.27.3 @@ -15721,10 +17778,31 @@ snapshots: tsx: 4.21.0 yaml: 2.8.2 - vitest@4.0.18(@types/node@25.3.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2): + vite@7.3.1(@types/node@25.4.0)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2): + dependencies: + esbuild: 0.27.3 + fdir: 6.5.0(picomatch@4.0.3) + picomatch: 4.0.3 + postcss: 8.5.6 + rollup: 4.59.0 + tinyglobby: 0.2.15 + optionalDependencies: + '@types/node': 25.4.0 + fsevents: 2.3.3 + jiti: 2.6.1 + lightningcss: 1.30.1 + terser: 5.46.0 + tsx: 4.21.0 + yaml: 2.8.2 + + vitefu@1.1.2(vite@7.3.1(@types/node@25.4.0)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)): + optionalDependencies: + vite: 7.3.1(@types/node@25.4.0)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2) + + vitest@4.0.18(@types/node@25.4.0)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2): dependencies: '@vitest/expect': 4.0.18 - '@vitest/mocker': 4.0.18(vite@7.3.1(@types/node@25.3.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)) + '@vitest/mocker': 4.0.18(vite@7.3.1(@types/node@25.4.0)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)) '@vitest/pretty-format': 4.0.18 '@vitest/runner': 4.0.18 '@vitest/snapshot': 4.0.18 @@ -15741,10 +17819,10 @@ snapshots: tinyexec: 1.0.2 tinyglobby: 0.2.15 tinyrainbow: 3.0.3 - vite: 7.3.1(@types/node@25.3.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2) + vite: 7.3.1(@types/node@25.4.0)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2) why-is-node-running: 2.3.0 optionalDependencies: - '@types/node': 25.3.2 + '@types/node': 25.4.0 transitivePeerDependencies: - jiti - less @@ -15772,8 +17850,16 @@ snapshots: webidl-conversions@3.0.1: {} + webpack-virtual-modules@0.6.2: {} + + whatwg-encoding@3.1.1: + dependencies: + iconv-lite: 0.6.3 + whatwg-fetch@3.6.20: {} + whatwg-mimetype@4.0.0: {} + whatwg-url-minimum@0.1.1: {} whatwg-url@5.0.0: @@ -15884,6 +17970,13 @@ snapshots: sax: 1.4.4 xmlbuilder: 11.0.1 + xmlbuilder2@4.0.3: + dependencies: + '@oozcitak/dom': 2.0.2 + '@oozcitak/infra': 2.0.2 + '@oozcitak/util': 10.0.0 + js-yaml: 4.1.1 + xmlbuilder@11.0.1: {} xmlbuilder@14.0.0: {} From dd052a52e2b6c3e6bed9f7e344a7807a2884de39 Mon Sep 17 00:00:00 2001 From: Benno <57860196+bennoinbeta@users.noreply.github.com> Date: Tue, 10 Mar 2026 07:54:01 +0100 Subject: [PATCH 03/51] #7 slim down --- .prettierignore | 8 +- apps/midimarble/.cta.json | 18 -- apps/midimarble/README.md | 2 +- apps/midimarble/public/manifest.json | 46 +-- apps/midimarble/src/components/Footer.tsx | 44 --- apps/midimarble/src/components/Header.tsx | 78 ----- .../midimarble/src/components/ThemeToggle.tsx | 81 ----- apps/midimarble/src/routeTree.gen.ts | 24 +- apps/midimarble/src/router.tsx | 25 +- apps/midimarble/src/routes/__root.tsx | 128 ++++---- apps/midimarble/src/routes/about.tsx | 23 -- apps/midimarble/src/routes/index.tsx | 88 +---- apps/midimarble/src/styles.css | 306 +++--------------- apps/midimarble/src/vite-env.d.ts | 1 + 14 files changed, 173 insertions(+), 699 deletions(-) delete mode 100644 apps/midimarble/.cta.json delete mode 100644 apps/midimarble/src/components/Footer.tsx delete mode 100644 apps/midimarble/src/components/Header.tsx delete mode 100644 apps/midimarble/src/components/ThemeToggle.tsx delete mode 100644 apps/midimarble/src/routes/about.tsx create mode 100644 apps/midimarble/src/vite-env.d.ts diff --git a/.prettierignore b/.prettierignore index e554bff..6c571fd 100644 --- a/.prettierignore +++ b/.prettierignore @@ -1,6 +1,10 @@ # Xcode asset catalogs and app icon (Xcode owns these JSON files) **/*.xcassets/** -**/AppIcon.icon/** +**/*.icon/** # Deprecated apps -apps/__deprecated/ +apps/_deprecated/ + +# Generated files +**/*.gen.ts +generated/ diff --git a/apps/midimarble/.cta.json b/apps/midimarble/.cta.json deleted file mode 100644 index 0f7df96..0000000 --- a/apps/midimarble/.cta.json +++ /dev/null @@ -1,18 +0,0 @@ -{ - "projectName": "midimarble", - "mode": "file-router", - "typescript": true, - "packageManager": "pnpm", - "includeExamples": false, - "tailwind": true, - "addOnOptions": {}, - "envVarValues": {}, - "git": false, - "routerOnly": false, - "version": 1, - "framework": "react", - "chosenAddOns": [ - "eslint", - "nitro" - ] -} \ No newline at end of file diff --git a/apps/midimarble/README.md b/apps/midimarble/README.md index 109a6cd..1d5d76f 100644 --- a/apps/midimarble/README.md +++ b/apps/midimarble/README.md @@ -1 +1 @@ -# `@repo/midimarble` \ No newline at end of file +# `@repo/midimarble` diff --git a/apps/midimarble/public/manifest.json b/apps/midimarble/public/manifest.json index 078ef50..4d9581b 100644 --- a/apps/midimarble/public/manifest.json +++ b/apps/midimarble/public/manifest.json @@ -1,25 +1,25 @@ { - "short_name": "TanStack App", - "name": "Create TanStack App Sample", - "icons": [ - { - "src": "favicon.ico", - "sizes": "64x64 32x32 24x24 16x16", - "type": "image/x-icon" - }, - { - "src": "logo192.png", - "type": "image/png", - "sizes": "192x192" - }, - { - "src": "logo512.png", - "type": "image/png", - "sizes": "512x512" - } - ], - "start_url": ".", - "display": "standalone", - "theme_color": "#000000", - "background_color": "#ffffff" + "short_name": "TanStack App", + "name": "Create TanStack App Sample", + "icons": [ + { + "src": "favicon.ico", + "sizes": "64x64 32x32 24x24 16x16", + "type": "image/x-icon" + }, + { + "src": "logo192.png", + "type": "image/png", + "sizes": "192x192" + }, + { + "src": "logo512.png", + "type": "image/png", + "sizes": "512x512" + } + ], + "start_url": ".", + "display": "standalone", + "theme_color": "#000000", + "background_color": "#ffffff" } diff --git a/apps/midimarble/src/components/Footer.tsx b/apps/midimarble/src/components/Footer.tsx deleted file mode 100644 index c8bfd17..0000000 --- a/apps/midimarble/src/components/Footer.tsx +++ /dev/null @@ -1,44 +0,0 @@ -export default function Footer() { - const year = new Date().getFullYear() - - return ( - - ) -} diff --git a/apps/midimarble/src/components/Header.tsx b/apps/midimarble/src/components/Header.tsx deleted file mode 100644 index fa196d6..0000000 --- a/apps/midimarble/src/components/Header.tsx +++ /dev/null @@ -1,78 +0,0 @@ -import { Link } from '@tanstack/react-router' -import ThemeToggle from './ThemeToggle' - -export default function Header() { - return ( - - - - ) -} diff --git a/apps/midimarble/src/components/ThemeToggle.tsx b/apps/midimarble/src/components/ThemeToggle.tsx deleted file mode 100644 index 081ebe2..0000000 --- a/apps/midimarble/src/components/ThemeToggle.tsx +++ /dev/null @@ -1,81 +0,0 @@ -import { useEffect, useState } from 'react' - -type ThemeMode = 'light' | 'dark' | 'auto' - -function getInitialMode(): ThemeMode { - if (typeof window === 'undefined') { - return 'auto' - } - - const stored = window.localStorage.getItem('theme') - if (stored === 'light' || stored === 'dark' || stored === 'auto') { - return stored - } - - return 'auto' -} - -function applyThemeMode(mode: ThemeMode) { - const prefersDark = window.matchMedia('(prefers-color-scheme: dark)').matches - const resolved = mode === 'auto' ? (prefersDark ? 'dark' : 'light') : mode - - document.documentElement.classList.remove('light', 'dark') - document.documentElement.classList.add(resolved) - - if (mode === 'auto') { - document.documentElement.removeAttribute('data-theme') - } else { - document.documentElement.setAttribute('data-theme', mode) - } - - document.documentElement.style.colorScheme = resolved -} - -export default function ThemeToggle() { - const [mode, setMode] = useState('auto') - - useEffect(() => { - const initialMode = getInitialMode() - setMode(initialMode) - applyThemeMode(initialMode) - }, []) - - useEffect(() => { - if (mode !== 'auto') { - return - } - - const media = window.matchMedia('(prefers-color-scheme: dark)') - const onChange = () => applyThemeMode('auto') - - media.addEventListener('change', onChange) - return () => { - media.removeEventListener('change', onChange) - } - }, [mode]) - - function toggleMode() { - const nextMode: ThemeMode = - mode === 'light' ? 'dark' : mode === 'dark' ? 'auto' : 'light' - setMode(nextMode) - applyThemeMode(nextMode) - window.localStorage.setItem('theme', nextMode) - } - - const label = - mode === 'auto' - ? 'Theme mode: auto (system). Click to switch to light mode.' - : `Theme mode: ${mode}. Click to switch mode.` - - return ( - - ) -} diff --git a/apps/midimarble/src/routeTree.gen.ts b/apps/midimarble/src/routeTree.gen.ts index 421daf2..dceedff 100644 --- a/apps/midimarble/src/routeTree.gen.ts +++ b/apps/midimarble/src/routeTree.gen.ts @@ -9,14 +9,8 @@ // Additionally, you should also exclude this file from your linter and/or formatter to prevent it from being checked or modified. import { Route as rootRouteImport } from './routes/__root' -import { Route as AboutRouteImport } from './routes/about' import { Route as IndexRouteImport } from './routes/index' -const AboutRoute = AboutRouteImport.update({ - id: '/about', - path: '/about', - getParentRoute: () => rootRouteImport, -} as any) const IndexRoute = IndexRouteImport.update({ id: '/', path: '/', @@ -25,39 +19,28 @@ const IndexRoute = IndexRouteImport.update({ export interface FileRoutesByFullPath { '/': typeof IndexRoute - '/about': typeof AboutRoute } export interface FileRoutesByTo { '/': typeof IndexRoute - '/about': typeof AboutRoute } export interface FileRoutesById { __root__: typeof rootRouteImport '/': typeof IndexRoute - '/about': typeof AboutRoute } export interface FileRouteTypes { fileRoutesByFullPath: FileRoutesByFullPath - fullPaths: '/' | '/about' + fullPaths: '/' fileRoutesByTo: FileRoutesByTo - to: '/' | '/about' - id: '__root__' | '/' | '/about' + to: '/' + id: '__root__' | '/' fileRoutesById: FileRoutesById } export interface RootRouteChildren { IndexRoute: typeof IndexRoute - AboutRoute: typeof AboutRoute } declare module '@tanstack/react-router' { interface FileRoutesByPath { - '/about': { - id: '/about' - path: '/about' - fullPath: '/about' - preLoaderRoute: typeof AboutRouteImport - parentRoute: typeof rootRouteImport - } '/': { id: '/' path: '/' @@ -70,7 +53,6 @@ declare module '@tanstack/react-router' { const rootRouteChildren: RootRouteChildren = { IndexRoute: IndexRoute, - AboutRoute: AboutRoute, } export const routeTree = rootRouteImport ._addFileChildren(rootRouteChildren) diff --git a/apps/midimarble/src/router.tsx b/apps/midimarble/src/router.tsx index dfab11b..61b5907 100644 --- a/apps/midimarble/src/router.tsx +++ b/apps/midimarble/src/router.tsx @@ -1,20 +1,19 @@ -import { createRouter as createTanStackRouter } from '@tanstack/react-router' -import { routeTree } from './routeTree.gen' +import { createRouter as createTanStackRouter } from '@tanstack/react-router'; +import { routeTree } from './routeTree.gen'; export function getRouter() { - const router = createTanStackRouter({ - routeTree, + const router = createTanStackRouter({ + routeTree, + scrollRestoration: true, + defaultPreload: 'intent', + defaultPreloadStaleTime: 0 + }); - scrollRestoration: true, - defaultPreload: 'intent', - defaultPreloadStaleTime: 0, - }) - - return router + return router; } declare module '@tanstack/react-router' { - interface Register { - router: ReturnType - } + interface Register { + router: ReturnType ; + } } diff --git a/apps/midimarble/src/routes/__root.tsx b/apps/midimarble/src/routes/__root.tsx index 3f7f8c2..79d2edf 100644 --- a/apps/midimarble/src/routes/__root.tsx +++ b/apps/midimarble/src/routes/__root.tsx @@ -1,61 +1,77 @@ -import { HeadContent, Scripts, createRootRoute } from '@tanstack/react-router' -import { TanStackRouterDevtoolsPanel } from '@tanstack/react-router-devtools' -import { TanStackDevtools } from '@tanstack/react-devtools' -import Footer from '../components/Footer' -import Header from '../components/Header' - -import appCss from '../styles.css?url' - -const THEME_INIT_SCRIPT = `(function(){try{var stored=window.localStorage.getItem('theme');var mode=(stored==='light'||stored==='dark'||stored==='auto')?stored:'auto';var prefersDark=window.matchMedia('(prefers-color-scheme: dark)').matches;var resolved=mode==='auto'?(prefersDark?'dark':'light'):mode;var root=document.documentElement;root.classList.remove('light','dark');root.classList.add(resolved);if(mode==='auto'){root.removeAttribute('data-theme')}else{root.setAttribute('data-theme',mode)}root.style.colorScheme=resolved;}catch(e){}})();` +import { TanStackDevtools } from '@tanstack/react-devtools'; +import { createRootRoute, HeadContent, Scripts } from '@tanstack/react-router'; +import { TanStackRouterDevtoolsPanel } from '@tanstack/react-router-devtools'; +import styles from '../styles.css?url'; export const Route = createRootRoute({ - head: () => ({ - meta: [ - { - charSet: 'utf-8', - }, - { - name: 'viewport', - content: 'width=device-width, initial-scale=1', - }, - { - title: 'TanStack Start Starter', - }, - ], - links: [ - { - rel: 'stylesheet', - href: appCss, - }, - ], - }), - shellComponent: RootDocument, -}) + head: () => ({ + meta: [ + { + charSet: 'utf-8' + }, + { + name: 'viewport', + content: 'width=device-width, initial-scale=1' + }, + { + title: 'Midimarble' + } + ], + links: [ + { rel: 'preconnect', href: 'https://fonts.googleapis.com' }, + { + rel: 'preconnect', + href: 'https://fonts.gstatic.com', + crossOrigin: 'anonymous' + }, + { rel: 'preconnect', href: 'https://api.fontshare.com' }, + // https://fonts.google.com/specimen/Inter + // https://fonts.google.com/specimen/Caveat + { + rel: 'stylesheet', + href: 'https://fonts.googleapis.com/css2?family=Inter:ital,opsz,wght@0,14..32,100..900;1,14..32,100..900&family=Caveat:wght@400..700&display=swap' + }, + // https://www.fontshare.com/fonts/erode + { + rel: 'stylesheet', + href: 'https://api.fontshare.com/v2/css?f[]=erode@1,2&display=swap' + }, + { + rel: 'stylesheet', + href: styles + } + ], + scripts: [ + // Apply theme before paint to prevent flash + { + children: `(function(){var mode='auto';try{var s=localStorage.getItem('focuscat-app-settings');if(s){var t=JSON.parse(s)?.appearance?.theme;if(t==='light'||t==='dark'||t==='auto')mode=t;}}catch(e){}var dark=mode==='dark'||(mode==='auto'&&window.matchMedia('(prefers-color-scheme: dark)').matches);var root=document.documentElement;root.classList.toggle('dark',dark);root.style.colorScheme=dark?'dark':'light';})();` + } + ] + }), + shellComponent: RootDocument +}); function RootDocument({ children }: { children: React.ReactNode }) { - return ( - - - - - - - - {children} - - , - }, - ]} - /> - - - - ) + return ( + + + + + + {children} + + } + ]} + /> + + + + ); } diff --git a/apps/midimarble/src/routes/about.tsx b/apps/midimarble/src/routes/about.tsx deleted file mode 100644 index e5bc399..0000000 --- a/apps/midimarble/src/routes/about.tsx +++ /dev/null @@ -1,23 +0,0 @@ -import { createFileRoute } from '@tanstack/react-router' - -export const Route = createFileRoute('/about')({ - component: About, -}) - -function About() { - return ( - - - ) -} diff --git a/apps/midimarble/src/routes/index.tsx b/apps/midimarble/src/routes/index.tsx index f732d82..8c87d1d 100644 --- a/apps/midimarble/src/routes/index.tsx +++ b/apps/midimarble/src/routes/index.tsx @@ -1,87 +1,7 @@ -import { createFileRoute } from '@tanstack/react-router' +import { createFileRoute } from '@tanstack/react-router'; -export const Route = createFileRoute('/')({ component: App }) +export const Route = createFileRoute('/')({ component: RouteComponent }); -function App() { - return ( -- -About
-- A small starter with room to grow. -
-- TanStack Start gives you type-safe routing, server functions, and - modern SSR defaults. Use this as a clean foundation, then layer in - your own routes, styling, and add-ons. -
-- - ) +function RouteComponent() { + return- - - - -TanStack Start Base Template
-- Start simple, ship quickly. -
-- This base starter intentionally keeps things light: two routes, clean - structure, and the essentials you need to build from scratch. -
- -- {[ - [ - 'Type-Safe Routing', - 'Routes and links stay in sync across every page.', - ], - [ - 'Server Functions', - 'Call server code from your UI without creating API boilerplate.', - ], - [ - 'Streaming by Default', - 'Ship progressively rendered responses for faster experiences.', - ], - [ - 'Tailwind Native', - 'Design quickly with utility-first styling and reusable tokens.', - ], - ].map(([title, desc], index) => ( - - -- - ))} -- {title} -
-{desc}
-- -Quick Start
--
-- - Edit
-src/routes/index.tsxto customize the home page. -- - Update
-src/components/Header.tsxand{' '} -src/components/Footer.tsxfor brand links. -- - Add routes in
-src/routesand tweak visual tokens in{' '} -src/styles.css. -Hello World; } diff --git a/apps/midimarble/src/styles.css b/apps/midimarble/src/styles.css index 498b4c5..914be3c 100644 --- a/apps/midimarble/src/styles.css +++ b/apps/midimarble/src/styles.css @@ -1,259 +1,55 @@ -@import url("https://fonts.googleapis.com/css2?family=Fraunces:opsz,wght@9..144,500;9..144,700&family=Manrope:wght@400;500;600;700;800&display=swap"); -@import "tailwindcss"; +@import 'tailwindcss'; @plugin "@tailwindcss/typography"; @theme { - --font-sans: "Manrope", ui-sans-serif, system-ui, sans-serif; -} - -:root { - --sea-ink: #173a40; - --sea-ink-soft: #416166; - --lagoon: #4fb8b2; - --lagoon-deep: #328f97; - --palm: #2f6a4a; - --sand: #e7f0e8; - --foam: #f3faf5; - --surface: rgba(255, 255, 255, 0.74); - --surface-strong: rgba(255, 255, 255, 0.9); - --line: rgba(23, 58, 64, 0.14); - --inset-glint: rgba(255, 255, 255, 0.82); - --kicker: rgba(47, 106, 74, 0.9); - --bg-base: #e7f3ec; - --header-bg: rgba(251, 255, 248, 0.84); - --chip-bg: rgba(255, 255, 255, 0.8); - --chip-line: rgba(47, 106, 74, 0.18); - --link-bg-hover: rgba(255, 255, 255, 0.9); - --hero-a: rgba(79, 184, 178, 0.36); - --hero-b: rgba(47, 106, 74, 0.2); -} - -:root[data-theme="dark"] { - --sea-ink: #d7ece8; - --sea-ink-soft: #afcdc8; - --lagoon: #60d7cf; - --lagoon-deep: #8de5db; - --palm: #6ec89a; - --sand: #0f1a1e; - --foam: #101d22; - --surface: rgba(16, 30, 34, 0.8); - --surface-strong: rgba(15, 27, 31, 0.92); - --line: rgba(141, 229, 219, 0.18); - --inset-glint: rgba(194, 247, 238, 0.14); - --kicker: #b8efe5; - --bg-base: #0a1418; - --header-bg: rgba(10, 20, 24, 0.8); - --chip-bg: rgba(13, 28, 32, 0.9); - --chip-line: rgba(141, 229, 219, 0.24); - --link-bg-hover: rgba(24, 44, 49, 0.8); - --hero-a: rgba(96, 215, 207, 0.18); - --hero-b: rgba(110, 200, 154, 0.12); -} - -@media (prefers-color-scheme: dark) { - :root:not([data-theme="light"]) { - --sea-ink: #d7ece8; - --sea-ink-soft: #afcdc8; - --lagoon: #60d7cf; - --lagoon-deep: #8de5db; - --palm: #6ec89a; - --sand: #0f1a1e; - --foam: #101d22; - --surface: rgba(16, 30, 34, 0.8); - --surface-strong: rgba(15, 27, 31, 0.92); - --line: rgba(141, 229, 219, 0.18); - --inset-glint: rgba(194, 247, 238, 0.14); - --kicker: #b8efe5; - --bg-base: #0a1418; - --header-bg: rgba(10, 20, 24, 0.8); - --chip-bg: rgba(13, 28, 32, 0.9); - --chip-line: rgba(141, 229, 219, 0.24); - --link-bg-hover: rgba(24, 44, 49, 0.8); - --hero-a: rgba(96, 215, 207, 0.18); - --hero-b: rgba(110, 200, 154, 0.12); - } -} - -* { - box-sizing: border-box; -} - -html, -body, -#app { - min-height: 100%; -} - -body { - margin: 0; - color: var(--sea-ink); - font-family: var(--font-sans); - background-color: var(--bg-base); - background: - radial-gradient(1100px 620px at -8% -10%, var(--hero-a), transparent 58%), - radial-gradient(1050px 620px at 112% -12%, var(--hero-b), transparent 62%), - radial-gradient(720px 380px at 50% 115%, rgba(79, 184, 178, 0.1), transparent 68%), - linear-gradient(180deg, color-mix(in oklab, var(--sand) 68%, white) 0%, var(--foam) 44%, var(--bg-base) 100%); - overflow-x: hidden; - -webkit-font-smoothing: antialiased; - -moz-osx-font-smoothing: grayscale; -} - -body::before { - content: ""; - position: fixed; - inset: 0; - pointer-events: none; - z-index: -1; - opacity: 0.28; - background: - radial-gradient(circle at 20% 15%, rgba(255, 255, 255, 0.8), transparent 34%), - radial-gradient(circle at 78% 26%, rgba(79, 184, 178, 0.2), transparent 42%), - radial-gradient(circle at 42% 82%, rgba(47, 106, 74, 0.14), transparent 36%); -} - -body::after { - content: ""; - position: fixed; - inset: 0; - pointer-events: none; - z-index: -1; - opacity: 0.14; - background-image: - linear-gradient(rgba(255, 255, 255, 0.07) 1px, transparent 1px), - linear-gradient(90deg, rgba(255, 255, 255, 0.06) 1px, transparent 1px); - background-size: 28px 28px; - mask-image: radial-gradient(circle at 50% 30%, black, transparent 78%); -} - -a { - color: var(--lagoon-deep); - text-decoration-color: rgba(50, 143, 151, 0.4); - text-decoration-thickness: 1px; - text-underline-offset: 2px; -} - -a:hover { - color: #246f76; -} - -code { - font-size: 0.9em; - border: 1px solid var(--line); - background: color-mix(in oklab, var(--surface-strong) 82%, white 18%); - border-radius: 7px; - padding: 2px 7px; -} - -pre code { - border: 0; - background: transparent; - padding: 0; - border-radius: 0; - font-size: inherit; - color: inherit; -} - -.page-wrap { - width: min(1080px, calc(100% - 2rem)); - margin-inline: auto; -} - -.display-title { - font-family: "Fraunces", Georgia, serif; -} - -.island-shell { - border: 1px solid var(--line); - background: linear-gradient(165deg, var(--surface-strong), var(--surface)); - box-shadow: - 0 1px 0 var(--inset-glint) inset, - 0 22px 44px rgba(30, 90, 72, 0.1), - 0 6px 18px rgba(23, 58, 64, 0.08); - backdrop-filter: blur(4px); -} - -.feature-card { - background: linear-gradient(165deg, color-mix(in oklab, var(--surface-strong) 93%, white 7%), var(--surface)); - box-shadow: - 0 1px 0 var(--inset-glint) inset, - 0 18px 34px rgba(30, 90, 72, 0.1), - 0 4px 14px rgba(23, 58, 64, 0.06); -} - -.feature-card:hover { - transform: translateY(-2px); - border-color: color-mix(in oklab, var(--lagoon-deep) 35%, var(--line)); -} - -button, -.island-shell, -a { - transition: background-color 180ms ease, color 180ms ease, border-color 180ms ease, - transform 180ms ease; -} - -.island-kicker { - letter-spacing: 0.16em; - text-transform: uppercase; - font-weight: 700; - font-size: 0.69rem; - color: var(--kicker); -} - -.nav-link { - position: relative; - display: inline-flex; - align-items: center; - text-decoration: none; - color: var(--sea-ink-soft); -} - -.nav-link::after { - content: ""; - position: absolute; - left: 0; - bottom: -6px; - width: 100%; - height: 2px; - transform: scaleX(0); - transform-origin: left; - background: linear-gradient(90deg, var(--lagoon), #7ed3bf); - transition: transform 170ms ease; -} - -.nav-link:hover, -.nav-link.is-active { - color: var(--sea-ink); -} - -.nav-link:hover::after, -.nav-link.is-active::after { - transform: scaleX(1); -} - -@media (max-width: 640px) { - .nav-link::after { - bottom: -4px; - } -} - -.site-footer { - border-top: 1px solid var(--line); - background: color-mix(in oklab, var(--header-bg) 84%, transparent 16%); -} - -.rise-in { - animation: rise-in 700ms cubic-bezier(0.16, 1, 0.3, 1) both; -} - -@keyframes rise-in { - from { - opacity: 0; - transform: translateY(12px); - } - to { - opacity: 1; - transform: translateY(0); - } + /* Zinc-based neutral scale (light mode) */ + --color-base-0: #ffffff; + --color-base-50: #fafafa; + --color-base-100: #f4f4f5; + --color-base-200: #e4e4e7; + --color-base-300: #d4d4d8; + --color-base-400: #a1a1aa; + --color-base-500: #71717a; + --color-base-600: #52525b; + --color-base-700: #3f3f46; + --color-base-800: #27272a; + --color-base-900: #18181b; + --color-base-950: #09090b; + + /* Semantic colors */ + --color-primary: #3b82f6; + --color-primary-content: #ffffff; + --color-secondary: #8b5cf6; + --color-secondary-content: #ffffff; + --color-accent: #f97316; + --color-accent-content: #ffffff; + --color-info: #0ea5e9; + --color-info-content: #ffffff; + --color-success: #22c55e; + --color-success-content: #ffffff; + --color-warning: #eab308; + --color-warning-content: #18181b; + --color-error: #ef4444; + --color-error-content: #ffffff; + + /* Fonts */ + --font-sans: 'Inter', system-ui, sans-serif; + --font-serif: 'Erode', serif; + --font-handwritten: 'Caveat', cursive; +} + +/* Dark mode */ +.dark { + --color-base-0: #09090b; + --color-base-50: #18181b; + --color-base-100: #27272a; + --color-base-200: #3f3f46; + --color-base-300: #52525b; + --color-base-400: #71717a; + --color-base-500: #a1a1aa; + --color-base-600: #d4d4d8; + --color-base-700: #e4e4e7; + --color-base-800: #f4f4f5; + --color-base-900: #fafafa; + --color-base-950: #ffffff; } diff --git a/apps/midimarble/src/vite-env.d.ts b/apps/midimarble/src/vite-env.d.ts new file mode 100644 index 0000000..11f02fe --- /dev/null +++ b/apps/midimarble/src/vite-env.d.ts @@ -0,0 +1 @@ +///From 4760b412f2bc2f1b6b6192ce75e8af2ea3dc8d52 Mon Sep 17 00:00:00 2001 From: Benno <57860196+bennoinbeta@users.noreply.github.com> Date: Tue, 10 Mar 2026 08:16:07 +0100 Subject: [PATCH 04/51] #7 setup native threejs viewport base --- apps/midimarble/package.json | 4 +- .../src/modules/three/ThreeViewportApp.ts | 83 +++++++++++++++++++ .../three/components/ThreeViewport.tsx | 16 ++++ .../three/components/ThreeViewportClient.tsx | 30 +++++++ .../src/modules/three/components/index.ts | 2 + apps/midimarble/src/modules/three/index.ts | 3 + apps/midimarble/src/routes/index.tsx | 32 ++++++- pnpm-lock.yaml | 59 +++++++++++++ 8 files changed, 227 insertions(+), 2 deletions(-) create mode 100644 apps/midimarble/src/modules/three/ThreeViewportApp.ts create mode 100644 apps/midimarble/src/modules/three/components/ThreeViewport.tsx create mode 100644 apps/midimarble/src/modules/three/components/ThreeViewportClient.tsx create mode 100644 apps/midimarble/src/modules/three/components/index.ts create mode 100644 apps/midimarble/src/modules/three/index.ts diff --git a/apps/midimarble/package.json b/apps/midimarble/package.json index 2220d7d..800939a 100644 --- a/apps/midimarble/package.json +++ b/apps/midimarble/package.json @@ -32,7 +32,8 @@ "@tanstack/react-start": "^1.166.6", "lucide-react": "^0.577.0", "react": "19.2.4", - "react-dom": "19.2.4" + "react-dom": "19.2.4", + "three": "^0.183.2" }, "devDependencies": { "@tailwindcss/typography": "^0.5.19", @@ -41,6 +42,7 @@ "@types/node": "^25.4.0", "@types/react": "^19.2.14", "@types/react-dom": "^19.2.3", + "@types/three": "^0.183.1", "@vitejs/plugin-react": "^5.1.4", "nitro": "3.0.1-alpha.2", "tailwindcss": "^4.2.1", diff --git a/apps/midimarble/src/modules/three/ThreeViewportApp.ts b/apps/midimarble/src/modules/three/ThreeViewportApp.ts new file mode 100644 index 0000000..a14b583 --- /dev/null +++ b/apps/midimarble/src/modules/three/ThreeViewportApp.ts @@ -0,0 +1,83 @@ +import * as THREE from 'three'; +import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; + +export class ThreeViewportApp { + private readonly container: HTMLDivElement; + private readonly scene: THREE.Scene; + private readonly camera: THREE.PerspectiveCamera; + private readonly renderer: THREE.WebGLRenderer; + private readonly controls: OrbitControls; + private readonly square: THREE.Mesh ; + private readonly resizeObserver: ResizeObserver; + + constructor(container: HTMLDivElement) { + this.container = container; + this.scene = new THREE.Scene(); + + const { width, height } = this.getContainerSize(); + this.camera = new THREE.PerspectiveCamera(55, width / height, 0.1, 100); + this.camera.position.set(0, 0, 4); + + this.renderer = new THREE.WebGLRenderer({ antialias: true }); + this.renderer.setPixelRatio(Math.min(window.devicePixelRatio, 2)); + this.renderer.setSize(width, height); + this.renderer.outputColorSpace = THREE.SRGBColorSpace; + this.container.appendChild(this.renderer.domElement); + + this.controls = new OrbitControls(this.camera, this.renderer.domElement); + this.controls.enableDamping = true; + + const ambient = new THREE.AmbientLight(0xffffff, 0.8); + const directional = new THREE.DirectionalLight(0xffffff, 1.1); + directional.position.set(2, 3, 3); + this.scene.add(ambient, directional); + + const squareGeometry = new THREE.PlaneGeometry(1.5, 1.5); + const squareMaterial = new THREE.MeshStandardMaterial({ color: '#3b82f6' }); + this.square = new THREE.Mesh(squareGeometry, squareMaterial); + this.scene.add(this.square); + + const grid = new THREE.GridHelper(10, 10, '#3f3f46', '#27272a'); + grid.position.y = -1.25; + this.scene.add(grid); + + this.resizeObserver = new ResizeObserver(() => this.resize()); + this.resizeObserver.observe(this.container); + + this.renderer.setAnimationLoop(this.render); + } + + private readonly render = (timeMs: number) => { + const t = timeMs * 0.001; + this.square.rotation.x = t * 0.6; + this.square.rotation.y = t * 0.9; + this.controls.update(); + this.renderer.render(this.scene, this.camera); + }; + + private getContainerSize() { + const width = Math.max(1, this.container.clientWidth); + const height = Math.max(1, this.container.clientHeight); + return { width, height }; + } + + private resize() { + const { width, height } = this.getContainerSize(); + this.camera.aspect = width / height; + this.camera.updateProjectionMatrix(); + this.renderer.setSize(width, height); + } + + dispose() { + this.renderer.setAnimationLoop(null); + this.resizeObserver.disconnect(); + this.controls.dispose(); + this.square.geometry.dispose(); + this.square.material.dispose(); + this.renderer.dispose(); + + if (this.renderer.domElement.parentNode === this.container) { + this.container.removeChild(this.renderer.domElement); + } + } +} diff --git a/apps/midimarble/src/modules/three/components/ThreeViewport.tsx b/apps/midimarble/src/modules/three/components/ThreeViewport.tsx new file mode 100644 index 0000000..1b39eff --- /dev/null +++ b/apps/midimarble/src/modules/three/components/ThreeViewport.tsx @@ -0,0 +1,16 @@ +import React from 'react'; +import { ThreeViewportApp } from '../ThreeViewportApp'; + +export const ThreeViewport: React.FC = () => { + const mountRef = React.useRef (null); + + React.useEffect(() => { + const mount = mountRef.current; + if (mount == null) return; + + const app = new ThreeViewportApp(mount); + return () => app.dispose(); + }, []); + + return ; +}; diff --git a/apps/midimarble/src/modules/three/components/ThreeViewportClient.tsx b/apps/midimarble/src/modules/three/components/ThreeViewportClient.tsx new file mode 100644 index 0000000..f8897a4 --- /dev/null +++ b/apps/midimarble/src/modules/three/components/ThreeViewportClient.tsx @@ -0,0 +1,30 @@ +import { ClientOnly } from '@tanstack/react-router'; +import React from 'react'; + +const LazyThreeViewport = React.lazy(() => + import('./ThreeViewport').then((module) => ({ + default: module.ThreeViewport + })) +); + +export const ThreeViewportClient: React.FC = () => { + return ( + + Loading 3D viewport... + + } + > + + ); +}; diff --git a/apps/midimarble/src/modules/three/components/index.ts b/apps/midimarble/src/modules/three/components/index.ts new file mode 100644 index 0000000..bb6f5a9 --- /dev/null +++ b/apps/midimarble/src/modules/three/components/index.ts @@ -0,0 +1,2 @@ +export * from './ThreeViewport'; +export * from './ThreeViewportClient'; diff --git a/apps/midimarble/src/modules/three/index.ts b/apps/midimarble/src/modules/three/index.ts new file mode 100644 index 0000000..b94785b --- /dev/null +++ b/apps/midimarble/src/modules/three/index.ts @@ -0,0 +1,3 @@ +// Sets up the native Three.js viewport and client-side mounting helpers. +export * from './components'; +export * from './ThreeViewportApp'; diff --git a/apps/midimarble/src/routes/index.tsx b/apps/midimarble/src/routes/index.tsx index 8c87d1d..4a042b4 100644 --- a/apps/midimarble/src/routes/index.tsx +++ b/apps/midimarble/src/routes/index.tsx @@ -1,7 +1,37 @@ import { createFileRoute } from '@tanstack/react-router'; +import { ThreeViewportClient } from '@/modules/three'; export const Route = createFileRoute('/')({ component: RouteComponent }); function RouteComponent() { - return+ Loading Three.js... + + } + > + ++ Hello World; + return ( ++ + ); } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 569482e..24e0868 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -385,6 +385,9 @@ importers: react-dom: specifier: 19.2.4 version: 19.2.4(react@19.2.4) + three: + specifier: ^0.183.2 + version: 0.183.2 devDependencies: '@tailwindcss/typography': specifier: ^0.5.19 @@ -404,6 +407,9 @@ importers: '@types/react-dom': specifier: ^19.2.3 version: 19.2.3(@types/react@19.2.14) + '@types/three': + specifier: ^0.183.1 + version: 0.183.1 '@vitejs/plugin-react': specifier: ^5.1.4 version: 5.1.4(vite@7.3.1(@types/node@25.4.0)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)) @@ -985,6 +991,9 @@ packages: resolution: {integrity: sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==} engines: {node: '>=12'} + '@dimforge/rapier3d-compat@0.12.0': + resolution: {integrity: sha512-uekIGetywIgopfD97oDL5PfeezkFpNhwlzlaEYNOA0N6ghdsOvh/HYjSMek5Q2O1PYvRSDFcqFVJl4r4ZBwOow==} + '@drizzle-team/brocli@0.11.0': resolution: {integrity: sha512-hD3pekGiPg0WPCCGAZmusBBJsDqGUR66Y452YgQsZOnkdQ7ViEPKuyP4huUGEZQefp8g34RRodXYmJ2TbCH+tg==} @@ -3098,6 +3107,9 @@ packages: '@tsconfig/node16@1.0.4': resolution: {integrity: sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==} + '@tweenjs/tween.js@23.1.3': + resolution: {integrity: sha512-vJmvvwFxYuGnF2axRtPYocag6Clbb5YS7kLL+SO/TeVFzHqDIWrNKYtcsPMibjDx9O+bu+psAy9NKfWklassUA==} + '@tybys/wasm-util@0.10.1': resolution: {integrity: sha512-9tTaPJLSiejZKx+Bmog4uSubteqTvFrVrURwkmHixBo0G4seD0zUxp98E1DzUBJxLQ3NPwXrGKDiVjwx/DpPsg==} @@ -3184,12 +3196,21 @@ packages: '@types/stack-utils@2.0.3': resolution: {integrity: sha512-9aEbYZ3TbYMznPdcdr3SmIrLXwC/AKZXQeCf9Pgao5CKb8CyHuEX5jzWPTkvregvhRJHcpRO6BFoGW9ycaOkYw==} + '@types/stats.js@0.17.4': + resolution: {integrity: sha512-jIBvWWShCvlBqBNIZt0KAshWpvSjhkwkEu4ZUcASoAvhmrgAUI2t1dXrjSL4xXVLB4FznPrIsX3nKXFl/Dt4vA==} + + '@types/three@0.183.1': + resolution: {integrity: sha512-f2Pu5Hrepfgavttdye3PsH5RWyY/AvdZQwIVhrc4uNtvF7nOWJacQKcoVJn0S4f0yYbmAE6AR+ve7xDcuYtMGw==} + '@types/unist@2.0.11': resolution: {integrity: sha512-CmBKiL6NNo/OqgmMn95Fk9Whlp2mtvIv+KNpQKN2F4SjvrEesubTRWGYSg+BnWZOnlCaSTU1sMpsBOzgbYhnsA==} '@types/unist@3.0.3': resolution: {integrity: sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q==} + '@types/webxr@0.5.24': + resolution: {integrity: sha512-h8fgEd/DpoS9CBrjEQXR+dIDraopAEfu4wYVNY2tEPwk60stPWhvZMf4Foo5FakuQ7HFZoa8WceaWFervK2Ovg==} + '@types/yargs-parser@21.0.3': resolution: {integrity: sha512-I4q9QU9MQv4oEOz4tAHJtNz1cwuLxn2F3xcc2iV5WdqLPpUnj30aUuxt1mAxYTG+oe8CZMV/+6rU4S4gRDzqtQ==} @@ -3477,6 +3498,9 @@ packages: '@vitest/utils@4.0.18': resolution: {integrity: sha512-msMRKLMVLWygpK3u2Hybgi4MNjcYJvwTb0Ru09+fOyCXIgT5raYP041DRRdiJiI3k/2U6SEbAETB3YtBrUkCFA==} + '@webgpu/types@0.1.69': + resolution: {integrity: sha512-RPmm6kgRbI8e98zSD3RVACvnuktIja5+yLgDAkTmxLr90BEwdTXRQWNLF3ETTTyH/8mKhznZuN5AveXYFEsMGQ==} + '@xmldom/xmldom@0.7.13': resolution: {integrity: sha512-lm2GW5PkosIzccsaZIz7tp8cPADSIlIHWDFTR1N0SzfinhhYgeIQjFMz4rYzanCScr3DqQLeomUDArp6MWKm+g==} engines: {node: '>=10.0.0'} @@ -5039,6 +5063,9 @@ packages: fetch-retry@4.1.1: resolution: {integrity: sha512-e6eB7zN6UBSwGVwrbWVH+gdLnkW9WwHhmq2YDK1Sh30pzx1onRVGBvogTlUeWxwTa+L86NYdo4hFkh7O8ZjSnA==} + fflate@0.8.2: + resolution: {integrity: sha512-cPJU47OaAoCbg0pBvzsgpTPhmhqI5eJjh/JIu8tPj5q+T7iLvW/JAYUqmE7KOB4R1ZyEhzBaIQpQpardBF5z8A==} + figures@3.2.0: resolution: {integrity: sha512-yaduQFRKLXYOGgEn6AZau90j3ggSOyiqXU0F9JZfeXYhNa+Jk4X+s45A2zg5jns87GAFa34BBm2kXw4XpNcbdg==} engines: {node: '>=8'} @@ -6026,6 +6053,9 @@ packages: resolution: {integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==} engines: {node: '>= 8'} + meshoptimizer@1.0.1: + resolution: {integrity: sha512-Vix+QlA1YYT3FwmBBZ+49cE5y/b+pRrcXKqGpS5ouh33d3lSp2PoTpCw19E0cKDFWalembrHnIaZetf27a+W2g==} + methods@1.1.2: resolution: {integrity: sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==} engines: {node: '>= 0.6'} @@ -7720,6 +7750,9 @@ packages: thenify@3.3.1: resolution: {integrity: sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw==} + three@0.183.2: + resolution: {integrity: sha512-di3BsL2FEQ1PA7Hcvn4fyJOlxRRgFYBpMTcyOgkwJIaDOdJMebEFPA+t98EvjuljDx4hNulAGwF6KIjtwI5jgQ==} + throat@5.0.0: resolution: {integrity: sha512-fcwX4mndzpLQKBS1DVYhGAcYaYt7vsHNIvQV+WXMvnow5cgjPphq5CaayLaGsjRdSCKZFNGt7/GYAuXaNOiYCA==} @@ -9198,6 +9231,8 @@ snapshots: dependencies: '@jridgewell/trace-mapping': 0.3.9 + '@dimforge/rapier3d-compat@0.12.0': {} + '@drizzle-team/brocli@0.11.0': {} '@egjs/hammerjs@2.0.17': @@ -11604,6 +11639,8 @@ snapshots: '@tsconfig/node16@1.0.4': {} + '@tweenjs/tween.js@23.1.3': {} + '@tybys/wasm-util@0.10.1': dependencies: tslib: 2.8.1 @@ -11705,10 +11742,24 @@ snapshots: '@types/stack-utils@2.0.3': {} + '@types/stats.js@0.17.4': {} + + '@types/three@0.183.1': + dependencies: + '@dimforge/rapier3d-compat': 0.12.0 + '@tweenjs/tween.js': 23.1.3 + '@types/stats.js': 0.17.4 + '@types/webxr': 0.5.24 + '@webgpu/types': 0.1.69 + fflate: 0.8.2 + meshoptimizer: 1.0.1 + '@types/unist@2.0.11': {} '@types/unist@3.0.3': {} + '@types/webxr@0.5.24': {} + '@types/yargs-parser@21.0.3': {} '@types/yargs@17.0.35': @@ -12020,6 +12071,8 @@ snapshots: '@vitest/pretty-format': 4.0.18 tinyrainbow: 3.0.3 + '@webgpu/types@0.1.69': {} + '@xmldom/xmldom@0.7.13': {} '@xmldom/xmldom@0.8.11': {} @@ -13967,6 +14020,8 @@ snapshots: fetch-retry@4.1.1: {} + fflate@0.8.2: {} + figures@3.2.0: dependencies: escape-string-regexp: 1.0.5 @@ -15072,6 +15127,8 @@ snapshots: merge2@1.4.1: {} + meshoptimizer@1.0.1: {} + methods@1.1.2: {} metro-babel-transformer@0.83.3: @@ -17313,6 +17370,8 @@ snapshots: dependencies: any-promise: 1.3.0 + three@0.183.2: {} + throat@5.0.0: {} tiny-invariant@1.3.3: {} From f0daf9090e7018c9669b9e17e07159eb0c076fbc Mon Sep 17 00:00:00 2001 From: Benno <57860196+bennoinbeta@users.noreply.github.com> Date: Tue, 10 Mar 2026 10:23:31 +0100 Subject: [PATCH 05/51] #7 scaffold ecs engine/editor foundation --- apps/midimarble/package.json | 3 + apps/midimarble/src/hooks/index.ts | 1 + apps/midimarble/src/hooks/use-memo-cleanup.ts | 52 ++++++++ apps/midimarble/src/modules/editor/Editor.tsx | 53 ++++++++ .../src/modules/editor/EditorCx.tsx | 46 +++++++ .../src/modules/editor/hooks/index.ts | 1 + .../modules/editor/hooks/use-cube-rotation.ts | 76 ++++++++++++ apps/midimarble/src/modules/editor/index.ts | 3 + apps/midimarble/src/modules/engine/Runtime.ts | 75 ++++++++++++ apps/midimarble/src/modules/engine/index.ts | 2 + .../engine/plugins/core/create-core-plugin.ts | 54 ++++++++ .../src/modules/engine/plugins/core/index.ts | 1 + .../src/modules/engine/plugins/index.ts | 2 + .../plugins/render/RenderViewportRuntime.ts | 115 ++++++++++++++++++ .../plugins/render/create-render-plugin.ts | 69 +++++++++++ .../modules/engine/plugins/render/index.ts | 2 + .../src/modules/three/ThreeViewportApp.ts | 83 ------------- .../three/components/ThreeViewport.tsx | 16 --- .../three/components/ThreeViewportClient.tsx | 30 ----- .../src/modules/three/components/index.ts | 2 - apps/midimarble/src/modules/three/index.ts | 3 - apps/midimarble/src/routes/index.tsx | 33 +---- pnpm-lock.yaml | 9 ++ 23 files changed, 566 insertions(+), 165 deletions(-) create mode 100644 apps/midimarble/src/hooks/index.ts create mode 100644 apps/midimarble/src/hooks/use-memo-cleanup.ts create mode 100644 apps/midimarble/src/modules/editor/Editor.tsx create mode 100644 apps/midimarble/src/modules/editor/EditorCx.tsx create mode 100644 apps/midimarble/src/modules/editor/hooks/index.ts create mode 100644 apps/midimarble/src/modules/editor/hooks/use-cube-rotation.ts create mode 100644 apps/midimarble/src/modules/editor/index.ts create mode 100644 apps/midimarble/src/modules/engine/Runtime.ts create mode 100644 apps/midimarble/src/modules/engine/index.ts create mode 100644 apps/midimarble/src/modules/engine/plugins/core/create-core-plugin.ts create mode 100644 apps/midimarble/src/modules/engine/plugins/core/index.ts create mode 100644 apps/midimarble/src/modules/engine/plugins/index.ts create mode 100644 apps/midimarble/src/modules/engine/plugins/render/RenderViewportRuntime.ts create mode 100644 apps/midimarble/src/modules/engine/plugins/render/create-render-plugin.ts create mode 100644 apps/midimarble/src/modules/engine/plugins/render/index.ts delete mode 100644 apps/midimarble/src/modules/three/ThreeViewportApp.ts delete mode 100644 apps/midimarble/src/modules/three/components/ThreeViewport.tsx delete mode 100644 apps/midimarble/src/modules/three/components/ThreeViewportClient.tsx delete mode 100644 apps/midimarble/src/modules/three/components/index.ts delete mode 100644 apps/midimarble/src/modules/three/index.ts diff --git a/apps/midimarble/package.json b/apps/midimarble/package.json index 800939a..9990d02 100644 --- a/apps/midimarble/package.json +++ b/apps/midimarble/package.json @@ -30,6 +30,9 @@ "@tanstack/react-router": "^1.166.6", "@tanstack/react-router-devtools": "^1.166.6", "@tanstack/react-start": "^1.166.6", + "ecsify": "^0.0.15", + "feature-react": "^0.0.67", + "feature-state": "^0.0.65", "lucide-react": "^0.577.0", "react": "19.2.4", "react-dom": "19.2.4", diff --git a/apps/midimarble/src/hooks/index.ts b/apps/midimarble/src/hooks/index.ts new file mode 100644 index 0000000..3b6a7d2 --- /dev/null +++ b/apps/midimarble/src/hooks/index.ts @@ -0,0 +1 @@ +export * from './use-memo-cleanup'; diff --git a/apps/midimarble/src/hooks/use-memo-cleanup.ts b/apps/midimarble/src/hooks/use-memo-cleanup.ts new file mode 100644 index 0000000..643310e --- /dev/null +++ b/apps/midimarble/src/hooks/use-memo-cleanup.ts @@ -0,0 +1,52 @@ +import React from 'react'; + +// Registry to handle cleanup when component gets garbage collected +const registry = new FinalizationRegistry((cleanupRef: React.RefObject<(() => void) | null>) => { + cleanupRef.current?.(); // cleanup on unmount +}); + +/** + * A version of useMemo that allows cleanup using FinalizationRegistry. + * This ensures proper cleanup even in React Strict Mode where components might mount/unmount multiple times. + * + * @see https://stackoverflow.com/questions/66446642/react-usememo-memory-clean + * + * @example + * ```ts + * const editor = useMemoCleanup(() => { + * const content = createState(initialValue); + * const unlisten = content.listen(() => {}); + * return [{ content }, unlisten]; + * }, [initialValue]); + * ``` + */ +export function useMemoCleanup+ + + + + ++ + Native Three.js viewport (no React Three Fiber) ++( + factory: () => [T, () => void], + deps: React.DependencyList = [] +): T { + const cleanupRef = React.useRef<(() => void) | null>(null); // Holds cleanup function + const valueRef = React.useRef (undefined); // Tracks latest value after cleanup + const unmountRef = React.useRef(false); // GC-triggering candidate, once true triggers registry + + // Register cleanup only once per component instance + if (!unmountRef.current) { + unmountRef.current = true; + registry.register(unmountRef, cleanupRef); + } + + const value = React.useMemo(() => { + // Clean up previous value before creating new one + cleanupRef.current?.(); + cleanupRef.current = null; + + // Create new value and store its cleanup + const [returned, cleanup] = factory(); + cleanupRef.current = cleanup; + valueRef.current = returned; // Track latest value for access after cleanup + + return returned; + }, deps); + + // Return latest value from ref in case previous was cleaned up + return valueRef.current ?? value; +} diff --git a/apps/midimarble/src/modules/editor/Editor.tsx b/apps/midimarble/src/modules/editor/Editor.tsx new file mode 100644 index 0000000..98a9873 --- /dev/null +++ b/apps/midimarble/src/modules/editor/Editor.tsx @@ -0,0 +1,53 @@ +import React from 'react'; +import { EditorCxProvider, useEditorCx } from './EditorCx'; +import { useCubeRotation } from './hooks'; + +export const Editor: React.FC = () => { + return ( + + + ); +}; + +const InnerEditor: React.FC = () => { + const editorCx = useEditorCx(); + const cubeRotation = useCubeRotation(); + + return ( ++ + + ); +}; diff --git a/apps/midimarble/src/modules/editor/EditorCx.tsx b/apps/midimarble/src/modules/editor/EditorCx.tsx new file mode 100644 index 0000000..a2b6ef4 --- /dev/null +++ b/apps/midimarble/src/modules/editor/EditorCx.tsx @@ -0,0 +1,46 @@ +import React from 'react'; +import { useMemoCleanup } from '@/hooks'; +import { Runtime } from '@/modules/engine'; + +export class EditorCx { + public readonly runtime: Runtime; + private _container: HTMLDivElement | null = null; + + constructor() { + this.runtime = new Runtime(); + } + + public readonly setContainer = (container: HTMLDivElement | null): void => { + if (this._container === container) { + return; + } + this._container = container; + this.runtime.setContainer(container); + }; + + public unmount(): void { + this.runtime.unmount(); + this._container = null; + } +} + +// MARK: - React Context + +const ReactEditorCx = React.createContext+ + + + + + ++ ECSify + native Three.js viewport ++(null); + +export const EditorCxProvider: React.FC<{ children: React.ReactNode }> = ({ children }) => { + const cx = useMemoCleanup(() => { + const editorCx = new EditorCx(); + return [editorCx, () => editorCx.unmount()]; + }, []); + + return {children} ; +}; + +export function useEditorCx(): EditorCx { + const cx = React.useContext(ReactEditorCx); + if (cx == null) { + throw new Error('useEditorCx must be used within EditorCxProvider'); + } + return cx; +} diff --git a/apps/midimarble/src/modules/editor/hooks/index.ts b/apps/midimarble/src/modules/editor/hooks/index.ts new file mode 100644 index 0000000..3a443c8 --- /dev/null +++ b/apps/midimarble/src/modules/editor/hooks/index.ts @@ -0,0 +1 @@ +export * from './use-cube-rotation'; diff --git a/apps/midimarble/src/modules/editor/hooks/use-cube-rotation.ts b/apps/midimarble/src/modules/editor/hooks/use-cube-rotation.ts new file mode 100644 index 0000000..b0ec92d --- /dev/null +++ b/apps/midimarble/src/modules/editor/hooks/use-cube-rotation.ts @@ -0,0 +1,76 @@ +import React from 'react'; +import { useEditorCx } from '../EditorCx'; + +export function useCubeRotation(): TCubeRotation | null { + const cx = useEditorCx(); + const [rotation, setRotation] = React.useState(null); + + React.useEffect(() => { + const { app } = cx.runtime; + const readCubeRotation = (): TCubeRotation | null => { + const { cubeEid } = app.r; + if (cubeEid == null) { + return null; + } + + if (!app.hasComponent(cubeEid, app.c.Rotation)) { + return null; + } + + const x = app.c.Rotation.x[cubeEid]; + const y = app.c.Rotation.y[cubeEid]; + const z = app.c.Rotation.z[cubeEid]; + if (x == null || y == null || z == null) { + return null; + } + + return { + x, + y, + z + }; + }; + + const syncFromEcs = () => { + setRotation(readCubeRotation()); + }; + + const onRotationChange = (eid: number) => { + if (eid === app.r.cubeEid) { + syncFromEcs(); + } + }; + + const onRotationAdd = (eid: number) => { + if (eid === app.r.cubeEid) { + syncFromEcs(); + } + }; + + const onRotationRemove = (eid: number) => { + if (eid === app.r.cubeEid) { + setRotation(null); + } + }; + + const unbindChange = app._componentRegistry.onComponentChange(app.c.Rotation, onRotationChange); + const unbindAdd = app._componentRegistry.onComponentAdd(app.c.Rotation, onRotationAdd); + const unbindRemove = app._componentRegistry.onComponentRemove(app.c.Rotation, onRotationRemove); + + syncFromEcs(); + + return () => { + unbindChange(); + unbindAdd(); + unbindRemove(); + }; + }, [cx]); + + return rotation; +} + +interface TCubeRotation { + x: number; + y: number; + z: number; +} diff --git a/apps/midimarble/src/modules/editor/index.ts b/apps/midimarble/src/modules/editor/index.ts new file mode 100644 index 0000000..2c27a72 --- /dev/null +++ b/apps/midimarble/src/modules/editor/index.ts @@ -0,0 +1,3 @@ +export * from './Editor'; +export * from './EditorCx'; +export * from './hooks'; diff --git a/apps/midimarble/src/modules/engine/Runtime.ts b/apps/midimarble/src/modules/engine/Runtime.ts new file mode 100644 index 0000000..25df7c5 --- /dev/null +++ b/apps/midimarble/src/modules/engine/Runtime.ts @@ -0,0 +1,75 @@ +import { + createApp, + createDefaultPlugin, + type TApp, + type TAppContext, + type TDefaultPlugin +} from 'ecsify'; +import { + createCorePlugin, + createRenderPlugin, + type TCorePlugin, + type TRenderPlugin +} from './plugins'; + +export class Runtime { + private readonly _app: TRuntimeApp; + private _frameId: number | null = null; + private _lastTime = 0; + private _isMounted = true; + + constructor() { + this._app = createApp({ + plugins: [createDefaultPlugin(), createCorePlugin(), createRenderPlugin()] as const, + systemSets: ['First', 'Update', 'Last'] + }); + this.start(); + } + + public get app(): TRuntimeApp { + return this._app; + } + + public start(): void { + if (!this._isMounted || this._frameId != null) { + return; + } + this._lastTime = performance.now(); + this._frameId = window.requestAnimationFrame(this._loop); + } + + public stop(): void { + if (this._frameId == null) { + return; + } + window.cancelAnimationFrame(this._frameId); + this._frameId = null; + } + + public setContainer(container: HTMLDivElement | null): void { + this._app.r.viewport.setContainer(container); + } + + public unmount(): void { + if (!this._isMounted) { + return; + } + this._isMounted = false; + this.stop(); + this._app.r.viewport.setContainer(null); + this._app.r.viewport.dispose(); + this._app.flush(); + } + + private readonly _loop = (time: number): void => { + if (!this._isMounted) { + return; + } + const dt = Math.max(0, (time - this._lastTime) / 1000); + this._lastTime = time; + this._app.update(dt); + this._frameId = window.requestAnimationFrame(this._loop); + }; +} + +export type TRuntimeApp = TApp >; diff --git a/apps/midimarble/src/modules/engine/index.ts b/apps/midimarble/src/modules/engine/index.ts new file mode 100644 index 0000000..91c3ece --- /dev/null +++ b/apps/midimarble/src/modules/engine/index.ts @@ -0,0 +1,2 @@ +export * from './plugins'; +export * from './Runtime'; diff --git a/apps/midimarble/src/modules/engine/plugins/core/create-core-plugin.ts b/apps/midimarble/src/modules/engine/plugins/core/create-core-plugin.ts new file mode 100644 index 0000000..7e88cbb --- /dev/null +++ b/apps/midimarble/src/modules/engine/plugins/core/create-core-plugin.ts @@ -0,0 +1,54 @@ +import { Entity, type TApp, type TAppContext, type TDefaultPlugin, type TPlugin } from 'ecsify'; + +export function createCorePlugin(): TCorePlugin { + return { + name: 'Core', + deps: ['Default'], + components: { + Rotation: { x: [], y: [], z: [] }, + RotationSpeed: { x: [], y: [], z: [] } + }, + resources: { + elapsedSeconds: 0 + }, + setup(app: TApp >) { + app.addSystem(rotationSystem, { set: 'Update' }); + } + }; +} + +export type TCorePlugin = TPlugin< + { + name: 'Core'; + components: { + Rotation: TCRotation; + RotationSpeed: TCRotationSpeed; + }; + resources: { + elapsedSeconds: number; + }; + systemSets: 'First' | 'Update' | 'Last'; + }, + [TDefaultPlugin] +>; + +type TCRotation = { x: number[]; y: number[]; z: number[] }; +type TCRotationSpeed = { x: number[]; y: number[]; z: number[] }; + +// MARK: - Systems + +function rotationSystem(app: TApp >, dt = 0) { + app.r.elapsedSeconds += dt; + + for (const [eid, rotation, speed] of app.queryComponents([ + Entity, + app.c.Rotation, + app.c.RotationSpeed + ] as const)) { + app.updateComponent(eid, app.c.Rotation, { + x: rotation.x + speed.x * dt, + y: rotation.y + speed.y * dt, + z: rotation.z + speed.z * dt + }); + } +} diff --git a/apps/midimarble/src/modules/engine/plugins/core/index.ts b/apps/midimarble/src/modules/engine/plugins/core/index.ts new file mode 100644 index 0000000..25d9212 --- /dev/null +++ b/apps/midimarble/src/modules/engine/plugins/core/index.ts @@ -0,0 +1 @@ +export * from './create-core-plugin'; diff --git a/apps/midimarble/src/modules/engine/plugins/index.ts b/apps/midimarble/src/modules/engine/plugins/index.ts new file mode 100644 index 0000000..15e3585 --- /dev/null +++ b/apps/midimarble/src/modules/engine/plugins/index.ts @@ -0,0 +1,2 @@ +export * from './core'; +export * from './render'; diff --git a/apps/midimarble/src/modules/engine/plugins/render/RenderViewportRuntime.ts b/apps/midimarble/src/modules/engine/plugins/render/RenderViewportRuntime.ts new file mode 100644 index 0000000..548595c --- /dev/null +++ b/apps/midimarble/src/modules/engine/plugins/render/RenderViewportRuntime.ts @@ -0,0 +1,115 @@ +import * as THREE from 'three'; +import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; + +export class RenderViewportRuntime { + private container: HTMLDivElement | null = null; + private readonly scene: THREE.Scene; + private readonly camera: THREE.PerspectiveCamera; + private readonly renderer: THREE.WebGLRenderer; + private readonly controls: OrbitControls; + private resizeObserver: ResizeObserver | null = null; + private readonly trackedMeshes: THREE.Mesh[] = []; + + constructor() { + this.scene = new THREE.Scene(); + + this.camera = new THREE.PerspectiveCamera(55, 1, 0.1, 100); + this.camera.position.set(0, 0.6, 3.5); + + this.renderer = new THREE.WebGLRenderer({ antialias: true }); + this.renderer.setPixelRatio(Math.min(window.devicePixelRatio, 2)); + this.renderer.setSize(1, 1); + this.renderer.outputColorSpace = THREE.SRGBColorSpace; + + this.controls = new OrbitControls(this.camera, this.renderer.domElement); + this.controls.enableDamping = true; + + const ambient = new THREE.AmbientLight(0xffffff, 0.8); + const directional = new THREE.DirectionalLight(0xffffff, 1.1); + directional.position.set(2, 3, 3); + this.scene.add(ambient, directional); + + const grid = new THREE.GridHelper(10, 10, '#3f3f46', '#27272a'); + grid.position.y = -1; + this.scene.add(grid); + } + + public createCube() { + const geometry = new THREE.BoxGeometry(1, 1, 1); + const material = new THREE.MeshStandardMaterial({ color: '#3b82f6' }); + const cube = new THREE.Mesh(geometry, material); + this.scene.add(cube); + this.trackedMeshes.push(cube); + return cube; + } + + public setContainer(container: HTMLDivElement | null): void { + if (this.container === container) { + return; + } + + this.detachContainer(); + this.container = container; + + if (container == null) { + return; + } + + container.appendChild(this.renderer.domElement); + this.resizeObserver = new ResizeObserver(() => this.resize()); + this.resizeObserver.observe(container); + this.resize(); + } + + public renderFrame() { + if (this.container == null) { + return; + } + this.controls.update(); + this.renderer.render(this.scene, this.camera); + } + + public dispose() { + this.detachContainer(); + this.controls.dispose(); + + for (const mesh of this.trackedMeshes) { + mesh.geometry.dispose(); + if (Array.isArray(mesh.material)) { + for (const material of mesh.material) { + material.dispose(); + } + } else { + mesh.material.dispose(); + } + } + + this.renderer.dispose(); + } + + private getContainerSize() { + if (this.container == null) { + return { width: 1, height: 1 }; + } + const width = Math.max(1, this.container.clientWidth); + const height = Math.max(1, this.container.clientHeight); + return { width, height }; + } + + private detachContainer() { + this.resizeObserver?.disconnect(); + this.resizeObserver = null; + + const parent = this.renderer.domElement.parentNode; + if (parent instanceof HTMLElement) { + parent.removeChild(this.renderer.domElement); + } + } + + private resize() { + const { width, height } = this.getContainerSize(); + this.camera.aspect = width / height; + this.camera.updateProjectionMatrix(); + this.renderer.setSize(width, height); + } +} diff --git a/apps/midimarble/src/modules/engine/plugins/render/create-render-plugin.ts b/apps/midimarble/src/modules/engine/plugins/render/create-render-plugin.ts new file mode 100644 index 0000000..6a8a56c --- /dev/null +++ b/apps/midimarble/src/modules/engine/plugins/render/create-render-plugin.ts @@ -0,0 +1,69 @@ +import { Entity, type TApp, type TAppContext, type TDefaultPlugin, type TPlugin } from 'ecsify'; +import type * as THREE from 'three'; +import type { TCorePlugin } from '../core/create-core-plugin'; +import { RenderViewportRuntime } from './RenderViewportRuntime'; + +export function createRenderPlugin(): TRenderPlugin { + const viewport = new RenderViewportRuntime(); + + return { + name: 'Render', + deps: ['Default', 'Core'], + components: { + MeshRef: { value: [] } + }, + resources: { + viewport, + cubeEid: null + }, + setup(app: TRenderApp) { + const cube = viewport.createCube(); + const cubeEid = app.createEntity(); + + app.addComponent(cubeEid, app.c.Rotation, { x: 0, y: 0, z: 0 }); + app.addComponent(cubeEid, app.c.RotationSpeed, { x: 0.6, y: 1.1, z: 0.2 }); + app.addComponent(cubeEid, app.c.MeshRef, { value: cube }); + app.r.cubeEid = cubeEid; + + app.addSystem(syncMeshTransformsSystem, { set: 'Update' }); + app.addSystem(renderFrameSystem, { set: 'Last', after: syncMeshTransformsSystem }); + } + }; +} + +export type TRenderPlugin = TPlugin< + { + name: 'Render'; + components: { + MeshRef: TCMeshRef; + }; + resources: { + viewport: RenderViewportRuntime; + cubeEid: number | null; + }; + systemSets: 'First' | 'Update' | 'Last'; + }, + [TDefaultPlugin, TCorePlugin] +>; + +type TCMeshRef = { value: (THREE.Object3D | null)[] }; +type TRenderApp = TApp >; + +// MARK: - Systems + +function syncMeshTransformsSystem(app: TRenderApp) { + for (const [, rotation, meshRef] of app.queryComponents([ + Entity, + app.c.Rotation, + app.c.MeshRef + ] as const)) { + const mesh = meshRef.value; + if (mesh == null) continue; + + mesh.rotation.set(rotation.x, rotation.y, rotation.z); + } +} + +function renderFrameSystem(app: TRenderApp) { + app.r.viewport.renderFrame(); +} diff --git a/apps/midimarble/src/modules/engine/plugins/render/index.ts b/apps/midimarble/src/modules/engine/plugins/render/index.ts new file mode 100644 index 0000000..bdaeab2 --- /dev/null +++ b/apps/midimarble/src/modules/engine/plugins/render/index.ts @@ -0,0 +1,2 @@ +export * from './create-render-plugin'; +export * from './RenderViewportRuntime'; diff --git a/apps/midimarble/src/modules/three/ThreeViewportApp.ts b/apps/midimarble/src/modules/three/ThreeViewportApp.ts deleted file mode 100644 index a14b583..0000000 --- a/apps/midimarble/src/modules/three/ThreeViewportApp.ts +++ /dev/null @@ -1,83 +0,0 @@ -import * as THREE from 'three'; -import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; - -export class ThreeViewportApp { - private readonly container: HTMLDivElement; - private readonly scene: THREE.Scene; - private readonly camera: THREE.PerspectiveCamera; - private readonly renderer: THREE.WebGLRenderer; - private readonly controls: OrbitControls; - private readonly square: THREE.Mesh ; - private readonly resizeObserver: ResizeObserver; - - constructor(container: HTMLDivElement) { - this.container = container; - this.scene = new THREE.Scene(); - - const { width, height } = this.getContainerSize(); - this.camera = new THREE.PerspectiveCamera(55, width / height, 0.1, 100); - this.camera.position.set(0, 0, 4); - - this.renderer = new THREE.WebGLRenderer({ antialias: true }); - this.renderer.setPixelRatio(Math.min(window.devicePixelRatio, 2)); - this.renderer.setSize(width, height); - this.renderer.outputColorSpace = THREE.SRGBColorSpace; - this.container.appendChild(this.renderer.domElement); - - this.controls = new OrbitControls(this.camera, this.renderer.domElement); - this.controls.enableDamping = true; - - const ambient = new THREE.AmbientLight(0xffffff, 0.8); - const directional = new THREE.DirectionalLight(0xffffff, 1.1); - directional.position.set(2, 3, 3); - this.scene.add(ambient, directional); - - const squareGeometry = new THREE.PlaneGeometry(1.5, 1.5); - const squareMaterial = new THREE.MeshStandardMaterial({ color: '#3b82f6' }); - this.square = new THREE.Mesh(squareGeometry, squareMaterial); - this.scene.add(this.square); - - const grid = new THREE.GridHelper(10, 10, '#3f3f46', '#27272a'); - grid.position.y = -1.25; - this.scene.add(grid); - - this.resizeObserver = new ResizeObserver(() => this.resize()); - this.resizeObserver.observe(this.container); - - this.renderer.setAnimationLoop(this.render); - } - - private readonly render = (timeMs: number) => { - const t = timeMs * 0.001; - this.square.rotation.x = t * 0.6; - this.square.rotation.y = t * 0.9; - this.controls.update(); - this.renderer.render(this.scene, this.camera); - }; - - private getContainerSize() { - const width = Math.max(1, this.container.clientWidth); - const height = Math.max(1, this.container.clientHeight); - return { width, height }; - } - - private resize() { - const { width, height } = this.getContainerSize(); - this.camera.aspect = width / height; - this.camera.updateProjectionMatrix(); - this.renderer.setSize(width, height); - } - - dispose() { - this.renderer.setAnimationLoop(null); - this.resizeObserver.disconnect(); - this.controls.dispose(); - this.square.geometry.dispose(); - this.square.material.dispose(); - this.renderer.dispose(); - - if (this.renderer.domElement.parentNode === this.container) { - this.container.removeChild(this.renderer.domElement); - } - } -} diff --git a/apps/midimarble/src/modules/three/components/ThreeViewport.tsx b/apps/midimarble/src/modules/three/components/ThreeViewport.tsx deleted file mode 100644 index 1b39eff..0000000 --- a/apps/midimarble/src/modules/three/components/ThreeViewport.tsx +++ /dev/null @@ -1,16 +0,0 @@ -import React from 'react'; -import { ThreeViewportApp } from '../ThreeViewportApp'; - -export const ThreeViewport: React.FC = () => { - const mountRef = React.useRef (null); - - React.useEffect(() => { - const mount = mountRef.current; - if (mount == null) return; - - const app = new ThreeViewportApp(mount); - return () => app.dispose(); - }, []); - - return ; -}; diff --git a/apps/midimarble/src/modules/three/components/ThreeViewportClient.tsx b/apps/midimarble/src/modules/three/components/ThreeViewportClient.tsx deleted file mode 100644 index f8897a4..0000000 --- a/apps/midimarble/src/modules/three/components/ThreeViewportClient.tsx +++ /dev/null @@ -1,30 +0,0 @@ -import { ClientOnly } from '@tanstack/react-router'; -import React from 'react'; - -const LazyThreeViewport = React.lazy(() => - import('./ThreeViewport').then((module) => ({ - default: module.ThreeViewport - })) -); - -export const ThreeViewportClient: React.FC = () => { - return ( - - Loading 3D viewport... - - } - > - - ); -}; diff --git a/apps/midimarble/src/modules/three/components/index.ts b/apps/midimarble/src/modules/three/components/index.ts deleted file mode 100644 index bb6f5a9..0000000 --- a/apps/midimarble/src/modules/three/components/index.ts +++ /dev/null @@ -1,2 +0,0 @@ -export * from './ThreeViewport'; -export * from './ThreeViewportClient'; diff --git a/apps/midimarble/src/modules/three/index.ts b/apps/midimarble/src/modules/three/index.ts deleted file mode 100644 index b94785b..0000000 --- a/apps/midimarble/src/modules/three/index.ts +++ /dev/null @@ -1,3 +0,0 @@ -// Sets up the native Three.js viewport and client-side mounting helpers. -export * from './components'; -export * from './ThreeViewportApp'; diff --git a/apps/midimarble/src/routes/index.tsx b/apps/midimarble/src/routes/index.tsx index 4a042b4..4697e46 100644 --- a/apps/midimarble/src/routes/index.tsx +++ b/apps/midimarble/src/routes/index.tsx @@ -1,37 +1,8 @@ import { createFileRoute } from '@tanstack/react-router'; -import { ThreeViewportClient } from '@/modules/three'; +import { Editor } from '@/modules/editor'; export const Route = createFileRoute('/')({ component: RouteComponent }); function RouteComponent() { - return ( -- Loading Three.js... - - } - > - -- - - ); + return- - - - - -- - Native Three.js viewport (no React Three Fiber) --; } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 24e0868..171335d 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -376,6 +376,15 @@ importers: '@tanstack/react-start': specifier: ^1.166.6 version: 1.166.6(crossws@0.4.4(srvx@0.10.1))(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(vite@7.3.1(@types/node@25.4.0)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)) + ecsify: + specifier: ^0.0.15 + version: 0.0.15 + feature-react: + specifier: ^0.0.67 + version: 0.0.67(react@19.2.4) + feature-state: + specifier: ^0.0.65 + version: 0.0.65 lucide-react: specifier: ^0.577.0 version: 0.577.0(react@19.2.4) From 15aa6252c583fffdbe2bf6f8bc79a66f57d0100c Mon Sep 17 00:00:00 2001 From: Benno <57860196+bennoinbeta@users.noreply.github.com> Date: Tue, 10 Mar 2026 14:15:48 +0100 Subject: [PATCH 06/51] #7 fixed typos --- .../src/modules/editor/EditorClient.tsx | 20 +++++ .../modules/editor/hooks/use-cube-rotation.ts | 86 +++++-------------- apps/midimarble/src/modules/editor/index.ts | 1 + apps/midimarble/src/modules/engine/Runtime.ts | 6 +- .../src/modules/engine/hooks/index.ts | 1 + .../engine/hooks/use-query-components.ts | 58 +++++++++++++ apps/midimarble/src/modules/engine/index.ts | 1 + .../plugins/render/create-render-plugin.ts | 9 +- apps/midimarble/src/routes/index.tsx | 4 +- 9 files changed, 113 insertions(+), 73 deletions(-) create mode 100644 apps/midimarble/src/modules/editor/EditorClient.tsx create mode 100644 apps/midimarble/src/modules/engine/hooks/index.ts create mode 100644 apps/midimarble/src/modules/engine/hooks/use-query-components.ts diff --git a/apps/midimarble/src/modules/editor/EditorClient.tsx b/apps/midimarble/src/modules/editor/EditorClient.tsx new file mode 100644 index 0000000..56c5b22 --- /dev/null +++ b/apps/midimarble/src/modules/editor/EditorClient.tsx @@ -0,0 +1,20 @@ +import React from 'react'; + +const LazyEditor = React.lazy(async () => { + const mod = await import('./Editor'); + return { default: mod.Editor }; +}); + +export const EditorClient: React.FC = () => { + return ( + + + ); +}; diff --git a/apps/midimarble/src/modules/editor/hooks/use-cube-rotation.ts b/apps/midimarble/src/modules/editor/hooks/use-cube-rotation.ts index b0ec92d..b0bacaf 100644 --- a/apps/midimarble/src/modules/editor/hooks/use-cube-rotation.ts +++ b/apps/midimarble/src/modules/editor/hooks/use-cube-rotation.ts @@ -1,72 +1,26 @@ -import React from 'react'; +import { Entity, With } from 'ecsify'; +import { useQueryComponents } from '@/modules/engine'; import { useEditorCx } from '../EditorCx'; export function useCubeRotation(): TCubeRotation | null { - const cx = useEditorCx(); - const [rotation, setRotation] = React.useStateLoading editor...
+ + } + > ++ (null); - - React.useEffect(() => { - const { app } = cx.runtime; - const readCubeRotation = (): TCubeRotation | null => { - const { cubeEid } = app.r; - if (cubeEid == null) { - return null; - } - - if (!app.hasComponent(cubeEid, app.c.Rotation)) { - return null; - } - - const x = app.c.Rotation.x[cubeEid]; - const y = app.c.Rotation.y[cubeEid]; - const z = app.c.Rotation.z[cubeEid]; - if (x == null || y == null || z == null) { - return null; - } - - return { - x, - y, - z - }; - }; - - const syncFromEcs = () => { - setRotation(readCubeRotation()); - }; - - const onRotationChange = (eid: number) => { - if (eid === app.r.cubeEid) { - syncFromEcs(); - } - }; - - const onRotationAdd = (eid: number) => { - if (eid === app.r.cubeEid) { - syncFromEcs(); - } - }; - - const onRotationRemove = (eid: number) => { - if (eid === app.r.cubeEid) { - setRotation(null); - } - }; - - const unbindChange = app._componentRegistry.onComponentChange(app.c.Rotation, onRotationChange); - const unbindAdd = app._componentRegistry.onComponentAdd(app.c.Rotation, onRotationAdd); - const unbindRemove = app._componentRegistry.onComponentRemove(app.c.Rotation, onRotationRemove); - - syncFromEcs(); - - return () => { - unbindChange(); - unbindAdd(); - unbindRemove(); - }; - }, [cx]); - - return rotation; + const app = useEditorCx().runtime.app; + const values = useQueryComponents(app, { + components: [Entity, app.c.Rotation] as const, + queryOrFilter: With(app.c.PrimaryCube), + watchComponents: [app.c.PrimaryCube, app.c.Rotation] + }); + + if (!values.length) { + return null; + } + + const first = values[0]; + if (first == null) { + return null; + } + + const [, rotation] = first; + return { x: rotation.x, y: rotation.y, z: rotation.z }; } interface TCubeRotation { diff --git a/apps/midimarble/src/modules/editor/index.ts b/apps/midimarble/src/modules/editor/index.ts index 2c27a72..5258c18 100644 --- a/apps/midimarble/src/modules/editor/index.ts +++ b/apps/midimarble/src/modules/editor/index.ts @@ -1,3 +1,4 @@ export * from './Editor'; +export * from './EditorClient'; export * from './EditorCx'; export * from './hooks'; diff --git a/apps/midimarble/src/modules/engine/Runtime.ts b/apps/midimarble/src/modules/engine/Runtime.ts index 25df7c5..a279b99 100644 --- a/apps/midimarble/src/modules/engine/Runtime.ts +++ b/apps/midimarble/src/modules/engine/Runtime.ts @@ -23,7 +23,6 @@ export class Runtime { plugins: [createDefaultPlugin(), createCorePlugin(), createRenderPlugin()] as const, systemSets: ['First', 'Update', 'Last'] }); - this.start(); } public get app(): TRuntimeApp { @@ -48,6 +47,11 @@ export class Runtime { public setContainer(container: HTMLDivElement | null): void { this._app.r.viewport.setContainer(container); + if (container == null) { + this.stop(); + return; + } + this.start(); } public unmount(): void { diff --git a/apps/midimarble/src/modules/engine/hooks/index.ts b/apps/midimarble/src/modules/engine/hooks/index.ts new file mode 100644 index 0000000..b45c21b --- /dev/null +++ b/apps/midimarble/src/modules/engine/hooks/index.ts @@ -0,0 +1 @@ +export * from './use-query-components'; diff --git a/apps/midimarble/src/modules/engine/hooks/use-query-components.ts b/apps/midimarble/src/modules/engine/hooks/use-query-components.ts new file mode 100644 index 0000000..764ac5f --- /dev/null +++ b/apps/midimarble/src/modules/engine/hooks/use-query-components.ts @@ -0,0 +1,58 @@ +import { + Entity, + type TApp, + type TComponentDataTuple, + type TComponentRef, + type TEntity, + type TQuery, + type TQueryFilter +} from 'ecsify'; +import React from 'react'; + +export function useQueryComponents ( + app: TApp , + options: TUseQueryComponentsFactoryValue , + deps: React.DependencyList = [] +): TComponentDataTuple [] { + const { components, queryOrFilter, watchComponents } = options; + const [values, setValues] = React.useState []>(() => + app.queryComponents(components, queryOrFilter) + ); + + React.useEffect(() => { + const watched = + watchComponents ?? + (components.filter((component) => component !== Entity) as TComponentRef[]); + + const sync = () => { + setValues(app.queryComponents(components, queryOrFilter)); + }; + + const unbinds: Array<() => void> = []; + for (const component of watched) { + unbinds.push( + app._componentRegistry.onComponentAdd(component, sync), + app._componentRegistry.onComponentChange(component, sync), + app._componentRegistry.onComponentRemove(component, sync) + ); + } + + sync(); + + return () => { + for (const unbind of unbinds) { + unbind(); + } + }; + }, [app, ...deps]); + + return values; +} + +interface TUseQueryComponentsFactoryValue< + GComponents extends readonly (TComponentRef | TEntity)[] +> { + components: GComponents; + queryOrFilter?: TQuery | TQueryFilter; + watchComponents?: TComponentRef[]; +} diff --git a/apps/midimarble/src/modules/engine/index.ts b/apps/midimarble/src/modules/engine/index.ts index 91c3ece..db3b129 100644 --- a/apps/midimarble/src/modules/engine/index.ts +++ b/apps/midimarble/src/modules/engine/index.ts @@ -1,2 +1,3 @@ +export * from './hooks'; export * from './plugins'; export * from './Runtime'; diff --git a/apps/midimarble/src/modules/engine/plugins/render/create-render-plugin.ts b/apps/midimarble/src/modules/engine/plugins/render/create-render-plugin.ts index 6a8a56c..075d775 100644 --- a/apps/midimarble/src/modules/engine/plugins/render/create-render-plugin.ts +++ b/apps/midimarble/src/modules/engine/plugins/render/create-render-plugin.ts @@ -10,20 +10,20 @@ export function createRenderPlugin(): TRenderPlugin { name: 'Render', deps: ['Default', 'Core'], components: { + PrimaryCube: {}, MeshRef: { value: [] } }, resources: { - viewport, - cubeEid: null + viewport }, setup(app: TRenderApp) { const cube = viewport.createCube(); const cubeEid = app.createEntity(); + app.addComponent(cubeEid, app.c.PrimaryCube); app.addComponent(cubeEid, app.c.Rotation, { x: 0, y: 0, z: 0 }); app.addComponent(cubeEid, app.c.RotationSpeed, { x: 0.6, y: 1.1, z: 0.2 }); app.addComponent(cubeEid, app.c.MeshRef, { value: cube }); - app.r.cubeEid = cubeEid; app.addSystem(syncMeshTransformsSystem, { set: 'Update' }); app.addSystem(renderFrameSystem, { set: 'Last', after: syncMeshTransformsSystem }); @@ -35,17 +35,18 @@ export type TRenderPlugin = TPlugin< { name: 'Render'; components: { + PrimaryCube: TCPrimaryCube; MeshRef: TCMeshRef; }; resources: { viewport: RenderViewportRuntime; - cubeEid: number | null; }; systemSets: 'First' | 'Update' | 'Last'; }, [TDefaultPlugin, TCorePlugin] >; +type TCPrimaryCube = Record ; type TCMeshRef = { value: (THREE.Object3D | null)[] }; type TRenderApp = TApp >; diff --git a/apps/midimarble/src/routes/index.tsx b/apps/midimarble/src/routes/index.tsx index 4697e46..e195b34 100644 --- a/apps/midimarble/src/routes/index.tsx +++ b/apps/midimarble/src/routes/index.tsx @@ -1,8 +1,8 @@ import { createFileRoute } from '@tanstack/react-router'; -import { Editor } from '@/modules/editor'; +import { EditorClient } from '@/modules/editor'; export const Route = createFileRoute('/')({ component: RouteComponent }); function RouteComponent() { - return ; + return ; } From 92e24c2e3d5f4daa2883e27d88b63e6e6d8ef416 Mon Sep 17 00:00:00 2001 From: Benno <57860196+bennoinbeta@users.noreply.github.com> Date: Tue, 10 Mar 2026 15:09:40 +0100 Subject: [PATCH 07/51] #7 lazy editor --- .../src/modules/editor/EditorClient.tsx | 20 ------------ .../editor/{ => components}/Editor.tsx | 8 ++--- .../modules/editor/components/LazyEditor.tsx | 32 +++++++++++++++++++ .../src/modules/editor/components/index.ts | 2 ++ apps/midimarble/src/modules/editor/index.ts | 3 +- apps/midimarble/src/routes/index.tsx | 4 +-- 6 files changed, 41 insertions(+), 28 deletions(-) delete mode 100644 apps/midimarble/src/modules/editor/EditorClient.tsx rename apps/midimarble/src/modules/editor/{ => components}/Editor.tsx (89%) create mode 100644 apps/midimarble/src/modules/editor/components/LazyEditor.tsx create mode 100644 apps/midimarble/src/modules/editor/components/index.ts diff --git a/apps/midimarble/src/modules/editor/EditorClient.tsx b/apps/midimarble/src/modules/editor/EditorClient.tsx deleted file mode 100644 index 56c5b22..0000000 --- a/apps/midimarble/src/modules/editor/EditorClient.tsx +++ /dev/null @@ -1,20 +0,0 @@ -import React from 'react'; - -const LazyEditor = React.lazy(async () => { - const mod = await import('./Editor'); - return { default: mod.Editor }; -}); - -export const EditorClient: React.FC = () => { - return ( - - - ); -}; diff --git a/apps/midimarble/src/modules/editor/Editor.tsx b/apps/midimarble/src/modules/editor/components/Editor.tsx similarity index 89% rename from apps/midimarble/src/modules/editor/Editor.tsx rename to apps/midimarble/src/modules/editor/components/Editor.tsx index 98a9873..c2120c1 100644 --- a/apps/midimarble/src/modules/editor/Editor.tsx +++ b/apps/midimarble/src/modules/editor/components/Editor.tsx @@ -1,6 +1,6 @@ import React from 'react'; -import { EditorCxProvider, useEditorCx } from './EditorCx'; -import { useCubeRotation } from './hooks'; +import { EditorCxProvider, useEditorCx } from '../EditorCx'; +import { useCubeRotation } from '../hooks'; export const Editor: React.FC = () => { return ( @@ -11,13 +11,13 @@ export const Editor: React.FC = () => { }; const InnerEditor: React.FC = () => { - const editorCx = useEditorCx(); + const cx = useEditorCx(); const cubeRotation = useCubeRotation(); return (Loading editor...
- - } - > -- - + ECSify + native Three.js viewportdiff --git a/apps/midimarble/src/modules/editor/components/LazyEditor.tsx b/apps/midimarble/src/modules/editor/components/LazyEditor.tsx new file mode 100644 index 0000000..1ae1767 --- /dev/null +++ b/apps/midimarble/src/modules/editor/components/LazyEditor.tsx @@ -0,0 +1,32 @@ +import React from 'react'; + +const EditorComponent = React.lazy(async () => { + const mod = await import('./Editor'); + return { default: mod.Editor }; +}); + +export const LazyEditor: React.FC = () => { + const [isMounted, setIsMounted] = React.useState(false); + + React.useEffect(() => { + setIsMounted(true); + }, []); + + if (!isMounted) { + return; + } + + return ( + }> + + + ); +}; + +const Fallback: React.FC = () => { + return ( + + + ); +}; diff --git a/apps/midimarble/src/modules/editor/components/index.ts b/apps/midimarble/src/modules/editor/components/index.ts new file mode 100644 index 0000000..1d79c54 --- /dev/null +++ b/apps/midimarble/src/modules/editor/components/index.ts @@ -0,0 +1,2 @@ +export * from './Editor'; +export * from './LazyEditor'; diff --git a/apps/midimarble/src/modules/editor/index.ts b/apps/midimarble/src/modules/editor/index.ts index 5258c18..f4e7966 100644 --- a/apps/midimarble/src/modules/editor/index.ts +++ b/apps/midimarble/src/modules/editor/index.ts @@ -1,4 +1,3 @@ -export * from './Editor'; -export * from './EditorClient'; +export * from './components'; export * from './EditorCx'; export * from './hooks'; diff --git a/apps/midimarble/src/routes/index.tsx b/apps/midimarble/src/routes/index.tsx index e195b34..8df66ed 100644 --- a/apps/midimarble/src/routes/index.tsx +++ b/apps/midimarble/src/routes/index.tsx @@ -1,8 +1,8 @@ import { createFileRoute } from '@tanstack/react-router'; -import { EditorClient } from '@/modules/editor'; +import { LazyEditor } from '@/modules/editor'; export const Route = createFileRoute('/')({ component: RouteComponent }); function RouteComponent() { - returnLoading editor...
+; + return ; } From 842a2b9ba98d9781d5b40e375f4d5d8d0e89eabe Mon Sep 17 00:00:00 2001 From: Benno <57860196+bennoinbeta@users.noreply.github.com> Date: Tue, 10 Mar 2026 17:02:44 +0100 Subject: [PATCH 08/51] #7 wip ecs setup --- .../public/textures/pegboard-normals.jpg | Bin 0 -> 780233 bytes .../src/modules/editor/components/Editor.tsx | 22 ++- .../src/modules/editor/hooks/index.ts | 2 +- .../modules/editor/hooks/use-cube-rotation.ts | 30 ---- .../modules/editor/hooks/use-scene-summary.ts | 43 +++++ apps/midimarble/src/modules/engine/Runtime.ts | 21 ++- apps/midimarble/src/modules/engine/index.ts | 1 + .../engine/plugins/core/core-plugin.ts | 42 +++++ .../engine/plugins/core/create-core-plugin.ts | 54 ------ .../src/modules/engine/plugins/core/index.ts | 3 +- .../modules/engine/plugins/core/systems.ts | 5 + .../src/modules/engine/plugins/core/types.ts | 37 +++++ .../src/modules/engine/plugins/index.ts | 1 + .../plugins/render/RenderViewportRuntime.ts | 115 ------------- .../plugins/render/create-render-plugin.ts | 70 -------- .../modules/engine/plugins/render/index.ts | 4 +- .../engine/plugins/render/lib/Viewport.ts | 157 ++++++++++++++++++ .../plugins/render/lib/create-mesh-object.ts | 49 ++++++ .../engine/plugins/render/lib/index.ts | 2 + .../engine/plugins/render/render-plugin.ts | 48 ++++++ .../modules/engine/plugins/render/systems.ts | 56 +++++++ .../modules/engine/plugins/render/types.ts | 42 +++++ .../src/modules/engine/plugins/scene/index.ts | 2 + .../engine/plugins/scene/scene-plugin.ts | 64 +++++++ .../modules/engine/plugins/scene/systems.ts | 23 +++ .../src/modules/engine/plugins/scene/types.ts | 45 +++++ apps/midimarble/src/modules/engine/types.ts | 5 + 27 files changed, 655 insertions(+), 288 deletions(-) create mode 100644 apps/midimarble/public/textures/pegboard-normals.jpg delete mode 100644 apps/midimarble/src/modules/editor/hooks/use-cube-rotation.ts create mode 100644 apps/midimarble/src/modules/editor/hooks/use-scene-summary.ts create mode 100644 apps/midimarble/src/modules/engine/plugins/core/core-plugin.ts delete mode 100644 apps/midimarble/src/modules/engine/plugins/core/create-core-plugin.ts create mode 100644 apps/midimarble/src/modules/engine/plugins/core/systems.ts create mode 100644 apps/midimarble/src/modules/engine/plugins/core/types.ts delete mode 100644 apps/midimarble/src/modules/engine/plugins/render/RenderViewportRuntime.ts delete mode 100644 apps/midimarble/src/modules/engine/plugins/render/create-render-plugin.ts create mode 100644 apps/midimarble/src/modules/engine/plugins/render/lib/Viewport.ts create mode 100644 apps/midimarble/src/modules/engine/plugins/render/lib/create-mesh-object.ts create mode 100644 apps/midimarble/src/modules/engine/plugins/render/lib/index.ts create mode 100644 apps/midimarble/src/modules/engine/plugins/render/render-plugin.ts create mode 100644 apps/midimarble/src/modules/engine/plugins/render/systems.ts create mode 100644 apps/midimarble/src/modules/engine/plugins/render/types.ts create mode 100644 apps/midimarble/src/modules/engine/plugins/scene/index.ts create mode 100644 apps/midimarble/src/modules/engine/plugins/scene/scene-plugin.ts create mode 100644 apps/midimarble/src/modules/engine/plugins/scene/systems.ts create mode 100644 apps/midimarble/src/modules/engine/plugins/scene/types.ts create mode 100644 apps/midimarble/src/modules/engine/types.ts diff --git a/apps/midimarble/public/textures/pegboard-normals.jpg b/apps/midimarble/public/textures/pegboard-normals.jpg new file mode 100644 index 0000000000000000000000000000000000000000..1410b9c350a75f98525a9d8abf11c0428768e957 GIT binary patch literal 780233 zcmeFacT^Ky8}2 s;IBPKr L+IoZLV z+1WGla^406?>$n$#s7l?FyI^n0$~3BQ^)e3x(ok#{p;oTG?B(5DJlKO%1Y9Y {=@uJmi$vTv9UG5Fn^ZW-o(b_Pq`6Oe(mCHiYY_oF=c-j z3sYB2xersmX6 3keA_J~VZ;Hg$61cx-5FW$0+aC}n43Z)ocd z0ROD>pSggGf4pVHn9R>D#Lv&c!-=sUJN++%Sn7XW__J;QA<$3$v&|rs?Wc98^Pbk( zB>{loHpZLK(>kLl04VVTfXl jftS^A-ng zVb1ucT1xpTqp`E2%bzl4pZN2F2b>2;flI&@fF585ZU7tr4 nKm;M;kOvTXh%!VIVgNCR*g~8kUXYiNcaRT|Xvk+s zIwTKL2C0LzLV6%WkSWM7$R^|f2Z}?4a|wqI=Q<7-jv&rm966k)IJ!9II1V@-IInPm zaUyY&a58a k;U-W=WzK0ZDrJ}bTe{zH6Cd`o;!{6PFT{2csR z{2u%n{B0Nvb_K=`6N4$i3}H?%e^?YO6IKKJ37doMog+NQaE|Ak^f|3_w&z})3qSYm zT=lu1=TPSk2`&(@5C{_}5ttCT6NC_?5R?;i5zG-Bo+mrcdS2}O)AN?+pP!FBpMC!O z`O))eLPEl;ghGT*2rUSG2_p$}30nxK2=|FD60s3U5$O;)69p5c5!Dh65uu5RiLVn& z5^E7V5eE~e6E_f#6Yr6blW>weA~7NHA&DU=CizLSN=iV=LVA}}kJN)SoV0+ni*)${ z!G-G=q%Ig<@V*dpq3i 88?{{nGIPW**CIQvW1JVi`OqcxM*_m)y3qC4Hsv~ zq2$cuQsl Cq+2OYbgaUFy8FPH~aq4uu+p8$}F76~!bal=3>| zBT8$^5XyYY0m=g^I;y)=rc`gJvZ;Pj?Ovw2EP2`V^4rTfm-{atTw%QO;EL6i_g6}; zj8WrKvr#{xcBPJ|{!YD2bBRWT#+c?UO+L*qEe #Wz+uLoQ& zxxT=9ne`E?2WtlF=ndi<5;q)fB;Dw{iGNe@rq#{3o84?UY +3(gYGRjzAXT3qkBnz>GH^WC<-opO7G z`y#h2_Y3ZF?oA#x9%G&uo<3e;UTIz*-csI;JM4E%@5J93 0Pf9RJ7)m5bOiMCLnn G?&`hU_Z;sP-P@HC zmO@C?-iO|ox&QWl=Yxw6R3Ah?7?-{(Z7!W5y)MHi<0(`75bvSf!}kx7kLVs5KT3bJ zE-N65kZqJBl2eh3mYbGmlXsLaSHMw_Rrshds>q^ft5~80C_Pg8s5JJN^|8a_iYNF_ z9zThBGOx_7?4{hSLaw5(@=ayu>Aj~RPe)X5s5-0GtC6bdsHLmzs^3@tpgyU=rGe0B z)1=n4&@9!0X{l+YYHe#j(Eg-7r^Bb?uQQ;_s_UlPsz XY}rD} zBHCiZ@}Xsd<*t>IRhrdrYjx`!n{ze>Hf6RKZLMq@?da{??0W3k?fva19fTb|IjlR% zIi|uPa9wz*( (H(R%McQ*Go?kEpwk1w9Mp2nW_ zUQAxky`~U%5ud#w-bUW_KFmI^eCB**e7` ?%$BWx9KD^j^ss6J372PY}S2KPx zei{BG{*M000Fi)%*SN1OUU$CXeG~QO h&w1U=y$MLaAydA zNPH-MsBP%Ldx`g7KahR!_%QQP;bU u#IFq=a@sjb`33LhX5)KkA5(huad@fG9o)n&ppX`!6pQ4u1 z{6+9fdMb75yVT<}+qB8A%3mAP1=7>M(S8fbz{zmV_?4-X*`0Mit2CP<`*RLu&bwS7 z*Ex4F&meCgUoOACK(HXYkfkuTh`i`+F{IeNc)jFV$z-W!X-}DKS$(-kc~J#tMOr0O zWlR-CRY>*u>Q~jjYdmVUYwc^7>&)wB>h Yoxn>w53^HuXK~YwK6+ z?-@`X7)0tICkIUi7ly2dHilh>4@Z1Q@kZZ{T^I`=ryWn4xH*wC$v;^&b$_aTT4j1< z#&~9F7Cw74_iCPaJ{-k>N?+hvsQe}Ut9wy 2TS9g={5u^~P%9n&evhy2kq4 zhU3QX%|P@OblTRPt@`c9+v7VnJBPb(_pa=H-51<%K2SeE9l9RDjv|k59+#iUos9mr z`ThI%D!_Et#LmbRFp mpHq`R2M3tx_XzL`bH?#MpK$&O;r!PG{qO1D zxiKi_I~)h+zk~m8-u A=MLd9s9AA?A?i0hSmlz$M zzt7`=eXhI5OmX4yde4-ykt6Rl$`>Ctq*U&(bSKqQ8Q11tH-NwV__WdVB1R9u#f9SG z;SylZ0&%DyIAl pINo*Jz@GUPhFq$HwYpbuRgPZ$} z9xKBT>NE}<22^(5gJ1OGn~36gWoGBs;IZ)MGV#9?DV_Bz0WS7;COP?G%;?N(p1h{E zU50yfYr;J4V`S^KZY6o|@qa)D7WEI1Mw1AJpraf4&mM&$$?uMne@nl_wspcN&M* zIehe+n{%l2>ogh`5w17jDGrmwhM{R=jVd?U0!$0&YHp(g?^r$xDmX+>p2krVZiK&x zn0c?Qs~1HWUq#>I=c;H9#l|7KH1JP;W-Ja%i)Bj>M^OYXT1J$yQGirTt~6Lpo$SY) znA18u@Q&l%;G%=S)_i6s1 V_hUDf(7h)iJyvjU%^_iczw c zIz u9V%b-a{p)Bz{W}79Gso1cFKp+w?OmQfV}R8YrAT>tD 6P zFH)CXICcyxSxd!obly2^%M+58CK+kd`!`ZKPlyRR?(S5xChfFo8=(31B|#F_{54$0 z(lR9{+fru?DUxNSJDJ!2@)qYaEkHu>IpRJ@IH8SIJux3L?^^wxbYR81` zs#9+m21A1f%8u5C_Nx5zf>y*UB3$;cCPG5C^S@Sj_r>(jW(cf?)7fds2vi5i7G)nU zmIYh>m<5}LW~@4X`7#no`dE7nc@?d4i3EN#jfPimZN98clY6ul %los&0*N?%wsgrNEE;arJv`$_vw%#wG@CGr+cORXK^A%q{4YE}#ENY%l zU ~626Er2BS z`;x(v;^Pw5jJAR1vGe#*@{Z2dU7Bk<84(X1b`3y`&d0IeF8F64a|tqAY(DiSZIjZ& zomZp?=k4u`%N@QTMsd} 1@oKb#lJGQj4J2Eo}GD1BOO^Jx)$k_GfZzv+*jcRUB z(5Lp8rJMtG3Byky1)GS7znoy=W>;utCz0k0MGyFNR5-jGQ44dl2N~!RMa>L%*- 0D;=;FA4x@Ie=9t|$N7St%ika9OfPiM;M& =E z*myRI5z%Y3CE;yL_At%;t~_^Fm!!ji`Z_sDusM$zzh4^j3`{Ihj >%w@{2g&!aSn@xD~`Oeu2^037p1Hg2dt zklkS*1n{d&6Dh*lv~1NX7W5woCxQ@4R*C+lORA!IV|+#F9*)Q=Qi@-ld(DeH`P$%U zH%Rf6Ry}{;uf51y?tTftk7*GMF?_a#2=E)i>Z~Py3jd|p muZE5fCTyBZ7}$J) zpTD>Wt>*&N6dZU#6~JQ!y=lXY>|R-Elmz(R-Tc858=JHh=yV&D5b{drMA9i-`C& {q0gg?}0GmFOwj#tNEkg z!1Jq-c1aKbSY{i)zg3YHW7q6z4+0{hqix&zT8*Zo8~rz40eJfQswy9{2#fOQTUR$U zK -R(pS=Y>#BFOQXg2Ujp)>Ss{P;Wy;mVhG0p+lG5{C4r$DI zN1aU~DB-HoBDaMyyjNUul}FGQNVYA!rS}Ln 6Y=bn_IqWP|`< zpr$5Xoo`K}Ez@NZB*emp*b8EXEdv)$G#AT~016IH-GvTAP9k+Z1OkM_tB0ctJe$Su z8&;@j`NATac-0*lqDAi79jGsV2?r_MYTjH^k9USot6*Ke0AF+(itiVE_@Xw)2aq88 z6mB^;fAT&_*cG$mKPlYnl!^!+7VN|x;=v?7ag2#{hYC?<1}$HH3>c)}Td=MnT1JE{ zm?K0cK^;Y=LkaGzlx^?*9!7xAtYqHh`_r}9xlAl@CDu9^iHbXx*=ptjfW)KqE!54D zOi{bLzW+)<%j3ScC3}cx4{Avf-g)PXiy! ZR}Z6(1Gm`8unsUKbW=3$F!^g z{B-rBnxT-Iq j4&uf zaNip)^s_=SejytUKr$zMgl(6`Yd;OHfEs`q_mD!!ylzF-F-2 ErtT` zWQ0D}MI+%>*+X-ixgc{*FmRv&etlp-FX89-tvCP{K}VLkEFqfN%CJz9(HI7D^lw#n zSQCnmRRodt3UPG6`A*jT);kf-oyMKhAOqPM892n3%H(<`9)Zb?A$Yfea{Aa;ouhxe zf4VzV;`;B+SAEPxsHA#uru%a5#W~~bH}dmaZL!xhnSfICBc4^E^JCwoZHZMV;*0=N zakhn$`OE{|k$njoL6Bn5w+(udzkh$lLh&Us5rY5DL0npiH_T)4F-Q;;>Zv%vGY>Tm zYUDR|*CDU#Eic `ebornmBG7&>TtbazkU>mON5(pqS#ZcKD|lBkZ4 z{|3mrLC$f1ai>>A1!~2R?izRvU>{7wZDH}uzrT ^k2=q;;N`i{44%XQ%Xih5~*G5HX{t;=l=p0`H-waQ* z_N%4RljBa1157h*T|%P2sLs1^OFK~{oPQqbx5Oao8Yns rGT=WJyZr1o;9WFTL((z!8{iqc?t#_JXL8SaK7SNn;B;S^L3C4m4;|Kb6cPBT z!A)L7ed+XgFaG q%Zj-sBoS ;d{ zU&J0u;5>O%Gfc1l;fb~pv+Am_q)8&RRD;EjV{L|V@xusTP|fp(>W~;7+d|-!bHUdQ zUDXC8Z2;osIx56`TNdq%#Sr^Dvjh1w@Oy{-oe4n(CUql*m`!rRwXQUKbdAn@TL;v` zF{f=^MslHwP_Fkgf->ZZvhz{$&hyU~6LtkAly8F=QP7vBE_li}W@RDCE$4vq&(~gC z#eYq^ _N-;a8$Xk1V#R zwWuEoq=>r0FJLj2NG?x`BnNjld1-=MA^SJ2O1HuZv~0y+)|(Z#V)tsmBuh+R%YVG9 z_sPRM!2++U{bp>7Y~ZEEuN3ub+&rqWa&+ `oj?u{`E^{zR}xbr)nruC^Q_o|V-Ec-QAA4ymat|1 zz 1l>)vEW5(fvPt>k-v!WnQ_CKD;b=3 z@b5yhTq*ZzQ6>LLCj5u=%&O8Gj`qt-nGStJWQP~(Ka `Q HVpY#@P)m0>bTfVhhBZuijR2{i9PDW z +>Hid&l3f+Q1c0 zYK&tvJ$C-Ja~Vx&WhF7~)0Tnl?u}b@Mw_MW^lT?##v%#LWAl>Od7%jjA9TdRLI_@< z)tWJmS@X+2X#UGFEO=HpbKuN@GY8HbICJ34finlr95{2}%z-lp&Kx*%;LL$D2mWt$ zU?JV%bw!KwL0Uv%?siYg>1sd&a@;C1Bi@!&237gX4o|FMZcTv`WMj9^0TEbUzNJ#w zHZ-*3z6nM!Ki}+7Ly@_L?(YN}bvE?MMxI7UYE-$^-MLuw%S5b*{EA3(e6cYIdM(rW z`w9R23{tj>!@|6)s}>sr#P`{Cjk0s9v(S_-Vp~V20bp@go80w1x^F+MD0g?H`!oV+ zUdy!UlwxquACYcmx3FqM{jImRq-SKiCL%gwc5At!((SL=dRMEjqM3WwnzVj4jNE&D z8X=KDOt0pPQ*VoH-Es^sp78cMjgf{_v%ecv?MER* <;sWe^vEXITGF<|;g*c_? z)fP@YF_yzL{vEu;o$D~)R_)WJfOe=bt2}hgPU#fpOz9F{a}Mrq+@G=J>!a6wor=|h zF%%gL*<@srD~2M4o(>Cyy_nEY^cV?p{br+4l_tT61u K>iDmhto4S`uts`hoFD;VLXCQ~- zsxo->LXmIomk@tI#!z5>2U>&_ZfXtI-uz2%u>T0H%W}-{4b4$N{zGaxLzk*#`0&yA z<4W~!q1eSELU^sPvMzAkjoqSUU}u !RV#Nh%v5JzWcDkMb;dO!CwDF}nM$ zaBsq6yL_^0*AY7B?6kr25|W@CruThKl`&e VOv*kqVprqKk6aaMb8qYy zdPMnhd9i{#7#ZW7#VcMej$HsjL}ga?LH_HE(w&PVZ_;)Sb|kb8rTJ;o$QTDaSH9WK zU2aPRg`vx4Gp (WRwK~5w|MJF>9(gPYtUrzJR@W_hk&ZK@ z 1L)tg{n!x07Webi;Fedx}H?1FM3)gFpQ{qSamE7#CKeOD!&M+q3#^$2%41yQGCwq z24qF{z}oJYVp6)c>YVT}MGvK9Z4sKXCl75~YI()ty?sI0>7czg0uiC9)@q#{()NF)Es@|xehnv#8}jHlLR z%6(*!u;H6+hxWiL*rc+lE*(V}M(%cFZxBG5S2{dh`-Fc3DhT~B!K9Yr0S)1ja=u)a zo-+RY30-w9!`GGIssZB78LJ%jrOQz-qjF+M;4{0O1wU9k-sN8%naaske=5O&y=e!X z*JHiBG9j%JnG&V&7|2-5i-zalF*~+Gti 4!{mda@QM(y={aXa9?)yM)#XE)6uF!td{(Hdl66CB}(&!tOjLU^VOfTQt2 z4*}~uxLh@pI7k39vd;RAB6>EQlOd+oH=s|ig<8`_)09S|;JdxpEeUH6G!q&gqoU@~ zj_olxKfT)Ua7WMY7(i+d$OQkuY8_5DZ@prL=H3!=r2>SzIus&43n&ZZbCfo=gACM< z?xS9#CrNFTw~xy~Az f9_Q^f5&9cyiot{c{li%<_V=YC_^&rerq6gd10q(##?>R z9vBEL5jH8{E569oT_XuXhq14>{FxbEE+#xn1OgB0Ec(`h1YF2RycekwL8fJTM_X&n z%Vm6~8=$7SJr!41@0{68!41Y?2- ${dDH4Ur5)Bq%PQ~X|q_S=zQn_N)A5v?zl ;9pufN2aU1IzC;UF@e*cr)sy2teho9XaIj zj~x7{T@D2a7q_ZTEBeOZP9gnpvs(c5+Q)9aTPMsWQ)8@u?Koyh$FRT<^@SnPMc{H* zu`s*vl+B|5E~nziHBgAuTfzX|e@qiJN^1f@rA Am|s@2WO17k-d)3XDcD4OW|e+- zk7t$-&EUZ(fFEo68@OGJqB~GnO^yJCaI^XH3$%W?>e_L70FVrUiFhP3yC&Rt=P^j| z@M|tfB$OK^EUZ2PAX2Kc@}24e_J$t5AV7Q6UsyycEBWO>os|1EfX~|Ks#$PETsRog zJ)yup31afoG*(F9y`-zlO8}Ct$<=ZE@yqBY`%UcU7th|%1Ha^w6@_lELIA42 sAV4xH|;pl|74(tIAS+ z0ZVZew7Gd!1)9%-4FvE#N$*5kAbQlcVBEgIz+pB`!Rqe!mv6^>L1L@BWyI^S|LJc) z(otWx0{}9_pIr|3RGk*QGlb1e-5mE?Vf}*e6L~;JnAmt^+_zFR$&AoPn$It)@aw_8Yhx> z-_5N7oRqrtOPvq89p8#zyB{XgNa0DbsGz9LlgjN{K#E&*$-m7~j&;o*zW)>yB7ay} z-`hO`)e{bo@r5bS>arT|e}S7x$cTl_CW27wkV!Fflt6f?Q}xS@S({p%*t!#E4M)!W z&?ln?AT);_n@M%Oq@1E$GHU-A@SPS?_qQT2a9@_F5d#^VTK~>8VGmU)r}!9vl%>!% zHhCZEI9nrgEY8aaLLD=_0>1%X+bpX^F-R|59=NGPHUBA@d1bkSE*^wPCMa?`$jdW? zT*~~cOTPkY8n#?*s4u*hx{4qIF{^dC^-^o@Cg ASBS<-kf<;!;Mo{mxzL$artqOQH^d0L!yQz6sN=u~D&k|5U~;+jO{ z6W3O%^|^dOF+|b!QS>BgG&S8hlcvpcmc;EcJvDFLKAqnLT{Whk|2tjux~}rfUCk;J z!IYB(*R~hZ9-7|HK?S6lIJ2fMd15(_1+^hPL|nsh^Nkb#T3^xO-XIUtt*W8%=EKcN zPz xV3y3eS~BD8dbJr0vF z#fsU9Tfxk$?_JWkPE)Zi-cqoMMCBwf=lv)#n&B3Be{!T4SNDTyy()P?&ok;ZsD??V z*!8hk+zAe?{ds6kM%O-Fv7v=*L(9~au*ywu9=^sN*+X_wBU&(c?$JnaW~##=?a$_* zO5PHJuF$HAf|(EFANF^!_5rf%sylE@P6`LJvwvN)@v3orCVps87kBQ;`~G9Tlu594 z=!Dgp(VZ_AC$S+ap4#NJ9n%OmG1cJe-gVvPzG|ZIJ`e 7JNmaf2cy5a`@WL5 z_8zJ`G(P%;Kc-y)Wm&LGu<`|2f 1{R)A)z)7C8Lau?pEdeCNSD`Wv`7tn5}e^VQ9> z4cj=;JWqDpGp_0d6PMJX$V!EISPl8t+@F^(v0HBYgs(bcL9t6!`qbgmquqPLK4w!_ zKgiqJis(6wEVyybEsQE!Imcrg7q1@5jfo4Lk44yUhDcr?pmR#1+c-h^uaq5`8TLwu zVUzv=0#5qkc63c=>5*l|;NGa}mJgEd=aZpI?<)o6ZAsHw*v9ddyS{%UsBgb&zwF%Z z0^@C~|Dp|Rb%?|QfX7X*ga;12d-6)33YD+09YUj&ZtvgJ#GZu!B>ETIDT?0X2hOeM z?sd8{05NjLnynM0s Hu9I@4-8A+E#u-_#0JRnQ$-icV*$uw@@D<(X_S3w z1hs>Pd~xMPWAX13k4_b6Pp)&1$k7v1wi+dIKca}mvET_YOFi=L$4UU^d10BQ{5T5K z{*#+-4~Yh($Ua!pzb%=>5~R*GF&Amx#7a%mn;4Pau6ij~j4!@<4;u%TH)EQttsmak z9twWlc&(68 +3D87O#7C|8RNQen_T;wiE96L#`V8jRioq!VEc< zzuvMFco`s#c5A^MP`}*OC48*oi`C#65Wf|vc2So+z}R-C`)0fm72BY=*1kO!02q`) z0=iG%0;D+!43dAn7suwI|EVNRtNkkmAiVxg a*vMVI Lrds++Y!u)b`x2r3p=I=`)u<;tb>S{RpG@S+jXuS_+cGt`kSZhz` zhN31gZKF`l6MtWhfv)N2=zDvi(Aaxmm^lPJwl{VQx_nP(2D}b;19H5M_WmB&3BV+J zVJfTL=FpRWp@JT}>&t)F;B%tHlpndw(Xb~>aU~Zo`#c$6Z_!DnlElsgL8W7cJmU8w z;~2h8i+r;xpgIvc=3vyEDYU Yd)G|U>_->4H1Y+%i+?9&nUg>#$ZFrh=myJ zcO8X26iUAC>!9kK$;+6d!_oc?vx19~ScH^AC&)ZuIP7VGS-s u(b^%$ z)3%@i!?~5!^~o$Twi%(bvn~h2d#@Ll%-H?5l}{naE}kb_sws{4$FO#fB`MCY179kp zdUX1OZe!bmy)9PD4qbVBT|57(ro8TFzdqzFC-hE(*72zfG^f9jiZ}m8lo>LMcUQSh z%oNeE9h7|KyKC<$gc${C{+^-i50_(J*09~f7h^p(Pn_>F3u!B1+X9H3n=HS+UnytP z%$*q`qR4yE7tzj1%F#IDi)DlnW61rgsQYa$Uz}sN`I{FHcj&ULzs?I3G}mGwal|fV zOUEw)z45f!pR^HiKJMT76k0Eam~d2{DsihTpZAw5dGPJmzbZJmgng5cve3{rLzXP zD?GG)HWbM2xxHFl{h3PV1S={oR=>8JojEUz=2d^t{?)R)msef;dZbuVouzK&fL=c3 zNiE3Y(@* 6oO7)eLiF9*0e {(%fluvGq7R^5vYk)%`XGXKhQdq5kmwHfk&hty5FY zagXoH B>1AUS}MUE<3?EQzV6tjVY@QSv>0nK7|69?*d4%-3kS!uZ- z3VD~qkEHFgsI{{;FLY89Un0m+o)F#i$noA*JMa9m6yyLdroEGfT5aj&qb@dpPgdbo zb}IF*TT$>pi#8I3AiESY-m0bIeq|=2(6*J^>=hHju)@NL1+}uF0&9Nky-{dd`)X>4 zE1h55l>Evw1A3ntAHE&$ypce9qdmV4Nl;Fl$6iO@(*0zSos_jRk(eW*N${bONJJKY zz_(A2L5M!L_?TJSuz0S4aY|9&;`x)=ufL=_dM7?>^;*h0xMM#LNCko-p2!?3_I9mP zDyFy*xz^M~izq#{9aU3xyg%m)%F%k8EwxM7AFP&jI{PHoQZoq#C^!l#6e2~~E1DBQ zio$rHN(Se 20Yj`dyU^gg{HU;1{) zxl*m+dwT5bZT#F8ho_Y&O}p@%kt=fAiJ%sPLtlxrg6|@G@PqyBiN*GFeqCLiK^bWh zcei(%6DA9=Af5hoRWoSW_5FC3P~`LH$lbO1lOISLp`eOEH_^4VT2N4&>vQR9Yr|td z&8T2qz~U%Xf-?NB09<25-{w3P+R|!2D(}iFv$3TFAc-I2MMed8Wjk+gu7fIYG~ySs zD&lPz8kQ!22M|lWNBg~WWv!kTNdyttgqP>%+&!8#`QJdaFV45}7fX$(yQ^WajH;*E zAOu;=AJiju=tWehy!M4=q0tA3CeM;fi&1Jk4?%|Hhr6vuLvf`x!#k0j+metk`SJP{ z-qso6T-dA&z+?COffcdg%WZ}IBj846a3*H2?y@zA6BwJuE|8ep%9kMDwd~`BCIiUK zp$vM>U_)=OK?Evc7!9@sbEf?b5bF+C(MSY{aB|l|l0Td%57E$dS;!P)d!G1F#%jQ} z3(acLw)~x3z{*8m*7%wRUDC@f8LkA$f2ANRjjQrHyq2!Z@iG9BOoiBmK~bCP3$_hy zS|+|AGhxTRFd+7(*}}et4U=_s&usL0aj9NFu00$?0LOjjr57&vth`<0QS`+Cv0@jx zFXra^!LMdp2mi_d(6JX2mtQwl^yUef08F29g`bPhDa<~1-YxeV1Q{{@j|r6dOC%k6 z^|gS6M4FdP*+zC;l#wa6r7lB$O1QesSI*`6+W>WP*pytu#G|e}8Us**zQU{OO=9`a z+y%Wm07Ov-K2It@Qj=U|{?~9@Yh5bGRzJz!Rk`{PQa1wlA&(?@TxIYM?uLF22X%16 zMGD0Z=6wjqXeR;aQ#dWF_s>O(U|wSofKHe*#XqY~$P$Kz)B;u=6D;$aWh2=VKPN!~ zHD46)P1u`^vnQTF=MHdN&$ztk=9E}z@QJTSx;{wZXp)bLPF=k0KZD7Hq;`!vLJuv` z4}8>6@coy7d}@}vPOYD0m4$A_jO$gr8^S6?9ArINg1yltl0GY@Wg1@u@@H0@n>- z952dZVVNgR4BDk~eLD%Z6n)P%;w9ldzQQ|+0P*cEZ%3PWfl73^BiImNmdE>sGk*Lr z@!F3>fG>pgd+`^WArr$AY^M^t JaIrYFEw|3K*_@e%g zu7yW!6`P2)sFHZ!e+ej)#m5@=gwM`1sbvMJ^Pzx>ny3Uv`-;%_G-)go(WTCrIF_g6 zaG8D#SqmY|`*}MyM?j~qVx*u0d#ugMedVY^rR`U+|4+<-TTQ*2tB0-L?@SitKp99x z^L&n?#f0#$zR^JdCp2$T8^+zexulC7tc;|K!j71!nq4zE=k4<4P(Zy{bjH8kiqLGN z*xl>vze@}dQWEE*g;9Ku*N*Q14B~D`YKaIMJof{Yl`l*ngYQGeT;|^EY&G!&9txa4 z--eDKY}+0UN7{l*1MQKW-$SiFPc82JP%mdM3DFqbj2P_{Z!cWx%1H!u3X7VC4$1b_ z>@dkn^s*WX-n;t+xz07R$9FbsK_<+=v^f6Na38BY=0t(mr|@W`bTh6bu6T$MBzCoR zt-A!4e|Q?)WsfU(1-LUue-Mxho>NZf7N3a13Sox-S?xo&S66T3i1Fb8Ud7E)j5X08 zg8at3yDIL3VmQte@2#o0I-J>a`P3gELvd~K>c`9Czqji;Ga$P`%GBDf7#_uMidR M79B0&N-fgo~7QD@MjqPM(&n5hIXNIZIuyx!EpgNWFjGXOD< z1@$3ux1mp7)f5^lN9Uj&3 qAJ+bhLAG~h`_b; -9RZEbDAz|39il}rA%k@0M>^PTHg(rSCdLi)sj+ n>05SuaXh zTD8!(H~NZl2eC6azDj*^02x8^fE2{A(UIn6d(q8~0J^jiRUfgAoBSoc65N$tS4QI0 z=UQymv1Dx1sP(R}iGyIvHl+LM`bF8HK@%$WoHBZWVwYl0x!wo0Ac`4Vrs7a>&f10} z5J~UXbdR5STn6uX=n{!hL;H*%@$ n*1?T%{b&)ZNjAiH_-0(@M_mif zZ?sF)BXka^%ArY67e~&&d}!Rh`b}SO_sIV1&ZnVuMHAIzt=w5 P@K|^{ zn8l14!LMDs!inXTu(NYmP!oE1CL$M}AxewNsrG2|1z}8YA4f)sOvF8V>=^@7U#X~G zB65n*dZte|9vEyRUjM6X5JUkSeTK@RRf~#j6Yd{!Zih|t;;noG8Cy+4(%hxO0u7N9 z=7}JS8S_f_WA~6w3KW)IMPWe^rE6y7aBC-bHgdK5{Zy)$$>Dnt1yHD!{!GUbb 5j$OZ19B&Q8TuA(Pi*0mIs2pXkCABg20G6y{p#4c~%R2f~+{6yh=V@PjB{!Bod z`}N9RpIbuNyv4!=9X`drAPJjz({2{jo1V<`6~Crdzn(qlvsU4dh#f3q5S9o+m|>>6 z1f;X;2cxTD!D+ZJmAEPVdj~hJh!0LJV!!YJQeC{FoV=ZZG{4>EL^1*$t=!?CrI%(L z_BnZLu}Y46xmTSygXAbe>lw*LQ`m}!1&XShMh3lNXR!xK0B!{7{IC8 _jk>V1)qB6}6M{CavfsGBg=ZKwGk^_dwL$RL^%^+PAR~%>2`P;^H#r zTXMX_$c@T&p8Vl5OO&B4t=T>784&=48&v9gq>Atl iITftl6cp(&Bs1Xnwa;vO_s8A)GV(Gt`ym!0S+o)-Gk36j=q<|%ynARw5j@bP zUa-;}QWfS4LXfSfW(!@dXaP=SHxb1wedUmBmzhl *v-qV)>rK;6PpSZzc|!b>m41T7o-OB|2lfjTlX 71b0X(n_#B}1>==_M0P29^f<5CtMG67!V%*37H?{5T@v1xcrCOHUY>LdwVI zZ=p{z)4Z^ir77^2yQODe!9-PTD5Vc%_W%f&BelV$#^j4c&23Uo7zF357KukV8Y> z=XYXr=q}_j?-6|}V#LNFyI0^5zVq{WL|Hp}<6K6QSAUAyoIddkz~o`M61BBYYGxh| zQ2M-jt#Es=bAkaoJ0`EJFUZ7{Z`DOJprSZ(dTNIfinscC@)STc>dsGIX-!dKg~t`X z9UMH@>B(Sy8m8AO=?-lFNf_0!>s70vaU-mOEChv`!~%aFf@mFET-7P-P{Pk^Eidfz z{J$S_=!K{sM=c%AcJjVYzncGMuxD@F?1wLQe!wlmB(W?#lbJhwr#Dz5@ mMWe^f)66@}GyB*T%**Z6XFYctJhNx^&&5)S;1BJM ze;BDU_wN`yy(UNN-T&NFz&l0OV^QF}|MqC@QtYg)J4(S$JoBZ7AgLsFnGT; OY8|ua{nDUZ*fYZL6^8ob$oj&R_jm5>E zp1N5ZWg_~Cpd>V4 wCbO8%P^+U8dWwo}8##x%*I4XZ#7z>LatXlB`$ zkZZZzoKr$QPZ|}xHL;krKHyP|3OG6)U hysts`j=6*+KkO?k~bXJDXGd+ju%3i7Tre5o)ZYk_FIZlz*?>{hHLQw%bu2=k;u z2B2hH`P6Y?u~|z|l&ob+L~>rqFuKA0Tn@Z@>|LFO!uNs8SMVjevFp9RJIcyZwtZa% znWqzIoVtjoYtEcs;{o?{wynue_V&es^<#>B-xQF2@wRfEOWF^3p15_I>)6p(_R&D_ z(#9sSoM=DKR v$&S8Zd`mUqR_&h?rS z8is+pD(E&-qwEmwto#AA;u^g#NOIS>6w#Ru@dr&@Y_DEQ Z|G!+Nh!~u<69jzqaA -l9wK>Osml{?Gx=cl)%y!4PKA~-dl-`8ZjMI;OxF*(5Z zQH4pK77QhW&+g=$Ch?G#;vap<5>`W%O+}G@ja))>TWsHIG9xTMsD`h8ehL}`ZQXHy zIOuw Uqy1s~ zs-JJ3RvP9TVC6;)d-~>5_p3Nd y-pZn)beE$jGwa6n@=9O!oxn|~Mn6tBY7Gw0C$68iwGo%-k zSi7;K3mGKUmdfGK-;@-BGI|&~5nz4yANo99!``y1*7c9N3g=u4BMsG0=uEwEe4fJ` z3x=h(@ngTHTV6}(B)f8d1n7@MIK)&DF>IfCvMWGFe02Sb1yA02 fEa&60{hA ;$AOM^}msm(gpM3sFt|(7F?>tyYg^-+XL#tJM0qK?Ot3a-05A>!hq` z+N-A@y}@`Z6^=Xb6S9)mC#8T+akPJ|u^=1U!GTy$5P%U)@{F#g2fmr(r*^~YSU@F5 z!ec~Zbsg8shM*BqTQu4o;qO^hD2VNL_6A(2O#@eZOVUd0ID8`v#w$Rrt)&cY%hb$V z1C~BBN$>qZa^!`%ErHUXTacCT9QGov2ZO}3y&jK& vmIJl7cv6>|9+6@`ibaipOt`kwrG&rZ*(*>+bzkpM%3m4wS-T=BK@2&`a`De zKdCJdEUqu#%$*YXJ=(2#1|~hUT<(i}(W{PsKq0SyGMlSc34?r`H?I*94*`VlM9c?y zNlCoowPDx89&bQMsDLkFI0LI~W3zk&puhIkHmIe~>3Q1;GzcKFd!%_g*v$_N-*^nb zHSD#cFE=#W93Vi;Xz;Mc9F$2{yZl1fQnS+taJ#J9>7_v((uZjwR)sec)VVvR75w~| z3FpA+E&zVln40_$Y2!D44~^CZ3A(_5?3;<3*6bw(Bf$O)6Ia&il0K0+cNY+V=hO@k z9<8SG>N^PNVg-Q{FRYXv+;`;fy1gY-T%!+S_s=1TRi}z8=XE^+*yrrnR!YnFb!%*+ z3<%Jr3p#x4!Xb_gZodTJkCr|394SNjx{Oxde+hV5=zYrs )vF6JWi_w>>-PLh>}RascB1Ee83L3bfMWWH(fTdbnD{s+O&iOSh=t5!f z@RTzu48vIBZ_eB}9a9Z!H(}4X#u+2BH*$rkdr}=#VrWAz&U59R^Bg;&IPdGd&+hQ{ zXjqFx`PIP+5IL#MYH9MMkR#8@Ite%srSwi>+{M+2V6sGpj`uM-MI$3|fAiUk3g*pN z(*f96&G$IfC^r3iFKHBq!w4v~n4o3o$k3l^dW3b|yiSS{&8zM;nc8pOU#NuC2cbQ^ z1fglq_y)_mhZetp=T#eFgS;X4W>$k~xl;FSH7HLft=^{$Dkp9eaw|>^h@`!wjJd8^ zt}qw3LbD`ClY81*5?}GXc^xB$-c$MrR@D!=TFaWwR~P1dqXWQzj2U>5l-|BmhzQOv zt3Lp#vmS`(aBFksbn2=3_Z3lVOb8Qh%d<>dA#r*Er#u+m1`Ii9&+-hF#@I;xg{Xa` z%KJDlL~52vao%lfqd>q()4-D2CvS4~1s`SqnrnpjUlLBu&r6T&+nD3#4xc)322lG^ z-o|sK^NUd6=3fGU=~pH63`;iU1*bZl0%YQ~TY{TsHKG@-?a9!RJxi*!vXN_jLON z%#|B2n_-i6w^N$UNHxCP6#5nNdnnvu8y=nAM(n3g85HFRl-mi`-7h-Vvn?0cR~(rl z)IrOIKbUHHAxFC=JWlkqY6kHSfIzx?w8oD|X;<=2hOdPU7wUuKql=EFcB+edC!{Eu zP7yMz>NQy%3SI8CkM%KKOU|zVF>1z6_w2VXBK#qrQc7i?Ro>kR##nGpd)x5~Jz0^Z zi ~Aar$KUbP9YEn`M?*CVg1D*bQCt`)$~ra POwI z+@gN}{(T+3MITWvUc0C%!76;H_w1liaKnuC<=VM>N-?rMUTSAR?$`~~LWjfYm+?_G z<_hcbbVHdW3~uuI5{6;e{hc>Rxqa>GooBwVUh!L^sjHy;r0i5frBhga8{1fZu=aK_ z5dt~&tOlK;ip3YwvmG7n&muQb>e`IOYIYn#X7h?sqz4ogP!b5!7i5!cBKHee)?Bt~ zAIJSBiGC$3vz+f4(jZt-wjv>Lov7LugnKuZ>B46>P2@!VFo~1!Phza!p^xtK;unD~ zScE{Vb&JlKyz6FxI@8U2J(XA7emyKV&HK4+`eO*^>KP2(XaR0tDTS-ihr{mH*q%7| za65!|Uj!j9{b#=&kM;7;nGGm3H9M@ Y-$>WEj@9d7e_x?K(hyS zzS^yqkH`Px>?PyN3M{p5gtsiUhw_LzaKFa6_t2dZu&zZZUezhhOFZ|m$uGo<=TL>& zh*RPSG0PP_H?}qog>_h7YkTfmo_pSs)BISV$=Qv_c`KdyZ^kFxf8b8!#6g_gRo#4M z*`MP_4qzniovNkgSQ@Gm*pxomg|pE1frVE|t?WxquH(Qho{-l+1xDHn&!5W~KqiZy z9q>Z;Kw|7=XyOq@=JZzqhCH{83NKl6olQ%@eMh}eSf~EHNInw+nVt*}zGzq1{vyai z|NhSJp}Z0{6I}Y5jr4|qsW(KKUO^8>U~8+oer?34^1dj2T5IxPv(459!{ChBhGsKr z^32YF=IDpP&!Ytb4=+tBvORCMEE=|%^K-27uw8!($#LG>R$ll%g+XB4IFG%#lSTb^ zEdXvY!8;%PV@K{AbPfP4+j?o Laz10=E)~gD=)Pu$#wFE8<#c$S#rPb=GYDP0TU2 zGQW4VAZA9rnM09uFr>|CGadRU!0}qw_@f6_rin42l=|5=K1=9w|6hl_m|6{zotPJ& z``tA?zMzt34;<~IbP3T1IoO!mYDM86N~??=N>H@x24Ga-JSHz9de+RZ+8CuT*tdw% zs-S(8L>l)wVG>zuu&s9T_gt+Jr&B0xBP=Wn|JERj^VA%J+F9Rvk_%;xwvnUB&0bqX zsE^us)!1UhzHlKTObXgcO%WXTXEF$_GuUQ+Y}Ds5{F=lKZ3H+yg~YbZ8Mqh;GnJBI z4Wl+WUTA36rxvKf-+{Gf&08t~5@+>MFmkR_smt@M6-EtY4kUwT%FiMZXOc>^iXPz^((k4(vLx z>%gu9yAJF+u VLqF|7D*#Nd>mhJqb=vMtnqxw$BHBA1 zv_1S^_dM&R0?Vd0l`Ec}RqRtqBeac-WrzK@>DQEli5SXD-m^B)`U>@jcX#BXPORxw z>4fFhOk&c+J!p>+fzznRRYN9O%+9(qrv_GEN*33>p=oYx1r^qhWMpgaXqwGk^XxzF zP21+0JUC*LJ#>G_K~+7qGy(r_wJd6-CT+e2EoLXXH~3mJ494BVmG(hu$37!|dlw{e zXISLXVLG$)f672ne+N(a$To+MNw_f)%FAnR{qNpqIAw+vdYH6mC*%u=8=3s4xgmMI zhkKFtMM>#OXJ%Wk5$-zeVIQ?r`v0?gc9m-P>jo{_V@1GjOBE4DEK0aOy(w`gx?()e zL5Wq*A+P5{iGj<`ram-iT<}oKYO7YKX2R70T{eotNEw0c1%lKPMR;3M^AW-r*)c7A z=cjOY!&j~#`Ph6XK4}TDk#I#l{hLlcw8w-9y_DCBLWQfBtvb6I+-5F(c+s!wcF{q& zHnz}EM5hdr1GY}pWBAO&Rwi>A^L2U8W)xemVt-1l@Yh$^iu2NT cI)!kAEFv@l#bxJMI&s6tW9D(^7v39#U(|RJWmg9%1rfvQeObwzo)Aav zs(4mhAuWYTF*fe}yAtmE`?$A~L}hiJ%uX@|taLyeeBs!FQHEe^ST~R7WYu__I+5ap zKT_u2k8);i?WLVD@Fq20#rmSd54lTO=$d3l3jIPGWeeME^74x^jaJIMK|yK_vmbP| zKf4cRC@G82eet@uH`1kp7@dB-g-D;dKs#*cI$rA*mv02DbIct)--_R-oOcQr`hL%M zztp$sm9bf@00j~L1FbL9h-Ct9c;hQ%=7=ctEEjnqXEFV?+q&Iqkk{a?I0$7dWGx!Y z;GzE7JNiBTXCI^AaOAuKTg?5D>_PK#)||5f)leb;!14LR`c7%r4AL$3bpLhX0|fEo zVG8-$%5Ed-P05_$peAstKXSiMT7T(IZcwGh(y*}Di3PP~;*+i3R7W< yUu_qSMqi9+ zCvZKUc+{fP`^IXWAhK4XNBgDzwG-H&((d_#$`KiCx(+8~l*QvBWjZb6f6d1d3U`J% zr9edq)LkA6O4^Zc&-##Pp*4@}YL&ttsNl2p6HYNJGbPlN#R3pT)Ku>$eSKn6+-7*` zS65{eSK90YZox(d*9<&KgOU~BcLpS><;3!T5+b5sp~#H{RQ|K$twxfcv}BJK{uXPk zu2>$}0YTtK%!H$pb$^ii3rtHaoAV_ZYk_jKh^}sJLC;o7ibEf-MI6YU_8jUVu$$c5 z>_>7+znnNeiu1ymI}WMIw+OdQaikYT83 EMr#kR-4{sC#UeScUDa}?o0A>!T0hV z9h?oswECGNXk8{5%N*XShuOF-dwhy%w3OQC Ojpkvcad3hJq+b8eInarg= z rL%kSNfsNJ&mOw8)9t;BCtw=jnpVgR5Hr;DqwyZuiPs582fS`-jxhJuSdMP zj^-rxg$tZAS^Ok*$mgt2cZ=^AJYH+DIV}NN%sL#PcsTu6yv{uqfcvqOO;?h#AsG z8)>gD#v=wsLnws)_PK*E*|Dk|fqin&x#qalgn7*QgaQIUg3xnmcio5lKW%W$E- Z$(hht`#A!uu9ec$Q1MRpwTrPisDz1RfCHihWc;`O~l4p(GcKnyV~g8cO9 zZA r>l~qZgZc!z+KO3kO0WC`V~K;!>&iziYBICg{87gT^G@S4@6TJSdPzl z|Ha^oQK=RJ#M4VrooAaYy!UdCHr>uQLoKeA4nNYi)&|88863QcqXixV{aW=SFfu;N z^$%cY>wa$7UlBwAG2;BCy`rh4oS;2(tJXl5I68l!bp+d_yP(^K2IIljTRkrvnct4` z4PF*Ma9~e*N%izv{SV?|y6Bp9(>YL#E(odbChRP2fM-5UE&9WwbPTg2nV8gT^$a8! zW;En?qUSbhiK9DeA1kPR0+U3ImqpnS$EITAKnVAyN !vsz9swDXYiyDW1%v8orS%oSbw#bpVrSo3*PzR$Ai#KsZp};qtL=`p%>?LGTI{>l zHqEd#>(EySdi&eCr%vcS`5CiO7E(a!%xuIVvsR+d;W@86NN-Ta Fj;^8biqF$&J z@WipnXI&84_ek60BM5L5YbYu`a7sit{-!2ZiM_EKB+fc$JsgC-vl%?CjWvnsT<`cj z$9M=MFonUH%l#_J*hIE&N(?m5z(v`HJWqxA*W^<3SP-O@;pHvY(dd?loEC5>@IfPy zwHb75rFHscfLdEj_iAs7r%(1(TD=GMGJ$c{_^dG`=i9RJUsA9PSANf5W|> ZI#!Vgt(MV+3K=?E(*FT`2ee(NnOr8?vbhCA zaZx`>pa}48 yz5`B}H0g<@}=s7)zh#2q599Im55DEP$DlypPJYuK@nO!em5LZ8Ta^ ztVnGmfUy1Ya_#1N?@}av5D3tH2=eSAwZ2PqlcnZfJlH8%M}@xEQumAk0cuv06;8ZE zWu;BdAo1Z5pi=p@WxD$d5oe}Nrl}-15Ib0c#BA#KCI11Oo>Ty=(O%@dY+Yozq?rgv z>^Eb%l$9$(`6|I1N=*Qw=n6y{V_$rD1@006I4c+79rYBu-PNK!j@>u{-1M+u%|W$9 z9`#*FA3jm>R|uvrg;$F}${fY7^inIO)$dqgy30K$<`cj`z#9Y8_g2CMm!tmxE!3>B z%JM^+&e8jB)LKL5uiIB+YX;{TH?vQL$n;5X;PH-Yt7H@bpU;*}_JGz*IWeW?Wtqo6 z+o3*DGZZa2l$Mz-s5zdp+1G`Si1O!bN%IB4t@Z=cG31q$*faJ6=xm@P TZkNTz2qV-3`m_Wb1%v583^zQRMm<(1RSB` zJm*X*RoGswqa{(PADJ%oNxTq2>14G9uJv4X%V>jZ^+~q3Qp=G&0EJAm3IktE^0lX- zWIx>?gm~|Xtk`*?v4kcycJzS^F#lVX(ykR+_+ILa`~6G6i5R$_P&Vq7KvJhZ$ehF= z4DJhKbze_W q=jC2uaFcWKSEEWuvyo;}p&~ tJA@7r2M!T`%yL38emK2qkyn0)J zCE^#tQTef<-Dz`b8@$D~IqE6+|6Y6Uy{w 5{j-k=)C zmStchNxX#V;;AnZhZzu;PYz17y>MIG|6|2?^EqT3gC2UYKUqVfb6$I s2#;zLYN!%}tZW4Gje-tU#+#V|yT^adv(dkdePSOvxe8hZ!lnT1-C zdB$%g466SS*U}(6Wxy%Dkz-|lfX{7lAUL-?v)%cgZn7Y+$NFo4?YCcyMa1_WkM5c! z%k^)ERe;#Z+x#~(Pd7w$?PU5GEbjpG0haRGUVb=t=2CZ*0!UFy8x_yTPfVvF3eTSC zY0rVjAnC^lCHvZpoe)k#&@2KhCMg>_Vmj0LUJ