From ddd40be036417733ae2efc74ced2d85d1f486747 Mon Sep 17 00:00:00 2001 From: Gourav Saini <128782564+grv-saini-20@users.noreply.github.com> Date: Wed, 30 Jul 2025 17:01:50 +0530 Subject: [PATCH 01/18] Merge platforms (#270) * feat: setup control-panel project, added-colors same as eid-wallet * feat: group * fix: separate page added for members * chore: added dummy data and commented the protection on routes for development purposes. * feat: added view participants button. * feat: added participants modal * feat: group * feat: group-charter-manager * feat: added nanoid * feat: added context menu and the owner or admin status * feat: added context menu functionality on frontend. * fix: lock file * fix: added a edit modal * chore: renamed to member. * fix: responsiveness * fix: responsiveness * feat: added group settings page. * fix: role based editing * feat: show info and not allow edits when not a group admin or owner. * fix: user role based edit in group info * fix: edit image with pencil icon * fix: added a text area * feat: new group functionality and textarea fixed * feat: new group functionality and textarea fixed * feat: added close icon on dialog boxes for accessibility improvement. * feat: removed save and close button on group settings for non admin or non owner users. * feat: added add members button. * feat: added add members component. * feat: added relevant checks. * feat: added icons next to owner and admin. * feat: added new chat button. * chore: fixed squigglies. * feat: added new chat flow. * chore: trimed down the non-required code and made a new next js project group charter manager. * feat: added working 404 page with some changes. * feat: fixed and added /dashboard route * chore: upgraded tailwind v3 to v4 in old group charter * chore: copied old index.css to new global.css * chore: added missing dependencies for tailwindcss * chore: upgraded new charter app's whole codebase to tailwind v4 * chore: moved dashboard page to correct route * feat: added new charter page * feat: added single charter page. * feat: added /charter/:id/edit route * chore: removed old charter codebase. * feat: eVoting * chore: project moved to platforms * chore: created a new next app and moved the older to the old folder * chore: moved the old to old dir. * chore: migrated old project to tailwindcss v4 * feat: added components and other stuff to the new proj. * feat: added the not found page. * feat: added homepage. * feat: added create page. * feat: added vote/id page. * chore: remove the old evoting proj. * feat: add a button, modal for sign charter * fix: lock file * fix: lock file --------- Co-authored-by: Sahil Garg Co-authored-by: Merul Dhiman <69296233+coodos@users.noreply.github.com> --- .vscode/settings.json | 3 +- infrastructure/control-panel/.gitignore | 29 + infrastructure/control-panel/.npmrc | 1 + infrastructure/control-panel/.prettierignore | 9 + infrastructure/control-panel/.prettierrc | 15 + .../control-panel/.storybook/main.ts | 25 + .../control-panel/.storybook/preview.ts | 15 + infrastructure/control-panel/README.md | 38 + infrastructure/control-panel/eslint.config.js | 44 + infrastructure/control-panel/messages/en.json | 4 + infrastructure/control-panel/messages/es.json | 4 + infrastructure/control-panel/package.json | 47 + .../cache/plugins/2sy648wh9sugi | 1 + .../project.inlang/cache/plugins/ygx0uiahq6uw | 16 + .../control-panel/project.inlang/project_id | 1 + .../project.inlang/settings.json | 12 + infrastructure/control-panel/src/app.css | 36 + infrastructure/control-panel/src/app.d.ts | 13 + infrastructure/control-panel/src/app.html | 12 + .../control-panel/src/hooks.server.ts | 13 + infrastructure/control-panel/src/hooks.ts | 3 + infrastructure/control-panel/src/lib/index.ts | 1 + .../control-panel/src/routes/+layout.svelte | 7 + .../control-panel/src/routes/+page.svelte | 2 + .../src/routes/demo/+page.svelte | 1 + .../src/routes/demo/paraglide/+page.svelte | 18 + .../control-panel/static/favicon.svg | 1 + infrastructure/control-panel/svelte.config.js | 12 + infrastructure/control-panel/tsconfig.json | 19 + infrastructure/control-panel/vite.config.ts | 15 + package.json | 7 +- platforms/blabsy/env.development | 31 + platforms/blabsy/package.json | 1 + .../src/components/chat/add-members.tsx | 320 + .../blabsy/src/components/chat/chat-list.tsx | 131 +- .../src/components/chat/chat-window.tsx | 146 +- .../src/components/chat/group-settings.tsx | 167 + .../src/components/chat/member-list.tsx | 256 + .../src/components/layout/common-layout.tsx | 3 +- .../blabsy/src/lib/context/auth-context.tsx | 2 +- .../blabsy/src/lib/context/chat-context.tsx | 59 +- platforms/blabsy/src/lib/firebase/utils.ts | 55 +- platforms/blabsy/src/lib/types/chat.ts | 3 + platforms/eVoting/.gitignore | 41 + platforms/eVoting/README.md | 36 + platforms/eVoting/eslint.config.mjs | 16 + platforms/eVoting/next.config.ts | 7 + platforms/eVoting/package.json | 39 + platforms/eVoting/postcss.config.mjs | 5 + platforms/eVoting/public/file.svg | 1 + platforms/eVoting/public/globe.svg | 1 + platforms/eVoting/public/next.svg | 1 + platforms/eVoting/public/vercel.svg | 1 + platforms/eVoting/public/window.svg | 1 + platforms/eVoting/src/app/create/page.tsx | 302 + platforms/eVoting/src/app/globals.css | 338 + platforms/eVoting/src/app/layout.tsx | 19 + platforms/eVoting/src/app/not-found.tsx | 23 + platforms/eVoting/src/app/page.tsx | 354 + platforms/eVoting/src/app/vote/[id]/page.tsx | 573 ++ .../eVoting/src/components/CountdownTimer.tsx | 42 + .../eVoting/src/components/navigation.tsx | 209 + .../eVoting/src/components/poll-card.tsx | 52 + .../eVoting/src/components/results-chart.tsx | 50 + .../eVoting/src/components/ui/accordion.tsx | 56 + .../src/components/ui/alert-dialog.tsx | 139 + platforms/eVoting/src/components/ui/alert.tsx | 59 + .../src/components/ui/aspect-ratio.tsx | 5 + .../eVoting/src/components/ui/avatar.tsx | 50 + platforms/eVoting/src/components/ui/badge.tsx | 40 + .../eVoting/src/components/ui/breadcrumb.tsx | 115 + .../eVoting/src/components/ui/button.tsx | 56 + .../eVoting/src/components/ui/calendar.tsx | 68 + platforms/eVoting/src/components/ui/card.tsx | 79 + .../eVoting/src/components/ui/carousel.tsx | 260 + platforms/eVoting/src/components/ui/chart.tsx | 365 + .../eVoting/src/components/ui/checkbox.tsx | 28 + .../eVoting/src/components/ui/collapsible.tsx | 11 + .../eVoting/src/components/ui/command.tsx | 151 + .../src/components/ui/context-menu.tsx | 198 + .../eVoting/src/components/ui/dialog.tsx | 122 + .../eVoting/src/components/ui/drawer.tsx | 118 + .../src/components/ui/dropdown-menu.tsx | 198 + platforms/eVoting/src/components/ui/form.tsx | 178 + .../eVoting/src/components/ui/hover-card.tsx | 29 + .../eVoting/src/components/ui/input-otp.tsx | 69 + platforms/eVoting/src/components/ui/input.tsx | 22 + platforms/eVoting/src/components/ui/label.tsx | 24 + .../eVoting/src/components/ui/menubar.tsx | 256 + .../src/components/ui/navigation-menu.tsx | 128 + .../eVoting/src/components/ui/pagination.tsx | 117 + .../eVoting/src/components/ui/popover.tsx | 29 + .../eVoting/src/components/ui/progress.tsx | 28 + .../eVoting/src/components/ui/radio-group.tsx | 42 + .../eVoting/src/components/ui/resizable.tsx | 45 + .../eVoting/src/components/ui/scroll-area.tsx | 46 + .../eVoting/src/components/ui/select.tsx | 160 + .../eVoting/src/components/ui/separator.tsx | 29 + platforms/eVoting/src/components/ui/sheet.tsx | 140 + .../eVoting/src/components/ui/sidebar.tsx | 771 ++ .../eVoting/src/components/ui/skeleton.tsx | 15 + .../eVoting/src/components/ui/slider.tsx | 26 + .../eVoting/src/components/ui/switch.tsx | 27 + platforms/eVoting/src/components/ui/table.tsx | 117 + platforms/eVoting/src/components/ui/tabs.tsx | 53 + .../eVoting/src/components/ui/textarea.tsx | 22 + platforms/eVoting/src/components/ui/toast.tsx | 127 + .../eVoting/src/components/ui/toaster.tsx | 33 + .../src/components/ui/toggle-group.tsx | 61 + .../eVoting/src/components/ui/toggle.tsx | 43 + .../eVoting/src/components/ui/tooltip.tsx | 30 + .../src/components/voting-interface.tsx | 108 + platforms/eVoting/src/hooks/use-mobile.tsx | 19 + platforms/eVoting/src/hooks/use-toast.ts | 191 + platforms/eVoting/src/hooks/useAuth.ts | 18 + platforms/eVoting/src/hooks/useCountdown.ts | 79 + platforms/eVoting/src/lib/authUtils.ts | 3 + platforms/eVoting/src/lib/utils.ts | 6 + platforms/eVoting/tsconfig.json | 27 + platforms/group-charter-manager/.gitignore | 41 + platforms/group-charter-manager/README.md | 36 + .../group-charter-manager/eslint.config.mjs | 16 + .../group-charter-manager/next.config.ts | 7 + platforms/group-charter-manager/package.json | 47 + .../group-charter-manager/postcss.config.mjs | 5 + .../group-charter-manager/public/file.svg | 1 + .../group-charter-manager/public/globe.svg | 1 + .../group-charter-manager/public/next.svg | 1 + .../group-charter-manager/public/vercel.svg | 1 + .../group-charter-manager/public/window.svg | 1 + .../src/app/charter/[id]/edit/page.tsx | 608 ++ .../src/app/charter/[id]/page.tsx | 930 +++ .../src/app/create/page.tsx | 547 ++ .../group-charter-manager/src/app/globals.css | 319 + .../group-charter-manager/src/app/layout.tsx | 34 + .../src/app/not-found.tsx | 25 + .../group-charter-manager/src/app/page.tsx | 246 + .../src/components/charter-card.tsx | 88 + .../components/icons/certificate-ribbon.tsx | 99 + .../src/components/layout/navbar.tsx | 123 + .../src/components/member-avatar.tsx | 48 + .../src/components/platform-badge.tsx | 38 + .../src/components/stats-card.tsx | 24 + .../src/components/ui/accordion.tsx | 56 + .../src/components/ui/alert-dialog.tsx | 139 + .../src/components/ui/alert.tsx | 59 + .../src/components/ui/aspect-ratio.tsx | 5 + .../src/components/ui/avatar.tsx | 50 + .../src/components/ui/badge.tsx | 36 + .../src/components/ui/breadcrumb.tsx | 115 + .../src/components/ui/button.tsx | 56 + .../src/components/ui/calendar.tsx | 68 + .../src/components/ui/card.tsx | 79 + .../src/components/ui/carousel.tsx | 260 + .../src/components/ui/chart.tsx | 365 + .../src/components/ui/checkbox.tsx | 28 + .../src/components/ui/collapsible.tsx | 11 + .../src/components/ui/command.tsx | 151 + .../src/components/ui/context-menu.tsx | 198 + .../src/components/ui/dialog.tsx | 122 + .../src/components/ui/drawer.tsx | 118 + .../src/components/ui/dropdown-menu.tsx | 198 + .../src/components/ui/form.tsx | 178 + .../src/components/ui/hover-card.tsx | 29 + .../src/components/ui/input-otp.tsx | 69 + .../src/components/ui/input.tsx | 22 + .../src/components/ui/label.tsx | 24 + .../src/components/ui/menubar.tsx | 256 + .../src/components/ui/navigation-menu.tsx | 128 + .../src/components/ui/pagination.tsx | 117 + .../src/components/ui/popover.tsx | 29 + .../src/components/ui/progress.tsx | 28 + .../src/components/ui/radio-group.tsx | 42 + .../src/components/ui/resizable.tsx | 45 + .../src/components/ui/scroll-area.tsx | 46 + .../src/components/ui/select.tsx | 160 + .../src/components/ui/separator.tsx | 29 + .../src/components/ui/sheet.tsx | 140 + .../src/components/ui/sidebar.tsx | 771 ++ .../src/components/ui/skeleton.tsx | 15 + .../src/components/ui/slider.tsx | 26 + .../src/components/ui/switch.tsx | 27 + .../src/components/ui/table.tsx | 117 + .../src/components/ui/tabs.tsx | 53 + .../src/components/ui/textarea.tsx | 22 + .../src/components/ui/toast.tsx | 127 + .../src/components/ui/toaster.tsx | 33 + .../src/components/ui/toggle-group.tsx | 61 + .../src/components/ui/toggle.tsx | 43 + .../src/components/ui/tooltip.tsx | 30 + .../src/components/wysiwyg-editor.tsx | 133 + .../src/hooks/use-mobile.tsx | 19 + .../src/hooks/use-toast.ts | 191 + .../src/hooks/useAuth.ts | 9 + .../src/lib/authUtils.ts | 3 + .../group-charter-manager/src/lib/utils.ts | 6 + .../group-charter-manager/src/types/index.ts | 1 + .../src/types/user.types.ts | 9 + platforms/group-charter-manager/tsconfig.json | 27 + .../src/lib/fragments/Group/Group.svelte | 53 + platforms/pictique/src/lib/fragments/index.ts | 1 + platforms/pictique/src/lib/stores/posts.ts | 6 +- platforms/pictique/src/lib/types.ts | 25 +- .../(protected)/group/[id]/+page.svelte | 213 + .../group/[id]/members/+page.svelte | 129 + .../routes/(protected)/messages/+page.svelte | 174 +- pnpm-lock.yaml | 7049 ++++++++++++----- 207 files changed, 22872 insertions(+), 2188 deletions(-) create mode 100644 infrastructure/control-panel/.gitignore create mode 100644 infrastructure/control-panel/.npmrc create mode 100644 infrastructure/control-panel/.prettierignore create mode 100644 infrastructure/control-panel/.prettierrc create mode 100644 infrastructure/control-panel/.storybook/main.ts create mode 100644 infrastructure/control-panel/.storybook/preview.ts create mode 100644 infrastructure/control-panel/README.md create mode 100644 infrastructure/control-panel/eslint.config.js create mode 100644 infrastructure/control-panel/messages/en.json create mode 100644 infrastructure/control-panel/messages/es.json create mode 100644 infrastructure/control-panel/package.json create mode 100644 infrastructure/control-panel/project.inlang/cache/plugins/2sy648wh9sugi create mode 100644 infrastructure/control-panel/project.inlang/cache/plugins/ygx0uiahq6uw create mode 100644 infrastructure/control-panel/project.inlang/project_id create mode 100644 infrastructure/control-panel/project.inlang/settings.json create mode 100644 infrastructure/control-panel/src/app.css create mode 100644 infrastructure/control-panel/src/app.d.ts create mode 100644 infrastructure/control-panel/src/app.html create mode 100644 infrastructure/control-panel/src/hooks.server.ts create mode 100644 infrastructure/control-panel/src/hooks.ts create mode 100644 infrastructure/control-panel/src/lib/index.ts create mode 100644 infrastructure/control-panel/src/routes/+layout.svelte create mode 100644 infrastructure/control-panel/src/routes/+page.svelte create mode 100644 infrastructure/control-panel/src/routes/demo/+page.svelte create mode 100644 infrastructure/control-panel/src/routes/demo/paraglide/+page.svelte create mode 100644 infrastructure/control-panel/static/favicon.svg create mode 100644 infrastructure/control-panel/svelte.config.js create mode 100644 infrastructure/control-panel/tsconfig.json create mode 100644 infrastructure/control-panel/vite.config.ts create mode 100644 platforms/blabsy/env.development create mode 100644 platforms/blabsy/src/components/chat/add-members.tsx create mode 100644 platforms/blabsy/src/components/chat/group-settings.tsx create mode 100644 platforms/blabsy/src/components/chat/member-list.tsx create mode 100644 platforms/eVoting/.gitignore create mode 100644 platforms/eVoting/README.md create mode 100644 platforms/eVoting/eslint.config.mjs create mode 100644 platforms/eVoting/next.config.ts create mode 100644 platforms/eVoting/package.json create mode 100644 platforms/eVoting/postcss.config.mjs create mode 100644 platforms/eVoting/public/file.svg create mode 100644 platforms/eVoting/public/globe.svg create mode 100644 platforms/eVoting/public/next.svg create mode 100644 platforms/eVoting/public/vercel.svg create mode 100644 platforms/eVoting/public/window.svg create mode 100644 platforms/eVoting/src/app/create/page.tsx create mode 100644 platforms/eVoting/src/app/globals.css create mode 100644 platforms/eVoting/src/app/layout.tsx create mode 100644 platforms/eVoting/src/app/not-found.tsx create mode 100644 platforms/eVoting/src/app/page.tsx create mode 100644 platforms/eVoting/src/app/vote/[id]/page.tsx create mode 100644 platforms/eVoting/src/components/CountdownTimer.tsx create mode 100644 platforms/eVoting/src/components/navigation.tsx create mode 100644 platforms/eVoting/src/components/poll-card.tsx create mode 100644 platforms/eVoting/src/components/results-chart.tsx create mode 100644 platforms/eVoting/src/components/ui/accordion.tsx create mode 100644 platforms/eVoting/src/components/ui/alert-dialog.tsx create mode 100644 platforms/eVoting/src/components/ui/alert.tsx create mode 100644 platforms/eVoting/src/components/ui/aspect-ratio.tsx create mode 100644 platforms/eVoting/src/components/ui/avatar.tsx create mode 100644 platforms/eVoting/src/components/ui/badge.tsx create mode 100644 platforms/eVoting/src/components/ui/breadcrumb.tsx create mode 100644 platforms/eVoting/src/components/ui/button.tsx create mode 100644 platforms/eVoting/src/components/ui/calendar.tsx create mode 100644 platforms/eVoting/src/components/ui/card.tsx create mode 100644 platforms/eVoting/src/components/ui/carousel.tsx create mode 100644 platforms/eVoting/src/components/ui/chart.tsx create mode 100644 platforms/eVoting/src/components/ui/checkbox.tsx create mode 100644 platforms/eVoting/src/components/ui/collapsible.tsx create mode 100644 platforms/eVoting/src/components/ui/command.tsx create mode 100644 platforms/eVoting/src/components/ui/context-menu.tsx create mode 100644 platforms/eVoting/src/components/ui/dialog.tsx create mode 100644 platforms/eVoting/src/components/ui/drawer.tsx create mode 100644 platforms/eVoting/src/components/ui/dropdown-menu.tsx create mode 100644 platforms/eVoting/src/components/ui/form.tsx create mode 100644 platforms/eVoting/src/components/ui/hover-card.tsx create mode 100644 platforms/eVoting/src/components/ui/input-otp.tsx create mode 100644 platforms/eVoting/src/components/ui/input.tsx create mode 100644 platforms/eVoting/src/components/ui/label.tsx create mode 100644 platforms/eVoting/src/components/ui/menubar.tsx create mode 100644 platforms/eVoting/src/components/ui/navigation-menu.tsx create mode 100644 platforms/eVoting/src/components/ui/pagination.tsx create mode 100644 platforms/eVoting/src/components/ui/popover.tsx create mode 100644 platforms/eVoting/src/components/ui/progress.tsx create mode 100644 platforms/eVoting/src/components/ui/radio-group.tsx create mode 100644 platforms/eVoting/src/components/ui/resizable.tsx create mode 100644 platforms/eVoting/src/components/ui/scroll-area.tsx create mode 100644 platforms/eVoting/src/components/ui/select.tsx create mode 100644 platforms/eVoting/src/components/ui/separator.tsx create mode 100644 platforms/eVoting/src/components/ui/sheet.tsx create mode 100644 platforms/eVoting/src/components/ui/sidebar.tsx create mode 100644 platforms/eVoting/src/components/ui/skeleton.tsx create mode 100644 platforms/eVoting/src/components/ui/slider.tsx create mode 100644 platforms/eVoting/src/components/ui/switch.tsx create mode 100644 platforms/eVoting/src/components/ui/table.tsx create mode 100644 platforms/eVoting/src/components/ui/tabs.tsx create mode 100644 platforms/eVoting/src/components/ui/textarea.tsx create mode 100644 platforms/eVoting/src/components/ui/toast.tsx create mode 100644 platforms/eVoting/src/components/ui/toaster.tsx create mode 100644 platforms/eVoting/src/components/ui/toggle-group.tsx create mode 100644 platforms/eVoting/src/components/ui/toggle.tsx create mode 100644 platforms/eVoting/src/components/ui/tooltip.tsx create mode 100644 platforms/eVoting/src/components/voting-interface.tsx create mode 100644 platforms/eVoting/src/hooks/use-mobile.tsx create mode 100644 platforms/eVoting/src/hooks/use-toast.ts create mode 100644 platforms/eVoting/src/hooks/useAuth.ts create mode 100644 platforms/eVoting/src/hooks/useCountdown.ts create mode 100644 platforms/eVoting/src/lib/authUtils.ts create mode 100644 platforms/eVoting/src/lib/utils.ts create mode 100644 platforms/eVoting/tsconfig.json create mode 100644 platforms/group-charter-manager/.gitignore create mode 100644 platforms/group-charter-manager/README.md create mode 100644 platforms/group-charter-manager/eslint.config.mjs create mode 100644 platforms/group-charter-manager/next.config.ts create mode 100644 platforms/group-charter-manager/package.json create mode 100644 platforms/group-charter-manager/postcss.config.mjs create mode 100644 platforms/group-charter-manager/public/file.svg create mode 100644 platforms/group-charter-manager/public/globe.svg create mode 100644 platforms/group-charter-manager/public/next.svg create mode 100644 platforms/group-charter-manager/public/vercel.svg create mode 100644 platforms/group-charter-manager/public/window.svg create mode 100644 platforms/group-charter-manager/src/app/charter/[id]/edit/page.tsx create mode 100644 platforms/group-charter-manager/src/app/charter/[id]/page.tsx create mode 100644 platforms/group-charter-manager/src/app/create/page.tsx create mode 100644 platforms/group-charter-manager/src/app/globals.css create mode 100644 platforms/group-charter-manager/src/app/layout.tsx create mode 100644 platforms/group-charter-manager/src/app/not-found.tsx create mode 100644 platforms/group-charter-manager/src/app/page.tsx create mode 100644 platforms/group-charter-manager/src/components/charter-card.tsx create mode 100644 platforms/group-charter-manager/src/components/icons/certificate-ribbon.tsx create mode 100644 platforms/group-charter-manager/src/components/layout/navbar.tsx create mode 100644 platforms/group-charter-manager/src/components/member-avatar.tsx create mode 100644 platforms/group-charter-manager/src/components/platform-badge.tsx create mode 100644 platforms/group-charter-manager/src/components/stats-card.tsx create mode 100644 platforms/group-charter-manager/src/components/ui/accordion.tsx create mode 100644 platforms/group-charter-manager/src/components/ui/alert-dialog.tsx create mode 100644 platforms/group-charter-manager/src/components/ui/alert.tsx create mode 100644 platforms/group-charter-manager/src/components/ui/aspect-ratio.tsx create mode 100644 platforms/group-charter-manager/src/components/ui/avatar.tsx create mode 100644 platforms/group-charter-manager/src/components/ui/badge.tsx create mode 100644 platforms/group-charter-manager/src/components/ui/breadcrumb.tsx create mode 100644 platforms/group-charter-manager/src/components/ui/button.tsx create mode 100644 platforms/group-charter-manager/src/components/ui/calendar.tsx create mode 100644 platforms/group-charter-manager/src/components/ui/card.tsx create mode 100644 platforms/group-charter-manager/src/components/ui/carousel.tsx create mode 100644 platforms/group-charter-manager/src/components/ui/chart.tsx create mode 100644 platforms/group-charter-manager/src/components/ui/checkbox.tsx create mode 100644 platforms/group-charter-manager/src/components/ui/collapsible.tsx create mode 100644 platforms/group-charter-manager/src/components/ui/command.tsx create mode 100644 platforms/group-charter-manager/src/components/ui/context-menu.tsx create mode 100644 platforms/group-charter-manager/src/components/ui/dialog.tsx create mode 100644 platforms/group-charter-manager/src/components/ui/drawer.tsx create mode 100644 platforms/group-charter-manager/src/components/ui/dropdown-menu.tsx create mode 100644 platforms/group-charter-manager/src/components/ui/form.tsx create mode 100644 platforms/group-charter-manager/src/components/ui/hover-card.tsx create mode 100644 platforms/group-charter-manager/src/components/ui/input-otp.tsx create mode 100644 platforms/group-charter-manager/src/components/ui/input.tsx create mode 100644 platforms/group-charter-manager/src/components/ui/label.tsx create mode 100644 platforms/group-charter-manager/src/components/ui/menubar.tsx create mode 100644 platforms/group-charter-manager/src/components/ui/navigation-menu.tsx create mode 100644 platforms/group-charter-manager/src/components/ui/pagination.tsx create mode 100644 platforms/group-charter-manager/src/components/ui/popover.tsx create mode 100644 platforms/group-charter-manager/src/components/ui/progress.tsx create mode 100644 platforms/group-charter-manager/src/components/ui/radio-group.tsx create mode 100644 platforms/group-charter-manager/src/components/ui/resizable.tsx create mode 100644 platforms/group-charter-manager/src/components/ui/scroll-area.tsx create mode 100644 platforms/group-charter-manager/src/components/ui/select.tsx create mode 100644 platforms/group-charter-manager/src/components/ui/separator.tsx create mode 100644 platforms/group-charter-manager/src/components/ui/sheet.tsx create mode 100644 platforms/group-charter-manager/src/components/ui/sidebar.tsx create mode 100644 platforms/group-charter-manager/src/components/ui/skeleton.tsx create mode 100644 platforms/group-charter-manager/src/components/ui/slider.tsx create mode 100644 platforms/group-charter-manager/src/components/ui/switch.tsx create mode 100644 platforms/group-charter-manager/src/components/ui/table.tsx create mode 100644 platforms/group-charter-manager/src/components/ui/tabs.tsx create mode 100644 platforms/group-charter-manager/src/components/ui/textarea.tsx create mode 100644 platforms/group-charter-manager/src/components/ui/toast.tsx create mode 100644 platforms/group-charter-manager/src/components/ui/toaster.tsx create mode 100644 platforms/group-charter-manager/src/components/ui/toggle-group.tsx create mode 100644 platforms/group-charter-manager/src/components/ui/toggle.tsx create mode 100644 platforms/group-charter-manager/src/components/ui/tooltip.tsx create mode 100644 platforms/group-charter-manager/src/components/wysiwyg-editor.tsx create mode 100644 platforms/group-charter-manager/src/hooks/use-mobile.tsx create mode 100644 platforms/group-charter-manager/src/hooks/use-toast.ts create mode 100644 platforms/group-charter-manager/src/hooks/useAuth.ts create mode 100644 platforms/group-charter-manager/src/lib/authUtils.ts create mode 100644 platforms/group-charter-manager/src/lib/utils.ts create mode 100644 platforms/group-charter-manager/src/types/index.ts create mode 100644 platforms/group-charter-manager/src/types/user.types.ts create mode 100644 platforms/group-charter-manager/tsconfig.json create mode 100644 platforms/pictique/src/lib/fragments/Group/Group.svelte create mode 100644 platforms/pictique/src/routes/(protected)/group/[id]/+page.svelte create mode 100644 platforms/pictique/src/routes/(protected)/group/[id]/members/+page.svelte diff --git a/.vscode/settings.json b/.vscode/settings.json index df1242fa..e62ae91a 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -27,5 +27,6 @@ "source.organizeImports.biome": "explicit", "source.fixAll.biome": "explicit" } - } + }, + "editor.formatOnSave": true } diff --git a/infrastructure/control-panel/.gitignore b/infrastructure/control-panel/.gitignore new file mode 100644 index 00000000..da4616b7 --- /dev/null +++ b/infrastructure/control-panel/.gitignore @@ -0,0 +1,29 @@ +node_modules + +# Output +.output +.vercel +.netlify +.wrangler +/.svelte-kit +/build + +# OS +.DS_Store +Thumbs.db + +# Env +.env +.env.* +!.env.example +!.env.test + +# Vite +vite.config.js.timestamp-* +vite.config.ts.timestamp-* + +# Paraglide +src/lib/paraglide + +*storybook.log +storybook-static diff --git a/infrastructure/control-panel/.npmrc b/infrastructure/control-panel/.npmrc new file mode 100644 index 00000000..b6f27f13 --- /dev/null +++ b/infrastructure/control-panel/.npmrc @@ -0,0 +1 @@ +engine-strict=true diff --git a/infrastructure/control-panel/.prettierignore b/infrastructure/control-panel/.prettierignore new file mode 100644 index 00000000..7d74fe24 --- /dev/null +++ b/infrastructure/control-panel/.prettierignore @@ -0,0 +1,9 @@ +# Package Managers +package-lock.json +pnpm-lock.yaml +yarn.lock +bun.lock +bun.lockb + +# Miscellaneous +/static/ diff --git a/infrastructure/control-panel/.prettierrc b/infrastructure/control-panel/.prettierrc new file mode 100644 index 00000000..7ebb855b --- /dev/null +++ b/infrastructure/control-panel/.prettierrc @@ -0,0 +1,15 @@ +{ + "useTabs": true, + "singleQuote": true, + "trailingComma": "none", + "printWidth": 100, + "plugins": ["prettier-plugin-svelte", "prettier-plugin-tailwindcss"], + "overrides": [ + { + "files": "*.svelte", + "options": { + "parser": "svelte" + } + } + ] +} diff --git a/infrastructure/control-panel/.storybook/main.ts b/infrastructure/control-panel/.storybook/main.ts new file mode 100644 index 00000000..0bd00f92 --- /dev/null +++ b/infrastructure/control-panel/.storybook/main.ts @@ -0,0 +1,25 @@ +import type { StorybookConfig } from '@storybook/sveltekit'; + +import { join, dirname } from "path" + +/** +* This function is used to resolve the absolute path of a package. +* It is needed in projects that use Yarn PnP or are set up within a monorepo. +*/ +function getAbsolutePath(value: string): any { + return dirname(require.resolve(join(value, 'package.json'))) +} +const config: StorybookConfig = { + "stories": [ + "../src/**/*.mdx", + "../src/**/*.stories.@(js|ts|svelte)" + ], + "addons": [ + getAbsolutePath('@storybook/addon-svelte-csf') + ], + "framework": { + "name": getAbsolutePath('@storybook/sveltekit'), + "options": {} + } +}; +export default config; \ No newline at end of file diff --git a/infrastructure/control-panel/.storybook/preview.ts b/infrastructure/control-panel/.storybook/preview.ts new file mode 100644 index 00000000..82ddc5b9 --- /dev/null +++ b/infrastructure/control-panel/.storybook/preview.ts @@ -0,0 +1,15 @@ +import type { Preview } from '@storybook/sveltekit' +import "../src/app.css"; + +const preview: Preview = { + parameters: { + controls: { + matchers: { + color: /(background|color)$/i, + date: /Date$/i, + }, + }, + }, +}; + +export default preview; \ No newline at end of file diff --git a/infrastructure/control-panel/README.md b/infrastructure/control-panel/README.md new file mode 100644 index 00000000..b5b29507 --- /dev/null +++ b/infrastructure/control-panel/README.md @@ -0,0 +1,38 @@ +# sv + +Everything you need to build a Svelte project, powered by [`sv`](https://github.com/sveltejs/cli). + +## Creating a project + +If you're seeing this, you've probably already done this step. Congrats! + +```bash +# create a new project in the current directory +npx sv create + +# create a new project in my-app +npx sv create my-app +``` + +## Developing + +Once you've created a project and installed dependencies with `npm install` (or `pnpm install` or `yarn`), start a development server: + +```bash +npm run dev + +# or start the server and open the app in a new browser tab +npm run dev -- --open +``` + +## Building + +To create a production version of your app: + +```bash +npm run build +``` + +You can preview the production build with `npm run preview`. + +> To deploy your app, you may need to install an [adapter](https://svelte.dev/docs/kit/adapters) for your target environment. diff --git a/infrastructure/control-panel/eslint.config.js b/infrastructure/control-panel/eslint.config.js new file mode 100644 index 00000000..6284fab2 --- /dev/null +++ b/infrastructure/control-panel/eslint.config.js @@ -0,0 +1,44 @@ +// For more info, see https://github.com/storybookjs/eslint-plugin-storybook#configuration-flat-config-format +import storybook from 'eslint-plugin-storybook'; + +import prettier from 'eslint-config-prettier'; +import { includeIgnoreFile } from '@eslint/compat'; +import js from '@eslint/js'; +import svelte from 'eslint-plugin-svelte'; +import globals from 'globals'; +import { fileURLToPath } from 'node:url'; +import ts from 'typescript-eslint'; +import svelteConfig from './svelte.config.js'; + +const gitignorePath = fileURLToPath(new URL('./.gitignore', import.meta.url)); + +export default ts.config( + includeIgnoreFile(gitignorePath), + js.configs.recommended, + ...ts.configs.recommended, + ...svelte.configs.recommended, + prettier, + ...svelte.configs.prettier, + { + languageOptions: { + globals: { ...globals.browser, ...globals.node } + }, + rules: { + // typescript-eslint strongly recommend that you do not use the no-undef lint rule on TypeScript projects. + // see: https://typescript-eslint.io/troubleshooting/faqs/eslint/#i-get-errors-from-the-no-undef-rule-about-global-variables-not-being-defined-even-though-there-are-no-typescript-errors + 'no-undef': 'off' + } + }, + { + files: ['**/*.svelte', '**/*.svelte.ts', '**/*.svelte.js'], + languageOptions: { + parserOptions: { + projectService: true, + extraFileExtensions: ['.svelte'], + parser: ts.parser, + svelteConfig + } + } + }, + storybook.configs['flat/recommended'] +); diff --git a/infrastructure/control-panel/messages/en.json b/infrastructure/control-panel/messages/en.json new file mode 100644 index 00000000..37a98944 --- /dev/null +++ b/infrastructure/control-panel/messages/en.json @@ -0,0 +1,4 @@ +{ + "$schema": "https://inlang.com/schema/inlang-message-format", + "hello_world": "Hello, {name} from en!" +} diff --git a/infrastructure/control-panel/messages/es.json b/infrastructure/control-panel/messages/es.json new file mode 100644 index 00000000..176345c1 --- /dev/null +++ b/infrastructure/control-panel/messages/es.json @@ -0,0 +1,4 @@ +{ + "$schema": "https://inlang.com/schema/inlang-message-format", + "hello_world": "Hello, {name} from es!" +} diff --git a/infrastructure/control-panel/package.json b/infrastructure/control-panel/package.json new file mode 100644 index 00000000..6d5f8162 --- /dev/null +++ b/infrastructure/control-panel/package.json @@ -0,0 +1,47 @@ +{ + "name": "control-panel", + "private": true, + "version": "0.0.1", + "type": "module", + "scripts": { + "dev": "vite dev", + "build": "vite build", + "preview": "vite preview", + "prepare": "svelte-kit sync || echo ''", + "check": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json", + "check:watch": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json --watch", + "format": "prettier --write .", + "lint": "prettier --check . && eslint .", + "storybook": "storybook dev -p 6006", + "build-storybook": "storybook build" + }, + "devDependencies": { + "@eslint/compat": "^1.2.5", + "@eslint/js": "^9.18.0", + "@storybook/addon-svelte-csf": "^5.0.7", + "@storybook/sveltekit": "^9.0.17", + "@sveltejs/adapter-static": "^3.0.8", + "@sveltejs/kit": "^2.22.0", + "@sveltejs/vite-plugin-svelte": "^6.0.0", + "@tailwindcss/vite": "^4.0.0", + "@types/node": "^22", + "eslint": "^9.18.0", + "eslint-config-prettier": "^10.0.1", + "eslint-plugin-storybook": "^9.0.17", + "eslint-plugin-svelte": "^3.0.0", + "globals": "^16.0.0", + "prettier": "^3.4.2", + "prettier-plugin-svelte": "^3.3.3", + "prettier-plugin-tailwindcss": "^0.6.11", + "storybook": "^9.0.17", + "svelte": "^5.0.0", + "svelte-check": "^4.0.0", + "tailwindcss": "^4.0.0", + "typescript": "^5.0.0", + "typescript-eslint": "^8.20.0", + "vite": "^7.0.4" + }, + "dependencies": { + "@inlang/paraglide-js": "^2.0.0" + } +} diff --git a/infrastructure/control-panel/project.inlang/cache/plugins/2sy648wh9sugi b/infrastructure/control-panel/project.inlang/cache/plugins/2sy648wh9sugi new file mode 100644 index 00000000..5b07e0dd --- /dev/null +++ b/infrastructure/control-panel/project.inlang/cache/plugins/2sy648wh9sugi @@ -0,0 +1 @@ +var Un=Object.create;var Xe=Object.defineProperty;var Pn=Object.getOwnPropertyDescriptor;var vn=Object.getOwnPropertyNames;var Nn=Object.getPrototypeOf,Sn=Object.prototype.hasOwnProperty;var Rn=(s,e)=>()=>(e||s((e={exports:{}}).exports,e),e.exports);var xn=(s,e,i,u)=>{if(e&&typeof e=="object"||typeof e=="function")for(let p of vn(e))!Sn.call(s,p)&&p!==i&&Xe(s,p,{get:()=>e[p],enumerable:!(u=Pn(e,p))||u.enumerable});return s};var jn=(s,e,i)=>(i=s!=null?Un(Nn(s)):{},xn(e||!s||!s.__esModule?Xe(i,"default",{value:s,enumerable:!0}):i,s));var he=Rn(o=>{"use strict";Object.defineProperty(o,"__esModule",{value:!0});o.Type=o.JsonType=o.JavaScriptTypeBuilder=o.JsonTypeBuilder=o.TypeBuilder=o.TypeBuilderError=o.TransformEncodeBuilder=o.TransformDecodeBuilder=o.TemplateLiteralDslParser=o.TemplateLiteralGenerator=o.TemplateLiteralGeneratorError=o.TemplateLiteralFinite=o.TemplateLiteralFiniteError=o.TemplateLiteralParser=o.TemplateLiteralParserError=o.TemplateLiteralResolver=o.TemplateLiteralPattern=o.TemplateLiteralPatternError=o.UnionResolver=o.KeyArrayResolver=o.KeyArrayResolverError=o.KeyResolver=o.ObjectMap=o.Intrinsic=o.IndexedAccessor=o.TypeClone=o.TypeExtends=o.TypeExtendsResult=o.TypeExtendsError=o.ExtendsUndefined=o.TypeGuard=o.TypeGuardUnknownTypeError=o.ValueGuard=o.FormatRegistry=o.TypeBoxError=o.TypeRegistry=o.PatternStringExact=o.PatternNumberExact=o.PatternBooleanExact=o.PatternString=o.PatternNumber=o.PatternBoolean=o.Kind=o.Hint=o.Optional=o.Readonly=o.Transform=void 0;o.Transform=Symbol.for("TypeBox.Transform");o.Readonly=Symbol.for("TypeBox.Readonly");o.Optional=Symbol.for("TypeBox.Optional");o.Hint=Symbol.for("TypeBox.Hint");o.Kind=Symbol.for("TypeBox.Kind");o.PatternBoolean="(true|false)";o.PatternNumber="(0|[1-9][0-9]*)";o.PatternString="(.*)";o.PatternBooleanExact=`^${o.PatternBoolean}$`;o.PatternNumberExact=`^${o.PatternNumber}$`;o.PatternStringExact=`^${o.PatternString}$`;var Ve;(function(s){let e=new Map;function i(){return new Map(e)}s.Entries=i;function u(){return e.clear()}s.Clear=u;function p(y){return e.delete(y)}s.Delete=p;function l(y){return e.has(y)}s.Has=l;function c(y,b){e.set(y,b)}s.Set=c;function T(y){return e.get(y)}s.Get=T})(Ve||(o.TypeRegistry=Ve={}));var D=class extends Error{constructor(e){super(e)}};o.TypeBoxError=D;var Ze;(function(s){let e=new Map;function i(){return new Map(e)}s.Entries=i;function u(){return e.clear()}s.Clear=u;function p(y){return e.delete(y)}s.Delete=p;function l(y){return e.has(y)}s.Has=l;function c(y,b){e.set(y,b)}s.Set=c;function T(y){return e.get(y)}s.Get=T})(Ze||(o.FormatRegistry=Ze={}));var I;(function(s){function e(m){return Array.isArray(m)}s.IsArray=e;function i(m){return typeof m=="bigint"}s.IsBigInt=i;function u(m){return typeof m=="boolean"}s.IsBoolean=u;function p(m){return m instanceof globalThis.Date}s.IsDate=p;function l(m){return m===null}s.IsNull=l;function c(m){return typeof m=="number"}s.IsNumber=c;function T(m){return typeof m=="object"&&m!==null}s.IsObject=T;function y(m){return typeof m=="string"}s.IsString=y;function b(m){return m instanceof globalThis.Uint8Array}s.IsUint8Array=b;function g(m){return m===void 0}s.IsUndefined=g})(I||(o.ValueGuard=I={}));var ze=class extends D{};o.TypeGuardUnknownTypeError=ze;var a;(function(s){function e(r){try{return new RegExp(r),!0}catch{return!1}}function i(r){if(!I.IsString(r))return!1;for(let L=0;L=7&&B<=13||B===27||B===127)return!1}return!0}function u(r){return c(r)||C(r)}function p(r){return I.IsUndefined(r)||I.IsBigInt(r)}function l(r){return I.IsUndefined(r)||I.IsNumber(r)}function c(r){return I.IsUndefined(r)||I.IsBoolean(r)}function T(r){return I.IsUndefined(r)||I.IsString(r)}function y(r){return I.IsUndefined(r)||I.IsString(r)&&i(r)&&e(r)}function b(r){return I.IsUndefined(r)||I.IsString(r)&&i(r)}function g(r){return I.IsUndefined(r)||C(r)}function m(r){return S(r,"Any")&&T(r.$id)}s.TAny=m;function U(r){return S(r,"Array")&&r.type==="array"&&T(r.$id)&&C(r.items)&&l(r.minItems)&&l(r.maxItems)&&c(r.uniqueItems)&&g(r.contains)&&l(r.minContains)&&l(r.maxContains)}s.TArray=U;function d(r){return S(r,"AsyncIterator")&&r.type==="AsyncIterator"&&T(r.$id)&&C(r.items)}s.TAsyncIterator=d;function O(r){return S(r,"BigInt")&&r.type==="bigint"&&T(r.$id)&&p(r.exclusiveMaximum)&&p(r.exclusiveMinimum)&&p(r.maximum)&&p(r.minimum)&&p(r.multipleOf)}s.TBigInt=O;function v(r){return S(r,"Boolean")&&r.type==="boolean"&&T(r.$id)}s.TBoolean=v;function N(r){return S(r,"Constructor")&&r.type==="Constructor"&&T(r.$id)&&I.IsArray(r.parameters)&&r.parameters.every(L=>C(L))&&C(r.returns)}s.TConstructor=N;function j(r){return S(r,"Date")&&r.type==="Date"&&T(r.$id)&&l(r.exclusiveMaximumTimestamp)&&l(r.exclusiveMinimumTimestamp)&&l(r.maximumTimestamp)&&l(r.minimumTimestamp)&&l(r.multipleOfTimestamp)}s.TDate=j;function R(r){return S(r,"Function")&&r.type==="Function"&&T(r.$id)&&I.IsArray(r.parameters)&&r.parameters.every(L=>C(L))&&C(r.returns)}s.TFunction=R;function A(r){return S(r,"Integer")&&r.type==="integer"&&T(r.$id)&&l(r.exclusiveMaximum)&&l(r.exclusiveMinimum)&&l(r.maximum)&&l(r.minimum)&&l(r.multipleOf)}s.TInteger=A;function K(r){return S(r,"Intersect")&&!(I.IsString(r.type)&&r.type!=="object")&&I.IsArray(r.allOf)&&r.allOf.every(L=>C(L)&&!oe(L))&&T(r.type)&&(c(r.unevaluatedProperties)||g(r.unevaluatedProperties))&&T(r.$id)}s.TIntersect=K;function pe(r){return S(r,"Iterator")&&r.type==="Iterator"&&T(r.$id)&&C(r.items)}s.TIterator=pe;function S(r,L){return ee(r)&&r[o.Kind]===L}s.TKindOf=S;function ee(r){return I.IsObject(r)&&o.Kind in r&&I.IsString(r[o.Kind])}s.TKind=ee;function ne(r){return V(r)&&I.IsString(r.const)}s.TLiteralString=ne;function Te(r){return V(r)&&I.IsNumber(r.const)}s.TLiteralNumber=Te;function Ke(r){return V(r)&&I.IsBoolean(r.const)}s.TLiteralBoolean=Ke;function V(r){return S(r,"Literal")&&T(r.$id)&&(I.IsBoolean(r.const)||I.IsNumber(r.const)||I.IsString(r.const))}s.TLiteral=V;function fe(r){return S(r,"Never")&&I.IsObject(r.not)&&Object.getOwnPropertyNames(r.not).length===0}s.TNever=fe;function $(r){return S(r,"Not")&&C(r.not)}s.TNot=$;function te(r){return S(r,"Null")&&r.type==="null"&&T(r.$id)}s.TNull=te;function re(r){return S(r,"Number")&&r.type==="number"&&T(r.$id)&&l(r.exclusiveMaximum)&&l(r.exclusiveMinimum)&&l(r.maximum)&&l(r.minimum)&&l(r.multipleOf)}s.TNumber=re;function _(r){return S(r,"Object")&&r.type==="object"&&T(r.$id)&&I.IsObject(r.properties)&&u(r.additionalProperties)&&l(r.minProperties)&&l(r.maxProperties)&&Object.entries(r.properties).every(([L,B])=>i(L)&&C(B))}s.TObject=_;function ie(r){return S(r,"Promise")&&r.type==="Promise"&&T(r.$id)&&C(r.item)}s.TPromise=ie;function de(r){return S(r,"Record")&&r.type==="object"&&T(r.$id)&&u(r.additionalProperties)&&I.IsObject(r.patternProperties)&&(L=>{let B=Object.getOwnPropertyNames(L.patternProperties);return B.length===1&&e(B[0])&&I.IsObject(L.patternProperties)&&C(L.patternProperties[B[0]])})(r)}s.TRecord=de;function Ee(r){return I.IsObject(r)&&o.Hint in r&&r[o.Hint]==="Recursive"}s.TRecursive=Ee;function ye(r){return S(r,"Ref")&&T(r.$id)&&I.IsString(r.$ref)}s.TRef=ye;function me(r){return S(r,"String")&&r.type==="string"&&T(r.$id)&&l(r.minLength)&&l(r.maxLength)&&y(r.pattern)&&b(r.format)}s.TString=me;function ge(r){return S(r,"Symbol")&&r.type==="symbol"&&T(r.$id)}s.TSymbol=ge;function z(r){return S(r,"TemplateLiteral")&&r.type==="string"&&I.IsString(r.pattern)&&r.pattern[0]==="^"&&r.pattern[r.pattern.length-1]==="$"}s.TTemplateLiteral=z;function Ie(r){return S(r,"This")&&T(r.$id)&&I.IsString(r.$ref)}s.TThis=Ie;function oe(r){return I.IsObject(r)&&o.Transform in r}s.TTransform=oe;function F(r){return S(r,"Tuple")&&r.type==="array"&&T(r.$id)&&I.IsNumber(r.minItems)&&I.IsNumber(r.maxItems)&&r.minItems===r.maxItems&&(I.IsUndefined(r.items)&&I.IsUndefined(r.additionalItems)&&r.minItems===0||I.IsArray(r.items)&&r.items.every(L=>C(L)))}s.TTuple=F;function be(r){return S(r,"Undefined")&&r.type==="undefined"&&T(r.$id)}s.TUndefined=be;function Be(r){return q(r)&&r.anyOf.every(L=>ne(L)||Te(L))}s.TUnionLiteral=Be;function q(r){return S(r,"Union")&&T(r.$id)&&I.IsObject(r)&&I.IsArray(r.anyOf)&&r.anyOf.every(L=>C(L))}s.TUnion=q;function W(r){return S(r,"Uint8Array")&&r.type==="Uint8Array"&&T(r.$id)&&l(r.minByteLength)&&l(r.maxByteLength)}s.TUint8Array=W;function E(r){return S(r,"Unknown")&&T(r.$id)}s.TUnknown=E;function Oe(r){return S(r,"Unsafe")}s.TUnsafe=Oe;function se(r){return S(r,"Void")&&r.type==="void"&&T(r.$id)}s.TVoid=se;function Me(r){return I.IsObject(r)&&r[o.Readonly]==="Readonly"}s.TReadonly=Me;function De(r){return I.IsObject(r)&&r[o.Optional]==="Optional"}s.TOptional=De;function C(r){return I.IsObject(r)&&(m(r)||U(r)||v(r)||O(r)||d(r)||N(r)||j(r)||R(r)||A(r)||K(r)||pe(r)||V(r)||fe(r)||$(r)||te(r)||re(r)||_(r)||ie(r)||de(r)||ye(r)||me(r)||ge(r)||z(r)||Ie(r)||F(r)||be(r)||q(r)||W(r)||E(r)||Oe(r)||se(r)||ee(r)&&Ve.Has(r[o.Kind]))}s.TSchema=C})(a||(o.TypeGuard=a={}));var Ge;(function(s){function e(i){return i[o.Kind]==="Intersect"?i.allOf.every(u=>e(u)):i[o.Kind]==="Union"?i.anyOf.some(u=>e(u)):i[o.Kind]==="Undefined"?!0:i[o.Kind]==="Not"?!e(i.not):!1}s.Check=e})(Ge||(o.ExtendsUndefined=Ge={}));var Ue=class extends D{};o.TypeExtendsError=Ue;var f;(function(s){s[s.Union=0]="Union",s[s.True=1]="True",s[s.False=2]="False"})(f||(o.TypeExtendsResult=f={}));var J;(function(s){function e(n){return n===f.False?n:f.True}function i(n){throw new Ue(n)}function u(n){return a.TNever(n)||a.TIntersect(n)||a.TUnion(n)||a.TUnknown(n)||a.TAny(n)}function p(n,t){return a.TNever(t)?S(n,t):a.TIntersect(t)?R(n,t):a.TUnion(t)?ke(n,t):a.TUnknown(t)?Qe(n,t):a.TAny(t)?l(n,t):i("StructuralRight")}function l(n,t){return f.True}function c(n,t){return a.TIntersect(t)?R(n,t):a.TUnion(t)&&t.anyOf.some(x=>a.TAny(x)||a.TUnknown(x))?f.True:a.TUnion(t)?f.Union:a.TUnknown(t)||a.TAny(t)?f.True:f.Union}function T(n,t){return a.TUnknown(n)?f.False:a.TAny(n)?f.Union:a.TNever(n)?f.True:f.False}function y(n,t){return a.TObject(t)&&z(t)?f.True:u(t)?p(n,t):a.TArray(t)?e(w(n.items,t.items)):f.False}function b(n,t){return u(t)?p(n,t):a.TAsyncIterator(t)?e(w(n.items,t.items)):f.False}function g(n,t){return u(t)?p(n,t):a.TObject(t)?F(n,t):a.TRecord(t)?E(n,t):a.TBigInt(t)?f.True:f.False}function m(n,t){return a.TLiteral(n)&&I.IsBoolean(n.const)||a.TBoolean(n)?f.True:f.False}function U(n,t){return u(t)?p(n,t):a.TObject(t)?F(n,t):a.TRecord(t)?E(n,t):a.TBoolean(t)?f.True:f.False}function d(n,t){return u(t)?p(n,t):a.TObject(t)?F(n,t):a.TConstructor(t)?n.parameters.length>t.parameters.length?f.False:n.parameters.every((x,M)=>e(w(t.parameters[M],x))===f.True)?e(w(n.returns,t.returns)):f.False:f.False}function O(n,t){return u(t)?p(n,t):a.TObject(t)?F(n,t):a.TRecord(t)?E(n,t):a.TDate(t)?f.True:f.False}function v(n,t){return u(t)?p(n,t):a.TObject(t)?F(n,t):a.TFunction(t)?n.parameters.length>t.parameters.length?f.False:n.parameters.every((x,M)=>e(w(t.parameters[M],x))===f.True)?e(w(n.returns,t.returns)):f.False:f.False}function N(n,t){return a.TLiteral(n)&&I.IsNumber(n.const)||a.TNumber(n)||a.TInteger(n)?f.True:f.False}function j(n,t){return a.TInteger(t)||a.TNumber(t)?f.True:u(t)?p(n,t):a.TObject(t)?F(n,t):a.TRecord(t)?E(n,t):f.False}function R(n,t){return t.allOf.every(x=>w(n,x)===f.True)?f.True:f.False}function A(n,t){return n.allOf.some(x=>w(x,t)===f.True)?f.True:f.False}function K(n,t){return u(t)?p(n,t):a.TIterator(t)?e(w(n.items,t.items)):f.False}function pe(n,t){return a.TLiteral(t)&&t.const===n.const?f.True:u(t)?p(n,t):a.TObject(t)?F(n,t):a.TRecord(t)?E(n,t):a.TString(t)?se(n,t):a.TNumber(t)?V(n,t):a.TInteger(t)?N(n,t):a.TBoolean(t)?m(n,t):f.False}function S(n,t){return f.False}function ee(n,t){return f.True}function ne(n){let[t,x]=[n,0];for(;a.TNot(t);)t=t.not,x+=1;return x%2===0?t:o.Type.Unknown()}function Te(n,t){return a.TNot(n)?w(ne(n),t):a.TNot(t)?w(n,ne(t)):i("Invalid fallthrough for Not")}function Ke(n,t){return u(t)?p(n,t):a.TObject(t)?F(n,t):a.TRecord(t)?E(n,t):a.TNull(t)?f.True:f.False}function V(n,t){return a.TLiteralNumber(n)||a.TNumber(n)||a.TInteger(n)?f.True:f.False}function fe(n,t){return u(t)?p(n,t):a.TObject(t)?F(n,t):a.TRecord(t)?E(n,t):a.TInteger(t)||a.TNumber(t)?f.True:f.False}function $(n,t){return Object.getOwnPropertyNames(n.properties).length===t}function te(n){return z(n)}function re(n){return $(n,0)||$(n,1)&&"description"in n.properties&&a.TUnion(n.properties.description)&&n.properties.description.anyOf.length===2&&(a.TString(n.properties.description.anyOf[0])&&a.TUndefined(n.properties.description.anyOf[1])||a.TString(n.properties.description.anyOf[1])&&a.TUndefined(n.properties.description.anyOf[0]))}function _(n){return $(n,0)}function ie(n){return $(n,0)}function de(n){return $(n,0)}function Ee(n){return $(n,0)}function ye(n){return z(n)}function me(n){let t=o.Type.Number();return $(n,0)||$(n,1)&&"length"in n.properties&&e(w(n.properties.length,t))===f.True}function ge(n){return $(n,0)}function z(n){let t=o.Type.Number();return $(n,0)||$(n,1)&&"length"in n.properties&&e(w(n.properties.length,t))===f.True}function Ie(n){let t=o.Type.Function([o.Type.Any()],o.Type.Any());return $(n,0)||$(n,1)&&"then"in n.properties&&e(w(n.properties.then,t))===f.True}function oe(n,t){return w(n,t)===f.False||a.TOptional(n)&&!a.TOptional(t)?f.False:f.True}function F(n,t){return a.TUnknown(n)?f.False:a.TAny(n)?f.Union:a.TNever(n)||a.TLiteralString(n)&&te(t)||a.TLiteralNumber(n)&&_(t)||a.TLiteralBoolean(n)&&ie(t)||a.TSymbol(n)&&re(t)||a.TBigInt(n)&&de(t)||a.TString(n)&&te(t)||a.TSymbol(n)&&re(t)||a.TNumber(n)&&_(t)||a.TInteger(n)&&_(t)||a.TBoolean(n)&&ie(t)||a.TUint8Array(n)&&ye(t)||a.TDate(n)&&Ee(t)||a.TConstructor(n)&&ge(t)||a.TFunction(n)&&me(t)?f.True:a.TRecord(n)&&a.TString(q(n))?t[o.Hint]==="Record"?f.True:f.False:a.TRecord(n)&&a.TNumber(q(n))?$(t,0)?f.True:f.False:f.False}function be(n,t){return u(t)?p(n,t):a.TRecord(t)?E(n,t):a.TObject(t)?(()=>{for(let x of Object.getOwnPropertyNames(t.properties)){if(!(x in n.properties)&&!a.TOptional(t.properties[x]))return f.False;if(a.TOptional(t.properties[x]))return f.True;if(oe(n.properties[x],t.properties[x])===f.False)return f.False}return f.True})():f.False}function Be(n,t){return u(t)?p(n,t):a.TObject(t)&&Ie(t)?f.True:a.TPromise(t)?e(w(n.item,t.item)):f.False}function q(n){return o.PatternNumberExact in n.patternProperties?o.Type.Number():o.PatternStringExact in n.patternProperties?o.Type.String():i("Unknown record key pattern")}function W(n){return o.PatternNumberExact in n.patternProperties?n.patternProperties[o.PatternNumberExact]:o.PatternStringExact in n.patternProperties?n.patternProperties[o.PatternStringExact]:i("Unable to get record value schema")}function E(n,t){let[x,M]=[q(t),W(t)];return a.TLiteralString(n)&&a.TNumber(x)&&e(w(n,M))===f.True?f.True:a.TUint8Array(n)&&a.TNumber(x)||a.TString(n)&&a.TNumber(x)||a.TArray(n)&&a.TNumber(x)?w(n,M):a.TObject(n)?(()=>{for(let On of Object.getOwnPropertyNames(n.properties))if(oe(M,n.properties[On])===f.False)return f.False;return f.True})():f.False}function Oe(n,t){return u(t)?p(n,t):a.TObject(t)?F(n,t):a.TRecord(t)?w(W(n),W(t)):f.False}function se(n,t){return a.TLiteral(n)&&I.IsString(n.const)||a.TString(n)?f.True:f.False}function Me(n,t){return u(t)?p(n,t):a.TObject(t)?F(n,t):a.TRecord(t)?E(n,t):a.TString(t)?f.True:f.False}function De(n,t){return u(t)?p(n,t):a.TObject(t)?F(n,t):a.TRecord(t)?E(n,t):a.TSymbol(t)?f.True:f.False}function C(n,t){return a.TTemplateLiteral(n)?w(k.Resolve(n),t):a.TTemplateLiteral(t)?w(n,k.Resolve(t)):i("Invalid fallthrough for TemplateLiteral")}function r(n,t){return a.TArray(t)&&n.items!==void 0&&n.items.every(x=>w(x,t.items)===f.True)}function L(n,t){return a.TNever(n)?f.True:a.TUnknown(n)?f.False:a.TAny(n)?f.Union:f.False}function B(n,t){return u(t)?p(n,t):a.TObject(t)&&z(t)||a.TArray(t)&&r(n,t)?f.True:a.TTuple(t)?I.IsUndefined(n.items)&&!I.IsUndefined(t.items)||!I.IsUndefined(n.items)&&I.IsUndefined(t.items)?f.False:I.IsUndefined(n.items)&&!I.IsUndefined(t.items)||n.items.every((x,M)=>w(x,t.items[M])===f.True)?f.True:f.False:f.False}function fn(n,t){return u(t)?p(n,t):a.TObject(t)?F(n,t):a.TRecord(t)?E(n,t):a.TUint8Array(t)?f.True:f.False}function dn(n,t){return u(t)?p(n,t):a.TObject(t)?F(n,t):a.TRecord(t)?E(n,t):a.TVoid(t)?gn(n,t):a.TUndefined(t)?f.True:f.False}function ke(n,t){return t.anyOf.some(x=>w(n,x)===f.True)?f.True:f.False}function yn(n,t){return n.anyOf.every(x=>w(x,t)===f.True)?f.True:f.False}function Qe(n,t){return f.True}function mn(n,t){return a.TNever(t)?S(n,t):a.TIntersect(t)?R(n,t):a.TUnion(t)?ke(n,t):a.TAny(t)?l(n,t):a.TString(t)?se(n,t):a.TNumber(t)?V(n,t):a.TInteger(t)?N(n,t):a.TBoolean(t)?m(n,t):a.TArray(t)?T(n,t):a.TTuple(t)?L(n,t):a.TObject(t)?F(n,t):a.TUnknown(t)?f.True:f.False}function gn(n,t){return a.TUndefined(n)||a.TUndefined(n)?f.True:f.False}function In(n,t){return a.TIntersect(t)?R(n,t):a.TUnion(t)?ke(n,t):a.TUnknown(t)?Qe(n,t):a.TAny(t)?l(n,t):a.TObject(t)?F(n,t):a.TVoid(t)?f.True:f.False}function w(n,t){return a.TTemplateLiteral(n)||a.TTemplateLiteral(t)?C(n,t):a.TNot(n)||a.TNot(t)?Te(n,t):a.TAny(n)?c(n,t):a.TArray(n)?y(n,t):a.TBigInt(n)?g(n,t):a.TBoolean(n)?U(n,t):a.TAsyncIterator(n)?b(n,t):a.TConstructor(n)?d(n,t):a.TDate(n)?O(n,t):a.TFunction(n)?v(n,t):a.TInteger(n)?j(n,t):a.TIntersect(n)?A(n,t):a.TIterator(n)?K(n,t):a.TLiteral(n)?pe(n,t):a.TNever(n)?ee(n,t):a.TNull(n)?Ke(n,t):a.TNumber(n)?fe(n,t):a.TObject(n)?be(n,t):a.TRecord(n)?Oe(n,t):a.TString(n)?Me(n,t):a.TSymbol(n)?De(n,t):a.TTuple(n)?B(n,t):a.TPromise(n)?Be(n,t):a.TUint8Array(n)?fn(n,t):a.TUndefined(n)?dn(n,t):a.TUnion(n)?yn(n,t):a.TUnknown(n)?mn(n,t):a.TVoid(n)?In(n,t):i(`Unknown left type operand '${n[o.Kind]}'`)}function bn(n,t){return w(n,t)}s.Extends=bn})(J||(o.TypeExtends=J={}));var P;(function(s){function e(y){return y.map(b=>l(b))}function i(y){return new Date(y.getTime())}function u(y){return new Uint8Array(y)}function p(y){let b=Object.getOwnPropertyNames(y).reduce((m,U)=>({...m,[U]:l(y[U])}),{}),g=Object.getOwnPropertySymbols(y).reduce((m,U)=>({...m,[U]:l(y[U])}),{});return{...b,...g}}function l(y){return I.IsArray(y)?e(y):I.IsDate(y)?i(y):I.IsUint8Array(y)?u(y):I.IsObject(y)?p(y):y}function c(y){return y.map(b=>T(b))}s.Rest=c;function T(y,b={}){return{...l(y),...b}}s.Type=T})(P||(o.TypeClone=P={}));var qe;(function(s){function e(d){return d.map(O=>{let{[o.Optional]:v,...N}=P.Type(O);return N})}function i(d){return d.every(O=>a.TOptional(O))}function u(d){return d.some(O=>a.TOptional(O))}function p(d){return i(d.allOf)?o.Type.Optional(o.Type.Intersect(e(d.allOf))):d}function l(d){return u(d.anyOf)?o.Type.Optional(o.Type.Union(e(d.anyOf))):d}function c(d){return d[o.Kind]==="Intersect"?p(d):d[o.Kind]==="Union"?l(d):d}function T(d,O){let v=d.allOf.reduce((N,j)=>{let R=m(j,O);return R[o.Kind]==="Never"?N:[...N,R]},[]);return c(o.Type.Intersect(v))}function y(d,O){let v=d.anyOf.map(N=>m(N,O));return c(o.Type.Union(v))}function b(d,O){let v=d.properties[O];return I.IsUndefined(v)?o.Type.Never():o.Type.Union([v])}function g(d,O){let v=d.items;if(I.IsUndefined(v))return o.Type.Never();let N=v[O];return I.IsUndefined(N)?o.Type.Never():N}function m(d,O){return d[o.Kind]==="Intersect"?T(d,O):d[o.Kind]==="Union"?y(d,O):d[o.Kind]==="Object"?b(d,O):d[o.Kind]==="Tuple"?g(d,O):o.Type.Never()}function U(d,O,v={}){let N=O.map(j=>m(d,j.toString()));return c(o.Type.Union(N,v))}s.Resolve=U})(qe||(o.IndexedAccessor=qe={}));var Y;(function(s){function e(g){let[m,U]=[g.slice(0,1),g.slice(1)];return`${m.toLowerCase()}${U}`}function i(g){let[m,U]=[g.slice(0,1),g.slice(1)];return`${m.toUpperCase()}${U}`}function u(g){return g.toUpperCase()}function p(g){return g.toLowerCase()}function l(g,m){let U=X.ParseExact(g.pattern);if(!Z.Check(U))return{...g,pattern:c(g.pattern,m)};let v=[...G.Generate(U)].map(R=>o.Type.Literal(R)),N=T(v,m),j=o.Type.Union(N);return o.Type.TemplateLiteral([j])}function c(g,m){return typeof g=="string"?m==="Uncapitalize"?e(g):m==="Capitalize"?i(g):m==="Uppercase"?u(g):m==="Lowercase"?p(g):g:g.toString()}function T(g,m){if(g.length===0)return[];let[U,...d]=g;return[b(U,m),...T(d,m)]}function y(g,m){return a.TTemplateLiteral(g)?l(g,m):a.TUnion(g)?o.Type.Union(T(g.anyOf,m)):a.TLiteral(g)?o.Type.Literal(c(g.const,m)):g}function b(g,m){return y(g,m)}s.Map=b})(Y||(o.Intrinsic=Y={}));var Q;(function(s){function e(c,T){return o.Type.Intersect(c.allOf.map(y=>p(y,T)),{...c})}function i(c,T){return o.Type.Union(c.anyOf.map(y=>p(y,T)),{...c})}function u(c,T){return T(c)}function p(c,T){return c[o.Kind]==="Intersect"?e(c,T):c[o.Kind]==="Union"?i(c,T):c[o.Kind]==="Object"?u(c,T):c}function l(c,T,y){return{...p(P.Type(c),T),...y}}s.Map=l})(Q||(o.ObjectMap=Q={}));var Pe;(function(s){function e(b){return b[0]==="^"&&b[b.length-1]==="$"?b.slice(1,b.length-1):b}function i(b,g){return b.allOf.reduce((m,U)=>[...m,...c(U,g)],[])}function u(b,g){let m=b.anyOf.map(U=>c(U,g));return[...m.reduce((U,d)=>d.map(O=>m.every(v=>v.includes(O))?U.add(O):U)[0],new Set)]}function p(b,g){return Object.getOwnPropertyNames(b.properties)}function l(b,g){return g.includePatterns?Object.getOwnPropertyNames(b.patternProperties):[]}function c(b,g){return a.TIntersect(b)?i(b,g):a.TUnion(b)?u(b,g):a.TObject(b)?p(b,g):a.TRecord(b)?l(b,g):[]}function T(b,g){return[...new Set(c(b,g))]}s.ResolveKeys=T;function y(b){return`^(${T(b,{includePatterns:!0}).map(U=>`(${e(U)})`).join("|")})$`}s.ResolvePattern=y})(Pe||(o.KeyResolver=Pe={}));var ve=class extends D{};o.KeyArrayResolverError=ve;var ae;(function(s){function e(i){return Array.isArray(i)?i:a.TUnionLiteral(i)?i.anyOf.map(u=>u.const.toString()):a.TLiteral(i)?[i.const]:a.TTemplateLiteral(i)?(()=>{let u=X.ParseExact(i.pattern);if(!Z.Check(u))throw new ve("Cannot resolve keys from infinite template expression");return[...G.Generate(u)]})():[]}s.Resolve=e})(ae||(o.KeyArrayResolver=ae={}));var Je;(function(s){function*e(u){for(let p of u.anyOf)p[o.Kind]==="Union"?yield*e(p):yield p}function i(u){return o.Type.Union([...e(u)],{...u})}s.Resolve=i})(Je||(o.UnionResolver=Je={}));var Ne=class extends D{};o.TemplateLiteralPatternError=Ne;var Se;(function(s){function e(l){throw new Ne(l)}function i(l){return l.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}function u(l,c){return a.TTemplateLiteral(l)?l.pattern.slice(1,l.pattern.length-1):a.TUnion(l)?`(${l.anyOf.map(T=>u(T,c)).join("|")})`:a.TNumber(l)?`${c}${o.PatternNumber}`:a.TInteger(l)?`${c}${o.PatternNumber}`:a.TBigInt(l)?`${c}${o.PatternNumber}`:a.TString(l)?`${c}${o.PatternString}`:a.TLiteral(l)?`${c}${i(l.const.toString())}`:a.TBoolean(l)?`${c}${o.PatternBoolean}`:e(`Unexpected Kind '${l[o.Kind]}'`)}function p(l){return`^${l.map(c=>u(c,"")).join("")}$`}s.Create=p})(Se||(o.TemplateLiteralPattern=Se={}));var k;(function(s){function e(i){let u=X.ParseExact(i.pattern);if(!Z.Check(u))return o.Type.String();let p=[...G.Generate(u)].map(l=>o.Type.Literal(l));return o.Type.Union(p)}s.Resolve=e})(k||(o.TemplateLiteralResolver=k={}));var ue=class extends D{};o.TemplateLiteralParserError=ue;var X;(function(s){function e(d,O,v){return d[O]===v&&d.charCodeAt(O-1)!==92}function i(d,O){return e(d,O,"(")}function u(d,O){return e(d,O,")")}function p(d,O){return e(d,O,"|")}function l(d){if(!(i(d,0)&&u(d,d.length-1)))return!1;let O=0;for(let v=0;v0&&N.push(m(A)),v=R+1}let j=d.slice(v);return j.length>0&&N.push(m(j)),N.length===0?{type:"const",const:""}:N.length===1?N[0]:{type:"or",expr:N}}function g(d){function O(j,R){if(!i(j,R))throw new ue("TemplateLiteralParser: Index must point to open parens");let A=0;for(let K=R;K0&&N.push(m(K)),j=A-1}return N.length===0?{type:"const",const:""}:N.length===1?N[0]:{type:"and",expr:N}}function m(d){return l(d)?m(c(d)):T(d)?b(d):y(d)?g(d):{type:"const",const:d}}s.Parse=m;function U(d){return m(d.slice(1,d.length-1))}s.ParseExact=U})(X||(o.TemplateLiteralParser=X={}));var Re=class extends D{};o.TemplateLiteralFiniteError=Re;var Z;(function(s){function e(c){throw new Re(c)}function i(c){return c.type==="or"&&c.expr.length===2&&c.expr[0].type==="const"&&c.expr[0].const==="0"&&c.expr[1].type==="const"&&c.expr[1].const==="[1-9][0-9]*"}function u(c){return c.type==="or"&&c.expr.length===2&&c.expr[0].type==="const"&&c.expr[0].const==="true"&&c.expr[1].type==="const"&&c.expr[1].const==="false"}function p(c){return c.type==="const"&&c.const===".*"}function l(c){return u(c)?!0:i(c)||p(c)?!1:c.type==="and"?c.expr.every(T=>l(T)):c.type==="or"?c.expr.every(T=>l(T)):c.type==="const"?!0:e("Unknown expression type")}s.Check=l})(Z||(o.TemplateLiteralFinite=Z={}));var xe=class extends D{};o.TemplateLiteralGeneratorError=xe;var G;(function(s){function*e(c){if(c.length===1)return yield*c[0];for(let T of c[0])for(let y of e(c.slice(1)))yield`${T}${y}`}function*i(c){return yield*e(c.expr.map(T=>[...l(T)]))}function*u(c){for(let T of c.expr)yield*l(T)}function*p(c){return yield c.const}function*l(c){return c.type==="and"?yield*i(c):c.type==="or"?yield*u(c):c.type==="const"?yield*p(c):(()=>{throw new xe("Unknown expression")})()}s.Generate=l})(G||(o.TemplateLiteralGenerator=G={}));var He;(function(s){function*e(l){let c=l.trim().replace(/"|'/g,"");return c==="boolean"?yield o.Type.Boolean():c==="number"?yield o.Type.Number():c==="bigint"?yield o.Type.BigInt():c==="string"?yield o.Type.String():yield(()=>{let T=c.split("|").map(y=>o.Type.Literal(y.trim()));return T.length===0?o.Type.Never():T.length===1?T[0]:o.Type.Union(T)})()}function*i(l){if(l[1]!=="{"){let c=o.Type.Literal("$"),T=u(l.slice(1));return yield*[c,...T]}for(let c=2;c{let l={Encode:c=>i[o.Transform].Encode(e(c)),Decode:c=>this.decode(i[o.Transform].Decode(c))};return{...i,[o.Transform]:l}})():(()=>{let u={Decode:this.decode,Encode:e};return{...i,[o.Transform]:u}})()}};o.TransformEncodeBuilder=we;var wn=0,Le=class extends D{};o.TypeBuilderError=Le;var Ae=class{Create(e){return e}Throw(e){throw new Le(e)}Discard(e,i){return i.reduce((u,p)=>{let{[p]:l,...c}=u;return c},e)}Strict(e){return JSON.parse(JSON.stringify(e))}};o.TypeBuilder=Ae;var le=class extends Ae{ReadonlyOptional(e){return this.Readonly(this.Optional(e))}Readonly(e){return{...P.Type(e),[o.Readonly]:"Readonly"}}Optional(e){return{...P.Type(e),[o.Optional]:"Optional"}}Any(e={}){return this.Create({...e,[o.Kind]:"Any"})}Array(e,i={}){return this.Create({...i,[o.Kind]:"Array",type:"array",items:P.Type(e)})}Boolean(e={}){return this.Create({...e,[o.Kind]:"Boolean",type:"boolean"})}Capitalize(e,i={}){return{...Y.Map(P.Type(e),"Capitalize"),...i}}Composite(e,i){let u=o.Type.Intersect(e,{}),l=Pe.ResolveKeys(u,{includePatterns:!1}).reduce((c,T)=>({...c,[T]:o.Type.Index(u,[T])}),{});return o.Type.Object(l,i)}Enum(e,i={}){if(I.IsUndefined(e))return this.Throw("Enum undefined or empty");let u=Object.getOwnPropertyNames(e).filter(c=>isNaN(c)).map(c=>e[c]),l=[...new Set(u)].map(c=>o.Type.Literal(c));return this.Union(l,{...i,[o.Hint]:"Enum"})}Extends(e,i,u,p,l={}){switch(J.Extends(e,i)){case f.Union:return this.Union([P.Type(u,l),P.Type(p,l)]);case f.True:return P.Type(u,l);case f.False:return P.Type(p,l)}}Exclude(e,i,u={}){return a.TTemplateLiteral(e)?this.Exclude(k.Resolve(e),i,u):a.TTemplateLiteral(i)?this.Exclude(e,k.Resolve(i),u):a.TUnion(e)?(()=>{let p=e.anyOf.filter(l=>J.Extends(l,i)===f.False);return p.length===1?P.Type(p[0],u):this.Union(p,u)})():J.Extends(e,i)!==f.False?this.Never(u):P.Type(e,u)}Extract(e,i,u={}){return a.TTemplateLiteral(e)?this.Extract(k.Resolve(e),i,u):a.TTemplateLiteral(i)?this.Extract(e,k.Resolve(i),u):a.TUnion(e)?(()=>{let p=e.anyOf.filter(l=>J.Extends(l,i)!==f.False);return p.length===1?P.Type(p[0],u):this.Union(p,u)})():J.Extends(e,i)!==f.False?P.Type(e,u):this.Never(u)}Index(e,i,u={}){return a.TArray(e)&&a.TNumber(i)?P.Type(e.items,u):a.TTuple(e)&&a.TNumber(i)?(()=>{let l=(I.IsUndefined(e.items)?[]:e.items).map(c=>P.Type(c));return this.Union(l,u)})():(()=>{let p=ae.Resolve(i),l=P.Type(e);return qe.Resolve(l,p,u)})()}Integer(e={}){return this.Create({...e,[o.Kind]:"Integer",type:"integer"})}Intersect(e,i={}){if(e.length===0)return o.Type.Never();if(e.length===1)return P.Type(e[0],i);e.some(c=>a.TTransform(c))&&this.Throw("Cannot intersect transform types");let u=e.every(c=>a.TObject(c)),p=P.Rest(e),l=a.TSchema(i.unevaluatedProperties)?{unevaluatedProperties:P.Type(i.unevaluatedProperties)}:{};return i.unevaluatedProperties===!1||a.TSchema(i.unevaluatedProperties)||u?this.Create({...i,...l,[o.Kind]:"Intersect",type:"object",allOf:p}):this.Create({...i,...l,[o.Kind]:"Intersect",allOf:p})}KeyOf(e,i={}){return a.TRecord(e)?(()=>{let u=Object.getOwnPropertyNames(e.patternProperties)[0];return u===o.PatternNumberExact?this.Number(i):u===o.PatternStringExact?this.String(i):this.Throw("Unable to resolve key type from Record key pattern")})():a.TTuple(e)?(()=>{let p=(I.IsUndefined(e.items)?[]:e.items).map((l,c)=>o.Type.Literal(c.toString()));return this.Union(p,i)})():a.TArray(e)?this.Number(i):(()=>{let u=Pe.ResolveKeys(e,{includePatterns:!1});if(u.length===0)return this.Never(i);let p=u.map(l=>this.Literal(l));return this.Union(p,i)})()}Literal(e,i={}){return this.Create({...i,[o.Kind]:"Literal",const:e,type:typeof e})}Lowercase(e,i={}){return{...Y.Map(P.Type(e),"Lowercase"),...i}}Never(e={}){return this.Create({...e,[o.Kind]:"Never",not:{}})}Not(e,i){return this.Create({...i,[o.Kind]:"Not",not:P.Type(e)})}Null(e={}){return this.Create({...e,[o.Kind]:"Null",type:"null"})}Number(e={}){return this.Create({...e,[o.Kind]:"Number",type:"number"})}Object(e,i={}){let u=Object.getOwnPropertyNames(e),p=u.filter(y=>a.TOptional(e[y])),l=u.filter(y=>!p.includes(y)),c=a.TSchema(i.additionalProperties)?{additionalProperties:P.Type(i.additionalProperties)}:{},T=u.reduce((y,b)=>({...y,[b]:P.Type(e[b])}),{});return l.length>0?this.Create({...i,...c,[o.Kind]:"Object",type:"object",properties:T,required:l}):this.Create({...i,...c,[o.Kind]:"Object",type:"object",properties:T})}Omit(e,i,u={}){let p=ae.Resolve(i);return Q.Map(this.Discard(P.Type(e),["$id",o.Transform]),l=>{I.IsArray(l.required)&&(l.required=l.required.filter(c=>!p.includes(c)),l.required.length===0&&delete l.required);for(let c of Object.getOwnPropertyNames(l.properties))p.includes(c)&&delete l.properties[c];return this.Create(l)},u)}Partial(e,i={}){return Q.Map(this.Discard(P.Type(e),["$id",o.Transform]),u=>{let p=Object.getOwnPropertyNames(u.properties).reduce((l,c)=>({...l,[c]:this.Optional(u.properties[c])}),{});return this.Object(p,this.Discard(u,["required"]))},i)}Pick(e,i,u={}){let p=ae.Resolve(i);return Q.Map(this.Discard(P.Type(e),["$id",o.Transform]),l=>{I.IsArray(l.required)&&(l.required=l.required.filter(c=>p.includes(c)),l.required.length===0&&delete l.required);for(let c of Object.getOwnPropertyNames(l.properties))p.includes(c)||delete l.properties[c];return this.Create(l)},u)}Record(e,i,u={}){return a.TTemplateLiteral(e)?(()=>{let p=X.ParseExact(e.pattern);return Z.Check(p)?this.Object([...G.Generate(p)].reduce((l,c)=>({...l,[c]:P.Type(i)}),{}),u):this.Create({...u,[o.Kind]:"Record",type:"object",patternProperties:{[e.pattern]:P.Type(i)}})})():a.TUnion(e)?(()=>{let p=Je.Resolve(e);if(a.TUnionLiteral(p)){let l=p.anyOf.reduce((c,T)=>({...c,[T.const]:P.Type(i)}),{});return this.Object(l,{...u,[o.Hint]:"Record"})}else this.Throw("Record key of type union contains non-literal types")})():a.TLiteral(e)?I.IsString(e.const)||I.IsNumber(e.const)?this.Object({[e.const]:P.Type(i)},u):this.Throw("Record key of type literal is not of type string or number"):a.TInteger(e)||a.TNumber(e)?this.Create({...u,[o.Kind]:"Record",type:"object",patternProperties:{[o.PatternNumberExact]:P.Type(i)}}):a.TString(e)?(()=>{let p=I.IsUndefined(e.pattern)?o.PatternStringExact:e.pattern;return this.Create({...u,[o.Kind]:"Record",type:"object",patternProperties:{[p]:P.Type(i)}})})():this.Never()}Recursive(e,i={}){I.IsUndefined(i.$id)&&(i.$id=`T${wn++}`);let u=e({[o.Kind]:"This",$ref:`${i.$id}`});return u.$id=i.$id,this.Create({...i,[o.Hint]:"Recursive",...u})}Ref(e,i={}){return I.IsString(e)?this.Create({...i,[o.Kind]:"Ref",$ref:e}):(I.IsUndefined(e.$id)&&this.Throw("Reference target type must specify an $id"),this.Create({...i,[o.Kind]:"Ref",$ref:e.$id}))}Required(e,i={}){return Q.Map(this.Discard(P.Type(e),["$id",o.Transform]),u=>{let p=Object.getOwnPropertyNames(u.properties).reduce((l,c)=>({...l,[c]:this.Discard(u.properties[c],[o.Optional])}),{});return this.Object(p,u)},i)}Rest(e){return a.TTuple(e)&&!I.IsUndefined(e.items)?P.Rest(e.items):a.TIntersect(e)?P.Rest(e.allOf):a.TUnion(e)?P.Rest(e.anyOf):[]}String(e={}){return this.Create({...e,[o.Kind]:"String",type:"string"})}TemplateLiteral(e,i={}){let u=I.IsString(e)?Se.Create(He.Parse(e)):Se.Create(e);return this.Create({...i,[o.Kind]:"TemplateLiteral",type:"string",pattern:u})}Transform(e){return new je(e)}Tuple(e,i={}){let[u,p,l]=[!1,e.length,e.length],c=P.Rest(e),T=e.length>0?{...i,[o.Kind]:"Tuple",type:"array",items:c,additionalItems:u,minItems:p,maxItems:l}:{...i,[o.Kind]:"Tuple",type:"array",minItems:p,maxItems:l};return this.Create(T)}Uncapitalize(e,i={}){return{...Y.Map(P.Type(e),"Uncapitalize"),...i}}Union(e,i={}){return a.TTemplateLiteral(e)?k.Resolve(e):(()=>{let u=e;if(u.length===0)return this.Never(i);if(u.length===1)return this.Create(P.Type(u[0],i));let p=P.Rest(u);return this.Create({...i,[o.Kind]:"Union",anyOf:p})})()}Unknown(e={}){return this.Create({...e,[o.Kind]:"Unknown"})}Unsafe(e={}){return this.Create({...e,[o.Kind]:e[o.Kind]||"Unsafe"})}Uppercase(e,i={}){return{...Y.Map(P.Type(e),"Uppercase"),...i}}};o.JsonTypeBuilder=le;var Fe=class extends le{AsyncIterator(e,i={}){return this.Create({...i,[o.Kind]:"AsyncIterator",type:"AsyncIterator",items:P.Type(e)})}Awaited(e,i={}){let u=p=>p.length>0?(()=>{let[l,...c]=p;return[this.Awaited(l),...u(c)]})():p;return a.TIntersect(e)?o.Type.Intersect(u(e.allOf)):a.TUnion(e)?o.Type.Union(u(e.anyOf)):a.TPromise(e)?this.Awaited(e.item):P.Type(e,i)}BigInt(e={}){return this.Create({...e,[o.Kind]:"BigInt",type:"bigint"})}ConstructorParameters(e,i={}){return this.Tuple([...e.parameters],{...i})}Constructor(e,i,u){let[p,l]=[P.Rest(e),P.Type(i)];return this.Create({...u,[o.Kind]:"Constructor",type:"Constructor",parameters:p,returns:l})}Date(e={}){return this.Create({...e,[o.Kind]:"Date",type:"Date"})}Function(e,i,u){let[p,l]=[P.Rest(e),P.Type(i)];return this.Create({...u,[o.Kind]:"Function",type:"Function",parameters:p,returns:l})}InstanceType(e,i={}){return P.Type(e.returns,i)}Iterator(e,i={}){return this.Create({...i,[o.Kind]:"Iterator",type:"Iterator",items:P.Type(e)})}Parameters(e,i={}){return this.Tuple(e.parameters,{...i})}Promise(e,i={}){return this.Create({...i,[o.Kind]:"Promise",type:"Promise",item:P.Type(e)})}RegExp(e,i={}){let u=I.IsString(e)?e:e.source;return this.Create({...i,[o.Kind]:"String",type:"string",pattern:u})}RegEx(e,i={}){return this.RegExp(e,i)}ReturnType(e,i={}){return P.Type(e.returns,i)}Symbol(e){return this.Create({...e,[o.Kind]:"Symbol",type:"symbol"})}Undefined(e={}){return this.Create({...e,[o.Kind]:"Undefined",type:"undefined"})}Uint8Array(e={}){return this.Create({...e,[o.Kind]:"Uint8Array",type:"Uint8Array"})}Void(e={}){return this.Create({...e,[o.Kind]:"Void",type:"void"})}};o.JavaScriptTypeBuilder=Fe;o.JsonType=new le;o.Type=new Fe});var ce=jn(he(),1),en=ce.Type.String({pattern:".*\\{languageTag|locale\\}.*\\.json$",examples:["./messages/{locale}.json","./i18n/{locale}.json"],title:"Path to language files",description:"Specify the pathPattern to locate resource files in your repository. It must include `{locale}` and end with `.json`."}),Ln=ce.Type.Array(en,{title:"Paths to language files",description:"Specify multiple pathPatterns to locate resource files in your repository. Each must include `{locale}` and end with `.json`."}),Ce=ce.Type.Object({pathPattern:ce.Type.Union([en,Ln])});var nn=s=>s.map(e=>{switch(e.type){case"Text":return e.value;case"VariableReference":return`{${e.name}}`}}).join("");var tn=s=>{let e={};for(let i of s.variants){if(e[i.languageTag]!==void 0)throw new Error(`The message "${s.id}" has multiple variants for the language tag "${i.languageTag}". The inlang-message-format plugin does not support multiple variants for the same language tag at the moment.`);e[i.languageTag]=nn(i.pattern)}return e};var rn=s=>{let e=/\{([^}]+)\}/g,i,u=0,p=[];for(;(i=e.exec(s))!==null;){let c=i[1],T=s.slice(u,i.index);T.length>0&&p.push({type:"Text",value:T}),p.push({type:"VariableReference",name:c}),u=i.index+i[0].length}let l=s.slice(Math.max(0,u));return l.length>0&&p.push({type:"Text",value:l}),p};var _e=s=>({id:s.key,alias:{},selectors:[],variants:[{languageTag:s.languageTag,match:[],pattern:rn(s.value)}]});var An="plugin.inlang.messageFormat",H={id:An,displayName:"Inlang Message Format",description:"A plugin for the inlang SDK that uses a JSON file per language tag to store translations.",key:"inlang-message-format",settingsSchema:Ce,loadMessages:async({settings:s,nodeishFs:e})=>{await $n({settings:s,nodeishFs:e});let i={};for(let u of s.languageTags)try{let p=await e.readFile(s["plugin.inlang.messageFormat"].pathPattern.replace("{languageTag}",u),{encoding:"utf-8"}),l=JSON.parse(p);for(let c in l)c!=="$schema"&&(i[c]?i[c].variants=[...i[c].variants,..._e({key:c,value:l[c],languageTag:u}).variants]:i[c]=_e({key:c,value:l[c],languageTag:u}))}catch(p){if(p?.code!=="ENOENT")throw p}return Object.values(i)},saveMessages:async({settings:s,nodeishFs:e,messages:i})=>{let u={};for(let p of i){let l=tn(p);for(let[c,T]of Object.entries(l))u[c]===void 0&&(u[c]={}),u[c][p.id]=T}for(let[p,l]of Object.entries(u)){let c=s["plugin.inlang.messageFormat"].pathPattern.replace("{languageTag}",p);await Fn({path:c,nodeishFs:e}),await e.writeFile(s["plugin.inlang.messageFormat"].pathPattern.replace("{languageTag}",p),(T=>JSON.stringify(T,void 0," "))({$schema:"https://inlang.com/schema/inlang-message-format",...l}))}}},Fn=async s=>{try{await s.nodeishFs.mkdir(Cn(s.path),{recursive:!0})}catch{}};function Cn(s){if(s.length===0)return".";let e=s.charCodeAt(0),i=e===47,u=-1,p=!0;for(let l=s.length-1;l>=1;--l)if(e=s.charCodeAt(l),e===47){if(!p){u=l;break}}else p=!1;return u===-1?i?"/":".":i&&u===1?"//":s.slice(0,u)}var $n=async s=>{if(s.settings["plugin.inlang.messageFormat"].filePath!=null)try{let e=await s.nodeishFs.readFile(s.settings["plugin.inlang.messageFormat"].filePath,{encoding:"utf-8"});await H.saveMessages?.({messages:JSON.parse(e).data,nodeishFs:s.nodeishFs,settings:s.settings}),console.log("Migration to v2 of the inlang-message-format plugin was successful. Please delete the old messages.json file and the filePath property in the settings file of the project.")}catch{}};var on=async({settings:s})=>{let e=[],i=s[h]?.pathPattern?Array.isArray(s[h].pathPattern)?s[h].pathPattern:[s[h].pathPattern]:[];for(let u of i)for(let p of s.locales)e.push({locale:p,path:u.replace(/{(locale|languageTag)}/,p)});return e};function sn(s){return s&&s.constructor&&typeof s.constructor.isBuffer=="function"&&s.constructor.isBuffer(s)}function an(s){return s}function We(s,e){e=e||{};let i=e.delimiter||".",u=e.maxDepth,p=e.transformKey||an,l={};function c(T,y,b){b=b||1,Object.keys(T).forEach(function(g){let m=T[g],U=e.safe&&Array.isArray(m),d=Object.prototype.toString.call(m),O=sn(m),v=d==="[object Object]"||d==="[object Array]",N=y?y+i+p(g):p(g);if(!U&&!O&&v&&Object.keys(m).length&&(!e.maxDepth||b0&&(U=T(m.shift()),d=T(m[0]))}O[U]=Ye(s[g],e)}),l}var ln=async({files:s})=>{let e=[],i=[],u=[];for(let p of s){let l=JSON.parse(new TextDecoder().decode(p.content)),c=We(l,{safe:!0});for(let T in c){if(T==="$schema")continue;let y=Kn(T,p.locale,c[T]);i.push(y.message),u.push(...y.variants);let b=e.find(g=>g.id===y.bundle.id);b===void 0?e.push(y.bundle):b.declarations=$e([...b.declarations,...y.bundle.declarations])}}return{bundles:e,messages:i,variants:u}};function Kn(s,e,i){let u=En(s,e,i),p=$e(u.declarations),l=$e(u.selectors),c=l.filter(T=>p.find(y=>y.name===T.name)===void 0);for(let T of c)p.push({type:"input-variable",name:T.name});return{bundle:{id:s,declarations:p},message:{bundleId:s,selectors:l,locale:e},variants:u.variants}}function En(s,e,i){if(typeof i=="string"){let y=un(i);return{variants:[{messageBundleId:s,messageLocale:e,matches:[],pattern:y.pattern}],declarations:y.declarations,selectors:[]}}let u=i[0],p=[],l=(u.selectors??[]).map(y=>({type:"variable-reference",name:y})),c=new Set;for(let y of u.declarations??[])c.add(Mn(y));let T=new Set;for(let[y,b]of Object.entries(u.match)){let g=un(b),m=Bn(y);for(let U of g.declarations){let d=!1;for(let O of c)if(O.name===U.name){d=!0;break}if(d)break;c.add(U)}for(let U of m.selectors)T.add(U);p.push({messageBundleId:s,messageLocale:e,matches:m.matches,pattern:g.pattern})}return{variants:p,declarations:Array.from(c),selectors:$e([...l,...Array.from(T)])}}function un(s){let e=[],i=[],u=s.split(/(\{.*?\})/).filter(p=>p!=="");for(let p of u)if((p.startsWith("{")&&p.endsWith("}"))===!1)e.push({type:"text",value:p});else{let l=p.slice(1,-1);i.push({type:"input-variable",name:l}),e.push({type:"expression",arg:{type:"variable-reference",name:l}})}return{declarations:i,pattern:e}}function Bn(s){let e=s.replace(" ",""),i=[],u=[],p=e.split(",");for(let l of p){let[c,T]=l.split("=");!c||!T||(T==="*"?i.push({type:"catchall-match",key:c}):i.push({type:"literal-match",key:c,value:T}),u.push({type:"variable-reference",name:c}))}return{matches:i,selectors:u}}var $e=s=>[...new Set(s.map(e=>JSON.stringify(e)))].map(e=>JSON.parse(e));function Mn(s){if(s.startsWith("input"))return{type:"input-variable",name:s.slice(6).trim()};if(s.startsWith("local")){let e=s.match(/local (\w+) = (\w+): (\w+)(.*)/),[,i,u,p,l]=e,c=l?.trim().split(/\s+/).map(T=>{let[y,b]=T.split("=");return y&&b?{name:y,value:{type:"literal",value:b}}:null}).filter(Boolean);return{type:"local-variable",name:i.trim(),value:{type:"expression",arg:{type:"variable-reference",name:u.trim()},annotation:p?{type:"function-reference",name:p.trim(),options:c??[]}:void 0}}}throw new Error("Unsupported declaration type")}var pn=async({bundles:s,messages:e,variants:i})=>{let u={};for(let l of e){let c=s.find(y=>y.id===l.bundleId),T=[...i.reduce((y,b)=>(b.messageId===l.id&&y.set(JSON.stringify(b.matches),b),y),new Map).values()];u[l.locale]={...u[l.locale],...Dn(c,l,T)}}let p=[];for(let l in u)p.push({locale:l,content:new TextEncoder().encode(JSON.stringify(Ye({$schema:"https://inlang.com/schema/inlang-message-format",...u[l]}),void 0," ")),name:l+".json"});return p};function Dn(s,e,i){let u=e.bundleId,p=kn(s,e,i);return{[u]:p}}function kn(s,e,i){if(i.length===1&&e.selectors.length===0&&s.declarations.some(p=>p.type!=="input-variable")===!1)return cn(i[0].pattern);let u=[];for(let p of i){if(p.matches.length===0)for(let T of p.pattern)T.type==="expression"&&T.arg.type==="variable-reference"&&p.matches.push({key:T.arg.name,type:"catchall-match"});let l=cn(p.pattern),c=Vn(p.matches);u.push([c,l])}return[{declarations:s.declarations.sort((p,l)=>p.name.localeCompare(l.name)).map(zn).sort(),selectors:e.selectors.map(p=>p.name).sort(),match:Object.fromEntries(u)}]}function cn(s){let e="";for(let i of s)if(i.type==="text")e+=i.value;else if(i.arg.type==="variable-reference")e+=`{${i.arg.name}}`;else throw new Error("Unsupported expression type");return e}function Vn(s){return s.sort((i,u)=>i.key.localeCompare(u.key)).map(i=>i.type==="literal-match"?`${i.key}=${i.value}`:`${i.key}=*`).join(", ")}function zn(s){if(s.type==="input-variable")return`input ${s.name}`;if(s.type==="local-variable"){let e="";if(s.value.arg.type==="variable-reference"?e=`local ${s.name} = ${s.value.arg.name}`:s.value.arg.type==="literal"&&(e=`local ${s.name} = "${s.value.arg.value}"`),s.value.annotation&&(e+=`: ${s.value.annotation.name}`),s.value.annotation?.options)for(let i of s.value?.annotation?.options??[]){if(i.value.type!=="literal")throw new Error("Unsupported option type");e+=` ${i.name}=${i.value.value}`}return e}throw new Error("Unsupported declaration type")}var h="plugin.inlang.messageFormat",Tn={key:h,id:H.id,displayName:H.displayName,description:H.description,loadMessages:H.loadMessages,saveMessages:H.saveMessages,settingsSchema:Ce,toBeImportedFiles:on,importFiles:ln,exportFiles:pn};var It=Tn;export{It as default}; diff --git a/infrastructure/control-panel/project.inlang/cache/plugins/ygx0uiahq6uw b/infrastructure/control-panel/project.inlang/cache/plugins/ygx0uiahq6uw new file mode 100644 index 00000000..8ce3dc57 --- /dev/null +++ b/infrastructure/control-panel/project.inlang/cache/plugins/ygx0uiahq6uw @@ -0,0 +1,16 @@ +var Vt=Object.create;var It=Object.defineProperty;var Ht=Object.getOwnPropertyDescriptor;var Xt=Object.getOwnPropertyNames;var Yt=Object.getPrototypeOf,tn=Object.prototype.hasOwnProperty;var nn=(l,c)=>()=>(c||l((c={exports:{}}).exports,c),c.exports);var rn=(l,c,p,u)=>{if(c&&typeof c=="object"||typeof c=="function")for(let f of Xt(c))!tn.call(l,f)&&f!==p&&It(l,f,{get:()=>c[f],enumerable:!(u=Ht(c,f))||u.enumerable});return l};var en=(l,c,p)=>(p=l!=null?Vt(Yt(l)):{},rn(c||!l||!l.__esModule?It(p,"default",{value:l,enumerable:!0}):p,l));var Lt=nn((J,gt)=>{(function(l,c){typeof J=="object"&&typeof gt=="object"?gt.exports=c():typeof define=="function"&&define.amd?define([],c):typeof J=="object"?J.Parsimmon=c():l.Parsimmon=c()})(typeof self<"u"?self:J,function(){return function(l){var c={};function p(u){if(c[u])return c[u].exports;var f=c[u]={i:u,l:!1,exports:{}};return l[u].call(f.exports,f,f.exports,p),f.l=!0,f.exports}return p.m=l,p.c=c,p.d=function(u,f,Z){p.o(u,f)||Object.defineProperty(u,f,{configurable:!1,enumerable:!0,get:Z})},p.r=function(u){Object.defineProperty(u,"__esModule",{value:!0})},p.n=function(u){var f=u&&u.__esModule?function(){return u.default}:function(){return u};return p.d(f,"a",f),f},p.o=function(u,f){return Object.prototype.hasOwnProperty.call(u,f)},p.p="",p(p.s=0)}([function(l,c,p){"use strict";function u(t){if(!(this instanceof u))return new u(t);this._=t}var f=u.prototype;function Z(t,n){for(var r=0;r>7),buf:function(o){var i=I(function(a,s,d,y){return a.concat(d===y.length-1?Buffer.from([s,0]).readUInt16BE(0):y.readUInt16BE(d))},[],o);return Buffer.from(j(function(a){return(a<<1&65535)>>8},i))}(r.buf)}}),r}function dt(){return typeof Buffer<"u"}function C(){if(!dt())throw new Error("Buffer global does not exist; please use webpack if you need to parse Buffers in the browser.")}function ht(t){C();var n=I(function(i,a){return i+a},0,t);if(n%8!=0)throw new Error("The bits ["+t.join(", ")+"] add up to "+n+" which is not an even number of bytes; the total should be divisible by 8");var r,e=n/8,o=(r=function(i){return i>48},I(function(i,a){return i||(r(a)?a:i)},null,t));if(o)throw new Error(o+" bit range requested exceeds 48 bit (6 byte) Number max.");return new u(function(i,a){var s=e+a;return s>i.length?b(a,e.toString()+" bytes"):h(s,I(function(d,y){var v=At(y,d.buf);return{coll:d.coll.concat(v.v),buf:v.buf}},{coll:[],buf:i.slice(a,s)},t).coll)})}function E(t,n){return new u(function(r,e){return C(),e+n>r.length?b(e,n+" bytes for "+t):h(e+n,r.slice(e,e+n))})}function K(t,n){if(typeof(r=n)!="number"||Math.floor(r)!==r||n<0||n>6)throw new Error(t+" requires integer length in range [0, 6].");var r}function V(t){return K("uintBE",t),E("uintBE("+t+")",t).map(function(n){return n.readUIntBE(0,t)})}function H(t){return K("uintLE",t),E("uintLE("+t+")",t).map(function(n){return n.readUIntLE(0,t)})}function X(t){return K("intBE",t),E("intBE("+t+")",t).map(function(n){return n.readIntBE(0,t)})}function Y(t){return K("intLE",t),E("intLE("+t+")",t).map(function(n){return n.readIntLE(0,t)})}function U(t){return t instanceof u}function q(t){return{}.toString.call(t)==="[object Array]"}function W(t){return dt()&&Buffer.isBuffer(t)}function h(t,n){return{status:!0,index:t,value:n,furthest:-1,expected:[]}}function b(t,n){return q(n)||(n=[n]),{status:!1,index:-1,value:null,furthest:t,expected:n}}function w(t,n){if(!n||t.furthest>n.furthest)return t;var r=t.furthest===n.furthest?function(e,o){if(function(){if(u._supportsSet!==void 0)return u._supportsSet;var S=typeof Set<"u";return u._supportsSet=S,S}()&&Array.from){for(var i=new Set(e),a=0;a=0;){if(a in r){e=r[a].line,i===0&&(i=r[a].lineStart);break}(t.charAt(a)===` +`||t.charAt(a)==="\r"&&t.charAt(a+1)!==` +`)&&(o++,i===0&&(i=a+1)),a--}var s=e+o,d=n-i;return r[n]={line:s,lineStart:i},{offset:n,line:s+1,column:d+1}}function A(t){if(!U(t))throw new Error("not a parser: "+t)}function nt(t,n){return typeof t=="string"?t.charAt(n):t[n]}function F(t){if(typeof t!="number")throw new Error("not a number: "+t)}function L(t){if(typeof t!="function")throw new Error("not a function: "+t)}function T(t){if(typeof t!="string")throw new Error("not a string: "+t)}var Ft=2,Nt=3,O=8,Rt=5*O,zt=4*O,vt=" ";function rt(t,n){return new Array(n+1).join(t)}function et(t,n,r){var e=n-t.length;return e<=0?t:rt(r,e)+t}function yt(t,n,r,e){return{from:t-n>0?t-n:0,to:t+r>e?e:t+r}}function Dt(t,n){var r,e,o,i,a,s=n.index,d=s.offset,y=1;if(d===t.length)return"Got the end of the input";if(W(t)){var v=d-d%O,_=d-v,x=yt(v,Rt,zt+O,t.length),S=j(function(m){return j(function(R){return et(R.toString(16),2,"0")},m)},function(m,R){var z=m.length,M=[],D=0;if(z<=R)return[m.slice()];for(var Q=0;Q=4&&(r+=1),y=2,o=j(function(m){return m.length<=4?m.join(" "):m.slice(0,4).join(" ")+" "+m.slice(4).join(" ")},S),(a=(8*(i.to>0?i.to-1:i.to)).toString(16).length)<2&&(a=2)}else{var N=t.split(/\r\n|[\n\r\u2028\u2029]/);r=s.column-1,e=s.line-1,i=yt(e,Ft,Nt,N.length),o=N.slice(i.from,i.to),a=i.to.toString().length}var Kt=e-i.from;return W(t)&&(a=(8*(i.to>0?i.to-1:i.to)).toString(16).length)<2&&(a=2),I(function(m,R,z){var M,D=z===Kt,Q=D?"> ":vt;return M=W(t)?et((8*(i.from+z)).toString(16),a,"0"):et((i.from+z+1).toString(),a," "),[].concat(m,[Q+M+" | "+R],D?[vt+rt(" ",a)+" | "+et("",r," ")+rt("^",y)]:[])},[],o).join(` +`)}function bt(t,n){return[` +`,"-- PARSING FAILED "+rt("-",50),` + +`,Dt(t,n),` + +`,(r=n.expected,r.length===1?`Expected: + +`+r[0]:`Expected one of the following: + +`+r.join(", ")),` +`].join("");var r}function xt(t){return t.flags!==void 0?t.flags:[t.global?"g":"",t.ignoreCase?"i":"",t.multiline?"m":"",t.unicode?"u":"",t.sticky?"y":""].join("")}function ut(){for(var t=[].slice.call(arguments),n=t.length,r=0;r=2?F(n):n=0;var r=function(o){return RegExp("^(?:"+o.source+")",xt(o))}(t),e=""+t;return u(function(o,i){var a=r.exec(o.slice(i));if(a){if(0<=n&&n<=a.length){var s=a[0],d=a[n];return h(i+s.length,d)}return b(i,"valid match group (0 to "+a.length+") in "+e)}return b(i,e)})}function P(t){return u(function(n,r){return h(r,t)})}function it(t){return u(function(n,r){return b(r,t)})}function at(t){if(U(t))return u(function(n,r){var e=t._(n,r);return e.index=r,e.value="",e});if(typeof t=="string")return at($(t));if(t instanceof RegExp)return at(B(t));throw new Error("not a string, regexp, or parser: "+t)}function Et(t){return A(t),u(function(n,r){var e=t._(n,r),o=n.slice(r,e.index);return e.status?b(r,'not "'+o+'"'):h(r,null)})}function ft(t){return L(t),u(function(n,r){var e=nt(n,r);return r=t.length?b(n,"any character/byte"):h(n+1,nt(t,n))}),Ut=u(function(t,n){return h(t.length,t.slice(n))}),pt=u(function(t,n){return n=0}).desc(n)},u.optWhitespace=Jt,u.Parser=u,u.range=function(t,n){return ft(function(r){return t<=r&&r<=n}).desc(t+"-"+n)},u.regex=B,u.regexp=B,u.sepBy=wt,u.sepBy1=st,u.seq=ut,u.seqMap=k,u.seqObj=function(){for(var t,n={},r=0,e=(t=arguments,Array.prototype.slice.call(t)),o=e.length,i=0;i255)throw new Error("Value specified to byte constructor ("+t+"=0x"+t.toString(16)+") is larger in value than a single byte.");var n=(t>15?"0x":"0x0")+t.toString(16);return u(function(r,e){var o=nt(r,e);return o===t?h(e+1,o):b(e,n)})},buffer:function(t){return E("buffer",t).map(function(n){return Buffer.from(n)})},encodedString:function(t,n){return E("string",n).map(function(r){return r.toString(t)})},uintBE:V,uint8BE:V(1),uint16BE:V(2),uint32BE:V(4),uintLE:H,uint8LE:H(1),uint16LE:H(2),uint32LE:H(4),intBE:X,int8BE:X(1),int16BE:X(2),int32BE:X(4),intLE:Y,int8LE:Y(1),int16LE:Y(2),int32LE:Y(4),floatBE:E("floatBE",4).map(function(t){return t.readFloatBE(0)}),floatLE:E("floatLE",4).map(function(t){return t.readFloatLE(0)}),doubleBE:E("doubleBE",8).map(function(t){return t.readDoubleBE(0)}),doubleLE:E("doubleLE",8).map(function(t){return t.readDoubleLE(0)})},l.exports=u}])})});var g=en(Lt(),1),un=()=>g.default.createLanguage({entry:l=>g.default.alt(l.findReference,g.default.any).many().map(c=>c.flatMap(p=>p)).map(c=>c.filter(p=>typeof p=="object").flat().filter(p=>p!==null)),findReference:function(l){return g.default.seq(g.default.regex(/(import \* as m)|(import { m })/),l.findMessage.many())},dotNotation:()=>g.default.seqMap(g.default.string("."),g.default.index,g.default.regex(/\w+/),g.default.index,(l,c,p,u)=>({messageId:p,start:c,end:u})),doubleQuote:()=>g.default.seqMap(g.default.string('"'),g.default.index,g.default.regex(/[\w.]+/),g.default.string('"'),(l,c,p)=>({messageId:p,start:c})),singleQuote:()=>g.default.seqMap(g.default.string("'"),g.default.index,g.default.regex(/[\w.]+/),g.default.string("'"),(l,c,p)=>({messageId:p,start:c})),bracketNotation:l=>g.default.seqMap(g.default.string("["),g.default.alt(l.doubleQuote,l.singleQuote),g.default.string("]"),g.default.index,(c,p,u,f)=>({messageId:p.messageId,start:p.start,end:f})),findMessage:l=>g.default.seqMap(g.default.regex(/.*?(?p===null?null:{messageId:`${p.messageId}`,position:{start:{line:p.start.line,character:p.start.column},end:{line:p.end.line,character:p.end.column+u.length}}})});function kt(l){try{return un().entry.tryParse(l)}catch{return[]}}function ct(l){let c=l.trim().replace(/[^a-zA-Z0-9\s_.]/g,"").replace(/[\s.]+/g,"_");return/^[0-9]/.test(c)&&(c="_"+c),c}var Pt={messageReferenceMatchers:[async l=>kt(l.documentText)],extractMessageOptions:[{callback:l=>{let c=ct(l.bundleId);return{bundleId:c,messageReplacement:`{m.${c}()}`}}},{callback:l=>{let c=ct(l.bundleId);return{bundleId:c,messageReplacement:`m.${c}()`}}}],documentSelectors:[{language:"typescriptreact"},{language:"javascript"},{language:"typescript"},{language:"svelte"},{language:"astro"},{language:"vue"}]};var Mt="plugin.inlang.mFunctionMatcher",qt={id:Mt,displayName:"Inlang M Function Matcher",description:"A plugin for the inlang SDK that uses a JSON file per language tag to store translations.",key:Mt,meta:{"app.inlang.ideExtension":Pt}};var yn=qt;export{yn as default}; diff --git a/infrastructure/control-panel/project.inlang/project_id b/infrastructure/control-panel/project.inlang/project_id new file mode 100644 index 00000000..4532ca65 --- /dev/null +++ b/infrastructure/control-panel/project.inlang/project_id @@ -0,0 +1 @@ +5BFJFCnZ9odC1qA9BH \ No newline at end of file diff --git a/infrastructure/control-panel/project.inlang/settings.json b/infrastructure/control-panel/project.inlang/settings.json new file mode 100644 index 00000000..adce4023 --- /dev/null +++ b/infrastructure/control-panel/project.inlang/settings.json @@ -0,0 +1,12 @@ +{ + "$schema": "https://inlang.com/schema/project-settings", + "modules": [ + "https://cdn.jsdelivr.net/npm/@inlang/plugin-message-format@4/dist/index.js", + "https://cdn.jsdelivr.net/npm/@inlang/plugin-m-function-matcher@2/dist/index.js" + ], + "plugin.inlang.messageFormat": { + "pathPattern": "./messages/{locale}.json" + }, + "baseLocale": "en", + "locales": ["en", "es"] +} diff --git a/infrastructure/control-panel/src/app.css b/infrastructure/control-panel/src/app.css new file mode 100644 index 00000000..439455e7 --- /dev/null +++ b/infrastructure/control-panel/src/app.css @@ -0,0 +1,36 @@ +@import 'tailwindcss'; + + +@theme { + /* Custom theme */ + --color-primary: #8e52ff; + --color-primary-100: #e8dcff; + --color-primary-200: #d2baff; + --color-primary-300: #bb97ff; + --color-primary-400: #a575ff; + --color-primary-500: #8e52ff; + + --color-secondary: #73efd5; + --color-secondary-100: #e3fcf7; + --color-secondary-200: #c7f9ee; + --color-secondary-300: #abf6e6; + --color-secondary-400: #8ff2dd; + --color-secondary-500: #73efd5; + + --color-white: #ffffff; + --color-gray: #f5f5f5; + + --color-black: #1f1f1f; + --color-black-100: #d2d2d2; + --color-black-300: #a5a5a5; + --color-black-500: #797979; + --color-black-700: #4c4c4c; + --color-black-900: #1f1f1f; + + --color-danger: #ff5255; + --color-danger-100: #ffdcdd; + --color-danger-200: #ffb1a7; + --color-danger-300: #ff968e; + --color-danger-400: #ff7b77; + --color-danger-500: #ff5255; +} \ No newline at end of file diff --git a/infrastructure/control-panel/src/app.d.ts b/infrastructure/control-panel/src/app.d.ts new file mode 100644 index 00000000..da08e6da --- /dev/null +++ b/infrastructure/control-panel/src/app.d.ts @@ -0,0 +1,13 @@ +// See https://svelte.dev/docs/kit/types#app.d.ts +// for information about these interfaces +declare global { + namespace App { + // interface Error {} + // interface Locals {} + // interface PageData {} + // interface PageState {} + // interface Platform {} + } +} + +export {}; diff --git a/infrastructure/control-panel/src/app.html b/infrastructure/control-panel/src/app.html new file mode 100644 index 00000000..f08d5fac --- /dev/null +++ b/infrastructure/control-panel/src/app.html @@ -0,0 +1,12 @@ + + + + + + + %sveltekit.head% + + +
%sveltekit.body%
+ + diff --git a/infrastructure/control-panel/src/hooks.server.ts b/infrastructure/control-panel/src/hooks.server.ts new file mode 100644 index 00000000..ad77efcf --- /dev/null +++ b/infrastructure/control-panel/src/hooks.server.ts @@ -0,0 +1,13 @@ +import type { Handle } from '@sveltejs/kit'; +import { paraglideMiddleware } from '$lib/paraglide/server'; + +const handleParaglide: Handle = ({ event, resolve }) => + paraglideMiddleware(event.request, ({ request, locale }) => { + event.request = request; + + return resolve(event, { + transformPageChunk: ({ html }) => html.replace('%paraglide.lang%', locale) + }); + }); + +export const handle: Handle = handleParaglide; diff --git a/infrastructure/control-panel/src/hooks.ts b/infrastructure/control-panel/src/hooks.ts new file mode 100644 index 00000000..e75600b3 --- /dev/null +++ b/infrastructure/control-panel/src/hooks.ts @@ -0,0 +1,3 @@ +import { deLocalizeUrl } from '$lib/paraglide/runtime'; + +export const reroute = (request) => deLocalizeUrl(request.url).pathname; diff --git a/infrastructure/control-panel/src/lib/index.ts b/infrastructure/control-panel/src/lib/index.ts new file mode 100644 index 00000000..856f2b6c --- /dev/null +++ b/infrastructure/control-panel/src/lib/index.ts @@ -0,0 +1 @@ +// place files you want to import through the `$lib` alias in this folder. diff --git a/infrastructure/control-panel/src/routes/+layout.svelte b/infrastructure/control-panel/src/routes/+layout.svelte new file mode 100644 index 00000000..b93e9bae --- /dev/null +++ b/infrastructure/control-panel/src/routes/+layout.svelte @@ -0,0 +1,7 @@ + + +{@render children()} diff --git a/infrastructure/control-panel/src/routes/+page.svelte b/infrastructure/control-panel/src/routes/+page.svelte new file mode 100644 index 00000000..cc88df0e --- /dev/null +++ b/infrastructure/control-panel/src/routes/+page.svelte @@ -0,0 +1,2 @@ +

Welcome to SvelteKit

+

Visit svelte.dev/docs/kit to read the documentation

diff --git a/infrastructure/control-panel/src/routes/demo/+page.svelte b/infrastructure/control-panel/src/routes/demo/+page.svelte new file mode 100644 index 00000000..a815390c --- /dev/null +++ b/infrastructure/control-panel/src/routes/demo/+page.svelte @@ -0,0 +1 @@ +paraglide diff --git a/infrastructure/control-panel/src/routes/demo/paraglide/+page.svelte b/infrastructure/control-panel/src/routes/demo/paraglide/+page.svelte new file mode 100644 index 00000000..0ccba11c --- /dev/null +++ b/infrastructure/control-panel/src/routes/demo/paraglide/+page.svelte @@ -0,0 +1,18 @@ + + +

{m.hello_world({ name: 'SvelteKit User' })}

+
+ + +
+

+ If you use VSCode, install the Sherlock i18n extension for a better i18n experience. +

diff --git a/infrastructure/control-panel/static/favicon.svg b/infrastructure/control-panel/static/favicon.svg new file mode 100644 index 00000000..cc5dc66a --- /dev/null +++ b/infrastructure/control-panel/static/favicon.svg @@ -0,0 +1 @@ +svelte-logo \ No newline at end of file diff --git a/infrastructure/control-panel/svelte.config.js b/infrastructure/control-panel/svelte.config.js new file mode 100644 index 00000000..4a423ba8 --- /dev/null +++ b/infrastructure/control-panel/svelte.config.js @@ -0,0 +1,12 @@ +import adapter from '@sveltejs/adapter-static'; +import { vitePreprocess } from '@sveltejs/vite-plugin-svelte'; + +/** @type {import('@sveltejs/kit').Config} */ +const config = { + // Consult https://svelte.dev/docs/kit/integrations + // for more information about preprocessors + preprocess: vitePreprocess(), + kit: { adapter: adapter() } +}; + +export default config; diff --git a/infrastructure/control-panel/tsconfig.json b/infrastructure/control-panel/tsconfig.json new file mode 100644 index 00000000..0b2d8865 --- /dev/null +++ b/infrastructure/control-panel/tsconfig.json @@ -0,0 +1,19 @@ +{ + "extends": "./.svelte-kit/tsconfig.json", + "compilerOptions": { + "allowJs": true, + "checkJs": true, + "esModuleInterop": true, + "forceConsistentCasingInFileNames": true, + "resolveJsonModule": true, + "skipLibCheck": true, + "sourceMap": true, + "strict": true, + "moduleResolution": "bundler" + } + // Path aliases are handled by https://svelte.dev/docs/kit/configuration#alias + // except $lib which is handled by https://svelte.dev/docs/kit/configuration#files + // + // If you want to overwrite includes/excludes, make sure to copy over the relevant includes/excludes + // from the referenced tsconfig.json - TypeScript does not merge them in +} diff --git a/infrastructure/control-panel/vite.config.ts b/infrastructure/control-panel/vite.config.ts new file mode 100644 index 00000000..2fa21a2c --- /dev/null +++ b/infrastructure/control-panel/vite.config.ts @@ -0,0 +1,15 @@ +import { paraglideVitePlugin } from '@inlang/paraglide-js'; +import tailwindcss from '@tailwindcss/vite'; +import { sveltekit } from '@sveltejs/kit/vite'; +import { defineConfig } from 'vite'; + +export default defineConfig({ + plugins: [ + tailwindcss(), + sveltekit(), + paraglideVitePlugin({ + project: './project.inlang', + outdir: './src/lib/paraglide' + }) + ] +}); diff --git a/package.json b/package.json index 8732a9df..967dfabb 100644 --- a/package.json +++ b/package.json @@ -20,5 +20,10 @@ "packageManager": "pnpm@10.13.1", "engines": { "node": ">=18" + }, + "pnpm": { + "onlyBuiltDependencies": [ + "esbuild" + ] } -} +} \ No newline at end of file diff --git a/platforms/blabsy/env.development b/platforms/blabsy/env.development new file mode 100644 index 00000000..32da7026 --- /dev/null +++ b/platforms/blabsy/env.development @@ -0,0 +1,31 @@ +REGISTRY_DATABASE_URL="postgres://merul:password@localhost:5432/registry" +REGISTRY_SHARED_SECRET="dogggggee" + +PROVISIONER_DATABASE_URL="postgres://merul:password@localhost:5432/provisioner" + +PUBLIC_VERIFF_KEY="a2b2d1a7-e060-4733-95e4-6f3bce6fc4da" +VERIFF_HMAC_KEY="a0359774-ac9d-4609-8fa7-754fcfc9df11" + +# set this to allow or deny +DUPLICATES_POLICY="allow" + +IP_ADDR="http://192.168.0.226" + +PICTIQUE_DATABASE_URL="postgres://merul:password@localhost:5432/pic" +PICTIQUE_MAPPING_DB_PATH=/Users/mrl/data/pic + +BLABSY_DATABASE_URL="postgres://merul:password@localhost:5432/blab" +BLABSY_MAPPING_DB_PATH="/Users/mrl/data/blabsy" + +GOOGLE_APPLICATION_CREDENTIALS="/Users/mrl/Projects/metastate//secrets/firebase-secrets.json" + +PUBLIC_REGISTRY_URL="https://registry.w3ds-prototype.merul.org" +PUBLIC_PROVISIONER_URL="https://provisioner.w3ds-prototype.merul.org" + +# PUBLIC_REGISTRY_URL="http://192.168.0.226:4321" +# PUBLIC_PROVISIONER_URL="http://192.168.0.226:3000" + +PUBLIC_PICTIQUE_URL="http://192.168.0.226:5173" +PUBLIC_PICTIQUE_BASE_URL="http://192.168.0.226:1111" +PUBLIC_BLABSY_URL="http://192.168.0.226:8080" +PUBLIC_BLABSY_BASE_URL="http://192.168.0.226:4444" \ No newline at end of file diff --git a/platforms/blabsy/package.json b/platforms/blabsy/package.json index 34971e86..7db34c56 100644 --- a/platforms/blabsy/package.json +++ b/platforms/blabsy/package.json @@ -16,6 +16,7 @@ "dependencies": { "@headlessui/react": "^1.7.2", "@heroicons/react": "^2.0.11", + "@sidekickicons/react": "^0.13.0", "axios": "^1.6.7", "clsx": "^1.2.1", "date-fns": "^4.1.0", diff --git a/platforms/blabsy/src/components/chat/add-members.tsx b/platforms/blabsy/src/components/chat/add-members.tsx new file mode 100644 index 00000000..49f0f92c --- /dev/null +++ b/platforms/blabsy/src/components/chat/add-members.tsx @@ -0,0 +1,320 @@ +import { useEffect, useRef, useState } from 'react'; +import { useChat } from '@lib/context/chat-context'; +import { useAuth } from '@lib/context/auth-context'; +import { + UserIcon, + PaperAirplaneIcon, + EllipsisVerticalIcon, + XMarkIcon +} from '@heroicons/react/24/outline'; +import Image from 'next/image'; +import { doc, getDoc, Timestamp } from 'firebase/firestore'; +import { db } from '@lib/firebase/app'; +import type { User } from '@lib/types/user'; +import { Loading } from '@components/ui/loading'; +import { Dialog } from '@headlessui/react'; + +export function AddMembers({ + open, + onClose, + newChat = false +}: { + open: boolean; + onClose: () => void; + newChat?: boolean; +}): JSX.Element { + const { + currentChat, + messages, + sendNewMessage, + markAsRead, + removeParticipant, + loading + } = useChat(); + const { user } = useAuth(); + const [messageText, setMessageText] = useState(''); + const messagesEndRef = useRef(null); + const [otherUser, setOtherUser] = useState(null); + const [isLoading, setIsLoading] = useState(false); + + const [openMenuId, setOpenMenuId] = useState(null); + const [allUsers, setAllUsers] = useState([]); + const [selectedUsers, setSelectedUsers] = useState([]); + + const otherParticipant = currentChat?.participants.find( + (p) => p !== user?.id + ); + + useEffect(() => { + if (!otherParticipant) { + return; + } + + const fetchUserData = async (): Promise => { + try { + const userDoc = await getDoc( + doc(db, 'users', otherParticipant) + ); + if (userDoc.exists()) { + setOtherUser(userDoc.data() as User); + } else { + } + } catch (error) {} + }; + + void fetchUserData(); + }, [otherParticipant]); + + useEffect(() => { + if (currentChat) { + setIsLoading(true); + // Simulate loading time for messages + const timer = setTimeout(() => { + setIsLoading(false); + }, 500); + return () => clearTimeout(timer); + } + }, [currentChat]); + + useEffect(() => { + if (messagesEndRef.current) { + messagesEndRef.current.scrollIntoView({ behavior: 'smooth' }); + } + }, [messages]); + + useEffect(() => { + if (!currentChat || !user) { + return; + } + + const unreadMessages = messages?.filter( + (message) => + message.senderId !== user.id && + !message.readBy.includes(user.id) + ); + + if (unreadMessages?.length) { + void Promise.all( + unreadMessages.map((message) => markAsRead(message.id)) + ); + } + }, [currentChat, messages, user, markAsRead]); + + useEffect(() => { + // Fetch all users on platform for selection + const fetchAllUsers = async (): Promise => { + try { + // Assuming a collection 'users' in Firestore + const usersSnapshot = await db.collection('users').get(); + const usersData: User[] = usersSnapshot.docs.map((doc) => ({ + id: doc.id, + ...(doc.data() as User) + })); + setAllUsers(usersData); + } catch (error) { + // handle error if needed + // TODO: Dummy users for development, remove when backend integrated + setAllUsers([ + { + id: 'user_5', + name: 'Alice Sharma', + username: 'alice.s', + bio: 'Techie and Coffee Lover', + theme: 'dark', + accent: 'blue', + website: 'https://alicesharma.dev', + location: 'Delhi, India', + photoURL: 'https://i.pravatar.cc/150?img=1', + verified: true, + following: [], + followers: [], + createdAt: Timestamp.fromDate(new Date()), + updatedAt: Timestamp.fromDate(new Date()), + totalTweets: 50, + totalPhotos: 5, + pinnedTweet: '', + coverPhotoURL: + 'https://source.unsplash.com/random/800x200?tech' + }, + { + id: 'user_6', + name: 'Rahul Verma', + username: 'rahulv', + bio: 'Frontend Wizard 🧙‍♂️', + theme: 'light', + accent: 'green', + website: 'https://rahulv.dev', + location: 'Bangalore, India', + photoURL: 'https://i.pravatar.cc/150?img=2', + verified: false, + following: [], + followers: [], + createdAt: Timestamp.fromDate(new Date()), + updatedAt: Timestamp.fromDate(new Date()), + totalTweets: 120, + totalPhotos: 20, + pinnedTweet: '', + coverPhotoURL: + 'https://source.unsplash.com/random/800x200?frontend' + }, + { + id: 'user_7', + name: 'Nisha Kapoor', + username: 'nishak', + bio: 'UI/UX Designer 🎨', + theme: 'dark', + accent: 'purple', + website: '', + location: 'Mumbai, India', + photoURL: 'https://i.pravatar.cc/150?img=3', + verified: true, + following: [], + followers: [], + createdAt: Timestamp.fromDate(new Date()), + updatedAt: Timestamp.fromDate(new Date()), + totalTweets: 300, + totalPhotos: 45, + pinnedTweet: '', + coverPhotoURL: + 'https://source.unsplash.com/random/800x200?design' + } + ]); + } + }; + void fetchAllUsers(); + }, []); + + const filteredUsers = allUsers.filter( + (u) => newChat || !currentChat?.participants.includes(u.id) + ); + + const toggleUserSelection = (user: User) => { + if (selectedUsers.some((u) => u.id === user.id)) { + setSelectedUsers(selectedUsers.filter((u) => u.id !== user.id)); + } else { + setSelectedUsers([...selectedUsers, user]); + } + }; + + const handleAddSelectedMembers = async () => { + if (!currentChat && !newChat) return; + // Replace this with actual logic to update Firestore group chat participants + if (newChat) { + // alert( + // `Creating new chat with: ${[...selectedUsers, user as User] + // .map((u) => u.name || u.username) + // .join(', ')}` + // ); + alert( + `Creating new chat with: ${selectedUsers + .map((u) => u.name || u.username) + .join(', ')}` + ); + } else { + alert( + `Added: ${selectedUsers + .map((u) => u.name || u.username) + .join(', ')}` + ); + } + setSelectedUsers([]); + onClose(); + }; + + const handleSubmit = async (e: React.FormEvent): Promise => { + e.preventDefault(); + if (!messageText.trim()) return; + + try { + await sendNewMessage(messageText); + setMessageText(''); + } catch (error) {} + }; + + return ( + + + ); +} diff --git a/platforms/blabsy/src/components/chat/chat-list.tsx b/platforms/blabsy/src/components/chat/chat-list.tsx index 1bc79d3e..53f1c57b 100644 --- a/platforms/blabsy/src/components/chat/chat-list.tsx +++ b/platforms/blabsy/src/components/chat/chat-list.tsx @@ -9,6 +9,7 @@ import { db } from '@lib/firebase/app'; import { Loading } from '@components/ui/loading'; import type { Chat } from '@lib/types/chat'; import type { User } from '@lib/types/user'; +import { AddMembers } from './add-members'; type ParticipantData = { [key: string]: User; @@ -18,6 +19,7 @@ export function ChatList(): JSX.Element { const { chats, currentChat, setCurrentChat, loading } = useChat(); const { user } = useAuth(); const [participantData, setParticipantData] = useState({}); + const [openCreateNewChatModal, setOpenCreateNewChatModal] = useState(false); useEffect(() => { if (!chats || !user) return; @@ -36,17 +38,19 @@ export function ChatList(): JSX.Element { const userDoc = await getDoc( doc(db, 'users', otherParticipantId) ); - if (userDoc.exists()) + if (userDoc.exists()) { newParticipantData[otherParticipantId] = userDoc.data() as User; + } } } - if (Object.keys(newParticipantData).length > 0) + if (Object.keys(newParticipantData).length > 0) { setParticipantData((prev) => ({ ...prev, ...newParticipantData })); + } }; void fetchParticipantData(); @@ -67,60 +71,74 @@ export function ChatList(): JSX.Element { } return ( -
- {chats.map((chat) => { - const otherParticipant = chat.participants.find( - (p) => p !== user?.id - ); - const participant = otherParticipant - ? participantData[otherParticipant] - : null; +
+
+ {chats.map((chat) => { + const otherParticipant = chat.participants.find( + (p) => p !== user?.id + ); + const participant = otherParticipant + ? participantData[otherParticipant] + : null; - return ( - - ); - })} + {chat.lastMessage && ( +

+ {chat.lastMessage.text} +

+ )} +
+ + ); + })} +
+ + setOpenCreateNewChatModal(false)} + newChat={true} + />
); } @@ -174,9 +192,8 @@ function ChatListItem({ stroke='currentColor' > - {otherParticipants.length > 0 - ? `Chat with ${otherParticipants.length} user(s)` - : 'Direct Chat'} + {otherParticipants.length} User + {otherParticipants.length > 1 ? 's' : ''} (null); const [otherUser, setOtherUser] = useState(null); const [isLoading, setIsLoading] = useState(false); + const [openMemberList, setOpenMemberList] = useState(false); + const [openEditMenu, setOpenEditMenu] = useState(false); + const [openAddMemberList, setOpenAddMemberList] = useState(false); const otherParticipant = currentChat?.participants.find( (p) => p !== user?.id @@ -70,11 +80,11 @@ export function ChatWindow(): JSX.Element { const userDoc = await getDoc( doc(db, 'users', otherParticipant) ); - if (userDoc.exists()) setOtherUser(userDoc.data() as User); - } catch (error) { - // eslint-disable-next-line no-console - console.error(error); - } + if (userDoc.exists()) { + setOtherUser(userDoc.data() as User); + } else { + } + } catch (error) {} }; void fetchUserData(); @@ -105,11 +115,11 @@ export function ChatWindow(): JSX.Element { !message.readBy.includes(user.id) ); - if (unreadMessages?.length) + if (unreadMessages?.length) { void Promise.all( unreadMessages.map((message) => markAsRead(message.id)) ); - }, [currentChat, messages, user, markAsRead]); + }}); const handleSubmit = async (e: React.FormEvent): Promise => { e.preventDefault(); @@ -118,48 +128,69 @@ export function ChatWindow(): JSX.Element { try { await sendNewMessage(messageText); setMessageText(''); - } catch (error) { - // eslint-disable-next-line no-console - console.error('Error sending message:', error); - } + } catch (error) {} }; return (
{currentChat ? ( <> -
-
- {otherUser?.photoURL ? ( - { - ) : ( - - )} -
-
-

- {currentChat.type === 'direct' - ? otherUser?.name || - otherUser?.username || - otherParticipant - : currentChat.name} -

-

- {currentChat.type === 'direct' - ? 'Direct Message' - : `${currentChat.participants.length} participants`} -

+
+
+
+ {otherUser?.photoURL ? ( + { + ) : ( + + )} +
+
+

+ {currentChat.type === 'direct' + ? otherUser?.name || + otherUser?.username || + otherParticipant + : currentChat.name} +

+

+ {currentChat.type === 'direct' + ? 'Direct Message' + : `${currentChat.participants.length} participants`} +

+
+ {currentChat.type === 'group' && ( +
+
+ +
+
+ +
+
+ )}
{isLoading ? ( @@ -228,6 +259,25 @@ export function ChatWindow(): JSX.Element {

)} + setOpenMemberList(false)} + onOpenAddMemberModal={() => { + setOpenMemberList(false); + setOpenAddMemberList(true); + }} + /> + { + setOpenAddMemberList(false); + setOpenMemberList(true); + }} + /> + setOpenEditMenu(false)} + />
); } diff --git a/platforms/blabsy/src/components/chat/group-settings.tsx b/platforms/blabsy/src/components/chat/group-settings.tsx new file mode 100644 index 00000000..7a238396 --- /dev/null +++ b/platforms/blabsy/src/components/chat/group-settings.tsx @@ -0,0 +1,167 @@ +import { useEffect, useState } from 'react'; +import { useChat } from '@lib/context/chat-context'; +import { useAuth } from '@lib/context/auth-context'; +import Image from 'next/image'; +import { doc, getDoc } from 'firebase/firestore'; +import { db } from '@lib/firebase/app'; +import type { User } from '@lib/types/user'; +import { Dialog } from '@headlessui/react'; +import { UserIcon, XMarkIcon } from '@heroicons/react/24/outline'; + +export function GroupSettings({ + open, + onClose +}: { + open: boolean; + onClose: () => void; +}): JSX.Element { + const { currentChat } = useChat(); + const { user } = useAuth(); + const [otherUser, setOtherUser] = useState(null); + const [isLoading, setIsLoading] = useState(false); + + const otherParticipant = currentChat?.participants.find( + (p) => p !== user?.id + ); + + useEffect(() => { + if (!otherParticipant) { + return; + } + + const fetchUserData = async (): Promise => { + try { + const userDoc = await getDoc( + doc(db, 'users', otherParticipant) + ); + if (userDoc.exists()) { + setOtherUser(userDoc.data() as User); + } else { + } + } catch (error) {} + }; + + void fetchUserData(); + }, [otherParticipant]); + + useEffect(() => { + if (currentChat) { + setIsLoading(true); + // Simulate loading time for messages + const timer = setTimeout(() => { + setIsLoading(false); + }, 500); + return () => clearTimeout(timer); + } + }, [currentChat]); + + return ( + +