From c4a809a8337e94c8607f6e141c6ce211e6f8e37b Mon Sep 17 00:00:00 2001 From: Travis Kuhl Date: Wed, 15 May 2024 12:09:45 -0700 Subject: [PATCH] moved migrations to tle extension. updated migration to use tle --- apps/docs/next.config.mjs | 13 ++- apps/www/eslint.config.js | 9 ++ apps/www/next-env.d.ts | 5 + apps/www/next.config.mjs | 36 +++++++ apps/www/package.json | 37 ++++++++ apps/www/postcss.config.js | 1 + apps/www/public/android-chrome-192x192.png | Bin 0 -> 3635 bytes apps/www/public/android-chrome-512x512.png | Bin 0 -> 11656 bytes apps/www/public/apple-touch-icon-114x114.png | Bin 0 -> 2085 bytes apps/www/public/apple-touch-icon-120x120.png | Bin 0 -> 2157 bytes apps/www/public/apple-touch-icon-144x144.png | Bin 0 -> 2689 bytes apps/www/public/apple-touch-icon-152x152.png | Bin 0 -> 2835 bytes apps/www/public/apple-touch-icon-167x167.png | Bin 0 -> 3157 bytes apps/www/public/apple-touch-icon-180x180.png | Bin 0 -> 3392 bytes apps/www/public/apple-touch-icon-57x57.png | Bin 0 -> 1093 bytes apps/www/public/apple-touch-icon-60x60.png | Bin 0 -> 1129 bytes apps/www/public/apple-touch-icon-72x72.png | Bin 0 -> 1310 bytes apps/www/public/apple-touch-icon-76x76.png | Bin 0 -> 1399 bytes apps/www/public/favicon-128x128.png | Bin 0 -> 2321 bytes apps/www/public/favicon-16x16.png | Bin 0 -> 385 bytes apps/www/public/favicon-196x196.png | Bin 0 -> 3752 bytes apps/www/public/favicon-32x32.png | Bin 0 -> 678 bytes apps/www/public/favicon-96x96.png | Bin 0 -> 1698 bytes apps/www/public/mstile-144x144.png | Bin 0 -> 2689 bytes apps/www/public/mstile-150x150.png | Bin 0 -> 2794 bytes apps/www/public/mstile-310x150.png | Bin 0 -> 2169 bytes apps/www/public/mstile-310x310.png | Bin 0 -> 6091 bytes apps/www/public/mstile-70x70.png | Bin 0 -> 1288 bytes apps/www/src/app/favicon.ico | Bin 0 -> 385 bytes apps/www/src/app/global.css | 3 + apps/www/src/app/layout.tsx | 28 ++++++ apps/www/src/app/page.tsx | 28 ++++++ apps/www/tailwind.config.js | 19 ++++ apps/www/tsconfig.json | 16 ++++ apps/www/turbo.json | 9 ++ package.json | 2 +- pnpm-lock.yaml | 64 +++++++++++++ supabase/migrations/20240218234006_schema.sql | 7 -- supabase/migrations/20240218234007_types.sql | 89 ------------------ .../migrations/20240218234008_tbl_member.sql | 62 ------------ .../migrations/20240218234009_tbl_setting.sql | 14 --- .../20240218234010_tbl_activity.sql | 75 --------------- .../migrations/20240218234011_tbl_follow.sql | 86 ----------------- .../20240218234012_tbl_notification.sql | 48 ---------- .../migrations/20240218234013_triggers.sql | 70 -------------- .../20240218234019_create_node_id.sql | 56 ----------- .../20240220162656_get_node_children.sql | 76 --------------- .../20240228151359_get_node_leaf.sql | 77 --------------- .../20240301183729__public_get_node.sql | 54 ----------- .../20240301183739__public_get_node_tree.sql | 62 ------------ supabase/migrations/20240515173522_elwood.sql | 32 +++++++ 51 files changed, 296 insertions(+), 782 deletions(-) create mode 100644 apps/www/eslint.config.js create mode 100644 apps/www/next-env.d.ts create mode 100644 apps/www/next.config.mjs create mode 100644 apps/www/package.json create mode 100644 apps/www/postcss.config.js create mode 100644 apps/www/public/android-chrome-192x192.png create mode 100644 apps/www/public/android-chrome-512x512.png create mode 100644 apps/www/public/apple-touch-icon-114x114.png create mode 100644 apps/www/public/apple-touch-icon-120x120.png create mode 100644 apps/www/public/apple-touch-icon-144x144.png create mode 100644 apps/www/public/apple-touch-icon-152x152.png create mode 100644 apps/www/public/apple-touch-icon-167x167.png create mode 100644 apps/www/public/apple-touch-icon-180x180.png create mode 100644 apps/www/public/apple-touch-icon-57x57.png create mode 100644 apps/www/public/apple-touch-icon-60x60.png create mode 100644 apps/www/public/apple-touch-icon-72x72.png create mode 100644 apps/www/public/apple-touch-icon-76x76.png create mode 100644 apps/www/public/favicon-128x128.png create mode 100644 apps/www/public/favicon-16x16.png create mode 100644 apps/www/public/favicon-196x196.png create mode 100644 apps/www/public/favicon-32x32.png create mode 100644 apps/www/public/favicon-96x96.png create mode 100644 apps/www/public/mstile-144x144.png create mode 100644 apps/www/public/mstile-150x150.png create mode 100644 apps/www/public/mstile-310x150.png create mode 100644 apps/www/public/mstile-310x310.png create mode 100644 apps/www/public/mstile-70x70.png create mode 100644 apps/www/src/app/favicon.ico create mode 100644 apps/www/src/app/global.css create mode 100644 apps/www/src/app/layout.tsx create mode 100644 apps/www/src/app/page.tsx create mode 100644 apps/www/tailwind.config.js create mode 100644 apps/www/tsconfig.json create mode 100644 apps/www/turbo.json delete mode 100644 supabase/migrations/20240218234006_schema.sql delete mode 100644 supabase/migrations/20240218234007_types.sql delete mode 100644 supabase/migrations/20240218234008_tbl_member.sql delete mode 100644 supabase/migrations/20240218234009_tbl_setting.sql delete mode 100644 supabase/migrations/20240218234010_tbl_activity.sql delete mode 100644 supabase/migrations/20240218234011_tbl_follow.sql delete mode 100644 supabase/migrations/20240218234012_tbl_notification.sql delete mode 100644 supabase/migrations/20240218234013_triggers.sql delete mode 100644 supabase/migrations/20240218234019_create_node_id.sql delete mode 100644 supabase/migrations/20240220162656_get_node_children.sql delete mode 100644 supabase/migrations/20240228151359_get_node_leaf.sql delete mode 100644 supabase/migrations/20240301183729__public_get_node.sql delete mode 100644 supabase/migrations/20240301183739__public_get_node_tree.sql create mode 100644 supabase/migrations/20240515173522_elwood.sql diff --git a/apps/docs/next.config.mjs b/apps/docs/next.config.mjs index 4b981c4..6ac017d 100644 --- a/apps/docs/next.config.mjs +++ b/apps/docs/next.config.mjs @@ -1,11 +1,14 @@ -import withMarkdoc from '@markdoc/next.js' -import withSearch from './src/markdoc/search.mjs' +import withMarkdoc from '@markdoc/next.js'; +import withSearch from './src/markdoc/search.mjs'; + +const isProd = process.env.NODE_ENV === 'production'; /** @type {import('next').NextConfig} */ const nextConfig = { + assetPrefix: isProd ? 'https://docs.elwood.software' : undefined, pageExtensions: ['js', 'jsx', 'md', 'ts', 'tsx'], -} +}; export default withSearch( - withMarkdoc({ schemaPath: './src/markdoc' })(nextConfig), -) + withMarkdoc({schemaPath: './src/markdoc'})(nextConfig), +); diff --git a/apps/www/eslint.config.js b/apps/www/eslint.config.js new file mode 100644 index 0000000..8fb4d8c --- /dev/null +++ b/apps/www/eslint.config.js @@ -0,0 +1,9 @@ +/** @type {import("eslint").Linter.Config} */ +module.exports = { + extends: ['@elwood/eslint-config/next.js'], + parser: '@typescript-eslint/parser', + ignorePatterns: ['next.config.mjs'], + parserOptions: { + project: true, + }, +}; diff --git a/apps/www/next-env.d.ts b/apps/www/next-env.d.ts new file mode 100644 index 0000000..4f11a03 --- /dev/null +++ b/apps/www/next-env.d.ts @@ -0,0 +1,5 @@ +/// +/// + +// NOTE: This file should not be edited +// see https://nextjs.org/docs/basic-features/typescript for more information. diff --git a/apps/www/next.config.mjs b/apps/www/next.config.mjs new file mode 100644 index 0000000..3047ff5 --- /dev/null +++ b/apps/www/next.config.mjs @@ -0,0 +1,36 @@ +/** @type {import('next').NextConfig} */ +export default { + reactStrictMode: true, + transpilePackages: [ + '@elwood/common', + '@elwood/react', + '@elwood/js', + '@elwood/ui', + ], + webpack(config) { + config.resolve.alias.canvas = false; + return config; + }, + async rewrites() { + return [ + { + source: '/db/latest.json', + destination: + 'https://github.com/elwood-software/db/raw/main/versions/latest.json', + }, + { + source: '/db/v:version', + destination: + 'https://github.com/elwood-software/db/raw/main/versions/:version', + }, + { + source: '/docs/', + destination: 'https://docs.elwood.software/docs/', + }, + { + source: '/docs/:path*/', + destination: 'https://docs.elwood.software/docs/:path*/', + }, + ]; + }, +}; diff --git a/apps/www/package.json b/apps/www/package.json new file mode 100644 index 0000000..69984eb --- /dev/null +++ b/apps/www/package.json @@ -0,0 +1,37 @@ +{ + "name": "@elwood/apps-www", + "version": "0.0.0", + "private": true, + "scripts": { + "build": "next build", + "clean": "rm -rf .next", + "dev": "next dev -p 3001", + "lint": "next lint", + "type-check": "tsc --noEmit", + "start": "next start" + }, + "dependencies": { + "@elwood/common": "workspace:*", + "@elwood/ui": "workspace:*", + "@supabase/ssr": "^0.3.0", + "autoprefixer": "^10.4.19", + "geist": "^1.3.0", + "next": "^14.2.3", + "postcss": "^8.4.38", + "react": "^18.3.1", + "react-dom": "^18.3.1", + "react-use": "^17.5.0", + "tailwindcss": "^3.4.3", + "zod": "^3.23.8" + }, + "devDependencies": { + "@elwood/eslint-config": "workspace:*", + "@elwood/typescript-config": "workspace:*", + "@next/eslint-plugin-next": "^14.2.3", + "@types/node": "^20.12.12", + "@types/react": "^18.3.2", + "@types/react-dom": "^18.3.0", + "prettier-plugin-tailwindcss": "^0.5.14", + "typescript": "^5.4.5" + } +} diff --git a/apps/www/postcss.config.js b/apps/www/postcss.config.js new file mode 100644 index 0000000..8caf5cc --- /dev/null +++ b/apps/www/postcss.config.js @@ -0,0 +1 @@ +module.exports = require('@elwood/ui/postcss.config.js'); \ No newline at end of file diff --git a/apps/www/public/android-chrome-192x192.png b/apps/www/public/android-chrome-192x192.png new file mode 100644 index 0000000000000000000000000000000000000000..9d25e5cdd17457537094835daf662347bdb20d1c GIT binary patch literal 3635 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 literal 0 HcmV?d00001 diff --git a/apps/www/public/apple-touch-icon-114x114.png b/apps/www/public/apple-touch-icon-114x114.png new file mode 100644 index 0000000000000000000000000000000000000000..e48e78e6b40a2adeb35fbcd56044e385ea1ba394 GIT binary patch literal 2085 zcmY*ac{~%08=qV=nPU^>$gx~M$!0{6%r&>qoI}O(dmS@3B}ZQ7sN5npQh23d$TfGQ z5GFSvDap#!i^(zG`Rn(4|9GC~^Zh>mJ>Sps{XVd@HWdJ!0|5X40W-7_hCPE%3dqCm z>GKKE?7t|Tnl6J$}TOz?2cw4tJ^=OorU9!lqDy}0ANvV z*__Wr`#1=O&l-KC|_R{so8_>1g@tv&1#wQBkZ(cM>J(uv@FbM_mCHj4=SLOjriZfaArfEb4d%l@U zY+cPp`lCnj3gbYtipRGWv-0!#tjdKEii*4&3!Q=oN4@Fi4Iz}2LVhu|XZ7{V^W#Z^ z=QmepG`!`Q)jHCG7orZBL(Wxik^}`KY{J7EgU)!*no>lvbffp7SS)sBp|cYn`+jS4 z(QtLTmb2(ubez_BMEEJB?>Nvf@wD<*Lq`njoPNw+wPKyI(^DYNSm&%~}KD9@><{OUHdD$TS=fp*Xeyt~Dd&y@`Pdjg2;1EV34n5^9 zs|E)K;<=1~d&@%-QLKH@#-OcbE3^SIW3WLdbVVpQB*cUN(yfl3Zv#(cx#0)scOZt2 zN2tEGjB4ul;iB7H%R{&_2RSwAndT6$!6N+y+KNk)KY=<@Oqildk&r$j%;QCJL2hnh zR+h*(H;34Ks>J0$)_xfJ4e2%F;%w)z=+DV2jm%@)w#Z$uX}Yv#Ng36so&z5ot^_je zX~0i?Xpg+J%@}(zswb%|aoHa^Sqh!P*4OxpSsP#p#uiPwhY{cDg&h#}*qmSJGUU^% zcc|T(SLRsA9G=?*_k6s&OiE9;!_lf&rD)cdTFY3NqGCyTIWXp(i!7rOtX)aI96+T8 zYGNv*cj{f5n_#C+c2`C?Pu5RVu^25-bFW*yxA0*~4oc0n@pRoELzFbU;3he}NjMxOGJ7I8xoP%Ya>pfQ1fCX~pUg z4?Reh-CS2ZFWhGo_FKxtTFYkmwZ+7La5V$97!lA<2&bN|tGmB+>` z{}#NWwEn4`zk1WMug+_jf`>5g(}KT&I_@8XPq@-jSmlk@GoAO36N?t5{~rCzLOXZ~ z*wzywCdDeTc%r6Rn0nTqV#SR(PCQl=;Z*tHS<~Sb8s&E{Oj~58ydS?1U_U17(=ahf zB8(Jsze|&PG*RIsQAAMkwk^08{c)RA(plG`q^g?YI~f-yki8 z^g)yl+*K@nNiq6>xt8-WGkWiD?$$dS%(cee_pcFe?7Zj&F9X-6Yj3Nh{|OYs+v!Q` z-nDgXe|t`lz;cp*>msXsQ>Hqn-HG#MW(*touz0#r+iNYMXp6-&un+Wv1H0U>duQ

-);8UWMuKD^Mrf;cp^-q=cQ^I39 z0Q+1`T9$Vr_+z)kQV1Ir8Be6@}3bdlf+XZj^^yx+V0i!&G*gDgwsJ3!@ z8#tJwOemOw%efReRQn!Fx*e;*OJ4Jzd1X8&tA?vv@fJXEV@Az%p%~xltF<>48K=g= zqo_}4hV;k(i;(FEE^7hxH}1^U83q479*fG9;@#w`SJ>E!+JRRscEb_$Go0h6?VY$I z=h+_L@BEfjqq0X)$eVg&UPYtPGIlrTOw;-lZJu6-P$tpgsh;{|l5;K2xIr^ltJnn1 zbCvj6NOL{H}lKruw$n}7VA`8MP5a`=_Mc3M6x9s z4g7hNC*dq&jHptPQ)S!DP-EMTT3Dv20}3JhP)_gOw$jqZ%+A*%*1?CwE5l$9^?Pii zEjx?_13-P<($?)Rtuf`$(RA8Ml1M>@c_2!qi|-|uV(GuZ5r@=w#;4I|QrhfP2bdXK K8&Og2asL3;P2f`i literal 0 HcmV?d00001 diff --git a/apps/www/public/apple-touch-icon-120x120.png b/apps/www/public/apple-touch-icon-120x120.png new file mode 100644 index 0000000000000000000000000000000000000000..aec02777e15690fac780d36e94679228bd3e4826 GIT binary patch literal 2157 zcmaJ@X*kqv7ate)|31Cf^?rCiocmnAbDwiB=Xag!oa8GQl&G+rFbD(^wL)7s z0Gjwm1djr%(RDZrP(s0IR{{tGmi!|;pxk^Jz{o>zK$(Lod!Y*e;Jb;mMS?)p>EK_U z{2-7ZuayN7OXOKDaQ4NzOFeLY=q{2qe3w39oTMUMHJzu>4gqUCrb z&9v%AHV}>f=J5Cm=cRqgQS#%*rfT989%r_$M~lIjc6X9g_U^cS$tBOWcp={bisf*8 zGhgh%-UBd1N5-4<1)tmy;Naz@;#BTJLf$`0mnItOy1f&e?|YVL(B4D;^i;Rr8fX5Q z_S*4Hf3-IXeensc!mX~2MmpkoDpSL;ZFAwXvZy_;xQrf6WZ->U#u-RF`IwqsGZy}L zu{r;j*N$KSR&8pdRA*+ogqKq!xC@_ORLPc|p&DkzpCQ>jGYbHiUHJ`Mm;vD3<;j+q zrUp+P3GM_yujs8LLg;v77+6+TwydyAdg4RmeIvr$)WQBvM#6ABq8=)F8e?!nO+=M% zDz+9!4OumhifT-TXR42kj9ls`%=dZ%=Xq7se^*c#hY z>TWxxDi}*Y!j(&BZx=FBAc-b@Qvxg3Z#j+C&>GRwmVRUJwbgBNum7B&OeyX%b6~@D zeoq(tJ2_5T66Z?##~vL1-m0{ z+OS2KNhRMhMV-mibna+-0RCe!A+F-@kJ@|F< zlOp23@7$buL!(E!p@a0*z7-78W9UD8<>XdJWB^dQ zWs2R!w3?5HScvX5=6*rM%6$RxsV++fd3$ebF*4m~=fb+Za&WNPk$E4KnFgO2hB{d8 zD)}fHD+rBFbuUGYGK7b~<5a>;?-_7^nQb2LC9X^7ZPMbGSKb)RS?Gy8L|n_Qi%V5l z{5FRJ(4}8_K48>fChQV5d})|ed@-@(!wt0mOR~zkl>Igv|0^frtmKJk<~-+es_Gqj z%(=T^Pr|iwc`||LO|8#=_&}*Z+P~M@rDj)nv??}5tRz^pGbpZy)El3q zYhB2r3#KwoSNj#ZeyyHUETgbkTWr-UdOzA)b2Hi`c2HfYr z!^$tE@cF1r`ZPpE98gk_qlxSj82wmh4Wi`}nt$?j*t=P@U!s;Zel8>+VXO76M{9zr zg;4YYOYM$Q2846u>743uwP0)Ohen3o9hk7tpun;BqO4;O^~R{J*9(Gpo6ZXfh!Lqw zF}q~Zk@gOXECp&5q8hcyA(fV@-m%vfW8`CqSd+XDXokXCCG;!W+6aT6{fm^z=5xX@ zxvnk)T{sxH(sdT1X<9Z2X2O!GsOS6VXis%Lf;s)l>@n8Fp~n_HdDk_3l59}NF9mNSBvcDa0N@eU!O_6pL z*UMy&yT+blJ{MOq`xi`~%|T-@aDMjED~6>@IaE;rHljN5YIJ2NxFP!gwcbO4Yx(P4 U_%GyLU^)ORLfadvn)F45QZd#PYNkPH zQSDVUhMH6doy}7!~AmpAI-#l>R`>%)7_eSyv#khP*($X=Qipmdb z2ql?|Vv50JhHilld18=g2`H0n1(em-QY#b{Mc3V@F%|!lyig(!`zio3Iy#4s85AdWOs8GBC*DhG6`K z!Ta=c`E-Gpq{nDS-!g>ihUXuKoJd!*xA`3{uyL&|KoJa9gZMs zOlRB&DSglqhNJ%6tRj&}%y+fVY0kN(>b@<}3W4?x4n&ftmRfpYW7PLY=ki~S)n8q5 zQ-`tQwFdGLzCJC{E1v=ji;CEaY*)gG9nC*KPNi3zE9+V353JvqF8d>&G*ap$Cog~a zh~-q?Qjo$(uHj~6BJar_3g#wPrfi>NYrJS=?dJ#JZzPx z>(uk>Wo}xedF@=@E>L;&|AuB4H^P;(77m!RKAzQHzmGZ*pb&Ajq}$^oBV~VdkP={+ z#o>~GRvOTV`pHlDtGh5AteqqH?bhSKfu4!_OGiyiTpimRO$P_Mp2kCpPH}bA4k{@q zloawx30NHw{Ag#QYKcvv3h`*o_O<2lv#0-Z!p9|;p>5IV@{L=rS-*#uV#_gBj$CD6 z!9k9&U&MfT1znB#mq|*ga2sSqy(&IALmwY+uY6dI!@j-)Zh+^0aeSc+RM2)oF9T3= z8Xa{B-|uA~2n~l_x!x49ZnK+IpE)0U46=prUX)u?=!6J1S0+<(bM@TBfE~e;4RO1V z)eY-;JVNJLT-R_5XuB;Lw*BL(;hrK;+}DrOI4PomZ!=7n?t6D-@=0&D$))z=36*iT z)wzP9qI8aXN4!F!Q)!_Sy$GRZpaSe&746`N!Nd>B)5AblU&i zTv@N<^h%_;7nhaw*80C(5KiI&M2)q%V6!ote|JbjGGny|*?C~qf4|w4u9FR)=Q<=j zYKbxXEF#mkSDlHAov1q9gO*Y5RaiKqM}jHN*9lVB@XnWjW*A)P7^Mo)Ny*I2Tr!~| z2eM7hu&tSw#tSu6_&Kf|xA%YRS%fVxp*-0)wN7U(q&k(3d39~_`q`&q1O!fXLaOE; zJ3A`)oC{We-C|aO(@f$MMNU)?qowhCv^erN;^dAp1pc}}0%*X%Zvd>My|hg(jlt&3MGs}g?=_3sb2YyEX8M&GS#eSy!1`m<*gwLf zn3KI)hvstIBz>MzQ6Kf*Cu8 zY=i_N_m=sX9LVhEPSf(+$F>$fjPl+a0|`@O#rCOKeQAnhB}rWR02W_oY_qu9t_k8k zFb?eBr@lHnTyn$2xk67PJT`J&A45O>Ww^Xdl#z#YJYy^ z_&D`^PB+S@A2=NdRx*6lx?lDpX_kPE%Y=BXuz^SSWp*Y^I$EtH$I6NvI~>@bo2-kg z{?=64_UHqY*>`P~=b_=8`|ZtK#1>}Iy5;gavxrYKR`iN`LtyWKW6Y?;M0U=J;B5X< zd5K4jA6@6jJjR<}yEQ9vQoa)9?hyuhF#~vZ^H+5I%hN%W$PU43#~mepXZ{SQ1Cu$cNPnz^|iFLCd1)ge)N_D4Kgy% z6ol!FrHF-T84@Y0YRP>pCdI7x|+rgzY+o&XUz5X9NYK_cqGJU2N z9{uzdaeH3Q$&j7`>sTyuU@pDJJLi@msHdw-<`nHNOUP<> zw1up&MDAx&rRKy4bumJk%!Ea z{r≀?)xAi$kTZU}aoCJufsj#;?aOU0u7(ne8%C z%mjz5>8jpbnJ}q;prNU$ioZkpK1H4LAop4Sk2Ls~ZiuDtyPqRcli)b#>)RtZw{Ib+uHv z#ysvO=;Bn<(?(QiXpNEKlT!^!ERM0)kOje0sY0{nISqcSTLGRK6ODqgc#RZmFW?($ zAFW9+pi)j3I; zu*mNSEP=ygi-SE+OvqG6oqz zvoq!)x3;%OukP=ZBDbkOC0Jk%+z*kM%r^K?lOs0pf7I8%rP+>Xq+5q}vWDktp<)Es MpLRx9qx^3D6CUR4ZU6uP literal 0 HcmV?d00001 diff --git a/apps/www/public/apple-touch-icon-152x152.png b/apps/www/public/apple-touch-icon-152x152.png new file mode 100644 index 0000000000000000000000000000000000000000..3ba8154cca7eb67ff9b8d5b2d80fec827234a863 GIT binary patch literal 2835 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 literal 0 HcmV?d00001 diff --git a/apps/www/public/apple-touch-icon-167x167.png b/apps/www/public/apple-touch-icon-167x167.png new file mode 100644 index 0000000000000000000000000000000000000000..c784b4cea736211a76eff2e580401a93b077d299 GIT binary patch literal 3157 zcmaJ^c|4R|8z!=rvNR?}C1hVl$(R{48M`!$CHqc=!B}GK-Yk3t#LzxiK*%V_o35q zz-v`sOT&!Fygp@)H=ht>`xe{84@nT<1Qj)Sa)5}U`z***rneFe{2U;;m}^Awm{~q? z)}XRunQR7$*(P`X!bo4;UI#7qQ8N9%dTmSv6>jWdav~-Fd+FARqr$NerIjWZLHFc z4+Oe|j(FiV%C9z#$2&x`opjx0Oqc)*4O=$0mp)eee$knz^U6yNelNsiqY1zJpV3(Lfo9gj6%tvGYYnr@POqD1#O>Sdni(viz z8(kAPQzDV2N&9HsK!wHg`NiJ6IcdCS9ErqzYnkcRFFmqso5LoyX847LWxsSLXOxtPi-wNxJMp8Y zjq>3X)bv1prmRIJI>JXwE5@5AVb!FsyebOh zamraF@x=+DD|+j*j~JioeW<){K&-991Ak~T4xuGskeTW}RH|Qw%^%Jfk}g1n%Upjb z2lXaILzB;ICkWs~G`%KkaYjaxZ#}tp_s%1UMfW_oTz(7u+*y-M7E<9Wld-BUF)T#c zZOy+ED^8ZL0| zeS-65v^kujkyRY9GU$9S>Xc-{TB*Qz&HKHLnGROw^H_o6LS*p8OtvOnn2XObv1v6m zm3?%*_ml|>#L!U-_OTHCQB7-Q_v@7GQLOm*`0C*8TfT5|8an((?W49wBE>-big*Y% zR_tBPtzKmh>U}7^o$Jh}AkwMxpt9gyM$V6*2T4f+8Q>sq5jTnNzA0cR#;(WNKx0w_ zq^@ZH+PDyWCy!Q>+!&Od$MFL%p^}Y z?~cfO?f=o&*H2qszN3O;b;x@^z>iik2yKmGra~v)Q!KuHokC1hyCp)9L}OIg{)NnN zSjwV9g9OV4zBfgX2h#-aN70na3 z8~68#Rsgc&ehxM`-tEm*+4`~LDLUf>vvVxCrGt=@G%7GVzcO!gqAc&R?t|YqyRW)m zS4vePdm9&MxGzfvr~@}+)V&ABs!E*-|M7igYy$`P`=x%sLt9}(7*^^gPINQSz+w}M z!7raNj-V1j*_(#{_}^U}#syV0c?_1sr*1&W3g3LETO$9=T#7pZf%W6Qcm=#AG`8-# z>2xJQ^-H`y)nS@D2&EO~6%Rj<)h^SHpN8jtYoQy$4pP3*;+5iJV!9K~$d+JYxgrly zA1=1-&6>z5tU%=^hd~9oKqU)lDJeaV(Wfh$W>>F7JF0Tp8AuJY4_;uoA{TkMziC0+ z`t@@!d{oYhbd%mre&49?`AT918HmWbf|qB{H#$wrLM3yfCAwC#Ya6 z)s-T`Z+EBaLL1MAd&jxKhUhi~ECr;BA2$y8TN~DubXM${^-I33=fLFqq_dZisPEY$ zhv%>mxwTLA&r{C<)HK53FS4&r2Cnvxl%Mu^X@hTVN5Dwy#VQgCKlrgxM&7pR59kI(T?5c`!b|GVN~ZcX}DPZtbOj z?4KKTd_Cj%nOldi*gQo$ct-Q~AV9tgKq3}%KeJvmcF;Vvlq#xe78LTzZvhgd{!-D& zvVHwiz1yGPzdU#|$z(bBKpp?Nj)Q8q9;!3pCQ5&kCCVOWsO~*hnLl~GF0@)%Ma4X; zwJ#r0)=1wZ3F+-vAJ#a}^MHzpCaaUZ8_V>n<$GN@MO7|cRLQzCL`9pHh&Lfdix(9_ z-8cJI6s7VU335VsfI#Jd8v@XQ+s(b=p8oljKM7%jY88a*H-$0T%{D~M8ojWJ+MwU? zZKe@QX`x>L?j9Mb>)SWQCFF0e`XB|J+^wx&FKm=8O3{{YLf(9>T99=U!yX zGIEcS+1vQyoU4mE0F!Th@$f|>0LPu59nRf3f=PE1&o)Lrb13;&G(8|12Ll-LU?(&z zd8Knc6xb#S(|+J(akiIH!ssG2UdwpbohBCPdG&3_v&Iub1irW-?dSGy0G<_@+$S^_ zgeB4q$DUeU&QWq|J1>YP7OyJfTcsgW`^+3JM||8Ie9NNIvEO{C^oIG9_`60k1bhz! zq~1`(RC8@}xOQkbY<*H?qB*=NCN7Q&mvTELMvE^K)$yozAJUnUjhQG!(?|{j_#|d$ zDc<0aSZ?b@K0dzT18>OS_JXSm@(nZ%j26E$<3HoA66;IXlG1%}P9AvHdgPM2F`b?D zS2<7^A94#S+;>k3S!$;WMH&NTC9s`xb3dkasKtM&Z*?WPtXw~dQxeq(5Hb~2na_s4 zPmJsgF6!>qgT_KB;$)UVC*|ChB6ddrbgR3(0RLk@q;Cv7Cc#8NA?2t?ZTAVqu)ajo zAxF_W2>|(nj>D&z=sx2SDsC5iT1nftr_z7B7$iEhlK4A(rqKtHr2-2qD6*86OMT3s zBSHm*vNv>Wzo(ZSoDOe|OuW`8e)Y0W%=Y2Ic34R1r5L$^Q10?q!LNxh2L#jo;#jvtsOM@C@gJ0_@l=7yjAD!jHi>3VA&a zZ#x(mB;@KC{zWQN{9iSkSSQNu7$=DhpDR^^41^zSQNHXQ)EuL&h>`;#FhUXBatW2g zW6?I-w*^q19v=TR^)@8@O;MSWxho*-R=37Kh+n$&o@!n(4gCe}TWUlMC}L(26O&7Fk}RMhiMK`v7% znYMG0^#>wusQB1%EzXNGbdixA%CEq9S##P4h{_x1vOZp= ziHyxi$Kh~CBJb)fhl0+`cr2D8as44URN{IdAP8H}sdY&|h8GqANKr>f%* zUvM(3`_9D(Sthn2t(TP3b91Sc_8NO8mX?oF!|^%Wrx&4rU*-&A`uhpXl)=7dgZIMd sGaH#!K}CDlp(?@utEv87U;k#d6vNO*Re6MfzW^qEZLC%$#_`^N0RO=L9{>OV literal 0 HcmV?d00001 diff --git a/apps/www/public/apple-touch-icon-180x180.png b/apps/www/public/apple-touch-icon-180x180.png new file mode 100644 index 0000000000000000000000000000000000000000..b9043663a29c3fe89c83fbd5752fb507ab2d25fe GIT binary patch literal 3392 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 N(SE4^0HbCX^&cMPYe4`2 literal 0 HcmV?d00001 diff --git a/apps/www/public/apple-touch-icon-57x57.png b/apps/www/public/apple-touch-icon-57x57.png new file mode 100644 index 0000000000000000000000000000000000000000..6fdab3aec720259d2b63ab3e46836edbd0c8acbc GIT binary patch literal 1093 zcmV-L1iJf)P)Yt9v}|-P?L>9p_i4&e`pK+FyIE|NmRxUZ#|klo!}JPWS;hMA{2KLZk(X@bdCP zad9!i!osk!vV!sPalE{!sd*+9)ip3M5dHoAOyD18W@b=dUk?>18LoMGc{T!x?CfkL zB_%-xN<>CRMt*qQ&(9AkP$F`6cJ|$|+uK{Lt*t=?N<=O$E~2lm56{of?DxgR1)7?g zu(!7d6_`}oIv*b&`1|`~cXt;zH#bm)vKB&|o}RLgY8+-jE7a&KD=U$inF*801YW2p zO-@c?cz75h5F)aztxb5(OH52;EvBcZ2fT0(*ZBB&X-&PNq5{s&&ftYxEI`-S*P3qn?(Pm_ zV`I$J(|2B^n1O(R0F;-PqpGTk{U&E)wOX;fybL3d>Ug@kx{#KZ#@3NrTU#&+sb*k$ zdK&xt`-Tc6q>6NNb7K`!ghAjzn#hol5R{aZz}MFoWo2bB65Vss-Q67t2?^{eefWpJ zpIUf$I7&-P5fl{kdYm$y`T2P~Jw4$oP`^AsKmStk(j}5s_++#GzIoNq{I0I9#@X4K z=4*5f*XHJCLj@Ai(a~%%pa;z&smaI1#o;?Zrb7>!MbccNcJLk8+1b%`zOLcg(b1tS z5dMs#qa$>7cIvuDcXg%Wlb@f@`rl_nL_{DbC&%X4_VzZGmX^4@=<)F}^Ry=?C%Uea zX6s^OW6|5&%Tj}ZfdRC)x4))!s*z>}XbDE~1*LM`-Q9)>B&6CpiXIOS4{?8g4EOgM#FRCUR_#>B+foI|e$R##Uw z4PDBO=+)lD!~{ejB$8}sXh30M;XluzNF+Ty9a_oF&4stOH-?6Wzzg?qrB?AjfnTMj zrUp(<{4M#+;bDk^%{)PsYAk&%%B6(|w;nO{}414M~PiY(p^OEM4(3ky(z z`F8=ZLNb(m)2bpWDvBipRD2p68*zDg2^E+ed(iC!he&(jM~M6dBs*(^b7ZtX00000 LNkvXXu0mjf#PRm5 literal 0 HcmV?d00001 diff --git a/apps/www/public/apple-touch-icon-60x60.png b/apps/www/public/apple-touch-icon-60x60.png new file mode 100644 index 0000000000000000000000000000000000000000..78c91130306fcab9ef2104672994d16ff7d28ec8 GIT binary patch literal 1129 zcmV-v1eW`WP)z(nw^UVCtnWvfgY@V6Z^Gto8IhXJ6dyXM9GxHNJga=#ng%XJ;o=qD*j7QWBz~qRiUU)6=06Wr9ymPAs;co}NM_$^>6tUSefs#jJgNd>ktA z{2E6_C}MGO5%>4^2nYzk-rgPt2L~}XHwTp%++NzrVPA&>0|Vjd=?M;=o}TdX@&ZoS z1jok4!e}(IFEa}Z3+V6f$Hm13IA9sW^p8$YPYWX4tmVVQ z1D2PUk(ii>`1p8XA$xm!@%Z=%M-_vY^ni51zYBgY_hm2A1(%kVifev; zKJzQ z_*`3CYZC8B*d{IV)s>Z%NKH)@C1GS_B$AVp&F$hyR7@eR7L5b zlKL0!69BUL8bT;6EEL_83JNOoRHF1yOMQL4h;DyF8*6krj}k~#DC^SXmg?&2zO_+| z`{xT#fil6Ac2dmyH(ITxy(kk*VVk9zcz1UfDp4kw%*n{e$hS7Cm}tLPCCX3YQK*-j vn=9hpnVA`-XQc`E(L-m)E!f#{Il;dGeB*7ZN+KaF00000NkvXXu0mjfZfFno literal 0 HcmV?d00001 diff --git a/apps/www/public/apple-touch-icon-72x72.png b/apps/www/public/apple-touch-icon-72x72.png new file mode 100644 index 0000000000000000000000000000000000000000..0d2fe22ca02b1df81d979ca2efa85253927c996d GIT binary patch literal 1310 zcmV+(1>yRMP)UtEvgG#m7ChiuYS2MVmW7Fl2`nruSm@8l$bg%h+uLWT_Ui2H z#KgqJm(4Ny{AX^!cc6JKM&fjIbiCQC)z#JL>+6H8XkKd2H{ROX%I?R<$E6mB5K@b6 zZf>&c%E}64M~FaAPfzS>X=w@B5h74>ax%Nd#l#-rwIJ<>lp4 zi)2s~v$nQop*tWT0H&s&8v|BWR;(Nd4-fzE8Trp-vwmj=etmt-I<#|hb1($e0#Sij zS69d00-5RW??+Wt71W}7i&3jsc5w*W&Xk<0MU_C*>`O>Uz)!&tD@2t*6rQPk_$km? zsTNfNQ8xS&lDt<|S687HRRU3>*U-?wdRVfvwY7z|wl=86pfK<0>B+jHj*gCsTaE^! z$iS!Td+hG+ve5ipkV`NZ=@zd)&J3Hv@?S&{9IypK00|7Wb zKE~A46dWBLVP$2-+KQo}AyiaU;OgoMq99CLp)V+%zC;wkB%%{*^y}9z*x1VjU^aL-s z33hgN2D#uF1#uH>baa$!@m0m%-X2z0SHTNzf>H2STU!fVa(#V`($dl|J*l?fZjGq$ z$Hm3L($bRkVN{S~Vq(7h+tbri<|n0IQq+g-@9$%Ld>j`S7vPC3UeejwnWYmR9v<(n zwY9aepS!y|h>R@O=-}W0MMXs{ksxMgXVKW$D7;vNY+iDAclSLs?CR=*z96glrkX{F zly`lHtb#c>IIu@|cX#LuvI*wnyMEsa}}p>1>?QIjyCp`oa%s$vG6u(Pvc z(e(QIx=^d!U!ieZK_4_LD~o;TA3wf7Vcp!^KC}~mLJjBg^78xLQ(L^eykK#05yQj7 zI6ps!CTJvBWMm}j>gx37aymRbM1FogdsG*-YnX|N3ChaK^hPX#Tt;qgE;K=H!TkOG z*=4A2Bqb%m(9jU-qPAeVNKtt}V#y-d=H@1zo}Qp@Q1O3wc!0X7Ef}Q&&CSiwH=3H7 zpa~lFVf5dk7J$-+x1LH=78VxR*ny^lEn16rOifMy>W)b_iiCs&WM^l8s3nwVH8eC} zX=zF8sRgZ9YU@2^o2|&q%w!P{addQqoSd9@GcGc+dC8uh9&B%Kv*!Z?19~AAA!}Me z-jNV#VD39)6^wFzg6f~XAe&$$5=}@GG?%Y0$RZfI1e(3Kx3_1%XJll&XJewHle;8s zTClaXW$_Og;FOdU=0*R@;NT$U=H?_Xl~LP3&V%<78^KjDUteFgm`j*=4CYQMCN^B zVgkHTw$4aI*$E;MMKFm7wN^$wRC;|o8lg`dg z_Bs`I5fJ8*EGQ`WBo;w~F7fg45CtIwqkTfLv9T(TM@L6P6oe3rzBPbEQ-w%toqCskroxj8c9SEOd^V45>W(`h$5Io{soUg$BZ%*x{d$<002ovPDHLk FV1naGgF65K literal 0 HcmV?d00001 diff --git a/apps/www/public/favicon-128x128.png b/apps/www/public/favicon-128x128.png new file mode 100644 index 0000000000000000000000000000000000000000..8d66d649cf28fc1e2b84f721b6877af49b2b237b GIT binary patch literal 2321 zcmaJ@X*kqv7yr*N7)wkT`&yBRkqpmd81XwzC`r)x1NUin{t=^=L`RWU9faKy z@7!xB(}{$A?5k#q5Ea$jlzpi={YyWdc6^nQ$bu~C}w z?y*^_qEky6Pm1qzAf5!1msSP7I6-*Yd5v@(faY?j&|Oh-2pBqa0Z2|x#^G>euTHFZ z&m-+OMb?k+rKK@t#gIrv9UU=lLD`n4wog8MPQ%@M!2d`$R8h(DQT*AAW3ZULwmVW; z+WttlhHEgDBo>S!t1l@bA)#>IU}2>E(9m<|xW&O@6JABmCX2lXDz=K4YVWR0-1+mj zL`-?)wY5bz76(&){knh1jESdV?vZ&Q;mZ@_{XazbN;wY-DUcs&`!}mp`3>IWH05D1 z7yy22eL?uJyfL5?JP{tgyYq87l-(}-kt^4-l+!b_wLxFeIP_}r~QGHP?lI@RQL@ZS2u`yaboVYt`BV9__^0s1d0Ra!4{ z#VByCw)5v!^kP-2oT2Cb?>(nVU&QL_syy79MK*fo@Zy>2%GR3C44Zwc;Y1dtHh>{_ z{p;2t85beN|LQZ{nX@9I)I43O$fn?S^_6G}+8}28gKdh%H`t0QK9Bcg;sKe(Wd8BK zTtoXyAMeVX3YmF}*r@6CmEoQrDB#P~aQ|MEWujbBQBfB8!!vqo6;{U#JX{tuUiZu( zwXxxBvBL|i$7ckne}!??F~2E>d>><-dEi}8P>^SG>%cqFFDh0fo*PO>3o+m*# zxQrYtMF7Vg(PMUGmGy6{pmtCT?gk4#Z2<|<2t0@x7V}jh-x8FQ^zOq%EQ$Z| zqnOn}+{z0x2s2+8lrwqjj_U3PPjK-ZyhMGs8ZJ)Mhms@(u9@qM;~9@ z+5DFA@Uz7V5*@V};94Jvz)UBnp}1_g1SInn{eO#U!?5jwcXG|m%@K{m;AtzrevmTC zlCMzd%Rjd_{OzM6H(|%A5LftxBGnjjGKu&g=vx$*% zBdXnq^8JXj_nlCv@2ARzTn6Hw+Zdmz@FradiYS8Xqw9OX?^r__U(z9YMkCS#ZZKmK z1(+8lF44SaV#B|WNs!v_CLGZ{v(8;ac!@@;yC!+ONd!^kSSc(Zg|-`H*#u7J9Zk1F zSu|WVW;UE$8|{@-ikp`q_In?mfH+8&>&CSSC?$9vPxPJW%QfCwXJW zYD2|OcqJ8GuP?wN%F-pqO~JOdfv&45GJK z$#U?SecTbf=fMnxLNELwx7rH6ES+F_)=+Ud@z=_i5?1n*I-uT5Mf+zS5NqGt`FTsK zg#h&A=$LJ-&U%C;W1h}FR*@88fWz{4#OjcQ9i|P=@N#kZ%Fml>4JGy{a2Usy zU5anujc*f&piXulKD)QQk)q!R^#A%X?E$}w=w*N)DSFKx$1QkZ`x@8+dyYj_$C4si z?5v@lFmGW_((G(Kl^YWmd3k5!tJr<5BzrW4&$aP7VV292#=oi@@%?k-zGJB(q2CP% z7xwn@DoS68tO@PpU?V^yOUa3h}9Zh0J=-Tx5`T~bAvFf0Y?BeZAC^7rta9!Lj z6E?)@!u8HV=Z?;d_kSA|gMt1+^LafEa|=jW;xagiQLs~5Zxy<~{F9Rex9UDp{2<(T zGy@qmyEIxO=$0tU8RXN&+_KI0rSVUVh^jMmwQ%eNI}|u_?R-RZ2nPL=$zDP(ouO*{ zwl6Vkj>xZ_eSMD21!6Yr;8$`aibCc*s^oC@6#xH_+>fC-3>S+2hs@@9LZUi8=|>1Y zdHSF#dO)a3AYiye2C3%6D5Pvhzw#^<6%iq>&Go$P?p{BK^-)7H)$|TV4h)yNmv&a( z9F#=CEXAxZUtV=bhNUCQxfmqhjFLv_e(TZs`A?ptWc!0Q zI9MXW^~?rNAt(X9UrTlTQY%b^@MsV#)i*d^!8Rz zQ8B-|v3ndn4iX*mKYOn{s$9MDf0jT literal 0 HcmV?d00001 diff --git a/apps/www/public/favicon-16x16.png b/apps/www/public/favicon-16x16.png new file mode 100644 index 0000000000000000000000000000000000000000..b37f4d79b8d4ea214428c250dc29f1fefb63367d GIT binary patch literal 385 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`oCO|{#S9GG!XV7ZFl&wkP>``W z$lZxy-8q?;Kn_c~qpu?a!^VE@KZ&eBIWbQc$B+ufrNOrA+#Ez~<7#AW1HB>|qF$_R z@JnXhmdGsTpkgI$x#CG9dJ;ufsd%S<9BsoWs$m{} z+sVZY2JWPi1Xtj};;Civ7zBcHo?LXG>|7q8lkTz6O*K$eAOAAYV06OjVL_nUMChSC z69~kvqOE~7_Muy!WQo^v5&&n9JKQ^X(0^+2L~-BT01%q znaolfj<9lQ~^%)Ckc%mG>kDhl7JkLMQHGWL$xRv!~-5?AvOkVkv%f{@_!EQhg<(%E`6y} z>(G8dRn;cwaQo)|_c)ok_BifGi+$&`akvZ#v#PG144H_DPE4aH?!|SZ<^bR2(Yn$L zA|g5jdZsslz2pCQ%#YMMz6scWq^+x)8Xpf6{5@xntG}j7TT@v6`YP(J`?x79mt^MZ za7)mUC6mM9pY5MBtqg+RTdcF80sB8cZOu}OwNpjtg8MJM3=qPvd`te`9@j%6Fw9SV z^jBNhE*N8)Y{EmuVNI-O#I+thdeby1^oxg?5_G)pwEV3+Re5{ZHdy;d$Fqpfjz}1V zT3}G1_FZG@gKx2JhV;t%>8y4Pk8z`?y|#`{iYIAxbf8!ldeWDcl!Vlb<4X4=Q44g^ z#ntZ1A;3pFgE$WT+2bS8YhW_6w4c2s7~P#fkX`zedWl0H_fqwYd>qi4c=wn?->EP6 z)JcmOO@a%krg{48uB7u{_c7>_1g3`DFZSheuxH5FE}S7V!NRdwSy}Sl8xu9B7khJ* z5--k5+aY1<9_lVGMCDqi{_~?BeCv{YVc}3CBcr>(c8SA+=Ct3NW*27)0%VwE7HFF- zI4=1O;8a$gL)g?r*ZbHW{?p(wT_t|UW4c*tj$M)Y9c-R|^1XLP>=_ASnBvFEvw}Xy zhwuD+Y#Kca{E)%FH}aDFd7_yy%*W006>m01M$D<$s23||l^%8hyEB1`g&}xP;ss9q zk4Q2{cXKG1#hn%tnhyM(7qCB{;Q~&Pn#zcsXu|92oe$ny%Npq$!`M|qJ9LN24AsTW zs@!%FvS~57D*mP>bA_J|7kYCXBqVf|WNjYpEPXXhWVkVI67}Ih*MryEbckk>g zRe_gqqK1Wx5awV|Ra)lNg!3E1Hxr`WD_Pq-T8=~pOK}pUL}jhV2K`eor8(pWBRK1hNNPx5MpyP&MQ5C z#`v`*%8eoCh!l&Ni6?}Gs)toD9+2GaHIZ8^PJ^Y^%I$4!TGrONBji|2z7ub7&1t^1 zuMH7r2&8Lx)^nze<3PV%@%oR>#0a&=>tm?elc9XO__U%Kduew+zb4?TtVH^5u=Rd@ zb#oqwYX_(+`@&GQtp`=WP1)|nT6elcyT}kD{q8Z8OL9iz15(ne;nv>9q=aHEu@Np& z^ljcm63m1bf+jW`JYLo#oAQXYR+NxwIz z{#iPkTI1Dx?J^+#jR4VwbPSGz-iy|3F9A{;nzFP+uki$a)7I7|UZ*Rb^@E&?r8Dda z)1CzMVtQ#xe-NHv2> zbGa;8`%pjGel|rqLD&Rx1$fos$Agm5d2r0!~dHaD>Du z`pK4H+mc&ZLcF}ZYR9b@#v>Cun=zaf7ofq?%OFZ`1mOs1P)bsuk#8aJW;VdeQ= zW>+R#z|&b5xCvk}J}Hj|_Pb?11Dat1EOD;d2YuZDHZ+nfqz= zT-_xlht4Mxua;J#^#7pN@{oV+k^DsST89QqTSrH?(sY3E92yqR(8&6YXd*G5z_Md; z+4&3RWOc~#;V&FY@mSrm-lbjphiV(Jht=wq=X4CXh6sj zf{tXN{wd{RF@AMu;LW|Bq`g~qxeGvSQRUSSRVcH1%}|X3wFu*DP5}WQR=gG8F)~3O zI)llE=aqa)jLQ9`LZ!2TKmPHU-kS`%I?YH=J9n_NEKDVu z+{Vsay|by-bt+yxioIOyd@1fFSIZV44c0pE&8d}M_I>C>Hf|})3y&8*Z)?`2Eea5G zP_80j5cvJTB;2e{0s+>z+ct5j8hy?8pqT+;s~!n6gxAm6`f#~^EsSUy@ISKds3VXn zx@Rd-bz0J~GrR~H(GQ=2E-IbJQ&GPe%IiSd-uHViV2skW&-hRrv8tkxJ3o6);lT9p zF9aB!@ZZ)eDH-08{_=0U`?hA**nE5 z7u!uXfs8~f9rIA>ywZAxzoMhcwx#NL`mm9MWF6Hks65gd)-Vnqmy?qN9Pv!OTdi@q zQENa&6CTLiQJ-I;Z3hMieOWi{`PDg#0E0DMFR!xt=OKm@?MX{YNh!SXMV5K06MGL! zK3fe)jyT?68+?T7tk&eY@r>_cd3m`Z-t}~^a?eFZQPsAcX5gRA|G@*Eo2r+i$g&S% zI3;u)Pxa2L28f=hPTj|}%MTPWNeyUU!2!)bt^Eg-#NpR-Ck^wOO#Cg? z1$Hm3P_!I^JzdJmG(wG=o4eEZt!g_)+4$X~dAHP0wVuh2%11E-Ptg3?de`B;z11=j zU>mQK{>mcQzg3vwCglUQfX@%BiY@K}JPQDYe4-7yVGL@!ZvsbY@=1B0p{FG*1b3w9KGt=DFi`?Q%uD_bj*ccFHCcm+R#)69-~#KJ z>vZcxz<>wxu?)MWVrgt;&ad0Pv8&+YKOHyU{Ti()$&(!cag3b(;Yn>P#LIXb z$h8wOPnN!5Rd{Z1Y&~`Rl8+r?3$GJF`1ssFnn&<8@}XR`c2}tFBBqS=g3gmo^{1sQ zjYU0uM(xJei-82VYRsQtxK*R31W=_LkV}tMpP2<4ZprpH+{%)7fJ)F4Ae2fK=xODg zDMgD@%*_sXktE)RuP3>*S0*YlqOT`eOF(rS4C6rpY{qqV27YS`J zM&N*tk7;}Phd(t;*!(Nw-#7P|AjXp$j$Ny|^dF!Od3-A5{JnT;C+Xg;E(+Ie;|zz{ zYu(?J9!``UXH9etuyNZrxW#cv6*+b$T#>fMinRlo?*a;Cf~O_>^Dt*1L4fkooA9gP zLzU&_Wf%N#mV#6GL@TBdL}>=NQY|~g8{m3gMK>OQ@*Q%N3&lVsuB6DI6YCImDjUC* zi(QaIMA|Fe0a&^{=Fxn&Ho&m|LN%FMaJy9Be!1IqsFJsula;|9A;JhSzZsdXJ*YF`9Ou8wFto_3T;un|EBo(NCRxD3?SXp4J0P9( zkJ+t=ww8^eJFpY4#wICq>np`?3lK7)uJeyE6yR^GHtd`sg6kmUy$NayF gu>Y&jvj2jv#v1o5L|+aC3QLf-roKj%nqBDs0Ad>WJ^%m! literal 0 HcmV?d00001 diff --git a/apps/www/public/favicon-32x32.png b/apps/www/public/favicon-32x32.png new file mode 100644 index 0000000000000000000000000000000000000000..dc06d72b554027343c2c017c54845289964ae2e5 GIT binary patch literal 678 zcmV;X0$KfuP)Gz-EN0|zYkX4XafZT0i;stS>JFt0CX)#wkqDN{<<(d!4}`;E>f{6>*y(gq#Zn2V*Xy{2&1Qp6 zr$ZG>Z9=6|39VKOyWNghEQV^eibA1)=xhRI|S zZnv9nm~*<%=K~F7)zazoU&na2;O&k2j=G9aDC8aE&5}x`xaIr01!N+FQFWR7e$%R7GaDIm%7`8*Pd1bV$5?&aoFK+HE9jW8aM@d&6lns|cLf1Aw)v)PPL zD1>6Mi2Z*5Eq1k9(N0UZ1uVrV8jWJHSX_<$v0~(KIH+Q&1k`FZ91aK2@*~BFT)!%n z>S`P*M)Uccx)@QLkQnRIT%_Y6UCI0$eWF?+HHM ziXM*#tS}2`wOU+D_PSImft9_NgDF6Tf literal 0 HcmV?d00001 diff --git a/apps/www/public/favicon-96x96.png b/apps/www/public/favicon-96x96.png new file mode 100644 index 0000000000000000000000000000000000000000..e5d3664eaf6109e099c852cd332935c322847b27 GIT binary patch literal 1698 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≀?)xAi$kTZU}aoCJufsj#;?aOU0u7(ne8%C z%mjz5>8jpbnJ}q;prNU$ioZkpK1H4LAop4Sk2Ls~ZiuDtyPqRcli)b#>)RtZw{Ib+uHv z#ysvO=;Bn<(?(QiXpNEKlT!^!ERM0)kOje0sY0{nISqcSTLGRK6ODqgc#RZmFW?($ zAFW9+pi)j3I; zu*mNSEP=ygi-SE+OvqG6oqz zvoq!)x3;%OukP=ZBDbkOC0Jk%+z*kM%r^K?lOs0pf7I8%rP+>Xq+5q}vWDktp<)Es MpLRx9qx^3D6CUR4ZU6uP literal 0 HcmV?d00001 diff --git a/apps/www/public/mstile-150x150.png b/apps/www/public/mstile-150x150.png new file mode 100644 index 0000000000000000000000000000000000000000..009b973a0f1e1103093a26bb95c496f3f718e1f2 GIT binary patch literal 2794 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 AcmMzZ literal 0 HcmV?d00001 diff --git a/apps/www/public/mstile-310x310.png b/apps/www/public/mstile-310x310.png new file mode 100644 index 0000000000000000000000000000000000000000..4687b2a5d57cfcce81bf99de110ad1083c30be09 GIT binary patch literal 6091 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 YXHqS!nXtpx4FLJ>i+urOgGq9BGs5LAqX z3B-swfa$%p;a={2I``f)&fa@2%-77EIR|w9GkdS~ueFX@Y;5d13_f5EgHJJpQNR#J z0YexC3}FB8t0BlA_j5JmxRnQwG-H2zzraCUZv*3kZQe0+@Q>1iAt9f1d2_L#!LLe$jMz|xYh z<2X4vL2YdGE! z`Bj?F0}Bfa@Idpspbhcr>I$M*T3W*6<0G_2b7AP8Y-wr1+uIv>LlLR9wG}+zmic;n zd$Vxu<>kdT;_&crBqSt!_}tmq8K$PDOnS;l^n-%~EG#VG{{9|35NZiRLPF5d(ZM1Y zF*-WRzVVlr7w8S4JLUHFHU%g@pB@$>UT zR#q140Q|_>+8PVHcXxNt3fkCbW@f%r1yn5z-DG`z{f8UX3nUIboodSxs)TWOcV{_> zm6a9r%*MtBii?Y(22~3@IXPMPq7Y$WVJ!1jgDPQUw@*#M+S(dwP$kUd|YHZFZ7&BHb2D?L3u2o4SgZ|Etsv$Mne{5-Tq^F1amE)D?! z0T4w_P7aqUAeU(ekx<>3_A#x|T$s(xO`(H@lsWV0m1`~x`JbVoA&8={uMa%n5|wDp z(}-$OQ4#xXfY#6xNu>|k``W z$lZxy-8q?;Kn_c~qpu?a!^VE@KZ&eBIWbQc$B+ufrNOrA+#Ez~<7#AW1HB>|qF$_R z@JnXhmdGsTpkgI$x#CG9dJ;ufsd%S<9BsoWs$ + + {props.children} + + + ); +} diff --git a/apps/www/src/app/page.tsx b/apps/www/src/app/page.tsx new file mode 100644 index 0000000..b75e7d1 --- /dev/null +++ b/apps/www/src/app/page.tsx @@ -0,0 +1,28 @@ +import {Logo, Button} from '@elwood/ui'; + +export default function Page() { + return ( +

+

+ + Elwood +

+ +

+ Open source Dropbox alternative +

+ +
+ + + +
+
+ ); +} diff --git a/apps/www/tailwind.config.js b/apps/www/tailwind.config.js new file mode 100644 index 0000000..2b99add --- /dev/null +++ b/apps/www/tailwind.config.js @@ -0,0 +1,19 @@ +const {theme, plugins} = require('@elwood/ui/tailwind.config.js'); +const {resolve, dirname} = require('path'); + +/** @type {import('tailwindcss').Config} */ +module.exports = { + content: [ + resolve( + dirname(require.resolve('@elwood/react')), + './**/*.{js,ts,jsx,tsx,mdx}', + ), + resolve( + dirname(require.resolve('@elwood/ui')), + './**/*.{js,ts,jsx,tsx,mdx}', + ), + './src/**/*.{js,ts,jsx,tsx,mdx}', + ], + theme, + plugins: [...plugins], +}; diff --git a/apps/www/tsconfig.json b/apps/www/tsconfig.json new file mode 100644 index 0000000..f4801d0 --- /dev/null +++ b/apps/www/tsconfig.json @@ -0,0 +1,16 @@ +{ + "exclude": ["node_modules", "next.config.mjs"], + "extends": "@elwood/typescript-config/nextjs.json", + "compilerOptions": { + "outDir": "dist", + "plugins": [ + { + "name": "next" + } + ], + "paths": { + "@/*": ["./src/*"] + } + }, + "include": ["src", "next-env.d.ts", ".next/types/**/*.ts"] +} diff --git a/apps/www/turbo.json b/apps/www/turbo.json new file mode 100644 index 0000000..347797e --- /dev/null +++ b/apps/www/turbo.json @@ -0,0 +1,9 @@ +{ + "extends": ["//"], + "globalEnv": [], + "pipeline": { + "build": { + "outputs": [".next/**", "!.next/cache/**"] + } + } +} diff --git a/package.json b/package.json index 2ddecb0..5c02454 100644 --- a/package.json +++ b/package.json @@ -26,7 +26,7 @@ "prettier-plugin-tailwindcss": "^0.5.14", "turbo": "latest" }, - "packageManager": "pnpm@9.1.0", + "packageManager": "pnpm@9.1.1", "engines": { "node": ">=20" }, diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index a02744a..649a411 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -197,6 +197,70 @@ importers: specifier: ^5.4.5 version: 5.4.5 + apps/www: + dependencies: + '@elwood/common': + specifier: workspace:* + version: link:../../packages/common + '@elwood/ui': + specifier: workspace:* + version: link:../../packages/ui + '@supabase/ssr': + specifier: ^0.3.0 + version: 0.3.0(@supabase/supabase-js@2.43.1) + autoprefixer: + specifier: ^10.4.19 + version: 10.4.19(postcss@8.4.38) + geist: + specifier: ^1.3.0 + version: 1.3.0(next@14.2.3(react-dom@18.3.1(react@18.3.1))(react@18.3.1)) + next: + specifier: ^14.2.3 + version: 14.2.3(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + postcss: + specifier: ^8.4.38 + version: 8.4.38 + react: + specifier: ^18.3.1 + version: 18.3.1 + react-dom: + specifier: ^18.3.1 + version: 18.3.1(react@18.3.1) + react-use: + specifier: ^17.5.0 + version: 17.5.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + tailwindcss: + specifier: ^3.4.3 + version: 3.4.3 + zod: + specifier: ^3.23.8 + version: 3.23.8 + devDependencies: + '@elwood/eslint-config': + specifier: workspace:* + version: link:../../config/eslint + '@elwood/typescript-config': + specifier: workspace:* + version: link:../../config/typescript + '@next/eslint-plugin-next': + specifier: ^14.2.3 + version: 14.2.3 + '@types/node': + specifier: ^20.12.12 + version: 20.12.12 + '@types/react': + specifier: ^18.3.2 + version: 18.3.2 + '@types/react-dom': + specifier: ^18.3.0 + version: 18.3.0 + prettier-plugin-tailwindcss: + specifier: ^0.5.14 + version: 0.5.14(prettier@3.2.5) + typescript: + specifier: ^5.4.5 + version: 5.4.5 + config/eslint: devDependencies: '@vercel/style-guide': diff --git a/supabase/migrations/20240218234006_schema.sql b/supabase/migrations/20240218234006_schema.sql deleted file mode 100644 index 2c9fa48..0000000 --- a/supabase/migrations/20240218234006_schema.sql +++ /dev/null @@ -1,7 +0,0 @@ -CREATE EXTENSION IF NOT EXISTS vector SCHEMA extensions; -CREATE SCHEMA IF NOT EXISTS elwood; - -grant usage on schema elwood to postgres, anon, authenticated, service_role; -alter default privileges in schema elwood grant all on tables to postgres, anon, authenticated, service_role; -alter default privileges in schema elwood grant all on functions to postgres, anon, authenticated, service_role; -alter default privileges in schema elwood grant all on sequences to postgres, anon, authenticated, service_role; diff --git a/supabase/migrations/20240218234007_types.sql b/supabase/migrations/20240218234007_types.sql deleted file mode 100644 index 3adc2f4..0000000 --- a/supabase/migrations/20240218234007_types.sql +++ /dev/null @@ -1,89 +0,0 @@ - --- NODE_TYPE -DROP TYPE IF EXISTS public.elwood_node_type CASCADE; -CREATE TYPE public.elwood_node_type AS ENUM ( - 'TREE', - 'BLOB', - 'BUCKET' -); - --- NODE -DROP TYPE IF EXISTS public.elwood_node CASCADE; -CREATE TYPE public.elwood_node AS ( - "id" text, - "object_id" uuid, - "type" public.elwood_node_type, - "prefix" text[], - "name" text, - "mime_type" text, - "size" int -); - - -DROP TYPE IF EXISTS public.elwood_storage_search_result CASCADE; -CREATE TYPE public.elwood_storage_search_result AS ( - name text, - id uuid, - updated_at timestamptz, - created_at timestamptz, - last_accessed_at timestamptz, - metadata jsonb -); - -DROP TYPE IF EXISTS public.elwood_get_node_result CASCADE; -CREATE TYPE public.elwood_get_node_result AS ( - "node" public.elwood_node, - "parent" public.elwood_node, - "children" public.elwood_node[], - "key_children" text[] -); - - -DROP TYPE IF EXISTS public.elwood_node_tree CASCADE; -CREATE TYPE public.elwood_node_tree AS ( - "node" public.elwood_node, - "id" text, - "parent" text -); - -DROP TYPE IF EXISTS public.elwood_get_node_tree_result CASCADE; -CREATE TYPE public.elwood_get_node_tree_result AS ( - "rootNodeId" text, - "expandedIds" text[], - "tree" public.elwood_node_tree[] -); - -DROP TYPE IF EXISTS public.elwood_member_type CASCADE; -CREATE TYPE public.elwood_member_type AS ENUM ( - 'USER', - 'TEAM' -); - --- --- @@ NAMESPACE: ELWOOD --- - -DROP TYPE IF EXISTS elwood.get_node_leaf_result CASCADE; -CREATE TYPE elwood.get_node_leaf_result AS ( - "node" public.elwood_node -); - -DROP TYPE IF EXISTS elwood.follow_type CASCADE; -CREATE TYPE elwood.follow_type AS ENUM ( - 'SAVE', - 'SUBSCRIBE' -); - -DROP TYPE IF EXISTS elwood.member_role CASCADE; -CREATE TYPE elwood.member_role AS ENUM ( - 'ADMIN', - 'MANAGER', - 'MEMBER' -); - -DROP TYPE IF EXISTS elwood.activity_type CASCADE; -CREATE TYPE elwood.activity_type AS ENUM ( - 'COMMENT', - 'REACTION', - 'LIKE' -); diff --git a/supabase/migrations/20240218234008_tbl_member.sql b/supabase/migrations/20240218234008_tbl_member.sql deleted file mode 100644 index c61894f..0000000 --- a/supabase/migrations/20240218234008_tbl_member.sql +++ /dev/null @@ -1,62 +0,0 @@ - - -CREATE TABLE elwood.member ( - "instance_id" uuid NOT NULL DEFAULT '00000000-0000-0000-0000-000000000000', - "id" uuid NOT NULL DEFAULT extensions.uuid_generate_v4(), - "user_id" uuid NOT NULL, - "type" public.elwood_member_type NOT NULL DEFAULT 'USER', - "username" text NULL, - "display_name" text NULL, - "added_by_user_id" uuid NULL, - "role" elwood.member_role NOT NULL DEFAULT 'MEMBER', - "created_at" timestamptz default now(), - "updated_at" timestamptz default now(), - - CONSTRAINT "elwood_member_user_id" FOREIGN KEY ("user_id") REFERENCES "auth"."users"("id"), - CONSTRAINT "elwood_member_added_by_user_id" FOREIGN KEY ("added_by_user_id") REFERENCES "auth"."users"("id"), - PRIMARY KEY ("id") -); - - -CREATE UNIQUE INDEX IF NOT EXISTS elwood_idx_member_user_id ON elwood.member("instance_id", "user_id"); -CREATE UNIQUE INDEX IF NOT EXISTS elwood_idx_member_username ON elwood.member("instance_id", "username"); -alter table elwood."member" enable row level security; - -DROP FUNCTION IF EXISTS elwood.is_a_member() CASCADE; -create function elwood.is_a_member() -returns boolean -language plpgsql -security definer -as $$ -begin - return exists ( - select 1 from elwood.member - where auth.uid() = user_id - ); -end; -$$; - - -CREATE VIEW public.elwood_member with (security_invoker=on) - AS SELECT - "id", - "user_id", - "type", - "username", - "display_name", - "added_by_user_id", - "role", - "created_at", - "updated_at" - FROM elwood.member; - -create policy "Members can view all members." -on elwood.member for select -to authenticated -using (elwood.is_a_member()); - -create policy "Member can update their own member row." -on elwood.member for update -to authenticated -using ( auth.uid() = user_id ) -with check ( auth.uid() = user_id ); \ No newline at end of file diff --git a/supabase/migrations/20240218234009_tbl_setting.sql b/supabase/migrations/20240218234009_tbl_setting.sql deleted file mode 100644 index 3f36364..0000000 --- a/supabase/migrations/20240218234009_tbl_setting.sql +++ /dev/null @@ -1,14 +0,0 @@ -create table elwood.setting ( - "instance_id" uuid not null default '00000000-0000-0000-0000-000000000000', - "name" varchar(20) not null primary key, - "value" jsonb not null default '{}'::jsonb, - "created_at" timestamptz default now(), - "updated_at" timestamptz default now() -); - -create unique index if not exists elwood_idx_settings_name on elwood.setting ( - "instance_id", - "name" -); - -alter table elwood."setting" enable row level security; diff --git a/supabase/migrations/20240218234010_tbl_activity.sql b/supabase/migrations/20240218234010_tbl_activity.sql deleted file mode 100644 index 049ee1e..0000000 --- a/supabase/migrations/20240218234010_tbl_activity.sql +++ /dev/null @@ -1,75 +0,0 @@ - - -CREATE TABLE IF NOT EXISTS elwood.activity ( - "instance_id" uuid NOT NULL DEFAULT '00000000-0000-0000-0000-000000000000', - "id" uuid NOT NULL DEFAULT uuid_generate_v4(), - "user_id" uuid NOT NULL, - "member_id" uuid NOT NULL, - "asset_id" text NOT NULL, - "asset_type" TEXT NOT NULL, - "is_resolved" BOOLEAN NOT NULL DEFAULT FALSE, - "is_deleted" BOOLEAN NOT NULL DEFAULT FALSE, - "type" elwood.activity_type NOT NULL, - "text" text NOT NULL, - "attachments" jsonb NOT NULL DEFAULT '{}'::jsonb, - "created_at" timestamptz default now(), - "updated_at" timestamptz default now(), - - CONSTRAINT "elwood_activity_user_id" FOREIGN KEY ("user_id") REFERENCES "auth"."users"("id"), - CONSTRAINT "elwood_activity_member_id" FOREIGN KEY ("member_id") REFERENCES "elwood"."member"("id"), - PRIMARY KEY ("id") -); - -alter table elwood."activity" enable row level security; - -DROP VIEW IF EXISTS public.elwood_activity; -CREATE VIEW public.elwood_activity with (security_invoker=on) - AS SELECT - "a"."id", - "a"."user_id", - "a"."member_id", - "a"."asset_id", - "a"."asset_type", - "a"."is_deleted", - "a"."is_resolved", - "a"."type", - "a"."text", - "a"."attachments", - "a"."created_at", - "a"."updated_at" - FROM elwood.activity as a; - -create policy "Members can view all activity." -on elwood.activity for select -to authenticated -using (elwood.is_a_member()); - -create policy "Members can create activity." -on elwood.activity for insert -to authenticated -with check (elwood.is_a_member()); - - --- BEFORE INSERT -CREATE OR REPLACE FUNCTION elwood.before_activity_insert() - RETURNS TRIGGER - LANGUAGE PLPGSQL -AS -$$ -DECLARE - _user_id uuid := auth.uid(); - _member_id uuid; -BEGIN - SELECT id INTO _member_id FROM elwood.member WHERE user_id = _user_id; - NEW.member_id = _member_id; - -- users can only insert activity for themselves - NEW.user_id = _user_id; - RETURN NEW; -END; -$$; - -CREATE TRIGGER trigger_before_activity_insert -BEFORE INSERT -ON elwood.activity -FOR EACH ROW -EXECUTE FUNCTION elwood.before_activity_insert(); diff --git a/supabase/migrations/20240218234011_tbl_follow.sql b/supabase/migrations/20240218234011_tbl_follow.sql deleted file mode 100644 index 848579d..0000000 --- a/supabase/migrations/20240218234011_tbl_follow.sql +++ /dev/null @@ -1,86 +0,0 @@ -create table if not exists elwood.follow ( - "instance_id" uuid not null default '00000000-0000-0000-0000-000000000000', - "id" uuid not null default uuid_generate_v4(), - "user_id" uuid not null, - "type" elwood.follow_type not null DEFAULT 'SAVE', - "asset_type" text not null, - "asset_id" text not null, - "is_active" boolean not null default false, - "created_at" timestamptz default now(), - "updated_at" timestamptz default now(), - - constraint "elwood_follow_user_id" - foreign key ("user_id") references "auth"."users" ("id"), - - primary key ("id") -); - -create unique index if not exists elwood_idx_follow_user_asset on elwood.follow ( - "user_id", - "type", - "asset_type", - "asset_id" -); - - -alter table "elwood"."follow" enable row level security; - -DROP VIEW IF EXISTS public.elwood_follow; -CREATE VIEW public.elwood_follow with (security_invoker=on) - AS SELECT - "id", - "user_id", - "type", - "asset_type", - "asset_id", - "is_active", - "created_at", - "updated_at", - (split_part(asset_id, ':', 3) = 'blob')::boolean as is_object_blob, - (select name from storage.buckets where id = split_part(asset_id, ':', 4)) as bucket_name, - replace( - CASE - WHEN split_part(asset_id, ':', 5) = '' THEN NULL - ELSE (select name from storage.objects where id = split_part(asset_id, ':', 5)::uuid) - END, - '/.emptyFolderPlaceholder', - '' - ) as object_name - FROM elwood.follow; - -create policy "Members can view their own follows." -on elwood.follow for select -to authenticated -using (elwood.is_a_member() AND "user_id" = auth.uid()); - -create policy "Members can create their own follow." -on elwood.follow for insert -to authenticated -with check (elwood.is_a_member() AND "user_id" = auth.uid()); - -create policy "Members can update their own follow." -on elwood.follow for update -to authenticated -with check (elwood.is_a_member() AND "user_id" = auth.uid()); - - --- BEFORE INSERT -CREATE OR REPLACE FUNCTION elwood.before_follow_insert() - RETURNS TRIGGER - LANGUAGE PLPGSQL -AS -$$ -DECLARE - _user_id uuid := auth.uid(); -BEGIN - -- users can only insert activity for themselves - NEW.user_id = _user_id; - RETURN NEW; -END; -$$; - -CREATE TRIGGER trigger_before_follow_insert -BEFORE INSERT -ON elwood.follow -FOR EACH ROW -EXECUTE FUNCTION elwood.before_follow_insert(); diff --git a/supabase/migrations/20240218234012_tbl_notification.sql b/supabase/migrations/20240218234012_tbl_notification.sql deleted file mode 100644 index f4c831c..0000000 --- a/supabase/migrations/20240218234012_tbl_notification.sql +++ /dev/null @@ -1,48 +0,0 @@ -create table if not exists elwood.notification ( - "instance_id" uuid not null default '00000000-0000-0000-0000-000000000000', - "id" uuid not null default uuid_generate_v4(), - "user_id" uuid not null, - "type" text not null default 'GENERIC', - "data" jsonb not null default '{}'::jsonb, - "has_seen" boolean not null default false, - "seen_at" timestamptz null, - "bucket_id" text null, - "object_id" uuid null, - "created_at" timestamptz default now(), - "updated_at" timestamptz default now(), - - constraint "elwood_notification_user_id" - foreign key ("user_id") references "auth"."users" ("id"), - constraint "elwood_follow_bucket_id" - foreign key ("bucket_id") references "storage"."buckets"("id"), - constraint "elwood_follow_object_id" - foreign key ("object_id") references "storage"."objects"("id"), - primary key ("id") -); - -alter table "elwood"."notification" enable row level security; - -drop view if exists public.elwood_notification; -create view public.elwood_notification with (security_invoker=on) - AS SELECT - "id", - "type", - "data", - "has_seen", - "seen_at", - "bucket_id", - "object_id", - "created_at", - "updated_at" - from elwood.notification; - - -create policy "Members can view their own notifications." -on elwood.notification for select -to authenticated -using (elwood.is_a_member() AND "user_id" = auth.uid()); - -create policy "Members can update their own notification." -on elwood.notification for update -to authenticated -with check (elwood.is_a_member() AND "user_id" = auth.uid()); diff --git a/supabase/migrations/20240218234013_triggers.sql b/supabase/migrations/20240218234013_triggers.sql deleted file mode 100644 index b4d6bac..0000000 --- a/supabase/migrations/20240218234013_triggers.sql +++ /dev/null @@ -1,70 +0,0 @@ --- BEFORE INSERT - -create or replace function elwood.after_object_insert_or_update() -returns trigger -language PLPGSQL -as $$ -DECLARE - _path_parts text[]; - _path_parts_length int; - _prefix text[]; - _part text; - _path_tokens text[]; -BEGIN - - -- ignore if there is a file name - IF storage.filename(NEW.name) = '.emptyFolderPlaceholder' THEN - RETURN NEW; - END IF; - - -- split the new path into parts - _path_parts := regexp_split_to_array(NEW.name, '/'); - _path_parts_length := array_length(_path_parts, 1); - - IF _path_parts_length = 1 THEN - RETURN NEW; - END IF; - - -- now loop through each part and make sure there's an object - -- for the tree path so we can have an object id - FOREACH _part IN ARRAY _path_parts[1:_path_parts_length-1] LOOP - _prefix := _prefix || array[_part]; - _path_tokens := _prefix || array['.emptyFolderPlaceholder']; - - -- insert a placeholder object if it doesn't exist - INSERT INTO storage.objects ("bucket_id", "owner_id", "name") VALUES ( - NEW.bucket_id, - NEW.owner_id, - array_to_string( - _path_tokens, - '/' - ) - ) ON CONFLICT ("bucket_id","name") DO NOTHING; - END LOOP; - - - -- if we think this is a folder, insert a placeholder object - IF NEW.metadata IS NULL OR NEW.metadata->>'eTag' IS NULL THEN - _path_tokens := _path_parts || array['.emptyFolderPlaceholder']; - - -- insert a placeholder object if it doesn't exist - INSERT INTO storage.objects ("bucket_id", "owner_id", "name") VALUES ( - NEW.bucket_id, - NEW.owner_id, - array_to_string( - _path_tokens, - '/' - ) - ) ON CONFLICT ("bucket_id","name") DO NOTHING; - END IF; - - RETURN NEW; -END; -$$; - -DROP TRIGGER IF EXISTS trigger_after_object_insert_or_update on storage.objects; -create trigger trigger_after_object_insert_or_update -before insert on storage.objects -for each row -when (pg_trigger_depth() < 1) -execute function elwood.after_object_insert_or_update(); diff --git a/supabase/migrations/20240218234019_create_node_id.sql b/supabase/migrations/20240218234019_create_node_id.sql deleted file mode 100644 index 9b9d8fe..0000000 --- a/supabase/migrations/20240218234019_create_node_id.sql +++ /dev/null @@ -1,56 +0,0 @@ - -DROP FUNCTION IF EXISTS elwood.create_node_id(text, text, uuid); -CREATE OR REPLACE FUNCTION elwood.create_node_id( - p_type public.elwood_node_type, - p_bucket text default null, - p_object_id uuid default null -) RETURNS text -AS $$ -DECLARE - _node_id text[]; - _prefix_part text; - _prefix_parts text[]; -BEGIN - _node_id := ARRAY['urn', 'enid', lower(p_type::text)]; - - IF p_bucket IS NOT NULL THEN - _node_id := _node_id || ARRAY[p_bucket::text]; - END IF; - - IF p_object_id IS NOT NULL THEN - _node_id := _node_id || ARRAY[p_object_id::text]; - END IF; - - return array_to_string(_node_id,':'); -END; -$$ language plpgsql; - - - -DROP FUNCTION IF EXISTS elwood.create_node_id_for_tree(text[]); -CREATE OR REPLACE FUNCTION elwood.create_node_id_for_tree( - p_path text[] -) RETURNS text -AS $$ -DECLARE - _bucket_id text; - _name text[]; - _object_row storage.objects; - _path_length int; -BEGIN - _path_length := array_length(p_path, 1); - _bucket_id := ARRAY_TO_STRING(p_path[:1], ''); - _name := p_path[2:] || ARRAY['.emptyFolderPlaceholder']; - - RAISE WARNING 'create_node_id_for_tree: p_path % || %', p_path, array_to_string(_name, '/'); - - SELECT * INTO _object_row FROM storage.objects WHERE "bucket_id" = _bucket_id AND "name" = array_to_string(_name, '/'); - - IF _object_row IS NULL THEN - return 'urn:enid:no_object_row_found'; - END IF; - - return elwood.create_node_id('TREE', _bucket_id, _object_row.id); - -END; -$$ language plpgsql; diff --git a/supabase/migrations/20240220162656_get_node_children.sql b/supabase/migrations/20240220162656_get_node_children.sql deleted file mode 100644 index e10d96f..0000000 --- a/supabase/migrations/20240220162656_get_node_children.sql +++ /dev/null @@ -1,76 +0,0 @@ -drop function if exists elwood.get_node_children(uuid, text[]); -create or replace function elwood.get_node_children(p_prefix text[]) -returns jsonb[] -language PLPGSQL -as $$ -DECLARE - _bucket_row storage.buckets; - _search_row public.elwood_storage_search_result; - _object_row public.elwood_node; - _nodes jsonb[]; - _node_type public.elwood_node_type; - _bucket_id text; - _prefix text; - _path text; - _depth int; -BEGIN - _nodes := ARRAY[]::jsonb[]; - _prefix := ARRAY_TO_STRING(p_prefix, '/'); - - -- if there's nothing in input then return the root - -- which is all the buckets - IF array_length(p_prefix, 1) IS NULL THEN - FOR _bucket_row IN - SELECT * FROM storage.buckets - LOOP - _object_row.id := elwood.create_node_id('BUCKET', _bucket_row.name::text, null); - _object_row.type := 'BUCKET'; - _object_row.prefix := p_prefix; - _object_row.name := _bucket_row.name; - _object_row.mime_type := 'inode/directory'; - _object_row.size := (SELECT SUM(COALESCE((o.metadata->>'size')::int, 0)) FROM storage.objects as o WHERE o.bucket_id = _bucket_row.id); - _nodes := _nodes || ARRAY[to_jsonb(_object_row)]; - END LOOP; - END IF; - - - _bucket_id := ARRAY_TO_STRING(p_prefix[:1], ''); - _path := ARRAY_TO_STRING(p_prefix[2:], '/'); - _depth := array_length(p_prefix[2:], 1) + 1; - - IF _depth IS NULL THEN - _depth := 1; - END IF; - - RAISE WARNING 'get_node_children: p_prefix %, _bucket_id: %, _path: %, _depth: %', p_prefix, _bucket_id, _path, _depth; - - FOR _search_row IN - SELECT * FROM storage.search(_path, _bucket_id, 100, _depth) - LOOP - RAISE WARNING 'get_node_children: _search_row %', _search_row.name; - - IF _search_row.id IS NULL THEN - - RAISE WARNING 'xxxx: xxx %', ARRAY[_bucket_id] || string_to_array(_path,'/')|| string_to_array(_search_row.name,'/'); - - _object_row.type := 'TREE'; - _object_row.id := elwood.create_node_id_for_tree(ARRAY[_bucket_id] || string_to_array(_path,'/')|| string_to_array(_search_row.name,'/')); - ELSE - _object_row.type := 'BLOB'; - _object_row.id := elwood.create_node_id(_node_type, _bucket_id, _search_row.id); - END IF; - - IF _search_row.name != '.emptyFolderPlaceholder' THEN - _object_row.prefix := p_prefix; - _object_row.name := _search_row.name; - _object_row.mime_type := _search_row.metadata->>'mimetype'; - _object_row.size := COALESCE((_search_row.metadata->>'size')::int, 0); - _nodes := _nodes || to_jsonb(_object_row); - END IF; - END LOOP; - - RAISE WARNING 'get_node_children: length _depth: %', array_length(_nodes, 1); - - return _nodes; -END; -$$; diff --git a/supabase/migrations/20240228151359_get_node_leaf.sql b/supabase/migrations/20240228151359_get_node_leaf.sql deleted file mode 100644 index 6573a27..0000000 --- a/supabase/migrations/20240228151359_get_node_leaf.sql +++ /dev/null @@ -1,77 +0,0 @@ - - -DROP FUNCTION IF EXISTS elwood.get_node_leaf(text[]); -CREATE OR REPLACE FUNCTION elwood.get_node_leaf( - "p_path" text[] -) RETURNS elwood.get_node_leaf_result LANGUAGE PLPGSQL -AS $$ -DECLARE - _path_length int; - _name text; - _path text; - _prefix text[]; - _bucket_id text; - _node public.elwood_node; - _bucket_row storage.buckets; - _object_row storage.objects; - _result elwood.get_node_leaf_result; -BEGIN - _path_length := array_length(p_path, 1); - - -- no path means root - IF _path_length IS NULL THEN - _node.id = 'root'; - _node.type = 'BUCKET'; - _node.prefix = ARRAY[]::text[]; - END IF; - - -- single path means bucket - IF _path_length = 1 THEN - SELECT * INTO _bucket_row FROM storage.buckets WHERE "name" = p_path[1]; - - IF _bucket_row.id IS NULL THEN - return null; - END IF; - - _node.id = elwood.create_node_id('BUCKET', _bucket_row.name, null); - _node.type = 'BUCKET'; - _node.prefix = ARRAY[]::text[]; - _node.name = _bucket_row.name; - _node.mime_type = 'inode/directory'; - END IF; - - -- multiple paths means object - IF _path_length > 1 THEN - _bucket_id := ARRAY_TO_STRING(p_path[:1], ''); - _prefix := p_path[1:_path_length-1]; - _path := ARRAY_TO_STRING(p_path[2:], '/'); - _name := p_path[_path_length]; - - SELECT * INTO _object_row FROM storage.objects WHERE "bucket_id" = _bucket_id AND "name" = _path; - - IF _object_row.id IS NULL THEN - _node.id = elwood.create_node_id_for_tree(p_path); - _node.type = 'TREE'; - _node.prefix = _prefix; - _node.name = _name; - _node.mime_type = 'inode/directory'; - END IF; - - IF _object_row.id IS NOT NULL THEN - _node.id = elwood.create_node_id('BLOB', _bucket_id, _object_row.id); - _node.type = 'BLOB'; - _node.prefix = _prefix; - _node.name = _name; - _node.mime_type = _object_row.metadata->>'mimetype'; - _node.size = COALESCE((_object_row.metadata->>'size')::int, 0); - END IF; - END IF; - - _result.node := _node; - - -- give it back - return _result; - -END; -$$; - diff --git a/supabase/migrations/20240301183729__public_get_node.sql b/supabase/migrations/20240301183729__public_get_node.sql deleted file mode 100644 index ac81514..0000000 --- a/supabase/migrations/20240301183729__public_get_node.sql +++ /dev/null @@ -1,54 +0,0 @@ --- @@ --- GET_NODE --- get a node with all the other info you might need for that node -drop function if exists public.elwood_get_node(text[], int, int); -create or replace function public.elwood_get_node( - p_path text[], - p_limit int default 100, - p_offset int default 0 -) -returns jsonb -as $$ -DECLARE - _node_leaf elwood.get_node_leaf_result; - _parent_leaf elwood.get_node_leaf_result; - _node public.elwood_node; - _prefix text[]; - _child_row jsonb; - _children jsonb[] = ARRAY[]::jsonb[]; - _key_children text[] = ARRAY[]::text[]; -BEGIN - -- get this node leaf - _node_leaf := elwood.get_node_leaf(p_path); - _node = _node_leaf.node; - - -- no node means stop - IF _node.id IS NULL THEN - return null; - END IF; - - -- if this isn't root, get the parent - IF _node.id != 'root' THEN - SELECT * INTO _parent_leaf FROM elwood.get_node_leaf(p_path[1:array_length(p_path, 1)-1]); - _prefix := _node.prefix || ARRAY[_node.name]::text[]; - END IF; - - IF _node.type = 'TREE' OR _node.type = 'BUCKET' THEN - _children := elwood.get_node_children(_prefix); - - FOREACH _child_row IN ARRAY _children LOOP - IF (SELECT _child_row->>'name' = ANY(ARRAY['readme.md']::text[])) THEN - _key_children := _key_children || ARRAY[_child_row->>'name']; - END IF; - END LOOP; - END IF; - - return jsonb_build_object( - 'node', to_jsonb(_node), - 'parent', to_jsonb(_parent_leaf.node), - 'children', _children, - 'key_children', _key_children - ); -END; -$$ -language plpgsql; diff --git a/supabase/migrations/20240301183739__public_get_node_tree.sql b/supabase/migrations/20240301183739__public_get_node_tree.sql deleted file mode 100644 index 63f1cf4..0000000 --- a/supabase/migrations/20240301183739__public_get_node_tree.sql +++ /dev/null @@ -1,62 +0,0 @@ -drop function if exists public.elwood_get_node_tree(text[]); -create or replace function public.elwood_get_node_tree(p_path text[]) -returns jsonb -as $$ -DECLARE - _id text; - _bucket_id text; - _path text; - _part text; - _result jsonb[]; - _row jsonb; - _node_row jsonb; - _row_path text[]; - _node_type public.elwood_node_type; - _expanded_ids text[]; - _path_id text; - _leaf elwood.get_node_leaf_result; - _leaf_node public.elwood_node; - _root_id text := 'root'; -BEGIN - - IF array_length(p_path, 1) > 0 THEN - _root_id := elwood.create_node_id('BUCKET', array_to_string(p_path[0:1],'')::text, null); - END IF; - - FOREACH _part IN ARRAY p_path LOOP - _row_path := _row_path || _part; - _node_row := elwood_get_node(_row_path); - - -- if this is a blob, it will be added when we loop to the parent - -- so don't push it to the row now - IF (_node_row->'node')::jsonb->>'type' != 'BLOB' THEN - - _result := _result || jsonb_build_object( - 'id', (_node_row->>'node')::jsonb->>'id', - 'node', _node_row->'node', - 'parent', (_node_row->'parent')::jsonb->>'id' - ); - - _expanded_ids := _expanded_ids || ARRAY[(_node_row->>'node')::jsonb->>'id'::text]; - - FOR _row IN SELECT jsonb_array_elements FROM jsonb_array_elements(_node_row->'children') LOOP - _result := _result || jsonb_build_object( - 'id', _row->>'id', - 'node', _row, - 'parent', (_node_row->>'node')::jsonb->>'id' - ); - END LOOP; - END IF; - - END LOOP; - - - RETURN jsonb_build_object( - 'rootNodeId', _root_id, - 'expandedIds', _expanded_ids, - 'tree', _result - ); - -END; -$$ -language plpgsql; diff --git a/supabase/migrations/20240515173522_elwood.sql b/supabase/migrations/20240515173522_elwood.sql new file mode 100644 index 0000000..0a353b8 --- /dev/null +++ b/supabase/migrations/20240515173522_elwood.sql @@ -0,0 +1,32 @@ +/* +Requires: + - pg_tle: https://github.com/aws/pg_tle + - pgsql-http: https://github.com/pramsey/pgsql-http +*/ +create extension if not exists http with schema extensions; +create extension if not exists pg_tle; +create extension if not exists vector schema extensions; +drop extension if exists "elwood-supabase"; +select pgtle.uninstall_extension_if_exists('elwood-supabase'); +select + pgtle.install_extension( + 'elwood-supabase', + resp.contents ->> 'version', + 'Elwood Supabase Database', + resp.contents ->> 'sql' + ) +from http( + ( + 'GET', + 'https://elwood.software/db/latest.json', + array[]::http_header[], + null, + null + ) +) x, +lateral ( + select + ((row_to_json(x) -> 'content') #>> '{}')::json +) resp(contents); + +create extension "elwood-supabase";