Full Code of OneArmyWorld/onearmy for AI

master ecddc5150337 cached
1080 files
2.8 MB
781.5k tokens
1392 symbols
1 requests
Download .txt
Showing preview only (3,115K chars total). Download the full file or copy to clipboard to get everything.
Repository: OneArmyWorld/onearmy
Branch: master
Commit: ecddc5150337
Files: 1080
Total size: 2.8 MB

Directory structure:
gitextract_7op3tyix/

├── .all-contributorsrc
├── .circleci/
│   └── config.yml
├── .dockerignore
├── .github/
│   ├── CODEOWNERS
│   ├── ISSUE_TEMPLATE/
│   │   ├── bug_report.md
│   │   ├── build-new-component.md
│   │   └── feature-request-or-suggestion.md
│   ├── actions/
│   │   └── destroy-fly-preview-app/
│   │       ├── Dockerfile
│   │       ├── action.yml
│   │       └── entrypoint.sh
│   ├── labels.yml
│   ├── pull_request_template.md
│   └── workflows/
│       ├── codeql-analysis.yml
│       ├── pr-preview-fly-deploy.yml
│       ├── pr-preview-fly-destroy.yml
│       ├── pr-preview-remove-label.yml
│       ├── pr-stale.yml
│       └── storybook-deploy.yml
├── .gitignore
├── .husky/
│   └── pre-commit
├── .node-version
├── .releaserc.json
├── .snaplet/
│   ├── config.json
│   ├── dataModel.json
│   ├── library.json
│   └── questions.json
├── .vscode/
│   └── launch.json
├── .yarnrc.yml
├── CNAME
├── CODE_OF_CONDUCT.md
├── CONTRIBUTING.md
├── Dockerfile
├── Dockerfile.preview
├── FUNDING.yml
├── LICENSE
├── README.md
├── SECURITY.md
├── biome.json
├── codecov.yml
├── docs/
│   ├── circle-ci.md
│   ├── db-seeding.md
│   ├── maintainers.md
│   ├── pwa-setup.md
│   ├── react-router-7.md
│   ├── supabase.md
│   ├── team-principles.md
│   └── technical-decisions.md
├── fly-ff.toml
├── fly-pk.toml
├── fly-pp.toml
├── fly-preview.toml
├── index.html
├── package.json
├── packages/
│   ├── components/
│   │   ├── .gitignore
│   │   ├── .storybook/
│   │   │   ├── main.ts
│   │   │   ├── manager.js
│   │   │   └── preview.tsx
│   │   ├── README.md
│   │   ├── package.json
│   │   ├── src/
│   │   │   ├── Accordion/
│   │   │   │   ├── Accordion.stories.tsx
│   │   │   │   ├── Accordion.test.tsx
│   │   │   │   └── Accordion.tsx
│   │   │   ├── ActionSet/
│   │   │   │   └── ActionSet.tsx
│   │   │   ├── Alert/
│   │   │   │   └── Alert.stories.tsx
│   │   │   ├── ArrowIcon/
│   │   │   │   ├── ArrowIcon.stories.tsx
│   │   │   │   ├── ArrowIcon.tsx
│   │   │   │   └── styles.css
│   │   │   ├── ArticleCallToActionSupabase/
│   │   │   │   ├── ArticleCallToActionSupabase.stories.tsx
│   │   │   │   └── ArticleCallToActionSupabase.tsx
│   │   │   ├── AuthorDisplay/
│   │   │   │   └── AuthorDisplay.tsx
│   │   │   ├── Banner/
│   │   │   │   ├── Banner.stories.tsx
│   │   │   │   ├── Banner.test.tsx
│   │   │   │   └── Banner.tsx
│   │   │   ├── BlockedRoute/
│   │   │   │   ├── BlockedRoute.stories.tsx
│   │   │   │   └── BlockedRoute.tsx
│   │   │   ├── Breadcrumbs/
│   │   │   │   ├── Breadcrumbs.stories.tsx
│   │   │   │   ├── Breadcrumbs.test.tsx
│   │   │   │   ├── Breadcrumbs.tsx
│   │   │   │   └── BreadcrumbsItem.tsx
│   │   │   ├── Button/
│   │   │   │   ├── Button.stories.tsx
│   │   │   │   └── Button.tsx
│   │   │   ├── ButtonIcon/
│   │   │   │   ├── ButtonIcon.stories.tsx
│   │   │   │   └── ButtonIcon.tsx
│   │   │   ├── ButtonShowReplies/
│   │   │   │   ├── ButtonShowReplies.stories.tsx
│   │   │   │   ├── ButtonShowReplies.test.tsx
│   │   │   │   └── ButtonShowReplies.tsx
│   │   │   ├── CardButton/
│   │   │   │   ├── CardButton.stories.tsx
│   │   │   │   └── CardButton.tsx
│   │   │   ├── CardListItem/
│   │   │   │   ├── CardListItem.stories.tsx
│   │   │   │   └── CardListItem.tsx
│   │   │   ├── CardProfile/
│   │   │   │   ├── CardDetailsMemberProfile.tsx
│   │   │   │   ├── CardDetailsSpaceProfile.tsx
│   │   │   │   ├── CardProfile.stories.tsx
│   │   │   │   ├── CardProfile.test.tsx
│   │   │   │   └── CardProfile.tsx
│   │   │   ├── Category/
│   │   │   │   ├── Category.stories.tsx
│   │   │   │   └── Category.tsx
│   │   │   ├── CategoryHorizonalList/
│   │   │   │   ├── CategoryHorizonalList.stories.tsx
│   │   │   │   ├── CategoryHorizonalList.test.tsx
│   │   │   │   └── CategoryHorizonalList.tsx
│   │   │   ├── CharacterCount/
│   │   │   │   ├── CharacterCount.stories.tsx
│   │   │   │   └── CharacterCount.tsx
│   │   │   ├── CommentAvatar/
│   │   │   │   └── CommentAvatar.tsx
│   │   │   ├── CommentBody/
│   │   │   │   └── CommentBody.tsx
│   │   │   ├── CommentDisplay/
│   │   │   │   ├── CommentDisplay.stories.tsx
│   │   │   │   ├── CommentDisplay.test.tsx
│   │   │   │   └── CommentDisplay.tsx
│   │   │   ├── CommentsTitle/
│   │   │   │   ├── CommentsTitle.stories.tsx
│   │   │   │   ├── CommentsTitle.test.tsx
│   │   │   │   └── CommentsTitle.tsx
│   │   │   ├── ConfirmModal/
│   │   │   │   ├── ConfirmModal.stories.tsx
│   │   │   │   └── ConfirmModal.tsx
│   │   │   ├── ContentStatistics/
│   │   │   │   ├── ContentStatistics.stories.tsx
│   │   │   │   ├── ContentStatistics.tsx
│   │   │   │   ├── ContentStatisticsList.tsx
│   │   │   │   └── types.ts
│   │   │   ├── CreateComment/
│   │   │   │   ├── CreateComment.css
│   │   │   │   ├── CreateComment.stories.tsx
│   │   │   │   ├── CreateComment.test.tsx
│   │   │   │   └── CreateComment.tsx
│   │   │   ├── CreateReply/
│   │   │   │   ├── CreateReply.stories.tsx
│   │   │   │   ├── CreateReply.test.tsx
│   │   │   │   └── CreateReply.tsx
│   │   │   ├── DisplayDate/
│   │   │   │   ├── DisplayDate.stories.tsx
│   │   │   │   ├── DisplayDate.test.tsx
│   │   │   │   ├── DisplayDate.tsx
│   │   │   │   └── display-date.css
│   │   │   ├── DonationRequestModal/
│   │   │   │   ├── DonationRequestModal.stories.tsx
│   │   │   │   ├── DonationRequestModal.test.tsx
│   │   │   │   └── DonationRequestModal.tsx
│   │   │   ├── DownloadButton/
│   │   │   │   ├── DownloadButton.stories.tsx
│   │   │   │   ├── DownloadButton.test.tsx
│   │   │   │   └── DownloadButton.tsx
│   │   │   ├── DownloadCounter/
│   │   │   │   ├── DownloadCounter.stories.tsx
│   │   │   │   ├── DownloadCounter.test.tsx
│   │   │   │   └── DownloadCounter.tsx
│   │   │   ├── DownloadStaticFile/
│   │   │   │   ├── DownloadStaticFile.stories.tsx
│   │   │   │   └── DownloadStaticFile.tsx
│   │   │   ├── EditComment/
│   │   │   │   ├── EditComment.stories.tsx
│   │   │   │   ├── EditComment.test.tsx
│   │   │   │   └── EditComment.tsx
│   │   │   ├── ElWithBeforeIcon/
│   │   │   │   ├── ElWithBeforeIcon.stories.tsx
│   │   │   │   └── ElWithBeforeIcon.tsx
│   │   │   ├── ExternalLink/
│   │   │   │   ├── ExternalLink.stories.tsx
│   │   │   │   └── ExternalLink.tsx
│   │   │   ├── FieldCheckbox/
│   │   │   │   └── FieldCheckbox.tsx
│   │   │   ├── FieldInput/
│   │   │   │   ├── FieldInput.stories.tsx
│   │   │   │   └── FieldInput.tsx
│   │   │   ├── FieldMarkdown/
│   │   │   │   ├── AddImage.tsx
│   │   │   │   ├── FieldMarkdown.stories.tsx
│   │   │   │   ├── FieldMarkdown.tsx
│   │   │   │   └── style.css
│   │   │   ├── FieldTextarea/
│   │   │   │   ├── FieldTextarea.stories.tsx
│   │   │   │   └── FieldTextarea.tsx
│   │   │   ├── FlagIcon/
│   │   │   │   └── FlagIcon.tsx
│   │   │   ├── FollowButton/
│   │   │   │   ├── FollowButton.stories.tsx
│   │   │   │   └── FollowButton.tsx
│   │   │   ├── FollowIcon/
│   │   │   │   ├── FollowIcon.stories.tsx
│   │   │   │   └── FollowIcon.tsx
│   │   │   ├── GlobalStyles/
│   │   │   │   └── GlobalStyles.tsx
│   │   │   ├── GridForm/
│   │   │   │   ├── GridForm.stories.tsx
│   │   │   │   └── GridForm.tsx
│   │   │   ├── Guidelines/
│   │   │   │   ├── Guidelines.stories.tsx
│   │   │   │   ├── Guidelines.test.tsx
│   │   │   │   └── Guidelines.tsx
│   │   │   ├── Heading/
│   │   │   │   └── Heading.stories.tsx
│   │   │   ├── HeroBanner/
│   │   │   │   ├── HeroBanner.stories.tsx
│   │   │   │   └── HeroBanner.tsx
│   │   │   ├── Icon/
│   │   │   │   ├── DonateIcon.tsx
│   │   │   │   ├── DownloadIcon.tsx
│   │   │   │   ├── ExternalUrl.tsx
│   │   │   │   ├── Icon.stories.tsx
│   │   │   │   ├── Icon.tsx
│   │   │   │   ├── svgs.tsx
│   │   │   │   └── types.ts
│   │   │   ├── IconCountWithTooltip/
│   │   │   │   ├── IconCountWithTooltip.stories.tsx
│   │   │   │   ├── IconCountWithTooltip.test.tsx
│   │   │   │   └── IconCountWithTooltip.tsx
│   │   │   ├── ImageGallery/
│   │   │   │   ├── ImageGallery.stories.tsx
│   │   │   │   ├── ImageGallery.test.tsx
│   │   │   │   └── ImageGallery.tsx
│   │   │   ├── ImageGalleryThumbnail/
│   │   │   │   ├── ImageGalleryThumbnail.stories.tsx
│   │   │   │   ├── ImageGalleryThumbnail.test.tsx
│   │   │   │   └── ImageGalleryThumbnail.tsx
│   │   │   ├── ImageInput/
│   │   │   │   ├── ImageInputDeleteOverlay.tsx
│   │   │   │   ├── ImageInputV2.tsx
│   │   │   │   ├── ImageInputWrapper.tsx
│   │   │   │   └── isImageValid.ts
│   │   │   ├── InformationTooltip/
│   │   │   │   ├── InformationTooltip.stories.tsx
│   │   │   │   └── InformationTooltip.tsx
│   │   │   ├── Input/
│   │   │   │   └── Input.stories.tsx
│   │   │   ├── InternalLink/
│   │   │   │   ├── InternalLink.stories.tsx
│   │   │   │   └── InternalLink.tsx
│   │   │   ├── LinkifyText/
│   │   │   │   ├── LinkifyText.stories.tsx
│   │   │   │   └── LinkifyText.tsx
│   │   │   ├── Loader/
│   │   │   │   ├── Loader.stories.tsx
│   │   │   │   └── Loader.tsx
│   │   │   ├── Map/
│   │   │   │   ├── Map.client.tsx
│   │   │   │   ├── Map.stories.tsx
│   │   │   │   └── index.css
│   │   │   ├── MapCardList/
│   │   │   │   ├── MapCardList.stories.tsx
│   │   │   │   ├── MapCardList.test.tsx
│   │   │   │   └── MapCardList.tsx
│   │   │   ├── MapFilterListItem/
│   │   │   │   └── MapFilterListItem.tsx
│   │   │   ├── MapWithPin/
│   │   │   │   ├── MapPin.client.tsx
│   │   │   │   ├── MapPin.stories.tsx
│   │   │   │   ├── MapWithPin.client.tsx
│   │   │   │   └── MapWithPin.stories.tsx
│   │   │   ├── MemberBadge/
│   │   │   │   ├── MemberBadge.stories.tsx
│   │   │   │   └── MemberBadge.tsx
│   │   │   ├── MemberHistory/
│   │   │   │   ├── MemberHistory.test.tsx
│   │   │   │   └── MemberHistory.tsx
│   │   │   ├── Modal/
│   │   │   │   ├── Modal.stories.tsx
│   │   │   │   └── Modal.tsx
│   │   │   ├── ModerationStatus/
│   │   │   │   ├── ModerationStatus.stories.tsx
│   │   │   │   └── ModerationStatus.tsx
│   │   │   ├── MoreContainer/
│   │   │   │   ├── MoreContainer.stories.tsx
│   │   │   │   └── MoreContainer.tsx
│   │   │   ├── NotificationItemSupabase/
│   │   │   │   ├── NotificationItemSupabase.stories.tsx
│   │   │   │   └── NotificationItemSupabase.tsx
│   │   │   ├── NotificationListSupabase/
│   │   │   │   ├── NotificationListSupabase.stories.tsx
│   │   │   │   ├── NotificationListSupabase.test.tsx
│   │   │   │   └── NotificationListSupabase.tsx
│   │   │   ├── NotificationsModal/
│   │   │   │   └── NotificationsModal.tsx
│   │   │   ├── OsmGeocoding/
│   │   │   │   ├── OsmGeocoding.stories.tsx
│   │   │   │   ├── OsmGeocoding.tsx
│   │   │   │   ├── OsmGeocodingLoader.tsx
│   │   │   │   ├── OsmGeocodingResultsList.tsx
│   │   │   │   └── types.tsx
│   │   │   ├── Pagination/
│   │   │   │   ├── Pagination.test.tsx
│   │   │   │   └── Pagination.tsx
│   │   │   ├── PaginationIcons/
│   │   │   │   ├── PaginationIcons.stories.tsx
│   │   │   │   ├── PaginationIcons.test.tsx
│   │   │   │   └── PaginationIcons.tsx
│   │   │   ├── PinProfile/
│   │   │   │   ├── PinProfile.stories.tsx
│   │   │   │   └── PinProfile.tsx
│   │   │   ├── ProfileBadgeContentLabel/
│   │   │   │   ├── ProfileBadgeContentLabel.stories.tsx
│   │   │   │   └── ProfileBadgeContentLabel.tsx
│   │   │   ├── ProfileLink/
│   │   │   │   ├── ProfileLink.stories.tsx
│   │   │   │   └── ProfileLink.tsx
│   │   │   ├── ProfileList/
│   │   │   │   ├── ProfileList.stories.tsx
│   │   │   │   ├── ProfileList.test.tsx
│   │   │   │   └── ProfileList.tsx
│   │   │   ├── ProfileTagsList/
│   │   │   │   ├── ProfileTagsList.stories.tsx
│   │   │   │   ├── ProfileTagsList.test.tsx
│   │   │   │   └── ProfileTagsList.tsx
│   │   │   ├── ResearchEditorOverview/
│   │   │   │   ├── ResearchEditorOverview.stories.tsx
│   │   │   │   ├── ResearchEditorOverview.test.tsx
│   │   │   │   ├── ResearchEditorOverview.tsx
│   │   │   │   └── __snapshots__/
│   │   │   │       └── ResearchEditorOverview.test.tsx.snap
│   │   │   ├── ReturnPathLink/
│   │   │   │   └── ReturnPathLink.tsx
│   │   │   ├── SearchField/
│   │   │   │   ├── SearchField.stories.tsx
│   │   │   │   └── SearchField.tsx
│   │   │   ├── Select/
│   │   │   │   ├── DropdownIndicator.tsx
│   │   │   │   ├── Option.tsx
│   │   │   │   ├── Select.stories.tsx
│   │   │   │   └── Select.tsx
│   │   │   ├── SiteFooter/
│   │   │   │   ├── SiteFooter.stories.tsx
│   │   │   │   └── SiteFooter.tsx
│   │   │   ├── TabbedContent/
│   │   │   │   ├── TabbedContent.stories.tsx
│   │   │   │   ├── TabbedContent.test.tsx
│   │   │   │   └── TabbedContent.tsx
│   │   │   ├── Tag/
│   │   │   │   ├── Tag.stories.tsx
│   │   │   │   └── Tag.tsx
│   │   │   ├── TagList/
│   │   │   │   ├── TagList.stories.tsx
│   │   │   │   ├── TagList.test.tsx
│   │   │   │   └── TagList.tsx
│   │   │   ├── Text/
│   │   │   │   └── Text.stories.tsx
│   │   │   ├── TextNotification/
│   │   │   │   ├── TextNotification.stories.tsx
│   │   │   │   └── TextNotification.tsx
│   │   │   ├── Textarea/
│   │   │   │   └── Textarea.stories.tsx
│   │   │   ├── Tooltip/
│   │   │   │   ├── Tooltip.stories.tsx
│   │   │   │   └── Tooltip.tsx
│   │   │   ├── UsefulStatsButton/
│   │   │   │   ├── UsefulButtonLite.test.tsx
│   │   │   │   ├── UsefulButtonLite.tsx
│   │   │   │   ├── UsefulStatsButton.stories.tsx
│   │   │   │   └── UsefulStatsButton.tsx
│   │   │   ├── UserEngagementWrapper/
│   │   │   │   ├── UserEngagementWrapper.stories.tsx
│   │   │   │   ├── UserEngagementWrapper.test.tsx
│   │   │   │   └── UserEngagementWrapper.tsx
│   │   │   ├── UserStatistics/
│   │   │   │   ├── UserStatistics.stories.tsx
│   │   │   │   ├── UserStatistics.test.tsx
│   │   │   │   └── UserStatistics.tsx
│   │   │   ├── Username/
│   │   │   │   ├── DisplayName.stories.tsx
│   │   │   │   ├── DisplayName.tsx
│   │   │   │   ├── UserBadge.tsx
│   │   │   │   ├── Username.stories.tsx
│   │   │   │   ├── Username.test.tsx
│   │   │   │   └── Username.tsx
│   │   │   ├── VerticalList/
│   │   │   │   ├── VerticalList.client.tsx
│   │   │   │   └── VerticalList.stories.tsx
│   │   │   ├── VideoPlayer/
│   │   │   │   ├── VideoPlayer.stories.tsx
│   │   │   │   ├── VideoPlayer.test.tsx
│   │   │   │   └── VideoPlayer.tsx
│   │   │   ├── VisitorModal/
│   │   │   │   ├── VisitorModal.tsx
│   │   │   │   ├── VisitorModalFooter.test.tsx
│   │   │   │   ├── VisitorModalFooter.tsx
│   │   │   │   ├── VisitorModalHeader.test.tsx
│   │   │   │   ├── VisitorModalHeader.tsx
│   │   │   │   └── props.ts
│   │   │   ├── __mocks__/
│   │   │   │   └── AuthWrapper.mock.tsx
│   │   │   ├── hooks/
│   │   │   │   ├── useImageLightbox.tsx
│   │   │   │   └── usePhotoSwipeLightbox.ts
│   │   │   ├── index.ts
│   │   │   ├── providers/
│   │   │   │   └── AuthorsContext.ts
│   │   │   ├── test/
│   │   │   │   ├── setup.ts
│   │   │   │   └── utils.tsx
│   │   │   ├── types/
│   │   │   │   └── common.ts
│   │   │   └── utils.ts
│   │   ├── tsconfig.json
│   │   ├── types/
│   │   │   ├── emotion.d.ts
│   │   │   ├── images.d.ts
│   │   │   └── photoswipe.d.ts
│   │   └── vite.config.ts
│   ├── cypress/
│   │   ├── .gitignore
│   │   ├── .npmrc
│   │   ├── README.md
│   │   ├── cypress.config.ts
│   │   ├── package.json
│   │   ├── scripts/
│   │   │   └── start.mts
│   │   ├── src/
│   │   │   ├── data/
│   │   │   │   └── index.ts
│   │   │   ├── fixtures/
│   │   │   │   ├── images/
│   │   │   │   │   └── file.random
│   │   │   │   └── searchResults.ts
│   │   │   ├── integration/
│   │   │   │   ├── SignIn.spec.ts
│   │   │   │   ├── SignUp.spec.ts
│   │   │   │   ├── academy.spec.ts
│   │   │   │   ├── common.spec.ts
│   │   │   │   ├── library/
│   │   │   │   │   ├── discussions.spec.ts
│   │   │   │   │   ├── read.spec.ts
│   │   │   │   │   ├── seo.spec.ts
│   │   │   │   │   └── write.spec.ts
│   │   │   │   ├── news/
│   │   │   │   │   ├── discussions.spec.ts
│   │   │   │   │   ├── read.spec.ts
│   │   │   │   │   ├── search.spec.ts
│   │   │   │   │   └── write.spec.ts
│   │   │   │   ├── notifications.spec.ts
│   │   │   │   ├── profile.spec.ts
│   │   │   │   ├── profileList.spec.ts
│   │   │   │   ├── questions/
│   │   │   │   │   ├── discussions.spec.ts
│   │   │   │   │   ├── read.spec.ts
│   │   │   │   │   ├── search.spec.ts
│   │   │   │   │   └── write.spec.ts
│   │   │   │   ├── research/
│   │   │   │   │   ├── discussions.spec.ts
│   │   │   │   │   ├── follow.spec.ts
│   │   │   │   │   ├── list.spec.ts
│   │   │   │   │   ├── read.spec.ts
│   │   │   │   │   └── write.spec.ts
│   │   │   │   └── settings.spec.ts
│   │   │   ├── support/
│   │   │   │   ├── commands.ts
│   │   │   │   ├── commandsUi.ts
│   │   │   │   ├── hooks.ts
│   │   │   │   ├── index.ts
│   │   │   │   └── rules.ts
│   │   │   └── utils/
│   │   │       ├── TestUtils.ts
│   │   │       └── supabaseTestsService.ts
│   │   └── tsconfig.json
│   └── themes/
│       ├── .gitignore
│       ├── assets/
│       │   └── fonts/
│       │       └── README.md
│       ├── package.json
│       ├── src/
│       │   ├── common/
│       │   │   ├── button.ts
│       │   │   ├── commonStyles.ts
│       │   │   └── index.ts
│       │   ├── fonts/
│       │   │   ├── fonts.d.ts
│       │   │   └── index.ts
│       │   ├── index.ts
│       │   └── types/
│       │       └── index.ts
│       └── tsconfig.json
├── react-router.config.ts
├── seed/
│   ├── profilesSeed.ts
│   └── usersSeed.ts
├── seed.config.ts
├── seed.sql
├── seed.ts
├── server.js
├── shared/
│   ├── .gitignore
│   ├── README.md
│   ├── index.ts
│   ├── messages.ts
│   ├── mocks/
│   │   ├── auth/
│   │   │   ├── index.ts
│   │   │   └── users.ts
│   │   ├── data/
│   │   │   ├── badges.ts
│   │   │   ├── categories.ts
│   │   │   ├── discussions.ts
│   │   │   ├── index.ts
│   │   │   ├── mappins.ts
│   │   │   ├── messages.ts
│   │   │   ├── news.ts
│   │   │   ├── profileTags.ts
│   │   │   ├── profileTypes.ts
│   │   │   ├── projects.ts
│   │   │   ├── questions.ts
│   │   │   ├── research.ts
│   │   │   ├── researchUpdates.ts
│   │   │   ├── tags.ts
│   │   │   └── users.ts
│   │   └── index.ts
│   ├── models/
│   │   ├── author.ts
│   │   ├── banner.ts
│   │   ├── category.ts
│   │   ├── comment.ts
│   │   ├── common.ts
│   │   ├── content.ts
│   │   ├── db.ts
│   │   ├── document.ts
│   │   ├── filesForm.ts
│   │   ├── index.ts
│   │   ├── library.ts
│   │   ├── maps.ts
│   │   ├── media.ts
│   │   ├── messages.ts
│   │   ├── moderation.ts
│   │   ├── news.ts
│   │   ├── notifications.ts
│   │   ├── notificationsPreferences.ts
│   │   ├── patreon.ts
│   │   ├── patreonSettings.ts
│   │   ├── profile.ts
│   │   ├── profileBadge.ts
│   │   ├── profileTag.ts
│   │   ├── profileType.ts
│   │   ├── question.ts
│   │   ├── research.ts
│   │   ├── selectValue.ts
│   │   ├── subscriber.ts
│   │   ├── tag.ts
│   │   ├── tags.ts
│   │   ├── tenantSettings.ts
│   │   ├── upgradeBadge.ts
│   │   ├── user.ts
│   │   ├── userCreatedDocs.ts
│   │   ├── userEmailData.ts
│   │   ├── voteUseful.ts
│   │   └── webmanifest.ts
│   ├── package.json
│   ├── tsconfig.json
│   └── utils/
│       ├── file.utils.ts
│       ├── index.ts
│       ├── markdown.test.ts
│       └── markdown.ts
├── src/
│   ├── .server/
│   │   ├── models/
│   │   │   └── messageSettings.ts
│   │   ├── resend.ts
│   │   └── templates/
│   │       ├── Layout.tsx
│   │       ├── ReceiverMessage.tsx
│   │       ├── components/
│   │       │   ├── box-text.tsx
│   │       │   ├── button.tsx
│   │       │   ├── footer.tsx
│   │       │   ├── header.tsx
│   │       │   └── heading.tsx
│   │       └── instant-notification-email.tsx
│   ├── common/
│   │   ├── Alerts/
│   │   │   ├── AlertBanner.test.tsx
│   │   │   ├── AlertBanner.tsx
│   │   │   ├── AlertIncompleteProfile.tsx
│   │   │   └── Alerts.tsx
│   │   ├── Analytics/
│   │   │   ├── GoogleAnalytics.tsx
│   │   │   └── index.tsx
│   │   ├── AuthWrapper.test.tsx
│   │   ├── AuthWrapper.tsx
│   │   ├── DonationRequestModalContainer.test.tsx
│   │   ├── DonationRequestModalContainer.tsx
│   │   ├── DownloadWrapper.test.tsx
│   │   ├── DownloadWrapper.tsx
│   │   ├── Form/
│   │   │   ├── Checkbox.tsx
│   │   │   ├── ErrorsContainer.test.tsx
│   │   │   ├── ErrorsContainer.tsx
│   │   │   ├── FieldContainer.ts
│   │   │   ├── FileInput/
│   │   │   │   ├── FileDisplay.tsx
│   │   │   │   └── FileInput.tsx
│   │   │   ├── FileInput.field.tsx
│   │   │   ├── FormWrapper.tsx
│   │   │   ├── PasswordField.tsx
│   │   │   ├── README.md
│   │   │   ├── Select.field.tsx
│   │   │   ├── TagsSelectField.tsx
│   │   │   ├── UnsavedChangesDialog.tsx
│   │   │   ├── labels.ts
│   │   │   └── types.ts
│   │   ├── HideDiscussionContainer.test.tsx
│   │   ├── HideDiscussionContainer.tsx
│   │   ├── Highlighter.tsx
│   │   ├── PageHeader.tsx
│   │   ├── PremiumTierWrapper.test.tsx
│   │   ├── PremiumTierWrapper.tsx
│   │   ├── Spinner.tsx
│   │   ├── Tags/
│   │   │   ├── ProfileTagsSelect.tsx
│   │   │   └── TagsSelect.tsx
│   │   ├── Toast/
│   │   │   ├── CustomToast.tsx
│   │   │   ├── index.tsx
│   │   │   └── useToast.tsx
│   │   ├── UserAction.test.tsx
│   │   ├── UserAction.tsx
│   │   └── hooks/
│   │       └── useClickOutside.ts
│   ├── config/
│   │   ├── config.ts
│   │   ├── constants.ts
│   │   ├── default.json
│   │   ├── imageTransforms.ts
│   │   └── types.ts
│   ├── constants.ts
│   ├── entry.client.tsx
│   ├── entry.server.tsx
│   ├── factories/
│   │   ├── commentFactory.server.ts
│   │   ├── mapPinFactory.server.ts
│   │   └── profileFactory.server.ts
│   ├── logger/
│   │   ├── index.test.ts
│   │   └── index.ts
│   ├── modules/
│   │   ├── index.test.ts
│   │   └── index.ts
│   ├── pages/
│   │   ├── Academy/
│   │   │   ├── Academy.test.tsx
│   │   │   ├── Academy.tsx
│   │   │   └── ExternalEmbed/
│   │   │       └── ExternalEmbed.tsx
│   │   ├── Library/
│   │   │   ├── Content/
│   │   │   │   ├── Common/
│   │   │   │   │   ├── DeleteProjectButton.tsx
│   │   │   │   │   ├── FormSettings.tsx
│   │   │   │   │   ├── Library.form.test.tsx
│   │   │   │   │   ├── LibraryCategory.field.tsx
│   │   │   │   │   ├── LibraryCategoryGuidance.test.tsx
│   │   │   │   │   ├── LibraryCategoryGuidance.tsx
│   │   │   │   │   ├── LibraryDescription.field.test.tsx
│   │   │   │   │   ├── LibraryDescription.field.tsx
│   │   │   │   │   ├── LibraryDifficulty.field.tsx
│   │   │   │   │   ├── LibraryFileLink.field.tsx
│   │   │   │   │   ├── LibraryFileUpload.field.tsx
│   │   │   │   │   ├── LibraryForm.tsx
│   │   │   │   │   ├── LibraryFormProvider.tsx
│   │   │   │   │   ├── LibraryPostingGuidelines.tsx
│   │   │   │   │   ├── LibraryStep.field.test.tsx
│   │   │   │   │   ├── LibraryStep.field.tsx
│   │   │   │   │   ├── LibraryStepsContainer.field.test.tsx
│   │   │   │   │   ├── LibraryStepsContainer.field.tsx
│   │   │   │   │   ├── LibraryTime.field.tsx
│   │   │   │   │   ├── LibraryTitle.field.test.tsx
│   │   │   │   │   └── LibraryTitle.field.tsx
│   │   │   │   ├── List/
│   │   │   │   │   ├── LibraryList.tsx
│   │   │   │   │   ├── LibraryListHeader.tsx
│   │   │   │   │   ├── LibrarySortOptions.ts
│   │   │   │   │   └── ProjectCard.tsx
│   │   │   │   ├── Page/
│   │   │   │   │   ├── LibraryDescription.tsx
│   │   │   │   │   ├── LibraryStep.tsx
│   │   │   │   │   └── ProjectPage.tsx
│   │   │   │   └── utils/
│   │   │   │       ├── downloadCooldown.ts
│   │   │   │       ├── index.ts
│   │   │   │       ├── transformLibraryErrors.test.ts
│   │   │   │       └── transformLibraryErrors.ts
│   │   │   ├── constants.ts
│   │   │   ├── labels.ts
│   │   │   └── library.service.ts
│   │   ├── Maps/
│   │   │   ├── Content/
│   │   │   │   ├── MapView/
│   │   │   │   │   ├── ButtonZoomIn.client.tsx
│   │   │   │   │   ├── Cluster.client.tsx
│   │   │   │   │   ├── MapList.tsx
│   │   │   │   │   ├── MapView.tsx
│   │   │   │   │   ├── MapWithListHeader.tsx
│   │   │   │   │   ├── Popup.client.tsx
│   │   │   │   │   ├── Sprites.tsx
│   │   │   │   │   ├── popup.css
│   │   │   │   │   └── sprites.css
│   │   │   │   └── MemberTypeVerticalList/
│   │   │   │       └── MemberTypeVerticalList.client.tsx
│   │   │   ├── MapContext.ts
│   │   │   ├── MapFilterList.tsx
│   │   │   ├── Maps.client.tsx
│   │   │   ├── map.service.ts
│   │   │   ├── styles.css
│   │   │   └── utils/
│   │   │       ├── geolocation.ts
│   │   │       ├── pinUtils.test.ts
│   │   │       └── pinUtils.ts
│   │   ├── News/
│   │   │   ├── Content/
│   │   │   │   └── Common/
│   │   │   │       ├── FormFields/
│   │   │   │       │   ├── NewsBodyField.tsx
│   │   │   │       │   ├── NewsImageField.tsx
│   │   │   │       │   └── index.ts
│   │   │   │       ├── NewsForm.test.tsx
│   │   │   │       ├── NewsForm.tsx
│   │   │   │       └── NewsPostingGuidelines.tsx
│   │   │   ├── NewsListHeader.tsx
│   │   │   ├── NewsListItem.tsx
│   │   │   ├── NewsListing.tsx
│   │   │   ├── NewsPage.test.tsx
│   │   │   ├── NewsPage.tsx
│   │   │   ├── NewsSortOptions.ts
│   │   │   ├── constants.ts
│   │   │   ├── labels.ts
│   │   │   └── newsContent.service.ts
│   │   ├── NotFound/
│   │   │   └── NotFound.tsx
│   │   ├── PageList.tsx
│   │   ├── Question/
│   │   │   ├── Content/
│   │   │   │   └── Common/
│   │   │   │       ├── FormFields/
│   │   │   │       │   ├── QuestionDescription.field.tsx
│   │   │   │       │   ├── QuestionImages.field.tsx
│   │   │   │       │   └── index.ts
│   │   │   │       ├── QuestionForm.tsx
│   │   │   │       ├── QuestionPostingGuidelines.tsx
│   │   │   │       └── index.ts
│   │   │   ├── QuestionListHeader.tsx
│   │   │   ├── QuestionListItem.tsx
│   │   │   ├── QuestionListing.tsx
│   │   │   ├── QuestionPage.test.tsx
│   │   │   ├── QuestionPage.tsx
│   │   │   ├── QuestionSortOptions.ts
│   │   │   ├── constants.ts
│   │   │   ├── labels.ts
│   │   │   └── question.service.ts
│   │   ├── Research/
│   │   │   ├── Content/
│   │   │   │   ├── Common/
│   │   │   │   │   ├── DeleteResearchButton.tsx
│   │   │   │   │   ├── FormFields/
│   │   │   │   │   │   ├── ResearchCollaboratorsField.tsx
│   │   │   │   │   │   ├── ResearchDescriptionField.tsx
│   │   │   │   │   │   └── ResearchTitleField.tsx
│   │   │   │   │   ├── ResearchCategorySelect.tsx
│   │   │   │   │   ├── ResearchForm.tsx
│   │   │   │   │   ├── ResearchPostingGuidelines.tsx
│   │   │   │   │   ├── ResearchUpdateForm.tsx
│   │   │   │   │   └── index.ts
│   │   │   │   ├── CreateResearch/
│   │   │   │   │   └── Form/
│   │   │   │   │       ├── DescriptionField.tsx
│   │   │   │   │       ├── ResearchImagesField.tsx
│   │   │   │   │       ├── TitleField.tsx
│   │   │   │   │       └── VideoUrlField.tsx
│   │   │   │   ├── ResearchArticle.test.tsx
│   │   │   │   ├── ResearchArticlePage.tsx
│   │   │   │   ├── ResearchDescription.tsx
│   │   │   │   ├── ResearchEngagementSection.tsx
│   │   │   │   ├── ResearchFooter.tsx
│   │   │   │   ├── ResearchLinkToUpdate.tsx
│   │   │   │   ├── ResearchList.tsx
│   │   │   │   ├── ResearchListHeader.tsx
│   │   │   │   ├── ResearchListItem.tsx
│   │   │   │   ├── ResearchSearchParams.ts
│   │   │   │   ├── ResearchUpdate.tsx
│   │   │   │   ├── helper.test.tsx
│   │   │   │   └── helper.ts
│   │   │   ├── ResearchSortOptions.ts
│   │   │   ├── constants.ts
│   │   │   ├── labels.ts
│   │   │   ├── research.service.test.ts
│   │   │   ├── research.service.ts
│   │   │   ├── researchHelpers.test.ts
│   │   │   └── researchHelpers.ts
│   │   ├── SignUp/
│   │   │   └── SignUpMessage.tsx
│   │   ├── User/
│   │   │   ├── constants.ts
│   │   │   ├── contact/
│   │   │   │   ├── UserContactFieldMessage.tsx
│   │   │   │   ├── UserContactFieldName.tsx
│   │   │   │   ├── UserContactForm.test.tsx
│   │   │   │   ├── UserContactForm.tsx
│   │   │   │   ├── UserContactFormAvailable.tsx
│   │   │   │   ├── UserContactFormNotLoggedIn.tsx
│   │   │   │   ├── UserContactNotLoggedIn.tsx
│   │   │   │   └── index.ts
│   │   │   ├── content/
│   │   │   │   ├── ProfileContact.tsx
│   │   │   │   ├── ProfileDetails.tsx
│   │   │   │   ├── ProfileHeader.tsx
│   │   │   │   ├── ProfileImage.tsx
│   │   │   │   ├── ProfilePage.tsx
│   │   │   │   ├── UserCreatedDocuments.test.tsx
│   │   │   │   ├── UserCreatedDocuments.tsx
│   │   │   │   ├── UserCreatedDocumentsItem.tsx
│   │   │   │   └── UserProfile.tsx
│   │   │   ├── impact/
│   │   │   │   ├── Impact.test.tsx
│   │   │   │   ├── Impact.tsx
│   │   │   │   ├── ImpactField.test.tsx
│   │   │   │   ├── ImpactField.tsx
│   │   │   │   ├── ImpactIcon.tsx
│   │   │   │   ├── ImpactItem.test.tsx
│   │   │   │   ├── ImpactItem.tsx
│   │   │   │   ├── ImpactMissing.test.tsx
│   │   │   │   ├── ImpactMissing.tsx
│   │   │   │   ├── constants.ts
│   │   │   │   └── labels.ts
│   │   │   └── labels.ts
│   │   ├── UserSettings/
│   │   │   ├── SettingsFormTab.tsx
│   │   │   ├── SettingsFormTabList.tsx
│   │   │   ├── SettingsPage.client.tsx
│   │   │   ├── SettingsPageAccount.tsx
│   │   │   ├── SettingsPageImpact.test.tsx
│   │   │   ├── SettingsPageImpact.tsx
│   │   │   ├── SettingsPageMapPin.test.tsx
│   │   │   ├── SettingsPageMapPin.tsx
│   │   │   ├── SettingsPageNotifications.tsx
│   │   │   ├── SettingsPageUserProfile.test.tsx
│   │   │   ├── SettingsPageUserProfile.tsx
│   │   │   ├── SupabaseNotifications.tsx
│   │   │   ├── SupabaseNotificationsForm.tsx
│   │   │   ├── SupabaseNotificationsViaEmail.tsx
│   │   │   ├── __mocks__/
│   │   │   │   └── FormProvider.tsx
│   │   │   ├── constants.ts
│   │   │   ├── content/
│   │   │   │   ├── elements.tsx
│   │   │   │   ├── fields/
│   │   │   │   │   ├── ImpactQuestion.field.tsx
│   │   │   │   │   ├── ImpactYear.field.tsx
│   │   │   │   │   ├── ImpactYearDisplay.field.tsx
│   │   │   │   │   ├── PatreonIntegration.test.tsx
│   │   │   │   │   ├── PatreonIntegration.tsx
│   │   │   │   │   └── ProfileTypeRadio.field.tsx
│   │   │   │   ├── impactQuestions.ts
│   │   │   │   └── sections/
│   │   │   │       ├── ChangeEmail.form.tsx
│   │   │   │       ├── ChangePassword.form.tsx
│   │   │   │       ├── EmailNotifications.section.tsx
│   │   │   │       ├── ImpactYear.section.tsx
│   │   │   │       ├── ProfileTags.section.tsx
│   │   │   │       ├── ProfileType.section.test.tsx
│   │   │   │       ├── ProfileType.section.tsx
│   │   │   │       ├── PublicContact.section.test.tsx
│   │   │   │       ├── PublicContact.section.tsx
│   │   │   │       ├── UserImages.section.tsx
│   │   │   │       ├── UserInfos.section.tsx
│   │   │   │       └── VisitorSection.tsx
│   │   │   ├── labels.ts
│   │   │   ├── services/
│   │   │   │   └── account.service.ts
│   │   │   ├── types.ts
│   │   │   ├── utils.test.ts
│   │   │   └── utils.ts
│   │   ├── common/
│   │   │   ├── Breadcrumbs/
│   │   │   │   └── Breadcrumbs.tsx
│   │   │   ├── Category/
│   │   │   │   └── CategoriesSelectV2.tsx
│   │   │   ├── CommentsSupabase/
│   │   │   │   ├── CollapsableCommentSection.tsx
│   │   │   │   ├── CommentItemSupabase.tsx
│   │   │   │   ├── CommentReplySupabase.tsx
│   │   │   │   ├── CommentSectionSupabase.tsx
│   │   │   │   ├── CommentSort.tsx
│   │   │   │   ├── CommentSortOptions.ts
│   │   │   │   ├── CreateCommentSupabase.css
│   │   │   │   ├── CreateCommentSupabase.tsx
│   │   │   │   └── useCopyCommentLink.ts
│   │   │   ├── Drafts/
│   │   │   │   ├── DraftButton.test.tsx
│   │   │   │   ├── DraftButton.tsx
│   │   │   │   ├── DraftTag.tsx
│   │   │   │   └── useDraftsSupabase.tsx
│   │   │   ├── FormFields/
│   │   │   │   ├── Category.field.tsx
│   │   │   │   ├── FilesFields.tsx
│   │   │   │   ├── FormFieldWrapper.test.tsx
│   │   │   │   ├── FormFieldWrapper.tsx
│   │   │   │   ├── ImageField.tsx
│   │   │   │   ├── ImageInputFieldWrapper.tsx
│   │   │   │   ├── ProfileBadgeField.tsx
│   │   │   │   ├── StepImagesField.tsx
│   │   │   │   ├── Tags.field.tsx
│   │   │   │   ├── Title.field.tsx
│   │   │   │   ├── index.ts
│   │   │   │   └── labels.ts
│   │   │   ├── GlobalSiteFooter/
│   │   │   │   └── GlobalSiteFooter.tsx
│   │   │   ├── Header/
│   │   │   │   ├── Header.tsx
│   │   │   │   ├── Menu/
│   │   │   │   │   ├── Logo/
│   │   │   │   │   │   └── Logo.tsx
│   │   │   │   │   ├── MenuDesktop.tsx
│   │   │   │   │   ├── MenuMobile/
│   │   │   │   │   │   ├── MenuMobileExternalLink.tsx
│   │   │   │   │   │   ├── MenuMobileLink.tsx
│   │   │   │   │   │   └── MenuMobilePanel.tsx
│   │   │   │   │   ├── Notifications/
│   │   │   │   │   │   └── NotificationsSupabase.tsx
│   │   │   │   │   ├── Profile/
│   │   │   │   │   │   ├── Profile.tsx
│   │   │   │   │   │   ├── ProfileButtonItem.tsx
│   │   │   │   │   │   ├── ProfileButtons.tsx
│   │   │   │   │   │   ├── UpgradeBadgeLink.tsx
│   │   │   │   │   │   └── profile.css
│   │   │   │   │   └── ProfileModal/
│   │   │   │   │       └── ProfileModal.tsx
│   │   │   │   └── MobileMenuContext.tsx
│   │   │   ├── Layout/
│   │   │   │   ├── ListHeader.tsx
│   │   │   │   ├── Main.tsx
│   │   │   │   └── MobileSortModal.tsx
│   │   │   ├── NotificationsContext.ts
│   │   │   ├── SessionContext.ts
│   │   │   ├── StickyButton.tsx
│   │   │   ├── TenantContext.ts
│   │   │   ├── UserNameSelect/
│   │   │   │   └── UserNameSelect.tsx
│   │   │   ├── UserNameTag/
│   │   │   │   └── UserNameTag.tsx
│   │   │   ├── banner.service.ts
│   │   │   └── labels.ts
│   │   ├── constants.ts
│   │   └── policy/
│   │       ├── PrivacyPolicy.tsx
│   │       └── TermsPolicy.tsx
│   ├── repository/
│   │   ├── supabase.server.ts
│   │   └── supabaseAdmin.server.ts
│   ├── root.tsx
│   ├── routes/
│   │   ├── [manifest.webmanifest].tsx
│   │   ├── [robots.txt].tsx
│   │   ├── _.$.tsx
│   │   ├── _.academy.$.tsx
│   │   ├── _.email-confirmation.tsx
│   │   ├── _.email-preferences.tsx
│   │   ├── _.feedback.tsx
│   │   ├── _.forbidden.tsx
│   │   ├── _.how-to.$slug._index.tsx
│   │   ├── _.how-to.$slug.edit.tsx
│   │   ├── _.how-to._index.tsx
│   │   ├── _.how-to.create.tsx
│   │   ├── _.how-to.tsx
│   │   ├── _.library.$slug._index.tsx
│   │   ├── _.library.$slug.edit.tsx
│   │   ├── _.library._index.tsx
│   │   ├── _.library.create.tsx
│   │   ├── _.library.tsx
│   │   ├── _.map.tsx
│   │   ├── _.news.$slug._index.tsx
│   │   ├── _.news.$slug.edit.tsx
│   │   ├── _.news._index.tsx
│   │   ├── _.news.create.tsx
│   │   ├── _.news.tsx
│   │   ├── _.patreon.tsx
│   │   ├── _.privacy.tsx
│   │   ├── _.questions.$slug._index.tsx
│   │   ├── _.questions.$slug.edit.tsx
│   │   ├── _.questions._index.tsx
│   │   ├── _.questions.create.tsx
│   │   ├── _.questions.tsx
│   │   ├── _.research.$slug._index.tsx
│   │   ├── _.research.$slug.edit-update.$updateId.tsx
│   │   ├── _.research.$slug.edit.tsx
│   │   ├── _.research.$slug.new-update.tsx
│   │   ├── _.research._index.tsx
│   │   ├── _.research.create.tsx
│   │   ├── _.research.tsx
│   │   ├── _.reset-password.tsx
│   │   ├── _.settings.$.tsx
│   │   ├── _.sign-in.tsx
│   │   ├── _.sign-up-message.tsx
│   │   ├── _.sign-up.tsx
│   │   ├── _.terms.tsx
│   │   ├── _.tsx
│   │   ├── _.u.$id._index.tsx
│   │   ├── _.u.tsx
│   │   ├── _.update-password.tsx
│   │   ├── _index.tsx
│   │   ├── api.account.change-email.tsx
│   │   ├── api.account.change-password.tsx
│   │   ├── api.banner.ts
│   │   ├── api.categories.$type.ts
│   │   ├── api.comments.$id.source.ts
│   │   ├── api.discussions.$sourceId.comments.$id.ts
│   │   ├── api.discussions.$sourceType.$sourceId.comments.ts
│   │   ├── api.documents.$type.$contentId.$docId.tsx
│   │   ├── api.documents.ts
│   │   ├── api.donation-settings.$profileId.ts
│   │   ├── api.favicon.ts
│   │   ├── api.images.ts
│   │   ├── api.map-filters.ts
│   │   ├── api.map-pin.ts
│   │   ├── api.map-pins.$userId.ts
│   │   ├── api.map-pins.ts
│   │   ├── api.messages.tsx
│   │   ├── api.news.$id.ts
│   │   ├── api.news.drafts.count.ts
│   │   ├── api.news.drafts.ts
│   │   ├── api.news.ts
│   │   ├── api.notifications-preferences-via-email.$userCode.ts
│   │   ├── api.notifications-preferences.ts
│   │   ├── api.notifications.$id.read.ts
│   │   ├── api.notifications.all.read.ts
│   │   ├── api.notifications.ts
│   │   ├── api.patreon.ts
│   │   ├── api.profile-badges.ts
│   │   ├── api.profile-tags.ts
│   │   ├── api.profile-types.ts
│   │   ├── api.profile.ts
│   │   ├── api.profile.username.ts
│   │   ├── api.profiles.ts
│   │   ├── api.projects.$id.ts
│   │   ├── api.projects.drafts.count.ts
│   │   ├── api.projects.drafts.ts
│   │   ├── api.projects.ts
│   │   ├── api.questions.$id.ts
│   │   ├── api.questions.drafts.count.ts
│   │   ├── api.questions.drafts.ts
│   │   ├── api.questions.ts
│   │   ├── api.research.$id.status.ts
│   │   ├── api.research.$id.ts
│   │   ├── api.research.$id.updates.$updateId.ts
│   │   ├── api.research.$id.updates.ts
│   │   ├── api.research.drafts.count.ts
│   │   ├── api.research.drafts.ts
│   │   ├── api.research.ts
│   │   ├── api.settings.impact.ts
│   │   ├── api.settings.map.ts
│   │   ├── api.subscribers.$contentType.$contentId.subscribed.ts
│   │   ├── api.subscribers.$contentType.$contentId.ts
│   │   ├── api.tags.ts
│   │   ├── api.upgrade-badges.ts
│   │   ├── api.useful.$contentType.$contentId.ts
│   │   ├── api.useful.$contentType.$contentId.users.ts
│   │   ├── api.useful.$contentType.$contentId.voted.ts
│   │   ├── api.useful.$contentType.$id.count.ts
│   │   ├── logout.ts
│   │   └── redirect.tsx
│   ├── routes.ts
│   ├── services/
│   │   ├── authService.server.ts
│   │   ├── broadcastCoordinationService.server.ts
│   │   ├── categoryService.ts
│   │   ├── commentService.ts
│   │   ├── contentRedirectService.server.ts
│   │   ├── contentService.server.ts
│   │   ├── discordService.server.ts
│   │   ├── formDataHelper.ts
│   │   ├── imageService.server.ts
│   │   ├── impactService.server.ts
│   │   ├── libraryService.server.ts
│   │   ├── mapPinsService.server.ts
│   │   ├── mapService.server.ts
│   │   ├── messageService.ts
│   │   ├── newsService.server.ts
│   │   ├── newsService.ts
│   │   ├── notificationEmailService.server.ts
│   │   ├── notificationMapperService.server.ts
│   │   ├── notificationsPreferencesService.ts
│   │   ├── notificationsPreferencesViaEmailService.ts
│   │   ├── notificationsSupabaseService.server.ts
│   │   ├── notificationsSupabaseService.ts
│   │   ├── patreonService.server.ts
│   │   ├── patreonService.ts
│   │   ├── profileBadgeService.ts
│   │   ├── profileService.server.ts
│   │   ├── profileService.ts
│   │   ├── profileTagsService.ts
│   │   ├── profileTypesService.server.ts
│   │   ├── profileTypesService.ts
│   │   ├── profilesService.ts
│   │   ├── questionService.server.test.ts
│   │   ├── questionService.server.ts
│   │   ├── questionService.ts
│   │   ├── redirectService.server.ts
│   │   ├── researchService.server.ts
│   │   ├── storageService.server.ts
│   │   ├── storageService.ts
│   │   ├── subscribersService.server.ts
│   │   ├── subscribersService.ts
│   │   ├── tagsService.server.ts
│   │   ├── tagsService.ts
│   │   ├── tenantSettingsService.server.ts
│   │   ├── upgradeBadgeService.ts
│   │   └── usefulService.ts
│   ├── stores/
│   │   ├── Profile/
│   │   │   ├── profile.store.test.ts
│   │   │   └── profile.store.tsx
│   │   ├── Subscription/
│   │   │   ├── subscription.store.test.ts
│   │   │   ├── subscription.store.tsx
│   │   │   └── useSubscription.tsx
│   │   └── UsefulVote/
│   │       ├── useUsefulVote.tsx
│   │       └── usefulVote.store.tsx
│   ├── styles/
│   │   ├── context.ts
│   │   ├── createEmotionCache.ts
│   │   └── leaflet.css
│   ├── test/
│   │   ├── components/
│   │   │   └── SettingsFormProvider.tsx
│   │   ├── factories/
│   │   │   ├── Category.ts
│   │   │   ├── Comment.ts
│   │   │   ├── Library.ts
│   │   │   ├── MapPin.ts
│   │   │   ├── News.ts
│   │   │   ├── Question.ts
│   │   │   ├── ResearchItem.ts
│   │   │   ├── User.ts
│   │   │   ├── dbNotification.ts
│   │   │   ├── notificationsPreferences.ts
│   │   │   ├── profile.ts
│   │   │   └── supabaseNotification.ts
│   │   ├── models/
│   │   │   └── profile.test.ts
│   │   ├── routes/
│   │   │   └── api.notifications-preferences.test.ts
│   │   ├── services/
│   │   │   ├── broadcastCoordinationService.server.ts
│   │   │   ├── notificationsPreferencesService.test.ts
│   │   │   ├── notificationsPreferencesViaEmailService.test.ts
│   │   │   └── subscribersService.server.test.ts
│   │   ├── setup.ts
│   │   └── utils/
│   │       └── supabaseClientMock.ts
│   ├── types/
│   │   └── emotion.d.ts
│   └── utils/
│       ├── comparisons.ts
│       ├── contentType.utils.ts
│       ├── filters.ts
│       ├── fireConfetti.ts
│       ├── formatImageListForGallery.ts
│       ├── getLocationData.ts
│       ├── getSummaryFromMarkdown.test.ts
│       ├── getSummaryFromMarkdown.ts
│       ├── helpers.test.ts
│       ├── helpers.ts
│       ├── httpException.ts
│       ├── mentions.utils.ts
│       ├── redirect.server.ts
│       ├── searchHelper.test.ts
│       ├── searchHelper.ts
│       ├── seo.utils.ts
│       ├── sessionStorage.ts
│       ├── slug.ts
│       ├── statistics.tsx
│       ├── stopwords.ts
│       ├── storage.ts
│       ├── tokens.server.ts
│       ├── urlHelper.ts
│       ├── urls.ts
│       ├── validators.test.ts
│       └── validators.ts
├── supabase/
│   ├── .gitignore
│   ├── README.md
│   ├── config.toml
│   ├── functions/
│   │   └── send-email/
│   │       ├── .npmrc
│   │       ├── _templates/
│   │       │   ├── components/
│   │       │   │   ├── box-text.tsx
│   │       │   │   ├── button.tsx
│   │       │   │   ├── footer.tsx
│   │       │   │   ├── header.tsx
│   │       │   │   ├── heading.tsx
│   │       │   │   ├── hero.tsx
│   │       │   │   ├── parent-box.tsx
│   │       │   │   └── plain-text.tsx
│   │       │   ├── email-change-new.tsx
│   │       │   ├── layout.tsx
│   │       │   ├── magic-link.tsx
│   │       │   ├── moderation-email.tsx
│   │       │   ├── reset-password.tsx
│   │       │   └── sign-up.tsx
│   │       ├── deno.json
│   │       ├── getTenantSettings.ts
│   │       ├── index.ts
│   │       └── signWebhookHeader.ts
│   ├── migrations/
│   │   ├── 20241125140428_profiles_and_comments.sql
│   │   ├── 20250111151556_questions.sql
│   │   ├── 20250113184950_profile_auth_columns.sql
│   │   ├── 20250208130256_auth_rpc.sql
│   │   ├── 20250209131232_profile_firebase.sql
│   │   ├── 20250214235014_messages.sql
│   │   ├── 20250225071100_unique_username.sql
│   │   ├── 20250307061534_messages_temp_fix.sql
│   │   ├── 20250312063008_patreon.sql
│   │   ├── 20250331134409_add_news.sql
│   │   ├── 20250416104948_research.sql
│   │   ├── 20250422092704_add_notifications.sql
│   │   ├── 20250512170000_research_sorting.sql
│   │   ├── 20250513090512_update_for_email_notifications.sql
│   │   ├── 20250514163118_update_notifications.sql
│   │   ├── 20250520134140_update_notifications_for_research_comments.sql
│   │   ├── 20250521044802_fix-research-sorting-useful.sql
│   │   ├── 20250523104253_20250523_add-get-user-questions.sql
│   │   ├── 20250603130017_add_notifications_preferences.sql
│   │   ├── 20250605115351_research-latest-updated.sql
│   │   ├── 20250609100159_research_query_ranking.sql
│   │   ├── 20250609101144_library.sql
│   │   ├── 20250617151457_update_notification_preferences.sql
│   │   ├── 20250621165139_user_research_filter_draft.sql
│   │   ├── 20250624101144_replace_get_projects_count.sql
│   │   ├── 20250624101145_replace_get_user_projects.sql
│   │   ├── 20250624101147_replace_get_user_projects_again.sql
│   │   ├── 20250625162400_update_questions_news_is_draft.sql
│   │   ├── 20250702155642_add_unsubscribe_to_preferences.sql
│   │   ├── 20250722145300_profile.sql
│   │   ├── 20250819103736_add_badge_id_to_news.sql
│   │   ├── 20250824222054_fix-author-vote-count-deleted.sql
│   │   ├── 20250830203011_banner.sql
│   │   ├── 20250902101059_map_pins-optimizations.sql
│   │   ├── 20250904101010_useful_comments.sql
│   │   ├── 20250912091153_fix-delete-comment-trigger.sql
│   │   ├── 20250912110000_optimize_get_comments_with_votes.sql
│   │   ├── 20250912210000_optimize_profile_indexes.sql
│   │   ├── 20250914104923_update_notifications.sql
│   │   ├── 20251011132910_fix_messages_receiver.sql
│   │   ├── 20251011233154_fix_policy_performance.sql
│   │   ├── 20251011234304_fix_function_security_warning.sql
│   │   ├── 20251012135652_fix_policy_performance_2.sql
│   │   ├── 20251024140004_fix_get_project_count.sql
│   │   ├── 20251025145021_add_most_views_sort.sql
│   │   ├── 20251031045802_add_favicon.sql
│   │   ├── 20251119072930_track_badges.sql
│   │   ├── 20251124054625_profile_donations.sql
│   │   ├── 20251130000401_create_upgrade_badge_table.sql
│   │   ├── 20251203151049_research_author_search_fix.sql
│   │   ├── 20251217132033_add_most_useful_last_week_feature.sql
│   │   ├── 20260103002808_add_premium_tier.sql
│   │   ├── 20260118140428_update_user_doc_gets.sql
│   │   ├── 20260118233300_batch_notifications.sql
│   │   ├── 20260216125228_more_tenant_settings.sql
│   │   ├── 20260227070309_site_description.sql
│   │   ├── 20260301000000_fix_partial_search.sql
│   │   ├── 20260309135320_questions_search_rpc.sql
│   │   ├── 20260317131051_add_published_at.sql
│   │   ├── 20260322000000_add_get_storage_object_path.sql
│   │   ├── 20260330124656_make_username_nullable.sql
│   │   ├── 20260401000000_tenant_settings_ga.sql
│   │   ├── 20260402103538_search_multiple_words.sql
│   │   ├── 20260402150623_search_stop_words.sql
│   │   └── 20260421051050_pwa_icons.sql
│   ├── schemas/
│   │   ├── banners.sql
│   │   ├── categories.sql
│   │   ├── comments.sql
│   │   ├── common.sql
│   │   ├── map.sql
│   │   ├── messages.sql
│   │   ├── news.sql
│   │   ├── notifications.sql
│   │   ├── patreon.sql
│   │   ├── profiles.sql
│   │   ├── projects.sql
│   │   ├── questions.sql
│   │   ├── research.sql
│   │   ├── subscribers.sql
│   │   ├── tags.sql
│   │   ├── tenant_settings.sql
│   │   └── useful.sql
│   └── seed.sql
├── tsconfig.json
├── tsconfig.prod.json
├── vite-env.d.ts
└── vite.config.ts

================================================
FILE CONTENTS
================================================

================================================
FILE: .all-contributorsrc
================================================
{
  "files": [
    "README.md"
  ],
  "imageSize": 60,
  "contributorsPerLine": 7,
  "contributorsSortAlphabetically": false,
  "badgeTemplate": "[![All Contributors](https://img.shields.io/badge/all_contributors-<%= contributors.length %>-orange.svg?style=flat-square)](#contributors)",
  "types": {
    "maintenance": {
      "symbol": "💪",
      "description": "Maintainer",
      "link": "[<%= symbol %>](\"<%= description %>\"),"
    }
  },
  "contributors": [
    {
      "login": "davehakkens",
      "name": "Dave Hakkens",
      "avatar_url": "https://avatars.githubusercontent.com/u/13672737?v=4",
      "profile": "http://davehakkens.nl",
      "contributions": [
        "design",
        "ideas",
        "projectManagement",
        "maintenance"
      ]
    },
    {
      "login": "chrismclarke",
      "name": "Chris Clarke",
      "avatar_url": "https://avatars.githubusercontent.com/u/10515065?v=4",
      "profile": "https://c2dev.co.uk/",
      "contributions": [
        "code",
        "maintenance"
      ]
    },
    {
      "login": "thisislawatts",
      "name": "Luke Watts",
      "avatar_url": "https://avatars.githubusercontent.com/u/472589?v=4",
      "profile": "https://thisis.la/",
      "contributions": [
        "code",
        "maintenance"
      ]
    },
    {
      "login": "amuroBosetti",
      "name": "Mauro Bosetti",
      "avatar_url": "https://avatars.githubusercontent.com/u/46928545?v=4",
      "profile": "https://github.com/amuroBosetti",
      "contributions": [
        "doc"
      ]
    },
    {
      "login": "patrycjapraczyk",
      "name": "patrycjapraczyk",
      "avatar_url": "https://avatars.githubusercontent.com/u/35103888?v=4",
      "profile": "https://github.com/patrycjapraczyk",
      "contributions": [
        "code"
      ]
    },
    {
      "login": "tedspare",
      "name": "Ted Spare",
      "avatar_url": "https://avatars.githubusercontent.com/u/36117635?v=4",
      "profile": "https://tedspare.com",
      "contributions": [
        "code"
      ]
    },
    {
      "login": "eliasvelardezft",
      "name": "Elias Velardez",
      "avatar_url": "https://avatars.githubusercontent.com/u/40184787?v=4",
      "profile": "https://www.linkedin.com/in/eliasvelardez",
      "contributions": [
        "code"
      ]
    },
    {
      "login": "AlfonsoGhislieri",
      "name": "Alfonso",
      "avatar_url": "https://avatars.githubusercontent.com/u/652368?v=4",
      "profile": "https://github.com/AlfonsoGhislieri",
      "contributions": [
        "code",
        "maintenance"
      ]
    },
    {
      "login": "Xyli0",
      "name": "Xyli0",
      "avatar_url": "https://avatars.githubusercontent.com/u/10441748?v=4",
      "profile": "https://github.com/Xyli0",
      "contributions": [
        "code"
      ]
    },
    {
      "login": "laianbraum",
      "name": "Laian Braum",
      "avatar_url": "https://avatars.githubusercontent.com/u/61033391?v=4",
      "profile": "http://www.linkedin.com/in/laianbraum",
      "contributions": [
        "code"
      ]
    },
    {
      "login": "osouthwell-scottlogic",
      "name": "osouthwell-scottlogic",
      "avatar_url": "https://avatars.githubusercontent.com/u/98388720?v=4",
      "profile": "https://github.com/osouthwell-scottlogic",
      "contributions": [
        "code"
      ]
    },
    {
      "login": "asheerrizvi",
      "name": "Asheer Rizvi",
      "avatar_url": "https://avatars.githubusercontent.com/u/17976252?v=4",
      "profile": "http://asheerrizvi.com",
      "contributions": [
        "code"
      ]
    },
    {
      "login": "franknoirot",
      "name": "Frank Noirot",
      "avatar_url": "https://avatars.githubusercontent.com/u/23481541?v=4",
      "profile": "https://franknoirot.co",
      "contributions": [
        "design"
      ]
    },
    {
      "login": "LucasGabrielBecker",
      "name": "Lucas Becker ",
      "avatar_url": "https://avatars.githubusercontent.com/u/48301172?v=4",
      "profile": "https://github.com/LucasGabrielBecker",
      "contributions": [
        "code"
      ]
    },
    {
      "login": "cschilbe",
      "name": "Conrad Schilbe",
      "avatar_url": "https://avatars.githubusercontent.com/u/485557?v=4",
      "profile": "https://github.com/cschilbe",
      "contributions": [
        "code"
      ]
    },
    {
      "login": "ThakurKarthik",
      "name": "Thakur Karthik",
      "avatar_url": "https://avatars.githubusercontent.com/u/26309938?v=4",
      "profile": "https://github.com/ThakurKarthik",
      "contributions": [
        "code"
      ]
    },
    {
      "login": "danitrod",
      "name": "Daniel T. Rodrigues",
      "avatar_url": "https://avatars.githubusercontent.com/u/45438149?v=4",
      "profile": "https://www.linkedin.com/in/danitrod/",
      "contributions": [
        "code"
      ]
    },
    {
      "login": "adrianduke",
      "name": "Adrian Duke",
      "avatar_url": "https://avatars.githubusercontent.com/u/711058?v=4",
      "profile": "https://github.com/adrianduke",
      "contributions": [
        "code"
      ]
    },
    {
      "login": "missalyss",
      "name": "Alyssa Helgason",
      "avatar_url": "https://avatars.githubusercontent.com/u/19866110?v=4",
      "profile": "https://github.com/missalyss",
      "contributions": [
        "code"
      ]
    },
    {
      "login": "Kiebert",
      "name": "Kieb",
      "avatar_url": "https://avatars.githubusercontent.com/u/3414938?v=4",
      "profile": "https://github.com/Kiebert",
      "contributions": [
        "code"
      ]
    },
    {
      "login": "Sc4ramouche",
      "name": "Kovechenkov Vladislav",
      "avatar_url": "https://avatars.githubusercontent.com/u/25829136?v=4",
      "profile": "https://github.com/Sc4ramouche",
      "contributions": [
        "code"
      ]
    },
    {
      "login": "cerkiewny",
      "name": "Devtato",
      "avatar_url": "https://avatars.githubusercontent.com/u/4504330?v=4",
      "profile": "http://devtato.com",
      "contributions": [
        "code"
      ]
    },
    {
      "login": "NoHara42",
      "name": "Ned O'Hara",
      "avatar_url": "https://avatars.githubusercontent.com/u/43496778?v=4",
      "profile": "https://github.com/NoHara42",
      "contributions": [
        "code"
      ]
    },
    {
      "login": "SophXN",
      "name": "Sophia Nguyen",
      "avatar_url": "https://avatars.githubusercontent.com/u/80185757?v=4",
      "profile": "https://github.com/SophXN",
      "contributions": [
        "code"
      ]
    },
    {
      "login": "evakill",
      "name": "Eva Killenberg",
      "avatar_url": "https://avatars.githubusercontent.com/u/37253846?v=4",
      "profile": "https://www.evakillenberg.com",
      "contributions": [
        "code",
        "maintenance"
      ]
    },
    {
      "login": "iSCJT",
      "name": "Sean Thompson",
      "avatar_url": "https://avatars.githubusercontent.com/u/80723794?v=4",
      "profile": "https://speckledbanana.com",
      "contributions": [
        "code",
        "maintenance"
      ]
    },
    {
      "login": "NguyenVanDo51",
      "name": "Nguyễn Văn Đỏ",
      "avatar_url": "https://avatars.githubusercontent.com/u/30190734?v=4",
      "profile": "https://github.com/NguyenVanDo51",
      "contributions": [
        "code"
      ]
    },
    {
      "login": "KungRaseri",
      "name": "KungRaseri",
      "avatar_url": "https://avatars.githubusercontent.com/u/1054240?v=4",
      "profile": "https://kungraseri.dev",
      "contributions": [
        "doc"
      ]
    },
    {
      "login": "BaltacMihai",
      "name": "Mihai-Cristian Bâltac",
      "avatar_url": "https://avatars.githubusercontent.com/u/72079422?v=4",
      "profile": "https://github.com/BaltacMihai",
      "contributions": [
        "code"
      ]
    },
    {
      "login": "CDeighton",
      "name": "Cullum Deighton",
      "avatar_url": "https://avatars.githubusercontent.com/u/13475443?v=4",
      "profile": "https://github.com/CDeighton",
      "contributions": [
        "code"
      ]
    },
    {
      "login": "d-skowronski",
      "name": "Dawid Skowroński",
      "avatar_url": "https://avatars.githubusercontent.com/u/98740166?v=4",
      "profile": "https://github.com/d-skowronski",
      "contributions": [
        "code"
      ]
    },
    {
      "login": "jonboiser",
      "name": "Jonathan Boiser",
      "avatar_url": "https://avatars.githubusercontent.com/u/10248067?v=4",
      "profile": "http://jonboiser.com",
      "contributions": [
        "code"
      ]
    },
    {
      "login": "benfurber",
      "name": "benfurber",
      "avatar_url": "https://avatars.githubusercontent.com/u/16688508?v=4",
      "profile": "https://github.com/benfurber",
      "contributions": [
        "code",
        "maintenance",
        "doc"
      ]
    },
    {
      "login": "AlimurtuzaCodes",
      "name": "Alimurtuza",
      "avatar_url": "https://avatars.githubusercontent.com/u/88965204?v=4",
      "profile": "https://github.com/AlimurtuzaCodes",
      "contributions": [
        "code"
      ]
    },
    {
      "login": "AliAbuSalam",
      "name": "Askell",
      "avatar_url": "https://avatars.githubusercontent.com/u/17426615?v=4",
      "profile": "https://github.com/AliAbuSalam",
      "contributions": [
        "code"
      ]
    },
    {
      "login": "manacespereira",
      "name": "Manacés Pereira",
      "avatar_url": "https://avatars.githubusercontent.com/u/8915867?v=4",
      "profile": "https://linkedin.com/in/manacesneto",
      "contributions": [
        "code"
      ]
    },
    {
      "login": "5niperspider",
      "name": "Georg Karl",
      "avatar_url": "https://avatars.githubusercontent.com/u/62932392?v=4",
      "profile": "https://github.com/5niperspider",
      "contributions": [
        "code"
      ]
    },
    {
      "login": "asdFletcher",
      "name": "asdFletcher",
      "avatar_url": "https://avatars.githubusercontent.com/u/42685363?v=4",
      "profile": "https://www.linkedin.com/in/fletcher-larue/",
      "contributions": [
        "code"
      ]
    },
    {
      "login": "bagiyal",
      "name": "Abhishek Bagiyal",
      "avatar_url": "https://avatars.githubusercontent.com/u/63339447?v=4",
      "profile": "https://github.com/bagiyal",
      "contributions": [
        "code"
      ]
    },
    {
      "login": "CrowsVeldt",
      "name": "Zack",
      "avatar_url": "https://avatars.githubusercontent.com/u/8883408?v=4",
      "profile": "https://github.com/CrowsVeldt",
      "contributions": [
        "code"
      ]
    },
    {
      "login": "benkelaar",
      "name": "Bart Enkelaar",
      "avatar_url": "https://avatars.githubusercontent.com/u/1822855?v=4",
      "profile": "https://careers.bol.com/",
      "contributions": [
        "code"
      ]
    },
    {
      "login": "laviodias",
      "name": "Lávio Vale",
      "avatar_url": "https://avatars.githubusercontent.com/u/44332001?v=4",
      "profile": "https://github.com/laviodias",
      "contributions": [
        "code"
      ]
    },
    {
      "login": "manuelrurda",
      "name": "Manuel Rodriguez Urdapilelta",
      "avatar_url": "https://avatars.githubusercontent.com/u/62727899?v=4",
      "profile": "https://github.com/manuelrurda",
      "contributions": [
        "code"
      ]
    },
    {
      "login": "LiptonB",
      "name": "Ben Lipton",
      "avatar_url": "https://avatars.githubusercontent.com/u/467965?v=4",
      "profile": "https://github.com/LiptonB",
      "contributions": [
        "code"
      ]
    },
    {
      "login": "ayachish",
      "name": "Ayachi Sharma",
      "avatar_url": "https://avatars.githubusercontent.com/u/102033230?v=4",
      "profile": "https://github.com/ayachish",
      "contributions": [
        "doc"
      ]
    },
    {
      "login": "arthurtyukayev",
      "name": "Arthur Tyukayev",
      "avatar_url": "https://avatars.githubusercontent.com/u/9029936?v=4",
      "profile": "https://tyukayev.com",
      "contributions": [
        "code"
      ]
    },
    {
      "login": "jgable",
      "name": "Jacob Gable",
      "avatar_url": "https://avatars.githubusercontent.com/u/164497?v=4",
      "profile": "https://github.com/jgable",
      "contributions": [
        "code"
      ]
    },
    {
      "login": "BeeMargarida",
      "name": "Ana Margarida Silva",
      "avatar_url": "https://avatars.githubusercontent.com/u/25725586?v=4",
      "profile": "https://beemargarida.github.io",
      "contributions": [
        "code"
      ]
    },
    {
      "login": "cjh1212",
      "name": "cjh1212",
      "avatar_url": "https://avatars.githubusercontent.com/u/45911291?v=4",
      "profile": "https://github.com/cjh1212",
      "contributions": [
        "code"
      ]
    },
    {
      "login": "pizzaisdavid",
      "name": "David Germain",
      "avatar_url": "https://avatars.githubusercontent.com/u/4391884?v=4",
      "profile": "https://pizzaisdavid.medium.com/",
      "contributions": [
        "doc",
        "code"
      ]
    },
    {
      "login": "ajotka",
      "name": "AJOTKA",
      "avatar_url": "https://avatars.githubusercontent.com/u/15144546?v=4",
      "profile": "http://ajotka.com",
      "contributions": [
        "code"
      ]
    },
    {
      "login": "CheRayLiu",
      "name": "Ray Liu",
      "avatar_url": "https://avatars.githubusercontent.com/u/17478640?v=4",
      "profile": "http://rayliu.me",
      "contributions": [
        "code"
      ]
    },
    {
      "login": "Erkanerkisi",
      "name": "Erkan Erkişi",
      "avatar_url": "https://avatars.githubusercontent.com/u/22741824?v=4",
      "profile": "http://erkanerkisi.github.io",
      "contributions": [
        "code"
      ]
    },
    {
      "login": "denyilm",
      "name": "denyilm",
      "avatar_url": "https://avatars.githubusercontent.com/u/65300462?v=4",
      "profile": "https://github.com/denyilm",
      "contributions": [
        "code"
      ]
    },
    {
      "login": "zweertsk",
      "name": "Koen",
      "avatar_url": "https://avatars.githubusercontent.com/u/131855633?v=4",
      "profile": "https://github.com/zweertsk",
      "contributions": [
        "code"
      ]
    },
    {
      "login": "goratt12",
      "name": "Guy Ribak",
      "avatar_url": "https://avatars.githubusercontent.com/u/23094928?v=4",
      "profile": "https://github.com/goratt12",
      "contributions": [
        "code"
      ]
    },
    {
      "login": "onim-at",
      "name": "Cosimo Chetta",
      "avatar_url": "https://avatars.githubusercontent.com/u/45094836?v=4",
      "profile": "https://github.com/onim-at",
      "contributions": [
        "code"
      ]
    },
    {
      "login": "rchick",
      "name": "Roger Chick",
      "avatar_url": "https://avatars.githubusercontent.com/u/555883?v=4",
      "profile": "http://uk.linkedin.com/in/rogerchick",
      "contributions": [
        "code"
      ]
    },
    {
      "login": "IgnasPlace",
      "name": "Ignas",
      "avatar_url": "https://avatars.githubusercontent.com/u/76262712?v=4",
      "profile": "http://ignasplace.com",
      "contributions": [
        "code"
      ]
    },
    {
      "login": "mariojsnunes",
      "name": "Mário Nunes",
      "avatar_url": "https://avatars.githubusercontent.com/u/8073622?v=4",
      "profile": "https://github.com/mariojsnunes",
      "contributions": [
        "code",
        "maintenance"
      ]
    },
    {
      "login": "oktomus",
      "name": "Kevin Masson",
      "avatar_url": "https://avatars.githubusercontent.com/u/4656466?v=4",
      "profile": "https://github.com/oktomus",
      "contributions": [
        "code"
      ]
    },
    {
      "login": "darigovresearch",
      "name": "Darigov Research",
      "avatar_url": "https://avatars.githubusercontent.com/u/30328618?v=4",
      "profile": "https://www.darigovresearch.com/",
      "contributions": [
        "doc"
      ]
    },
    {
      "login": "Shamauk",
      "name": "Zachary Doucet",
      "avatar_url": "https://avatars.githubusercontent.com/u/21955868?v=4",
      "profile": "http://cs.mcgill.ca/~zdouce",
      "contributions": [
        "code"
      ]
    },
    {
      "login": "viracoding",
      "name": "viracoding",
      "avatar_url": "https://avatars.githubusercontent.com/u/20618068?v=4",
      "profile": "https://github.com/viracoding",
      "contributions": [
        "code"
      ]
    },
    {
      "login": "Gashmoh",
      "name": "Gashmoh",
      "avatar_url": "https://avatars.githubusercontent.com/u/24207256?v=4",
      "profile": "https://github.com/Gashmoh",
      "contributions": [
        "code"
      ]
    },
    {
      "login": "dariusmihut",
      "name": "dariusmihut",
      "avatar_url": "https://avatars.githubusercontent.com/u/7417010?v=4",
      "profile": "https://github.com/dariusmihut",
      "contributions": [
        "code"
      ]
    },
    {
      "login": "dcustodio",
      "name": "David Custódio",
      "avatar_url": "https://avatars.githubusercontent.com/u/2907004?v=4",
      "profile": "https://github.com/dcustodio",
      "contributions": [
        "code"
      ]
    },
    {
      "login": "saile515",
      "name": "Elias Jörgensen",
      "avatar_url": "https://avatars.githubusercontent.com/u/63782477?v=4",
      "profile": "https://www.eliasjorgensen.se",
      "contributions": [
        "code"
      ]
    },
    {
      "login": "devChary",
      "name": "devChary",
      "avatar_url": "https://avatars.githubusercontent.com/u/26999371?v=4",
      "profile": "http://www.jagan-chary.com",
      "contributions": [
        "code"
      ]
    },
    {
      "login": "paposeco",
      "name": "Fabi",
      "avatar_url": "https://avatars.githubusercontent.com/u/13892562?v=4",
      "profile": "https://github.com/paposeco",
      "contributions": [
        "code"
      ]
    },
    {
      "login": "Robert-LC",
      "name": "Robert",
      "avatar_url": "https://avatars.githubusercontent.com/u/72999492?v=4",
      "profile": "https://github.com/Robert-LC",
      "contributions": [
        "code"
      ]
    },
    {
      "login": "phlapjack",
      "name": "Phillip Atkinson",
      "avatar_url": "https://avatars.githubusercontent.com/u/1590042?v=4",
      "profile": "https://github.com/phlapjack",
      "contributions": [
        "code"
      ]
    },
    {
      "login": "exabyssus",
      "name": "Andris",
      "avatar_url": "https://avatars.githubusercontent.com/u/6299387?v=4",
      "profile": "http://agw.lv/",
      "contributions": [
        "code"
      ]
    },
    {
      "login": "EdwardAndress",
      "name": "Edward Andress",
      "avatar_url": "https://avatars.githubusercontent.com/u/7963978?v=4",
      "profile": "https://github.com/EdwardAndress",
      "contributions": [
        "code"
      ]
    },
    {
      "login": "tuliobluz",
      "name": "Túlio Luz",
      "avatar_url": "https://avatars.githubusercontent.com/u/21323883?v=4",
      "profile": "https://github.com/tuliobluz",
      "contributions": [
        "code"
      ]
    },
    {
      "login": "codisart",
      "name": "Louis",
      "avatar_url": "https://avatars.githubusercontent.com/u/1767237?v=4",
      "profile": "https://github.com/codisart",
      "contributions": [
        "code"
      ]
    },
    {
      "login": "V24039",
      "name": "Venu G Soganadgi",
      "avatar_url": "https://avatars.githubusercontent.com/u/52736045?v=4",
      "profile": "https://venugsportfolio.netlify.app/",
      "contributions": [
        "code"
      ]
    },
    {
      "login": "Augustindou",
      "name": "Augustindou",
      "avatar_url": "https://avatars.githubusercontent.com/u/44368825?v=4",
      "profile": "https://github.com/Augustindou",
      "contributions": [
        "code"
      ]
    },
    {
      "login": "prashik0202",
      "name": "Prashik Gamre",
      "avatar_url": "https://avatars.githubusercontent.com/u/88095936?v=4",
      "profile": "https://prashikgamre.vercel.app/",
      "contributions": [
        "code"
      ]
    },
    {
      "login": "simontree",
      "name": "Robert",
      "avatar_url": "https://avatars.githubusercontent.com/u/59532700?v=4",
      "profile": "https://github.com/simontree",
      "contributions": [
        "code"
      ]
    },
    {
      "login": "kimskovhusandersen",
      "name": "Kim Skovhus Andersen",
      "avatar_url": "https://avatars.githubusercontent.com/u/5513342?v=4",
      "profile": "https://github.com/kimskovhusandersen",
      "contributions": [
        "code"
      ]
    },
    {
      "login": "leoasimon",
      "name": "leoasimon",
      "avatar_url": "https://avatars.githubusercontent.com/u/89898967?v=4",
      "profile": "https://github.com/leoasimon",
      "contributions": [
        "code"
      ]
    },
    {
      "login": "lucaasrojas",
      "name": "Lucas Rojas",
      "avatar_url": "https://avatars.githubusercontent.com/u/26610409?v=4",
      "profile": "https://lucaasrojas-portfolio.vercel.app/",
      "contributions": [
        "code"
      ]
    },
    {
      "login": "luismgsantos",
      "name": "Luís Santos",
      "avatar_url": "https://avatars.githubusercontent.com/u/13033016?v=4",
      "profile": "http://luismgsantos.github.io",
      "contributions": [
        "code"
      ]
    },
    {
      "login": "koeppel",
      "name": "Janik Köppel",
      "avatar_url": "https://avatars.githubusercontent.com/u/12177323?v=4",
      "profile": "https://github.com/koeppel",
      "contributions": [
        "code"
      ]
    },
    {
      "login": "Shalankwa",
      "name": "Jonathan Goodman",
      "avatar_url": "https://avatars.githubusercontent.com/u/31330598?v=4",
      "profile": "https://github.com/Shalankwa",
      "contributions": [
        "code"
      ]
    },
    {
      "login": "LahuenGR",
      "name": "LahuenGR",
      "avatar_url": "https://avatars.githubusercontent.com/u/101137877?v=4",
      "profile": "https://github.com/LahuenGR",
      "contributions": [
        "code"
      ]
    },
    {
      "login": "JoseAConcepcion",
      "name": "José Antonio Concepción",
      "avatar_url": "https://avatars.githubusercontent.com/u/99701565?v=4",
      "profile": "https://github.com/JoseAConcepcion",
      "contributions": [
        "code"
      ]
    },
    {
      "login": "jaykayudo",
      "name": "Joshua Kelechi",
      "avatar_url": "https://avatars.githubusercontent.com/u/58009744?v=4",
      "profile": "https://github.com/jaykayudo",
      "contributions": [
        "code"
      ]
    },
    {
      "login": "mchen10",
      "name": "Michael Chen",
      "avatar_url": "https://avatars.githubusercontent.com/u/16161485?v=4",
      "profile": "https://github.com/mchen10",
      "contributions": [
        "code"
      ]
    },
    {
      "login": "motuz0001",
      "name": "Matúš Motyka",
      "avatar_url": "https://avatars.githubusercontent.com/u/61076969?v=4",
      "profile": "https://github.com/motuz0001",
      "contributions": [
        "code"
      ]
    },
    {
      "login": "cypherpepe",
      "name": "Cypher Pepe",
      "avatar_url": "https://avatars.githubusercontent.com/u/125112044?v=4",
      "profile": "https://github.com/cypherpepe",
      "contributions": [
        "doc"
      ]
    },
    {
      "login": "dalibormrska",
      "name": "Dalibor Mrška",
      "avatar_url": "https://avatars.githubusercontent.com/u/35503298?v=4",
      "profile": "https://www.behance.net/dalibormrska",
      "contributions": [
        "design"
      ]
    },
    {
      "login": "sky-coderay",
      "name": "Skylar Ray",
      "avatar_url": "https://avatars.githubusercontent.com/u/137945430?v=4",
      "profile": "https://github.com/sky-coderay",
      "contributions": [
        "doc"
      ]
    },
    {
      "login": "johannes-ross",
      "name": "Johannes Roß",
      "avatar_url": "https://avatars.githubusercontent.com/u/74828657?v=4",
      "profile": "http://johannesross.de",
      "contributions": [
        "code"
      ]
    },
    {
      "login": "detrina",
      "name": "Devkuni",
      "avatar_url": "https://avatars.githubusercontent.com/u/155117116?v=4",
      "profile": "https://github.com/detrina",
      "contributions": [
        "doc"
      ]
    },
    {
      "login": "Bilogweb3",
      "name": "Bilog WEB3",
      "avatar_url": "https://avatars.githubusercontent.com/u/155262265?v=4",
      "profile": "https://github.com/Bilogweb3",
      "contributions": [
        "doc"
      ]
    },
    {
      "login": "ebradbury",
      "name": "Elliot Bradbury",
      "avatar_url": "https://avatars.githubusercontent.com/u/253679?v=4",
      "profile": "https://github.com/ebradbury",
      "contributions": [
        "code"
      ]
    },
    {
      "login": "joseh29",
      "name": "José",
      "avatar_url": "https://avatars.githubusercontent.com/u/70706814?v=4",
      "profile": "http://www.linkedin.com/in/joseh29",
      "contributions": [
        "code"
      ]
    },
    {
      "login": "maximevtush",
      "name": "Maxim Evtush",
      "avatar_url": "https://avatars.githubusercontent.com/u/154841002?v=4",
      "profile": "https://github.com/maximevtush",
      "contributions": [
        "doc"
      ]
    },
    {
      "login": "kilavvy",
      "name": "kilavvy",
      "avatar_url": "https://avatars.githubusercontent.com/u/140459108?v=4",
      "profile": "https://github.com/kilavvy",
      "contributions": [
        "doc"
      ]
    },
    {
      "login": "mohitsharma23",
      "name": "Mohit Sharma",
      "avatar_url": "https://avatars.githubusercontent.com/u/32203733?v=4",
      "profile": "https://github.com/mohitsharma23",
      "contributions": [
        "code"
      ]
    },
    {
      "login": "paulaFenner",
      "name": "Paula Fenner",
      "avatar_url": "https://avatars.githubusercontent.com/u/18422622?v=4",
      "profile": "https://github.com/paulaFenner",
      "contributions": [
        "code"
      ]
    },
    {
      "login": "ismaelabujadur",
      "name": "Ismael Abu-jadur Garcia",
      "avatar_url": "https://avatars.githubusercontent.com/u/112013216?v=4",
      "profile": "http://ismaelabujadur.github.io",
      "contributions": [
        "code"
      ]
    },
    {
      "login": "NickTheWilder",
      "name": "Nick Wilder",
      "avatar_url": "https://avatars.githubusercontent.com/u/38483425?v=4",
      "profile": "https://nickthewilder.com",
      "contributions": [
        "code"
      ]
    },
    {
      "login": "dizer-ti",
      "name": "James Niken",
      "avatar_url": "https://avatars.githubusercontent.com/u/155266991?v=4",
      "profile": "https://github.com/dizer-ti",
      "contributions": [
        "code"
      ]
    },
    {
      "login": "omahs",
      "name": "omahs",
      "avatar_url": "https://avatars.githubusercontent.com/u/73983677?v=4",
      "profile": "https://github.com/omahs",
      "contributions": [
        "doc"
      ]
    },
    {
      "login": "GTaf",
      "name": "GTaf",
      "avatar_url": "https://avatars.githubusercontent.com/u/3484782?v=4",
      "profile": "https://github.com/GTaf",
      "contributions": [
        "code",
        "doc"
      ]
    },
    {
      "login": "cajohn2757",
      "name": "Corey Johnson",
      "avatar_url": "https://avatars.githubusercontent.com/u/71300075?v=4",
      "profile": "https://github.com/cajohn2757",
      "contributions": [
        "code"
      ]
    },
    {
      "login": "devianweb",
      "name": "Ian Webster",
      "avatar_url": "https://avatars.githubusercontent.com/u/87659522?v=4",
      "profile": "https://github.com/devianweb",
      "contributions": [
        "code"
      ]
    },
    {
      "login": "JCSergent",
      "name": "JC Sergent",
      "avatar_url": "https://avatars.githubusercontent.com/u/34434102?v=4",
      "profile": "https://github.com/JCSergent",
      "contributions": [
        "code"
      ]
    },
    {
      "login": "fel4-dev",
      "name": "Fel4",
      "avatar_url": "https://avatars.githubusercontent.com/u/94372355?v=4",
      "profile": "https://github.com/fel4-dev",
      "contributions": [
        "code"
      ]
    },
    {
      "login": "matteobu",
      "name": "Matteo Bucciol",
      "avatar_url": "https://avatars.githubusercontent.com/u/62759388?v=4",
      "profile": "http://matteo.codes",
      "contributions": [
        "code"
      ]
    },
    {
      "login": "ernestorbemx",
      "name": "ernestorbemx",
      "avatar_url": "https://avatars.githubusercontent.com/u/204041962?v=4",
      "profile": "https://github.com/ernestorbemx",
      "contributions": [
        "code"
      ]
    },
    {
      "login": "jproberson",
      "name": "jproberson",
      "avatar_url": "https://avatars.githubusercontent.com/u/50461518?v=4",
      "profile": "https://github.com/jproberson",
      "contributions": [
        "code"
      ]
    },
    {
      "login": "Abhishek-singh88",
      "name": "Abhishek Singh",
      "avatar_url": "https://avatars.githubusercontent.com/u/177325053?v=4",
      "profile": "https://abhishekdotsol.vercel.app/",
      "contributions": [
        "code"
      ]
    },
    {
      "login": "chris-staunton",
      "name": "Chris Staunton",
      "avatar_url": "https://avatars.githubusercontent.com/u/60261694?v=4",
      "profile": "https://github.com/chris-staunton",
      "contributions": [
        "code"
      ]
    },
    {
      "login": "rejected-l",
      "name": "Rej Ect",
      "avatar_url": "https://avatars.githubusercontent.com/u/99460023?v=4",
      "profile": "https://github.com/rejected-l",
      "contributions": [
        "doc"
      ]
    },
    {
      "login": "othman-shamla",
      "name": "othman-shamla",
      "avatar_url": "https://avatars.githubusercontent.com/u/16326221?v=4",
      "profile": "https://github.com/othman-shamla",
      "contributions": [
        "code"
      ]
    },
    {
      "login": "rsgb",
      "name": "RSGB",
      "avatar_url": "https://avatars.githubusercontent.com/u/96707736?v=4",
      "profile": "https://github.com/rsgb",
      "contributions": [
        "code"
      ]
    },
    {
      "login": "GMetaxakis",
      "name": "Georgios Metaxakis",
      "avatar_url": "https://avatars.githubusercontent.com/u/4234419?v=4",
      "profile": "https://github.com/GMetaxakis",
      "contributions": [
        "code"
      ]
    },
    {
      "login": "tmchow",
      "name": "Trevin Chow",
      "avatar_url": "https://avatars.githubusercontent.com/u/517103?v=4",
      "profile": "https://trev.in",
      "contributions": [
        "code"
      ]
    },
    {
      "login": "elbotho",
      "name": "Botho",
      "avatar_url": "https://avatars.githubusercontent.com/u/1258870?v=4",
      "profile": "https://botho.cc",
      "contributions": [
        "code"
      ]
    }
  ],
  "projectName": "community-platform",
  "projectOwner": "ONEARMY",
  "repoType": "github",
  "repoHost": "https://github.com",
  "commitConvention": "angular",
  "commitType": "docs"
}


================================================
FILE: .circleci/config.yml
================================================
version: 2.1
######################################################################################################
# Pre-Requisites
#
# In order to use these scripts various env variables need to be set on CircleCI
# See `packages/documentation/docs/Deployment/circle-ci.md` for more information
#
# For general config info see: https://circleci.com/docs/2.0/configuration-reference
######################################################################################################

######################################################################################################
#  Orbs - preconfigured environments for running specific jobs
######################################################################################################

orbs:
  # for use with cimg image, to install web browsers
  browser-tools: circleci/browser-tools@1.4.5
  # used to track coverage
  codecov: codecov/codecov@3.2.5

######################################################################################################
#  Aliases - code snippets that can be included inline in any other markup
######################################################################################################
aliases:
  # use a base image running node v18 with chrome/firefox browsers preinstalled
  # This can be applied to any job via `docker: *docker` syntax
  - &docker
    - image: cimg/node:22.18.0-browsers

  # Use base image with support for node version parameter and matrix
  # This can be applied to any job via `<<: *docker_matrix` syntax
  - docker_matrix: &docker_matrix
      parameters:
        node-version:
          type: string
          default: 22.18.0-browsers
      docker:
        - image: cimg/node:<< parameters.node-version >>

    # These can also be created as commands, but slighly tidier to just use inline
    # restore/install/save can all be done with a single circle-ci orb, but less flexible and breaks intellisense
  - &install_bun
    run:
      name: Install Bun
      command: curl -fsSL https://bun.sh/install | bash && echo 'export PATH="$HOME/.bun/bin:$PATH"' >> $BASH_ENV
  - &restore_bun_cache
    restore_cache:
      name: Restore bun cache
      keys:
        - v1-bun-{{ checksum "bun.lock" }}
        - v1-bun-
  - &install_packages
    run:
      name: Install Packages
      command: bun install --frozen-lockfile
  - &save_bun_cache
    save_cache:
      paths:
        - /home/circleci/.bun/install/cache
      key: v1-bun-{{ checksum "bun.lock" }}

  - &filter_only_default_branch
    filters:
      branches:
        only:
          - master

######################################################################################################
#  Commands - Reusable collections of steps
######################################################################################################
commands:
  setup_repo:
    description: checkout repo and install packages
    # no parameters currently used, but could be specified here to use within steps
    # parameters:
    steps:
      - checkout
      - *install_bun
      - *restore_bun_cache
      - *install_packages
      - *save_bun_cache

######################################################################################################
#  Jobs - Independently specified lists of tasks and environments for execution
######################################################################################################
jobs:
  lint:
    docker: *docker
    resource_class: medium+
    environment:
      CYPRESS_INSTALL_BINARY: 0
    steps:
      - setup_repo
      - run:
          command: bun run lint
      - run:
          command: bun run --filter oa-components lint
  # Prepare node module caches so that future tasks run more quickly
  # NOTE - not currently used as we only have one workflow
  setup:
    docker: *docker
    environment:
      CYPRESS_INSTALL_BINARY: 0
    steps:
      - setup_repo

  # Create a production build
  # NOTE - not currently used in test workflow as different build_env required for each machine
  test_unit:
    docker: *docker
    resource_class: medium+
    environment:
      CYPRESS_INSTALL_BINARY: 0
    steps:
      - setup_repo
      - run:
          # NOTE - run-in-band to try reduce memory leaks (https://github.com/facebook/jest/issues/7874)
          command: bun run test:unit
      - run:
          command: bun run test:components
      - store_artifacts:
          path: coverage
      - store_artifacts:
          path: packages/components/coverage
      - codecov/upload
      - store_artifacts:
          path: packages/components/reports
      - store_test_results:
          path: packages/components/reports
      - store_artifacts:
          path: reports
      - store_test_results:
          path: reports

  build:
    <<: *docker_matrix
    environment:
      GENERATE_SOURCEMAP: 'false'
      SKIP_PREFLIGHT_CHECK: 'true'
      NODE_OPTIONS: '--max-old-space-size=5632'
      CYPRESS_INSTALL_BINARY: 0
    # If experiencing out-of-memory issues can increase resource_class below and max space size above
    # https://circleci.com/docs/2.0/configuration-reference/#resourceclass
    resource_class: large
    steps:
      - setup_repo
      # As environment variables can only be set from strings add additional dynamic variable mappings here
      # https://discuss.circleci.com/t/using-environment-variables-in-config-yml-not-working/14237/13
      - run:
          name: Set branch environment
          command: |
            echo 'export VITE_SITE_VARIANT=test-ci' >> $BASH_ENV
      - run:
          name: Check environment variables
          command: |
            echo $VITE_SITE_VARIANT
      - run:
          command: bun run build
      - persist_to_workspace:
          root: .
          paths:
            - build
  storybook:
    docker: *docker
    resource_class: medium
    environment:
      CYPRESS_INSTALL_BINARY: 0
    steps:
      - setup_repo
      - attach_workspace:
          at: '.'
      - run:
          command: bun run storybook:build
  deploy:
    docker:
      - image: cimg/node:22.18.0
    resource_class: medium+
    parameters:
      # optional environment variables to set during build process
      DEPLOY_ALIAS:
        type: string
        default: 'default'
      FLY_APP_NAME:
        type: string
        default: 'default'
      FLY_TOML:
        type: string
        default: 'default'
    environment:
      CYPRESS_INSTALL_BINARY: 0
    steps:
      - setup_repo
      - attach_workspace:
          at: '.'
      - run:
          name: Prune Docker resources
          command: |
            docker system prune -a
      - run:
          name: Install fly command
          command: curl -L https://fly.io/install.sh | sh -s -- --non-interactive --setup-path
      - run:
          name: Add fly to PATH
          command: echo "export PATH=\"/home/circleci/.fly/bin:$PATH\"" >> $BASH_ENV
      - run:
          name: Login fly
          command: flyctl auth token $FLY_API_TOKEN --debug --verbose
      - run:
          name: Deploy to fly
          command: |
            flyctl deploy \
              --app << parameters.FLY_APP_NAME >> \
              --config << parameters.FLY_TOML >> \
              --debug --verbose \
              --build-secret NODE_ENV="production" \
              --build-secret VITE_BRANCH="$VITE_BRANCH" \
              --build-secret VITE_SENTRY_DSN="$VITE_SENTRY_DSN"
      - run:
          name: Set Server Secrets
          command: flyctl -a << parameters.FLY_APP_NAME >> secrets set SUPABASE_API_URL=$SUPABASE_API_URL SUPABASE_KEY=$SUPABASE_KEY SUPABASE_SERVICE_ROLE_KEY=$SUPABASE_SERVICE_ROLE_KEY DISCORD_WEBHOOK_URL=$DISCORD_WEBHOOK_URL RESEND_API_KEY=$RESEND_API_KEY TENANT_ID=$TENANT_ID PATREON_CLIENT_SECRET=$PATREON_CLIENT_SECRET TOKEN_SECRET="$TOKEN_SECRET"
  # deploy-supabase:
  #   docker:
  #     - image: cimg/node:20.7.0
  #   steps:
  #     - checkout
  #     - attach_workspace:
  #         at: '.'
  #     - run: npx supabase@2.6.8 login --token $SUPABASE_ACCESS_TOKEN
  #     - run: (yes || true) | npx supabase@2.6.8 db push --db-url $SUPABASE_DB_URL --debug --password $SUPABASE_DB_PASSWORD
  # - run: npx supabase@2.6.8 functions deploy --no-verify-jwt
  # Run cypress e2e tests on chrome
  test_e2e:
    docker: *docker
    resource_class: medium+
    # build matrix will run 4 parallel builds handled by cypress, so don't need to specify more here
    parallelism: 1
    parameters:
      CI_NODE:
        type: integer
      CI_BROWSER:
        type: string
    steps:
      - setup_repo
      # retrieve build folder
      - attach_workspace:
          at: '.'
      # install testing browsers are required
      - when:
          condition:
            equal: ['chrome', << parameters.CI_BROWSER >>]
          steps:
            - browser-tools/install-chrome
      - when:
          condition:
            equal: ['firefox', << parameters.CI_BROWSER >>]
          steps:
            - browser-tools/install-firefox
      # call main testing script
      - run:
          command: npm run test ci prod
          environment:
            VITE_SITE_VARIANT: test-ci
            CI_BROWSER: << parameters.CI_BROWSER >>
            CI_NODE: << parameters.CI_NODE >>
            CI_GROUP: ci-<< parameters.CI_BROWSER >>
      - store_artifacts:
          path: ./packages/cypress/src/screenshots/

  release:
    docker: *docker
    resource_class: medium+
    environment:
      CYPRESS_INSTALL_BINARY: 0
    steps:
      - setup_repo
      - attach_workspace:
          at: '.'
      - run:
          command: npx semantic-release@22

######################################################################################################
#  Workflows - Collections of jobs to define overall processes
######################################################################################################
workflows:
  version: 2
  main_workflow:
    max_auto_reruns: 1
    # by default jobs will run concurrently, so specify requires if want to run sequentially
    jobs:
      - lint:
          name: Lint code
      #---------------------- Test ----------------------
      # Note - when calling test we also let the test script handle building as it injects random variables for seeding the DB
      - build:
          requires:
            - 'Lint code'
          name: Build Application
      - test_unit:
          name: 'Unit tests'
          requires:
            - 'Lint code'
      - storybook:
          name: Build Storybook
          requires:
            - 'Lint code'
      - test_e2e:
          name: e2e-<< matrix.CI_BROWSER >>-<< matrix.CI_NODE >>
          requires:
            - 'Build Application'
            - 'Unit tests'
            - 'Build Storybook'
          context:
            - e2e-tests
          matrix:
            parameters:
              CI_NODE: [1, 2, 3, 4]
              CI_BROWSER: ['chrome']
      #---------------------- Approval ----------------------
      - approve:
          type: approval
          name: 'Approve Production deployment'
          requires:
            - test_e2e
          <<: *filter_only_default_branch
      #---------------------- Deploy ----------------------
      # - deploy-supabase:
      #     name: 'Deploy to Supabase'
      #     requires:
      #       - 'Approve Production deployment'
      #     <<: *filter_only_default_branch
      #     context:
      #       - supabase-deploy
      - deploy:
          name: 'Deploy: community.fixing.fashion'
          requires:
            - 'Approve Production deployment'
          <<: *filter_only_default_branch
          DEPLOY_ALIAS: fixing-fashion-prod
          FLY_APP_NAME: community-platform-ff
          FLY_TOML: fly-ff.toml
          context:
            - circle-ci-patreon-context
            - fixing-fashion-prod
            - fly-deploy
            - supabase-deploy
      - deploy:
          name: 'Deploy: community.preciousplastic.com'
          requires:
            - 'Approve Production deployment'
          <<: *filter_only_default_branch
          DEPLOY_ALIAS: 'production'
          FLY_APP_NAME: community-platform-pp
          FLY_TOML: fly-pp.toml
          context:
            - circle-ci-patreon-context
            - community-platform-production
            - fly-deploy
            - supabase-deploy
      - deploy:
          name: 'Deploy: community.projectkamp.com'
          requires:
            - 'Approve Production deployment'
          <<: *filter_only_default_branch
          DEPLOY_ALIAS: project-kamp-production
          FLY_APP_NAME: community-platform-pk
          FLY_TOML: fly-pk.toml
          context:
            - circle-ci-patreon-context
            - project-kamp-production
            - fly-deploy
            - supabase-deploy
      - release:
          name: Release new version to GitHub
          context:
            - release-context
          requires:
            - 'Deploy: community.preciousplastic.com'
          <<: *filter_only_default_branch


================================================
FILE: .dockerignore
================================================
*node_modules*
dump
build
.circleci
.github
.nxs
.yarn
.yarnrc.yml
yarn.lock
docs
packages/cypress
packages/documentation
# Build artifacts and caches
coverage
reports
*.log
.env.local
.env.*.local
# Storybook
**/storybook-static
# Git
.git
.gitignore
# IDE
.vscode
.idea
*.swp
*.swo
# Testing
*.test.ts
*.test.tsx
*.spec.ts
*.spec.tsx

================================================
FILE: .github/CODEOWNERS
================================================
* @ONEARMY/maintainers

================================================
FILE: .github/ISSUE_TEMPLATE/bug_report.md
================================================
---
name: Bug report
about: Create a report to help us improve
title: '[bug]'
labels: "Type:Bug\U0001F41B"
assignees: ''
---

**Describe the bug**
A clear and concise description of what the bug is.

**To Reproduce**
Steps to reproduce the behaviour:

1. Go to '...'
2. Click on '....'
3. Scroll down to '....'
4. See error

**Expected behaviour**
A clear and concise description of what you expected to happen.

**Screenshots**
If applicable, add screenshots to help explain your problem.

**Additional context**
Add any other context about the problem here.


================================================
FILE: .github/ISSUE_TEMPLATE/build-new-component.md
================================================
---
name: Build new component
about: Describe the new component you want to build
title: ''
labels: ''
assignees: ''
---

## Component infos

### Description

Write a quick description of what is the component for, and as mainy details you consider useful to the person that will have to build it.

### Page related

Will be used in :

- Related page name (#issue-number)

### Mockup

[Add here the mockup of the component]

### Example(s)

If you have any examples of existing similar components, add the link here. It can be a link to a code snippet and/or to a page of a projet/website where we can interact with the similar component.

### Build suggestion

Here describe how you would build it, briefly but clearly. For example : the component MyComponent will take 2 props : `prop1`& `prop2`. It will extend the existing `Heading` component.


================================================
FILE: .github/ISSUE_TEMPLATE/feature-request-or-suggestion.md
================================================
---
name: Feature request or suggestion
about: Suggest an idea for this project
title: '[feature request]'
labels: 'Feedback: Question'
assignees: ''
---

**Is your feature request related to a problem? Please describe.**
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]

**Describe the solution you'd like**
A clear and concise description of what you want to happen.

**Describe alternatives you've considered**
A clear and concise description of any alternative solutions or features you've considered.

**Additional context**
Add any other context or screenshots about the feature request here.


================================================
FILE: .github/actions/destroy-fly-preview-app/Dockerfile
================================================
FROM alpine

RUN apk add --no-cache curl jq

RUN curl -L https://fly.io/install.sh | FLYCTL_INSTALL=/usr/local sh

COPY entrypoint.sh /entrypoint.sh

RUN chmod +x /entrypoint.sh

ENTRYPOINT ["/entrypoint.sh"]

================================================
FILE: .github/actions/destroy-fly-preview-app/action.yml
================================================
name: "Destroy fly.io app"
description: "Destroy fly.io app if matching app name found"
author: iSCJT
branding:
  icon: "delete"
  color: "red"
runs:
  using: "docker"
  image: "Dockerfile"
inputs:
  name:
    description: Fly app name

================================================
FILE: .github/actions/destroy-fly-preview-app/entrypoint.sh
================================================
#!/bin/sh -l

set -ex

# Change underscores to hyphens.
app="${INPUT_NAME//_/-}"


if ! flyctl status --app "$app"; then
  echo "App name not found"
  exit 1
fi

flyctl apps destroy "$app" -y
echo "App $app successfully destroyed"
exit 0

================================================
FILE: .github/labels.yml
================================================
# This is currently just an export of labels used in the project
# In the future we could also use to add more and keep in sync via actions such as:
# https://github.com/micnncim/action-label-syncer
[
  { 'name': 'Backend', 'color': 'EF592F', 'description': '' },
  { 'name': 'Code: Tidying', 'color': 'B2864C', 'description': '' },
  { 'name': 'Design', 'color': '2FF7AB', 'description': null },
  { 'name': 'Difficulty:Easy', 'color': 'FFDDB2', 'description': '' },
  { 'name': 'Difficulty:Hard', 'color': 'C198E2', 'description': '' },
  { 'name': 'Difficulty:Super-Easy', 'color': 'C2E0C6', 'description': '' },
  { 'name': 'Difficulty:medium', 'color': '629AFC', 'description': '' },
  { 'name': 'Discussions', 'color': 'CC317C', 'description': '' },
  { 'name': 'Documentation', 'color': 'E0D323', 'description': '' },
  { 'name': 'Frontend', 'color': '5319E7', 'description': '' },
  { 'name': 'Global Good 🌍', 'color': 'B3E572', 'description': '' },
  { 'name': 'Good first issue', 'color': '74B5E3', 'description': null },
  { 'name': 'Help wanted', 'color': '56D639', 'description': '' },
  { 'name': 'In progress', 'color': '440B89', 'description': '' },
  { 'name': 'Mod: DevOps 🤖', 'color': 'BFD4F2', 'description': '' },
  { 'name': 'Mod: Discussions 💬', 'color': 'BFD4F2', 'description': '' },
  { 'name': 'Mod: Library 📰', 'color': 'BFD4F2', 'description': '' },
  { 'name': 'Mod: Maps 🗺', 'color': 'BFD4F2', 'description': '' },
  { 'name': 'Mod: Other ⬜️', 'color': 'BFD4F2', 'description': '' },
  { 'name': 'Mod: Profiles 👱', 'color': 'BFD4F2', 'description': '' },
  { 'name': 'Mod: Research 🔬', 'color': 'BFD4F2', 'description': '' },
  { 'name': 'Mod: Security👮', 'color': 'BFD4F2', 'description': '' },
  { 'name': 'Module Overview 👀', 'color': 'CEF45D', 'description': '' },
  { 'name': 'Non-Dev', 'color': 'ADADAD', 'description': '' },
  { 'name': 'Priority: High❕', 'color': 'FFB266', 'description': '' },
  { 'name': 'Priority: Low', 'color': 'C2E0C6', 'description': '' },
  { 'name': 'Priority: Medium', 'color': 'FFFF00', 'description': '' },
  { 'name': 'Priority: Urgent❕❕❕', 'color': 'FF0000', 'description': '' },
  {
    'name': 'Review: Assigned 👉',
    'color': 'D7C0A1',
    'description': 'Waiting on review from a specific dev',
  },
  {
    'name': 'Review: Changes Requested 🗨️',
    'color': 'D7C0A1',
    'description': 'Code reviewed, pending update to changes requested',
  },
  {
    'name': 'Review allow-preview ✅',
    'color': 'FFF',
    'description': 'Has received manual check for malicious code and can be safely built for preview',
  },
]


================================================
FILE: .github/pull_request_template.md
================================================
## PR Checklist

- [ ] - Unit and/or e2e tests for the changes that have been added (for bug fixes / features)

## What kind of change does this PR introduce?

- [ ] 🐛 Bugfix — fixes incorrect behavior without changing functionality
- [ ] ✨ Feature — adds new functionality
- [ ] ♻️ Refactoring — improves code structure with no functional changes
- [ ] ⚡️ Performance — improves speed, memory, or efficiency
- [ ] 🧪 Tests — adds or updates tests only
- [ ] 🔧 Tools / CI — changes to build, deploy, or developer tooling
- [ ] 📝 Documentation — updates docs, comments, or READMEs
- [ ] 📦 Dependencies — upgrades, downgrades, or removes packages
- [ ] 🔖 Other:

## What is the new behavior?

_Describe the new behaviour_
_If useful, provide screenshot or capture to highlight main changes_

## Does this PR introduce a DB Schema Change or Migration?

- [ ] Yes
- [ ] No

## Git Issues

Closes #

## What happens next?

Thank you for the contribution! We will review it ASAP.

If you need more immediate feedback you can reach out to us on Discord in the [Community Platform `development` channel](https://discord.com/channels/586676777334865928/938781727017558018).


================================================
FILE: .github/workflows/codeql-analysis.yml
================================================
name: 'CodeQL'

on:
  push:
    branches: [master]
  pull_request:
    branches: [master]
  schedule:
    - cron: '35 21 * * 2'

jobs:
  analyze:
    name: Analyze
    runs-on: ubuntu-latest
    permissions:
      actions: read
      contents: read
      security-events: write

    strategy:
      fail-fast: false
      matrix:
        language: ['javascript-typescript']

    steps:
      - name: Checkout repository
        uses: actions/checkout@v4

      - name: Initialize CodeQL
        uses: github/codeql-action/init@v4
        with:
          languages: ${{ matrix.language }}

      - name: Autobuild
        uses: github/codeql-action/autobuild@v4

      - name: Perform CodeQL Analysis
        uses: github/codeql-action/analyze@v4
        with:
          category: '/language:${{ matrix.language }}'


================================================
FILE: .github/workflows/pr-preview-fly-deploy.yml
================================================
name: Deploy Fly PR Preview
on:
  pull_request_target:
    types: [labeled, synchronize]

env:
  FLY_API_TOKEN: ${{ secrets.FLY_API_TOKEN }}
  FLY_REGION: ams
  FLY_ORG: one-army
  SUPABASE_ACCESS_TOKEN: ${{ secrets.SUPABASE_ACCESS_TOKEN }}
  SUPABASE_DB_PASSWORD: ${{ secrets.PREVIEW_DB_PASSWORD }}
  SUPABASE_PROJECT_ID: ${{ secrets.PREVIEW_PROJECT_ID }}
  FLY_APP_NAME: community-platform-pr-${{ github.event.number }}

jobs:
  preview_app:
    if: contains(github.event.pull_request.labels.*.name, 'Review allow-preview ✅')
    runs-on: ubuntu-latest
    continue-on-error: false
    outputs:
      url: ${{ steps.deploy.outputs.url }}
    concurrency:
      group: pr-${{ github.event.number }}-${{ github.sha }}

    environment:
      name: preview
      url: ${{ steps.deploy.outputs.url }}

    steps:
      - name: Get code
        uses: actions/checkout@v4
        with:
          ref: ${{ github.event.pull_request.head.sha }}

      - name: Install Fly CLI
        run: |
          curl -L https://fly.io/install.sh | sh
          echo "$HOME/.fly/bin" >> "$GITHUB_PATH"

      - name: Deploy PR app to Fly.io
        id: deploy
        uses: superfly/fly-pr-review-apps@1.5.0
        with:
          config: fly-preview.toml
          name: community-platform-pr-${{ github.event.number }}
          args: --build-arg COMMIT_SHA=${{ github.event.pull_request.head.sha }}
          secrets: |
            SUPABASE_API_URL=${{ secrets.SUPABASE_API_URL }}
            SUPABASE_KEY=${{ secrets.SUPABASE_KEY }}
            SUPABASE_SERVICE_ROLE_KEY=${{ secrets.SUPABASE_SERVICE_ROLE_KEY }}
            RESEND_API_KEY=${{ secrets.RESEND_API_KEY }}
            TENANT_ID=precious-plastic


================================================
FILE: .github/workflows/pr-preview-fly-destroy.yml
================================================
name: Destroy Fly PR Preview

on:
  pull_request_target:
    types:
      - unlabeled
      - closed

env:
  FLY_API_TOKEN: ${{ secrets.FLY_API_TOKEN }}

jobs:
  label_removed:
    if: |
      (github.event.action == 'unlabeled' && github.event.label.name == 'Review allow-preview ✅') ||
      (github.event.action == 'closed' && contains(github.event.pull_request.labels.*.name, 'Review allow-preview ✅'))
    runs-on: ubuntu-latest
    continue-on-error: true
    concurrency:
      group: pr-${{ github.event.number }}
    steps:
      - name: Checkout
        uses: actions/checkout@v4

      - name: Destroy fly.io preview app
        id: destroy
        uses: ./.github/actions/destroy-fly-preview-app
        with:
          name: community-platform-pr-${{ github.event.number }}


================================================
FILE: .github/workflows/pr-preview-remove-label.yml
================================================
name: Remove PR Preview Label
on:
  # Run this workflow on every PR event. Existing review apps will be updated when the PR is updated.
  pull_request_target:
    # Trigger when labels are changed or more commits added to a PR that contains labels
    types: [closed]

jobs:
  preview_app:
    if: contains(github.event.pull_request.labels.*.name, 'Review allow-preview ✅')
    runs-on: ubuntu-latest
    continue-on-error: true
    # Only run one deployment at a time per PR.
    concurrency:
      group: pr-${{ github.event.number }}

    steps:
      - name: Get code
        uses: actions/checkout@v4
        with:
          # pull the repo from the pull request source, not the default local repo
          ref: ${{ github.event.pull_request.head.sha }}

      - name: Remove preview label
        uses: actions/github-script@v7
        with:
          script: |
            await github.rest.issues.removeLabel({
              owner: context.repo.owner,
              repo: context.repo.repo,
              issue_number: github.event.number,
              name: 'Review allow-preview ✅',
            });
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

================================================
FILE: .github/workflows/pr-stale.yml
================================================
name: 'Close stale issues and PRs'
on:
  schedule:
    - cron: '30 1 * * *'

jobs:
  stale:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/stale@v8
        with:
          stale-pr-message: 'This PR is stale because it has been open 45 days with no activity. Remove stale label or comment or this will be closed in 5 days.'
          close-pr-message: 'This PR was closed because it has been stalled for 5 days with no activity.'
          days-before-pr-stale: 45
          days-before-pr-close: 5
          debug-only: true


================================================
FILE: .github/workflows/storybook-deploy.yml
================================================
# Build and deploy Storybook to GitHub Pages
name: Storybook Deploy
on:
  push:
    branches:
      - master
    # Only run action if changes have been made to the components or themes packages
    paths:
      - 'packages/components/**'
      - 'packages/themes/**'
      - '.github/workflows/storybook-deploy.yml'
  # Allow manual trigger
  workflow_dispatch:

# Sets permissions of the GITHUB_TOKEN to allow deployment to GitHub Pages
permissions:
  contents: read
  pages: write
  id-token: write

# Allow only one concurrent deployment, skipping runs queued between the run in-progress and latest queued.
# However, do NOT cancel in-progress runs as we want to allow these production deployments to complete.
concurrency:
  group: 'pages'
  cancel-in-progress: false

jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout
        uses: actions/checkout@v4

      - name: Setup Node.js
        uses: actions/setup-node@v4
        with:
          node-version: '22.18.0'

      - name: Install Bun
        uses: oven-sh/setup-bun@v2

      - name: Setup Cache
        uses: actions/cache@v4
        id: bun-cache
        with:
          path: ~/.bun/install/cache
          key: ${{ runner.os }}-bun-${{ hashFiles('bun.lock') }}
          restore-keys: |
            ${{ runner.os }}-bun-

      - name: Install dependencies
        run: bun install --frozen-lockfile

      - name: Build themes
        run: bun run --filter oa-themes build

      - name: Build Storybook
        run: bun run --filter oa-components build:sb

      - name: Setup Pages
        uses: actions/configure-pages@v4

      - name: Upload artifact
        uses: actions/upload-pages-artifact@v4
        with:
          path: ./packages/components/storybook-static

  deploy:
    environment:
      name: github-pages
      url: ${{ steps.deployment.outputs.page_url }}
    runs-on: ubuntu-latest
    needs: build
    steps:
      - name: Deploy to GitHub Pages
        id: deployment
        uses: actions/deploy-pages@v4


================================================
FILE: .gitignore
================================================
# See https://help.github.com/ignore-files/ for more about ignoring files.

# dependencies
node_modules

# testing
/coverage
/reports
/junit.xml

# production
/build
/lib

# misc
.DS_Store
.env.local
.env.development.local
.env.test.local
.env.production.local
npm-debug.log*
yarn-debug.log*
yarn-error.log*
.vscode/*
!.vscode/launch.json
*.log
.vs

# IntelliJ
/.idea

# https://yarnpkg.com/getting-started/qa#which-files-should-be-gitignored
.yarn/*
!.yarn/patches
!.yarn/releases
!.yarn/plugins
!.yarn/sdks
!.yarn/versions
.pnp.*

*.tsbuildinfo
supabase/.branches
supabase/.temp
supabase/.env
.react-router/


================================================
FILE: .husky/pre-commit
================================================
  bun run lint-staged


================================================
FILE: .node-version
================================================
22.18.0


================================================
FILE: .releaserc.json
================================================
{
  "branches": ["master"],
  "ci": false,
  "plugins": [
    [
      "@semantic-release/commit-analyzer",
      {
        "preset": "angular",
        "releaseRules": [
          { "type": "docs", "scope": "README", "release": "patch" },
          { "type": "refactor", "release": "patch" },
          { "type": "style", "release": "patch" }
        ],
        "parserOpts": {
          "noteKeywords": ["MAJOR VERSION", "MAJOR VERSIONS"]
        }
      }
    ],
    "@semantic-release/release-notes-generator",
    "@semantic-release/github",
    "@semantic-release/changelog"
  ]
}


================================================
FILE: .snaplet/config.json
================================================
{
  "adapter": "pg"
}


================================================
FILE: .snaplet/dataModel.json
================================================
{
  "models": {
    "_http_response": {
      "id": "net._http_response",
      "schemaName": "net",
      "tableName": "_http_response",
      "fields": [
        {
          "id": "net._http_response.id",
          "name": "id",
          "columnName": "id",
          "type": "int8",
          "isRequired": false,
          "kind": "scalar",
          "isList": false,
          "isGenerated": false,
          "sequence": false,
          "hasDefaultValue": false,
          "isId": false,
          "maxLength": null
        },
        {
          "id": "net._http_response.status_code",
          "name": "status_code",
          "columnName": "status_code",
          "type": "int4",
          "isRequired": false,
          "kind": "scalar",
          "isList": false,
          "isGenerated": false,
          "sequence": false,
          "hasDefaultValue": false,
          "isId": false,
          "maxLength": null
        },
        {
          "id": "net._http_response.content_type",
          "name": "content_type",
          "columnName": "content_type",
          "type": "text",
          "isRequired": false,
          "kind": "scalar",
          "isList": false,
          "isGenerated": false,
          "sequence": false,
          "hasDefaultValue": false,
          "isId": false,
          "maxLength": null
        },
        {
          "id": "net._http_response.headers",
          "name": "headers",
          "columnName": "headers",
          "type": "jsonb",
          "isRequired": false,
          "kind": "scalar",
          "isList": false,
          "isGenerated": false,
          "sequence": false,
          "hasDefaultValue": false,
          "isId": false,
          "maxLength": null
        },
        {
          "id": "net._http_response.content",
          "name": "content",
          "columnName": "content",
          "type": "text",
          "isRequired": false,
          "kind": "scalar",
          "isList": false,
          "isGenerated": false,
          "sequence": false,
          "hasDefaultValue": false,
          "isId": false,
          "maxLength": null
        },
        {
          "id": "net._http_response.timed_out",
          "name": "timed_out",
          "columnName": "timed_out",
          "type": "bool",
          "isRequired": false,
          "kind": "scalar",
          "isList": false,
          "isGenerated": false,
          "sequence": false,
          "hasDefaultValue": false,
          "isId": false,
          "maxLength": null
        },
        {
          "id": "net._http_response.error_msg",
          "name": "error_msg",
          "columnName": "error_msg",
          "type": "text",
          "isRequired": false,
          "kind": "scalar",
          "isList": false,
          "isGenerated": false,
          "sequence": false,
          "hasDefaultValue": false,
          "isId": false,
          "maxLength": null
        },
        {
          "id": "net._http_response.created",
          "name": "created",
          "columnName": "created",
          "type": "timestamptz",
          "isRequired": true,
          "kind": "scalar",
          "isList": false,
          "isGenerated": false,
          "sequence": false,
          "hasDefaultValue": true,
          "isId": false,
          "maxLength": null
        }
      ],
      "uniqueConstraints": []
    },
    "audit_log_entries": {
      "id": "auth.audit_log_entries",
      "schemaName": "auth",
      "tableName": "audit_log_entries",
      "fields": [
        {
          "id": "auth.audit_log_entries.instance_id",
          "name": "instance_id",
          "columnName": "instance_id",
          "type": "uuid",
          "isRequired": false,
          "kind": "scalar",
          "isList": false,
          "isGenerated": false,
          "sequence": false,
          "hasDefaultValue": false,
          "isId": false,
          "maxLength": null
        },
        {
          "id": "auth.audit_log_entries.id",
          "name": "id",
          "columnName": "id",
          "type": "uuid",
          "isRequired": true,
          "kind": "scalar",
          "isList": false,
          "isGenerated": false,
          "sequence": false,
          "hasDefaultValue": false,
          "isId": true,
          "maxLength": null
        },
        {
          "id": "auth.audit_log_entries.payload",
          "name": "payload",
          "columnName": "payload",
          "type": "json",
          "isRequired": false,
          "kind": "scalar",
          "isList": false,
          "isGenerated": false,
          "sequence": false,
          "hasDefaultValue": false,
          "isId": false,
          "maxLength": null
        },
        {
          "id": "auth.audit_log_entries.created_at",
          "name": "created_at",
          "columnName": "created_at",
          "type": "timestamptz",
          "isRequired": false,
          "kind": "scalar",
          "isList": false,
          "isGenerated": false,
          "sequence": false,
          "hasDefaultValue": false,
          "isId": false,
          "maxLength": null
        },
        {
          "id": "auth.audit_log_entries.ip_address",
          "name": "ip_address",
          "columnName": "ip_address",
          "type": "varchar",
          "isRequired": true,
          "kind": "scalar",
          "isList": false,
          "isGenerated": false,
          "sequence": false,
          "hasDefaultValue": true,
          "isId": false,
          "maxLength": 64
        }
      ],
      "uniqueConstraints": []
    },
    "banners": {
      "id": "public.banners",
      "schemaName": "public",
      "tableName": "banners",
      "fields": [
        {
          "id": "public.banners.id",
          "name": "id",
          "columnName": "id",
          "type": "int8",
          "isRequired": true,
          "kind": "scalar",
          "isList": false,
          "isGenerated": false,
          "sequence": {
            "identifier": "\"public\".\"banners_id_seq\"",
            "increment": 1,
            "start": 1
          },
          "hasDefaultValue": false,
          "isId": true,
          "maxLength": null
        },
        {
          "id": "public.banners.created_at",
          "name": "created_at",
          "columnName": "created_at",
          "type": "timestamptz",
          "isRequired": true,
          "kind": "scalar",
          "isList": false,
          "isGenerated": false,
          "sequence": false,
          "hasDefaultValue": true,
          "isId": false,
          "maxLength": null
        },
        {
          "id": "public.banners.modified_at",
          "name": "modified_at",
          "columnName": "modified_at",
          "type": "timestamptz",
          "isRequired": false,
          "kind": "scalar",
          "isList": false,
          "isGenerated": false,
          "sequence": false,
          "hasDefaultValue": false,
          "isId": false,
          "maxLength": null
        },
        {
          "id": "public.banners.text",
          "name": "text",
          "columnName": "text",
          "type": "text",
          "isRequired": true,
          "kind": "scalar",
          "isList": false,
          "isGenerated": false,
          "sequence": false,
          "hasDefaultValue": false,
          "isId": false,
          "maxLength": null
        },
        {
          "id": "public.banners.url",
          "name": "url",
          "columnName": "url",
          "type": "text",
          "isRequired": false,
          "kind": "scalar",
          "isList": false,
          "isGenerated": false,
          "sequence": false,
          "hasDefaultValue": false,
          "isId": false,
          "maxLength": null
        },
        {
          "id": "public.banners.tenant_id",
          "name": "tenant_id",
          "columnName": "tenant_id",
          "type": "text",
          "isRequired": true,
          "kind": "scalar",
          "isList": false,
          "isGenerated": false,
          "sequence": false,
          "hasDefaultValue": false,
          "isId": false,
          "maxLength": null
        }
      ],
      "uniqueConstraints": [
        {
          "name": "banners_pkey",
          "fields": ["id"],
          "nullNotDistinct": false
        }
      ]
    },
    "buckets": {
      "id": "storage.buckets",
      "schemaName": "storage",
      "tableName": "buckets",
      "fields": [
        {
          "id": "storage.buckets.id",
          "name": "id",
          "columnName": "id",
          "type": "text",
          "isRequired": true,
          "kind": "scalar",
          "isList": false,
          "isGenerated": false,
          "sequence": false,
          "hasDefaultValue": false,
          "isId": true,
          "maxLength": null
        },
        {
          "id": "storage.buckets.name",
          "name": "name",
          "columnName": "name",
          "type": "text",
          "isRequired": true,
          "kind": "scalar",
          "isList": false,
          "isGenerated": false,
          "sequence": false,
          "hasDefaultValue": false,
          "isId": false,
          "maxLength": null
        },
        {
          "id": "storage.buckets.owner",
          "name": "owner",
          "columnName": "owner",
          "type": "uuid",
          "isRequired": false,
          "kind": "scalar",
          "isList": false,
          "isGenerated": false,
          "sequence": false,
          "hasDefaultValue": false,
          "isId": false,
          "maxLength": null
        },
        {
          "id": "storage.buckets.created_at",
          "name": "created_at",
          "columnName": "created_at",
          "type": "timestamptz",
          "isRequired": false,
          "kind": "scalar",
          "isList": false,
          "isGenerated": false,
          "sequence": false,
          "hasDefaultValue": true,
          "isId": false,
          "maxLength": null
        },
        {
          "id": "storage.buckets.updated_at",
          "name": "updated_at",
          "columnName": "updated_at",
          "type": "timestamptz",
          "isRequired": false,
          "kind": "scalar",
          "isList": false,
          "isGenerated": false,
          "sequence": false,
          "hasDefaultValue": true,
          "isId": false,
          "maxLength": null
        },
        {
          "id": "storage.buckets.public",
          "name": "public",
          "columnName": "public",
          "type": "bool",
          "isRequired": false,
          "kind": "scalar",
          "isList": false,
          "isGenerated": false,
          "sequence": false,
          "hasDefaultValue": true,
          "isId": false,
          "maxLength": null
        },
        {
          "id": "storage.buckets.avif_autodetection",
          "name": "avif_autodetection",
          "columnName": "avif_autodetection",
          "type": "bool",
          "isRequired": false,
          "kind": "scalar",
          "isList": false,
          "isGenerated": false,
          "sequence": false,
          "hasDefaultValue": true,
          "isId": false,
          "maxLength": null
        },
        {
          "id": "storage.buckets.file_size_limit",
          "name": "file_size_limit",
          "columnName": "file_size_limit",
          "type": "int8",
          "isRequired": false,
          "kind": "scalar",
          "isList": false,
          "isGenerated": false,
          "sequence": false,
          "hasDefaultValue": false,
          "isId": false,
          "maxLength": null
        },
        {
          "id": "storage.buckets.allowed_mime_types",
          "name": "allowed_mime_types",
          "columnName": "allowed_mime_types",
          "type": "text[]",
          "isRequired": false,
          "kind": "scalar",
          "isList": false,
          "isGenerated": false,
          "sequence": false,
          "hasDefaultValue": false,
          "isId": false,
          "maxLength": null
        },
        {
          "id": "storage.buckets.owner_id",
          "name": "owner_id",
          "columnName": "owner_id",
          "type": "text",
          "isRequired": false,
          "kind": "scalar",
          "isList": false,
          "isGenerated": false,
          "sequence": false,
          "hasDefaultValue": false,
          "isId": false,
          "maxLength": null
        },
        {
          "id": "storage.buckets.type",
          "name": "type",
          "columnName": "type",
          "type": "buckettype",
          "isRequired": true,
          "kind": "scalar",
          "isList": false,
          "isGenerated": false,
          "sequence": false,
          "hasDefaultValue": true,
          "isId": false,
          "maxLength": null
        },
        {
          "name": "objects",
          "type": "objects",
          "isRequired": false,
          "kind": "object",
          "relationName": "objectsTobuckets",
          "relationFromFields": [],
          "relationToFields": [],
          "isList": true,
          "isId": false,
          "isGenerated": false,
          "sequence": false,
          "hasDefaultValue": false
        },
        {
          "name": "s3_multipart_uploads",
          "type": "s3_multipart_uploads",
          "isRequired": false,
          "kind": "object",
          "relationName": "s3_multipart_uploadsTobuckets",
          "relationFromFields": [],
          "relationToFields": [],
          "isList": true,
          "isId": false,
          "isGenerated": false,
          "sequence": false,
          "hasDefaultValue": false
        },
        {
          "name": "s3_multipart_uploads_parts",
          "type": "s3_multipart_uploads_parts",
          "isRequired": false,
          "kind": "object",
          "relationName": "s3_multipart_uploads_partsTobuckets",
          "relationFromFields": [],
          "relationToFields": [],
          "isList": true,
          "isId": false,
          "isGenerated": false,
          "sequence": false,
          "hasDefaultValue": false
        }
      ],
      "uniqueConstraints": [
        {
          "name": "bname",
          "fields": ["name"],
          "nullNotDistinct": false
        }
      ]
    },
    "buckets_analytics": {
      "id": "storage.buckets_analytics",
      "schemaName": "storage",
      "tableName": "buckets_analytics",
      "fields": [
        {
          "id": "storage.buckets_analytics.name",
          "name": "name",
          "columnName": "name",
          "type": "text",
          "isRequired": true,
          "kind": "scalar",
          "isList": false,
          "isGenerated": false,
          "sequence": false,
          "hasDefaultValue": false,
          "isId": false,
          "maxLength": null
        },
        {
          "id": "storage.buckets_analytics.type",
          "name": "type",
          "columnName": "type",
          "type": "buckettype",
          "isRequired": true,
          "kind": "scalar",
          "isList": false,
          "isGenerated": false,
          "sequence": false,
          "hasDefaultValue": true,
          "isId": false,
          "maxLength": null
        },
        {
          "id": "storage.buckets_analytics.format",
          "name": "format",
          "columnName": "format",
          "type": "text",
          "isRequired": true,
          "kind": "scalar",
          "isList": false,
          "isGenerated": false,
          "sequence": false,
          "hasDefaultValue": true,
          "isId": false,
          "maxLength": null
        },
        {
          "id": "storage.buckets_analytics.created_at",
          "name": "created_at",
          "columnName": "created_at",
          "type": "timestamptz",
          "isRequired": true,
          "kind": "scalar",
          "isList": false,
          "isGenerated": false,
          "sequence": false,
          "hasDefaultValue": true,
          "isId": false,
          "maxLength": null
        },
        {
          "id": "storage.buckets_analytics.updated_at",
          "name": "updated_at",
          "columnName": "updated_at",
          "type": "timestamptz",
          "isRequired": true,
          "kind": "scalar",
          "isList": false,
          "isGenerated": false,
          "sequence": false,
          "hasDefaultValue": true,
          "isId": false,
          "maxLength": null
        },
        {
          "id": "storage.buckets_analytics.id",
          "name": "id",
          "columnName": "id",
          "type": "uuid",
          "isRequired": true,
          "kind": "scalar",
          "isList": false,
          "isGenerated": false,
          "sequence": false,
          "hasDefaultValue": true,
          "isId": true,
          "maxLength": null
        },
        {
          "id": "storage.buckets_analytics.deleted_at",
          "name": "deleted_at",
          "columnName": "deleted_at",
          "type": "timestamptz",
          "isRequired": false,
          "kind": "scalar",
          "isList": false,
          "isGenerated": false,
          "sequence": false,
          "hasDefaultValue": false,
          "isId": false,
          "maxLength": null
        },
        {
          "name": "iceberg_namespaces",
          "type": "iceberg_namespaces",
          "isRequired": false,
          "kind": "object",
          "relationName": "iceberg_namespacesTobuckets_analytics",
          "relationFromFields": [],
          "relationToFields": [],
          "isList": true,
          "isId": false,
          "isGenerated": false,
          "sequence": false,
          "hasDefaultValue": false
        },
        {
          "name": "iceberg_tables",
          "type": "iceberg_tables",
          "isRequired": false,
          "kind": "object",
          "relationName": "iceberg_tablesTobuckets_analytics",
          "relationFromFields": [],
          "relationToFields": [],
          "isList": true,
          "isId": false,
          "isGenerated": false,
          "sequence": false,
          "hasDefaultValue": false
        }
      ],
      "uniqueConstraints": [
        {
          "name": "buckets_analytics_unique_name_idx",
          "fields": ["name"],
          "nullNotDistinct": false
        }
      ]
    },
    "buckets_vectors": {
      "id": "storage.buckets_vectors",
      "schemaName": "storage",
      "tableName": "buckets_vectors",
      "fields": [
        {
          "id": "storage.buckets_vectors.id",
          "name": "id",
          "columnName": "id",
          "type": "text",
          "isRequired": true,
          "kind": "scalar",
          "isList": false,
          "isGenerated": false,
          "sequence": false,
          "hasDefaultValue": false,
          "isId": true,
          "maxLength": null
        },
        {
          "id": "storage.buckets_vectors.type",
          "name": "type",
          "columnName": "type",
          "type": "buckettype",
          "isRequired": true,
          "kind": "scalar",
          "isList": false,
          "isGenerated": false,
          "sequence": false,
          "hasDefaultValue": true,
          "isId": false,
          "maxLength": null
        },
        {
          "id": "storage.buckets_vectors.created_at",
          "name": "created_at",
          "columnName": "created_at",
          "type": "timestamptz",
          "isRequired": true,
          "kind": "scalar",
          "isList": false,
          "isGenerated": false,
          "sequence": false,
          "hasDefaultValue": true,
          "isId": false,
          "maxLength": null
        },
        {
          "id": "storage.buckets_vectors.updated_at",
          "name": "updated_at",
          "columnName": "updated_at",
          "type": "timestamptz",
          "isRequired": true,
          "kind": "scalar",
          "isList": false,
          "isGenerated": false,
          "sequence": false,
          "hasDefaultValue": true,
          "isId": false,
          "maxLength": null
        },
        {
          "name": "vector_indexes",
          "type": "vector_indexes",
          "isRequired": false,
          "kind": "object",
          "relationName": "vector_indexesTobuckets_vectors",
          "relationFromFields": [],
          "relationToFields": [],
          "isList": true,
          "isId": false,
          "isGenerated": false,
          "sequence": false,
          "hasDefaultValue": false
        }
      ],
      "uniqueConstraints": []
    },
    "categories": {
      "id": "public.categories",
      "schemaName": "public",
      "tableName": "categories",
      "fields": [
        {
          "id": "public.categories.id",
          "name": "id",
          "columnName": "id",
          "type": "int8",
          "isRequired": true,
          "kind": "scalar",
          "isList": false,
          "isGenerated": false,
          "sequence": {
            "identifier": "\"public\".\"categories_id_seq\"",
            "increment": 1,
            "start": 1
          },
          "hasDefaultValue": false,
          "isId": true,
          "maxLength": null
        },
        {
          "id": "public.categories.created_at",
          "name": "created_at",
          "columnName": "created_at",
          "type": "timestamptz",
          "isRequired": true,
          "kind": "scalar",
          "isList": false,
          "isGenerated": false,
          "sequence": false,
          "hasDefaultValue": true,
          "isId": false,
          "maxLength": null
        },
        {
          "id": "public.categories.tenant_id",
          "name": "tenant_id",
          "columnName": "tenant_id",
          "type": "text",
          "isRequired": true,
          "kind": "scalar",
          "isList": false,
          "isGenerated": false,
          "sequence": false,
          "hasDefaultValue": false,
          "isId": false,
          "maxLength": null
        },
        {
          "id": "public.categories.name",
          "name": "name",
          "columnName": "name",
          "type": "text",
          "isRequired": true,
          "kind": "scalar",
          "isList": false,
          "isGenerated": false,
          "sequence": false,
          "hasDefaultValue": false,
          "isId": false,
          "maxLength": null
        },
        {
          "id": "public.categories.legacy_id",
          "name": "legacy_id",
          "columnName": "legacy_id",
          "type": "text",
          "isRequired": false,
          "kind": "scalar",
          "isList": false,
          "isGenerated": false,
          "sequence": false,
          "hasDefaultValue": false,
          "isId": false,
          "maxLength": null
        },
        {
          "id": "public.categories.type",
          "name": "type",
          "columnName": "type",
          "type": "content_types",
          "isRequired": false,
          "kind": "scalar",
          "isList": false,
          "isGenerated": false,
          "sequence": false,
          "hasDefaultValue": false,
          "isId": false,
          "maxLength": null
        },
        {
          "name": "news",
          "type": "news",
          "isRequired": false,
          "kind": "object",
          "relationName": "newsTocategories",
          "relationFromFields": [],
          "relationToFields": [],
          "isList": true,
          "isId": false,
          "isGenerated": false,
          "sequence": false,
          "hasDefaultValue": false
        },
        {
          "name": "projects",
          "type": "projects",
          "isRequired": false,
          "kind": "object",
          "relationName": "projectsTocategories",
          "relationFromFields": [],
          "relationToFields": [],
          "isList": true,
          "isId": false,
          "isGenerated": false,
          "sequence": false,
          "hasDefaultValue": false
        },
        {
          "name": "questions",
          "type": "questions",
          "isRequired": false,
          "kind": "object",
          "relationName": "questionsTocategories",
          "relationFromFields": [],
          "relationToFields": [],
          "isList": true,
          "isId": false,
          "isGenerated": false,
          "sequence": false,
          "hasDefaultValue": false
        },
        {
          "name": "research",
          "type": "research",
          "isRequired": false,
          "kind": "object",
          "relationName": "researchTocategories",
          "relationFromFields": [],
          "relationToFields": [],
          "isList": true,
          "isId": false,
          "isGenerated": false,
          "sequence": false,
          "hasDefaultValue": false
        }
      ],
      "uniqueConstraints": [
        {
          "name": "categories_pkey",
          "fields": ["id"],
          "nullNotDistinct": false
        }
      ]
    },
    "comments": {
      "id": "public.comments",
      "schemaName": "public",
      "tableName": "comments",
      "fields": [
        {
          "id": "public.comments.id",
          "name": "id",
          "columnName": "id",
          "type": "int8",
          "isRequired": true,
          "kind": "scalar",
          "isList": false,
          "isGenerated": false,
          "sequence": {
            "identifier": "\"public\".\"comments_id_seq\"",
            "increment": 1,
            "start": 1
          },
          "hasDefaultValue": false,
          "isId": true,
          "maxLength": null
        },
        {
          "id": "public.comments.created_at",
          "name": "created_at",
          "columnName": "created_at",
          "type": "timestamptz",
          "isRequired": true,
          "kind": "scalar",
          "isList": false,
          "isGenerated": false,
          "sequence": false,
          "hasDefaultValue": true,
          "isId": false,
          "maxLength": null
        },
        {
          "id": "public.comments.comment",
          "name": "comment",
          "columnName": "comment",
          "type": "text",
          "isRequired": true,
          "kind": "scalar",
          "isList": false,
          "isGenerated": false,
          "sequence": false,
          "hasDefaultValue": false,
          "isId": false,
          "maxLength": null
        },
        {
          "id": "public.comments.source_id",
          "name": "source_id",
          "columnName": "source_id",
          "type": "int8",
          "isRequired": false,
          "kind": "scalar",
          "isList": false,
          "isGenerated": false,
          "sequence": false,
          "hasDefaultValue": false,
          "isId": false,
          "maxLength": null
        },
        {
          "id": "public.comments.parent_id",
          "name": "parent_id",
          "columnName": "parent_id",
          "type": "int8",
          "isRequired": false,
          "kind": "scalar",
          "isList": false,
          "isGenerated": false,
          "sequence": false,
          "hasDefaultValue": false,
          "isId": false,
          "maxLength": null
        },
        {
          "id": "public.comments.tenant_id",
          "name": "tenant_id",
          "columnName": "tenant_id",
          "type": "text",
          "isRequired": true,
          "kind": "scalar",
          "isList": false,
          "isGenerated": false,
          "sequence": false,
          "hasDefaultValue": true,
          "isId": false,
          "maxLength": null
        },
        {
          "id": "public.comments.created_by",
          "name": "created_by",
          "columnName": "created_by",
          "type": "int8",
          "isRequired": false,
          "kind": "scalar",
          "isList": false,
          "isGenerated": false,
          "sequence": false,
          "hasDefaultValue": false,
          "isId": false,
          "maxLength": null
        },
        {
          "id": "public.comments.source_type",
          "name": "source_type",
          "columnName": "source_type",
          "type": "text",
          "isRequired": true,
          "kind": "scalar",
          "isList": false,
          "isGenerated": false,
          "sequence": false,
          "hasDefaultValue": false,
          "isId": false,
          "maxLength": null
        },
        {
          "id": "public.comments.modified_at",
          "name": "modified_at",
          "columnName": "modified_at",
          "type": "timestamptz",
          "isRequired": false,
          "kind": "scalar",
          "isList": false,
          "isGenerated": false,
          "sequence": false,
          "hasDefaultValue": false,
          "isId": false,
          "maxLength": null
        },
        {
          "id": "public.comments.source_id_legacy",
          "name": "source_id_legacy",
          "columnName": "source_id_legacy",
          "type": "text",
          "isRequired": false,
          "kind": "scalar",
          "isList": false,
          "isGenerated": false,
          "sequence": false,
          "hasDefaultValue": false,
          "isId": false,
          "maxLength": null
        },
        {
          "id": "public.comments.deleted",
          "name": "deleted",
          "columnName": "deleted",
          "type": "bool",
          "isRequired": false,
          "kind": "scalar",
          "isList": false,
          "isGenerated": false,
          "sequence": false,
          "hasDefaultValue": false,
          "isId": false,
          "maxLength": null
        },
        {
          "id": "public.comments.legacy_id",
          "name": "legacy_id",
          "columnName": "legacy_id",
          "type": "text",
          "isRequired": false,
          "kind": "scalar",
          "isList": false,
          "isGenerated": false,
          "sequence": false,
          "hasDefaultValue": false,
          "isId": false,
          "maxLength": null
        },
        {
          "name": "profiles",
          "type": "profiles",
          "isRequired": false,
          "kind": "object",
          "relationName": "commentsToprofiles",
          "relationFromFields": ["created_by"],
          "relationToFields": ["id"],
          "isList": false,
          "isId": false,
          "isGenerated": false,
          "sequence": false,
          "hasDefaultValue": false
        }
      ],
      "uniqueConstraints": [
        {
          "name": "comments_pkey",
          "fields": ["id"],
          "nullNotDistinct": false
        }
      ]
    },
    "custom_oauth_providers": {
      "id": "auth.custom_oauth_providers",
      "schemaName": "auth",
      "tableName": "custom_oauth_providers",
      "fields": [
        {
          "id": "auth.custom_oauth_providers.id",
          "name": "id",
          "columnName": "id",
          "type": "uuid",
          "isRequired": true,
          "kind": "scalar",
          "isList": false,
          "isGenerated": false,
          "sequence": false,
          "hasDefaultValue": true,
          "isId": true,
          "maxLength": null
        },
        {
          "id": "auth.custom_oauth_providers.provider_type",
          "name": "provider_type",
          "columnName": "provider_type",
          "type": "text",
          "isRequired": true,
          "kind": "scalar",
          "isList": false,
          "isGenerated": false,
          "sequence": false,
          "hasDefaultValue": false,
          "isId": false,
          "maxLength": null
        },
        {
          "id": "auth.custom_oauth_providers.identifier",
          "name": "identifier",
          "columnName": "identifier",
          "type": "text",
          "isRequired": true,
          "kind": "scalar",
          "isList": false,
          "isGenerated": false,
          "sequence": false,
          "hasDefaultValue": false,
          "isId": false,
          "maxLength": null
        },
        {
          "id": "auth.custom_oauth_providers.name",
          "name": "name",
          "columnName": "name",
          "type": "text",
          "isRequired": true,
          "kind": "scalar",
          "isList": false,
          "isGenerated": false,
          "sequence": false,
          "hasDefaultValue": false,
          "isId": false,
          "maxLength": null
        },
        {
          "id": "auth.custom_oauth_providers.client_id",
          "name": "client_id",
          "columnName": "client_id",
          "type": "text",
          "isRequired": true,
          "kind": "scalar",
          "isList": false,
          "isGenerated": false,
          "sequence": false,
          "hasDefaultValue": false,
          "isId": false,
          "maxLength": null
        },
        {
          "id": "auth.custom_oauth_providers.client_secret",
          "name": "client_secret",
          "columnName": "client_secret",
          "type": "text",
          "isRequired": true,
          "kind": "scalar",
          "isList": false,
          "isGenerated": false,
          "sequence": false,
          "hasDefaultValue": false,
          "isId": false,
          "maxLength": null
        },
        {
          "id": "auth.custom_oauth_providers.acceptable_client_ids",
          "name": "acceptable_client_ids",
          "columnName": "acceptable_client_ids",
          "type": "text[]",
          "isRequired": true,
          "kind": "scalar",
          "isList": false,
          "isGenerated": false,
          "sequence": false,
          "hasDefaultValue": true,
          "isId": false,
          "maxLength": null
        },
        {
          "id": "auth.custom_oauth_providers.scopes",
          "name": "scopes",
          "columnName": "scopes",
          "type": "text[]",
          "isRequired": true,
          "kind": "scalar",
          "isList": false,
          "isGenerated": false,
          "sequence": false,
          "hasDefaultValue": true,
          "isId": false,
          "maxLength": null
        },
        {
          "id": "auth.custom_oauth_providers.pkce_enabled",
          "name": "pkce_enabled",
          "columnName": "pkce_enabled",
          "type": "bool",
          "isRequired": true,
          "kind": "scalar",
          "isList": false,
          "isGenerated": false,
          "sequence": false,
          "hasDefaultValue": true,
          "isId": false,
          "maxLength": null
        },
        {
          "id": "auth.custom_oauth_providers.attribute_mapping",
          "name": "attribute_mapping",
          "columnName": "attribute_mapping",
          "type": "jsonb",
          "isRequired": true,
          "kind": "scalar",
          "isList": false,
          "isGenerated": false,
          "sequence": false,
          "hasDefaultValue": true,
          "isId": false,
          "maxLength": null
        },
        {
          "id": "auth.custom_oauth_providers.authorization_params",
          "name": "authorization_params",
          "columnName": "authorization_params",
          "type": "jsonb",
          "isRequired": true,
          "kind": "scalar",
          "isList": false,
          "isGenerated": false,
          "sequence": false,
          "hasDefaultValue": true,
          "isId": false,
          "maxLength": null
        },
        {
          "id": "auth.custom_oauth_providers.enabled",
          "name": "enabled",
          "columnName": "enabled",
          "type": "bool",
          "isRequired": true,
          "kind": "scalar",
          "isList": false,
          "isGenerated": false,
          "sequence": false,
          "hasDefaultValue": true,
          "isId": false,
          "maxLength": null
        },
        {
          "id": "auth.custom_oauth_providers.email_optional",
          "name": "email_optional",
          "columnName": "email_optional",
          "type": "bool",
          "isRequired": true,
          "kind": "scalar",
          "isList": false,
          "isGenerated": false,
          "sequence": false,
          "hasDefaultValue": true,
          "isId": false,
          "maxLength": null
        },
        {
          "id": "auth.custom_oauth_providers.issuer",
          "name": "issuer",
          "columnName": "issuer",
          "type": "text",
          "isRequired": false,
          "kind": "scalar",
          "isList": false,
          "isGenerated": false,
          "sequence": false,
          "hasDefaultValue": false,
          "isId": false,
          "maxLength": null
        },
        {
          "id": "auth.custom_oauth_providers.discovery_url",
          "name": "discovery_url",
          "columnName": "discovery_url",
          "type": "text",
          "isRequired": false,
          "kind": "scalar",
          "isList": false,
          "isGenerated": false,
          "sequence": false,
          "hasDefaultValue": false,
          "isId": false,
          "maxLength": null
        },
        {
          "id": "auth.custom_oauth_providers.skip_nonce_check",
          "name": "skip_nonce_check",
          "columnName": "skip_nonce_check",
          "type": "bool",
          "isRequired": true,
          "kind": "scalar",
          "isList": false,
          "isGenerated": false,
          "sequence": false,
          "hasDefaultValue": true,
          "isId": false,
          "maxLength": null
        },
        {
          "id": "auth.custom_oauth_providers.cached_discovery",
          "name": "cached_discovery",
          "columnName": "cached_discovery",
          "type": "jsonb",
          "isRequired": false,
          "kind": "scalar",
          "isList": false,
          "isGenerated": false,
          "sequence": false,
          "hasDefaultValue": false,
          "isId": false,
          "maxLength": null
        },
        {
          "id": "auth.custom_oauth_providers.discovery_cached_at",
          "name": "discovery_cached_at",
          "columnName": "discovery_cached_at",
          "type": "timestamptz",
          "isRequired": false,
          "kind": "scalar",
          "isList": false,
          "isGenerated": false,
          "sequence": false,
          "hasDefaultValue": false,
          "isId": false,
          "maxLength": null
        },
        {
          "id": "auth.custom_oauth_providers.authorization_url",
          "name": "authorization_url",
          "columnName": "authorization_url",
          "type": "text",
          "isRequired": false,
          "kind": "scalar",
          "isList": false,
          "isGenerated": false,
          "sequence": false,
          "hasDefaultValue": false,
          "isId": false,
          "maxLength": null
        },
        {
          "id": "auth.custom_oauth_providers.token_url",
          "name": "token_url",
          "columnName": "token_url",
          "type": "text",
          "isRequired": false,
          "kind": "scalar",
          "isList": false,
          "isGenerated": false,
          "sequence": false,
          "hasDefaultValue": false,
          "isId": false,
          "maxLength": null
        },
        {
          "id": "auth.custom_oauth_providers.userinfo_url",
          "name": "userinfo_url",
          "columnName": "userinfo_url",
          "type": "text",
          "isRequired": false,
          "kind": "scalar",
          "isList": false,
          "isGenerated": false,
          "sequence": false,
          "hasDefaultValue": false,
          "isId": false,
          "maxLength": null
        },
        {
          "id": "auth.custom_oauth_providers.jwks_uri",
          "name": "jwks_uri",
          "columnName": "jwks_uri",
          "type": "text",
          "isRequired": false,
          "kind": "scalar",
          "isList": false,
          "isGenerated": false,
          "sequence": false,
          "hasDefaultValue": false,
          "isId": false,
          "maxLength": null
        },
        {
          "id": "auth.custom_oauth_providers.created_at",
          "name": "created_at",
          "columnName": "created_at",
          "type": "timestamptz",
          "isRequired": true,
          "kind": "scalar",
          "isList": false,
          "isGenerated": false,
          "sequence": false,
          "hasDefaultValue": true,
          "isId": false,
          "maxLength": null
        },
        {
          "id": "auth.custom_oauth_providers.updated_at",
          "name": "updated_at",
          "columnName": "updated_at",
          "type": "timestamptz",
          "isRequired": true,
          "kind": "scalar",
          "isList": false,
          "isGenerated": false,
          "sequence": false,
          "hasDefaultValue": true,
          "isId": false,
          "maxLength": null
        }
      ],
      "uniqueConstraints": [
        {
          "name": "custom_oauth_providers_identifier_key",
          "fields": ["identifier"],
          "nullNotDistinct": false
        }
      ]
    },
    "extensions": {
      "id": "_realtime.extensions",
      "schemaName": "_realtime",
      "tableName": "extensions",
      "fields": [
        {
          "id": "_realtime.extensions.id",
          "name": "id",
          "columnName": "id",
          "type": "uuid",
          "isRequired": true,
          "kind": "scalar",
          "isList": false,
          "isGenerated": false,
          "sequence": false,
          "hasDefaultValue": false,
          "isId": true,
          "maxLength": null
        },
        {
          "id": "_realtime.extensions.type",
          "name": "type",
          "columnName": "type",
          "type": "text",
          "isRequired": false,
          "kind": "scalar",
          "isList": false,
          "isGenerated": false,
          "sequence": false,
          "hasDefaultValue": false,
          "isId": false,
          "maxLength": null
        },
        {
          "id": "_realtime.extensions.settings",
          "name": "settings",
          "columnName": "settings",
          "type": "jsonb",
          "isRequired": false,
          "kind": "scalar",
          "isList": false,
          "isGenerated": false,
          "sequence": false,
          "hasDefaultValue": false,
          "isId": false,
          "maxLength": null
        },
        {
          "id": "_realtime.extensions.tenant_external_id",
          "name": "tenant_external_id",
          "columnName": "tenant_external_id",
          "type": "text",
          "isRequired": false,
          "kind": "scalar",
          "isList": false,
          "isGenerated": false,
          "sequence": false,
          "hasDefaultValue": false,
          "isId": false,
          "maxLength": null
        },
        {
          "id": "_realtime.extensions.inserted_at",
          "name": "inserted_at",
          "columnName": "inserted_at",
          "type": "timestamp",
          "isRequired": true,
          "kind": "scalar",
          "isList": false,
          "isGenerated": false,
          "sequence": false,
          "hasDefaultValue": false,
          "isId": false,
          "maxLength": null
        },
        {
          "id": "_realtime.extensions.updated_at",
          "name": "updated_at",
          "columnName": "updated_at",
          "type": "timestamp",
          "isRequired": true,
          "kind": "scalar",
          "isList": false,
          "isGenerated": false,
          "sequence": false,
          "hasDefaultValue": false,
          "isId": false,
          "maxLength": null
        },
        {
          "name": "tenants",
          "type": "tenants",
          "isRequired": false,
          "kind": "object",
          "relationName": "extensionsTotenants",
          "relationFromFields": ["tenant_external_id"],
          "relationToFields": ["external_id"],
          "isList": false,
          "isId": false,
          "isGenerated": false,
          "sequence": false,
          "hasDefaultValue": false
        }
      ],
      "uniqueConstraints": [
        {
          "name": "extensions_tenant_external_id_type_index",
          "fields": ["tenant_external_id", "type"],
          "nullNotDistinct": false
        }
      ]
    },
    "flow_state": {
      "id": "auth.flow_state",
      "schemaName": "auth",
      "tableName": "flow_state",
      "fields": [
        {
          "id": "auth.flow_state.id",
          "name": "id",
          "columnName": "id",
          "type": "uuid",
          "isRequired": true,
          "kind": "scalar",
          "isList": false,
          "isGenerated": false,
          "sequence": false,
          "hasDefaultValue": false,
          "isId": true,
          "maxLength": null
        },
        {
          "id": "auth.flow_state.user_id",
          "name": "user_id",
          "columnName": "user_id",
          "type": "uuid",
          "isRequired": false,
          "kind": "scalar",
          "isList": false,
          "isGenerated": false,
          "sequence": false,
          "hasDefaultValue": false,
          "isId": false,
          "maxLength": null
        },
        {
          "id": "auth.flow_state.auth_code",
          "name": "auth_code",
          "columnName": "auth_code",
          "type": "text",
          "isRequired": false,
          "kind": "scalar",
          "isList": false,
          "isGenerated": false,
          "sequence": false,
          "hasDefaultValue": false,
          "isId": false,
          "maxLength": null
        },
        {
          "id": "auth.flow_state.code_challenge_method",
          "name": "code_challenge_method",
          "columnName": "code_challenge_method",
          "type": "code_challenge_method",
          "isRequired": false,
          "kind": "scalar",
          "isList": false,
          "isGenerated": false,
          "sequence": false,
          "hasDefaultValue": false,
          "isId": false,
          "maxLength": null
        },
        {
          "id": "auth.flow_state.code_challenge",
          "name": "code_challenge",
          "columnName": "code_challenge",
          "type": "text",
          "isRequired": false,
          "kind": "scalar",
          "isList": false,
          "isGenerated": false,
          "sequence": false,
          "hasDefaultValue": false,
          "isId": false,
          "maxLength": null
        },
        {
          "id": "auth.flow_state.provider_type",
          "name": "provider_type",
          "columnName": "provider_type",
          "type": "text",
          "isRequired": true,
          "kind": "scalar",
          "isList": false,
          "isGenerated": false,
          "sequence": false,
          "hasDefaultValue": false,
          "isId": false,
          "maxLength": null
        },
        {
          "id": "auth.flow_state.provider_access_token",
          "name": "provider_access_token",
          "columnName": "provider_access_token",
          "type": "text",
          "isRequired": false,
          "kind": "scalar",
          "isList": false,
          "isGenerated": false,
          "sequence": false,
          "hasDefaultValue": false,
          "isId": false,
          "maxLength": null
        },
        {
          "id": "auth.flow_state.provider_refresh_token",
          "name": "provider_refresh_token",
          "columnName": "provider_refresh_token",
          "type": "text",
          "isRequired": false,
          "kind": "scalar",
          "isList": false,
          "isGenerated": false,
          "sequence": false,
          "hasDefaultValue": false,
          "isId": false,
          "maxLength": null
        },
        {
          "id": "auth.flow_state.created_at",
          "name": "created_at",
          "columnName": "created_at",
          "type": "timestamptz",
          "isRequired": false,
          "kind": "scalar",
          "isList": false,
          "isGenerated": false,
          "sequence": false,
          "hasDefaultValue": false,
          "isId": false,
          "maxLength": null
        },
        {
          "id": "auth.flow_state.updated_at",
          "name": "updated_at",
          "columnName": "updated_at",
          "type": "timestamptz",
          "isRequired": false,
          "kind": "scalar",
          "isList": false,
          "isGenerated": false,
          "sequence": false,
          "hasDefaultValue": false,
          "isId": false,
          "maxLength": null
        },
        {
          "id": "auth.flow_state.authentication_method",
          "name": "authentication_method",
          "columnName": "authentication_method",
          "type": "text",
          "isRequired": true,
          "kind": "scalar",
          "isList": false,
          "isGenerated": false,
          "sequence": false,
          "hasDefaultValue": false,
          "isId": false,
          "maxLength": null
        },
        {
          "id": "auth.flow_state.auth_code_issued_at",
          "name": "auth_code_issued_at",
          "columnName": "auth_code_issued_at",
          "type": "timestamptz",
          "isRequired": false,
          "kind": "scalar",
          "isList": false,
          "isGenerated": false,
          "sequence": false,
          "hasDefaultValue": false,
          "isId": false,
          "maxLength": null
        },
        {
          "id": "auth.flow_state.invite_token",
          "name": "invite_token",
          "columnName": "invite_token",
          "type": "text",
          "isRequired": false,
          "kind": "scalar",
          "isList": false,
          "isGenerated": false,
          "sequence": false,
          "hasDefaultValue": false,
          "isId": false,
          "maxLength": null
        },
        {
          "id": "auth.flow_state.referrer",
          "name": "referrer",
          "columnName": "referrer",
          "type": "text",
          "isRequired": false,
          "kind": "scalar",
          "isList": false,
          "isGenerated": false,
          "sequence": false,
          "hasDefaultValue": false,
          "isId": false,
          "maxLength": null
        },
        {
          "id": "auth.flow_state.oauth_client_state_id",
          "name": "oauth_client_state_id",
          "columnName": "oauth_client_state_id",
          "type": "uuid",
          "isRequired": false,
          "kind": "scalar",
          "isList": false,
          "isGenerated": false,
          "sequence": false,
          "hasDefaultValue": false,
          "isId": false,
          "maxLength": null
        },
        {
          "id": "auth.flow_state.linking_target_id",
          "name": "linking_target_id",
          "columnName": "linking_target_id",
          "type": "uuid",
          "isRequired": false,
          "kind": "scalar",
          "isList": false,
          "isGenerated": false,
          "sequence": false,
          "hasDefaultValue": false,
          "isId": false,
          "maxLength": null
        },
        {
          "id": "auth.flow_state.email_optional",
          "name": "email_optional",
          "columnName": "email_optional",
          "type": "bool",
          "isRequired": true,
          "kind": "scalar",
          "isList": false,
          "isGenerated": false,
          "sequence": false,
          "hasDefaultValue": true,
          "isId": false,
          "maxLength": null
        },
        {
          "name": "saml_relay_states",
          "type": "saml_relay_states",
          "isRequired": false,
          "kind": "object",
          "relationName": "saml_relay_statesToflow_state",
          "relationFromFields": [],
          "relationToFields": [],
          "isList": true,
          "isId": false,
          "isGenerated": false,
          "sequence": false,
          "hasDefaultValue": false
        }
      ],
      "uniqueConstraints": []
    },
    "hooks": {
      "id": "supabase_functions.hooks",
      "schemaName": "supabase_functions",
      "tableName": "hooks",
      "fields": [
        {
          "id": "supabase_functions.hooks.id",
          "name": "id",
          "columnName": "id",
          "type": "int8",
          "isRequired": true,
          "kind": "scalar",
          "isList": false,
          "isGenerated": false,
          "sequence": {
            "identifier": "\"supabase_functions\".\"hooks_id_seq\"",
            "increment": 1,
            "start": 1
          },
          "hasDefaultValue": true,
          "isId": true,
          "maxLength": null
        },
        {
          "id": "supabase_functions.hooks.hook_table_id",
          "name": "hook_table_id",
          "columnName": "hook_table_id",
          "type": "int4",
          "isRequired": true,
          "kind": "scalar",
          "isList": false,
          "isGenerated": false,
          "sequence": false,
          "hasDefaultValue": false,
          "isId": false,
          "maxLength": null
        },
        {
          "id": "supabase_functions.hooks.hook_name",
          "name": "hook_name",
          "columnName": "hook_name",
          "type": "text",
          "isRequired": true,
          "kind": "scalar",
          "isList": false,
          "isGenerated": false,
          "sequence": false,
          "hasDefaultValue": false,
          "isId": false,
          "maxLength": null
        },
        {
          "id": "supabase_functions.hooks.created_at",
          "name": "created_at",
          "columnName": "created_at",
          "type": "timestamptz",
          "isRequired": true,
          "kind": "scalar",
          "isList": false,
          "isGenerated": false,
          "sequence": false,
          "hasDefaultValue": true,
          "isId": false,
          "maxLength": null
        },
        {
          "id": "supabase_functions.hooks.request_id",
          "name": "request_id",
          "columnName": "request_id",
          "type": "int8",
          "isRequired": false,
          "kind": "scalar",
          "isList": false,
          "isGenerated": false,
          "sequence": false,
          "hasDefaultValue": false,
          "isId": false,
          "maxLength": null
        }
      ],
      "uniqueConstraints": [
        {
          "name": "hooks_pkey",
          "fields": ["id"],
          "nullNotDistinct": false
        }
      ]
    },
    "http_request_queue": {
      "id": "net.http_request_queue",
      "schemaName": "net",
      "tableName": "http_request_queue",
      "fields": [
        {
          "id": "net.http_request_queue.id",
          "name": "id",
          "columnName": "id",
          "type": "int8",
          "isRequired": true,
          "kind": "scalar",
          "isList": false,
          "isGenerated": false,
          "sequence": {
            "identifier": "\"net\".\"http_request_queue_id_seq\"",
            "increment": 1,
            "start": 1
          },
          "hasDefaultValue": true,
          "isId": false,
          "maxLength": null
        },
        {
          "id": "net.http_request_queue.method",
          "name": "method",
          "columnName": "method",
          "type": "text",
          "isRequired": true,
          "kind": "scalar",
          "isList": false,
          "isGenerated": false,
          "sequence": false,
          "hasDefaultValue": false,
          "isId": false,
          "maxLength": null
        },
        {
          "id": "net.http_request_queue.url",
          "name": "url",
          "columnName": "url",
          "type": "text",
          "isRequired": true,
          "kind": "scalar",
          "isList": false,
          "isGenerated": false,
          "sequence": false,
          "hasDefaultValue": false,
          "isId": false,
          "maxLength": null
        },
        {
          "id": "net.http_request_queue.headers",
          "name": "headers",
          "columnName": "headers",
          "type": "jsonb",
          "isRequired": true,
          "kind": "scalar",
          "isList": false,
          "isGenerated": false,
          "sequence": false,
          "hasDefaultValue": false,
          "isId": false,
          "maxLength": null
        },
        {
          "id": "net.http_request_queue.body",
          "name": "body",
          "columnName": "body",
          "type": "bytea",
          "isRequired": false,
          "kind": "scalar",
          "isList": false,
          "isGenerated": false,
          "sequence": false,
          "hasDefaultValue": false,
          "isId": false,
          "maxLength": null
        },
        {
          "id": "net.http_request_queue.timeout_milliseconds",
          "name": "timeout_milliseconds",
          "columnName": "timeout_milliseconds",
          "type": "int4",
          "isRequired": true,
          "kind": "scalar",
          "isList": false,
          "isGenerated": false,
          "sequence": false,
          "hasDefaultValue": false,
          "isId": false,
          "maxLength": null
        }
      ],
      "uniqueConstraints": []
    },
    "iceberg_namespaces": {
      "id": "storage.iceberg_namespaces",
      "schemaName": "storage",
      "tableName": "iceberg_namespaces",
      "fields": [
        {
          "id": "storage.iceberg_namespaces.id",
          "name": "id",
          "columnName": "id",
          "type": "uuid",
          "isRequired": true,
          "kind": "scalar",
          "isList": false,
          "isGenerated": false,
          "sequence": false,
          "hasDefaultValue": true,
          "isId": true,
          "maxLength": null
        },
        {
          "id": "storage.iceberg_namespaces.bucket_name",
          "name": "bucket_name",
          "columnName": "bucket_name",
          "type": "text",
          "isRequired": true,
          "kind": "scalar",
          "isList": false,
          "isGenerated": false,
          "sequence": false,
          "hasDefaultValue": false,
          "isId": false,
          "maxLength": null
        },
        {
          "id": "storage.iceberg_namespaces.name",
          "name": "name",
          "columnName": "name",
          "type": "text",
          "isRequired": true,
          "kind": "scalar",
          "isList": false,
          "isGenerated": false,
          "sequence": false,
          "hasDefaultValue": false,
          "isId": false,
          "maxLength": null
        },
        {
          "id": "storage.iceberg_namespaces.created_at",
          "name": "created_at",
          "columnName": "created_at",
          "type": "timestamptz",
          "isRequired": true,
          "kind": "scalar",
          "isList": false,
          "isGenerated": false,
          "sequence": false,
          "hasDefaultValue": true,
          "isId": false,
          "maxLength": null
        },
        {
          "id": "storage.iceberg_namespaces.updated_at",
          "name": "updated_at",
          "columnName": "updated_at",
          "type": "timestamptz",
          "isRequired": true,
          "kind": "scalar",
          "isList": false,
          "isGenerated": false,
          "sequence": false,
          "hasDefaultValue": true,
          "isId": false,
          "maxLength": null
        },
        {
          "id": "storage.iceberg_namespaces.metadata",
          "name": "metadata",
          "columnName": "metadata",
          "type": "jsonb",
          "isRequired": true,
          "kind": "scalar",
          "isList": false,
          "isGenerated": false,
          "sequence": false,
          "hasDefaultValue": true,
          "isId": false,
          "maxLength": null
        },
        {
          "id": "storage.iceberg_namespaces.catalog_id",
          "name": "catalog_id",
          "columnName": "catalog_id",
          "type": "uuid",
          "isRequired": true,
          "kind": "scalar",
          "isList": false,
          "isGenerated": false,
          "sequence": false,
          "hasDefaultValue": false,
          "isId": false,
          "maxLength": null
        },
        {
          "name": "buckets_analytics",
          "type": "buckets_analytics",
          "isRequired": true,
          "kind": "object",
          "relationName": "iceberg_namespacesTobuckets_analytics",
          "relationFromFields": ["catalog_id"],
          "relationToFields": ["id"],
          "isList": false,
          "isId": false,
          "isGenerated": false,
          "sequence": false,
          "hasDefaultValue": false
        },
        {
          "name": "iceberg_tables",
          "type": "iceberg_tables",
          "isRequired": false,
          "kind": "object",
          "relationName": "iceberg_tablesToiceberg_namespaces",
          "relationFromFields": [],
          "relationToFields": [],
          "isList": true,
          "isId": false,
          "isGenerated": false,
          "sequence": false,
          "hasDefaultValue": false
        }
      ],
      "uniqueConstraints": [
        {
          "name": "idx_iceberg_namespaces_bucket_id",
          "fields": ["catalog_id", "name"],
          "nullNotDistinct": false
        }
      ]
    },
    "iceberg_tables": {
      "id": "storage.iceberg_tables",
      "schemaName": "storage",
      "tableName": "iceberg_tables",
      "fields": [
        {
          "id": "storage.iceberg_tables.id",
          "name": "id",
          "columnName": "id",
          "type": "uuid",
          "isRequired": true,
          "kind": "scalar",
          "isList": false,
          "isGenerated": false,
          "sequence": false,
          "hasDefaultValue": true,
          "isId": true,
          "maxLength": null
        },
        {
          "id": "storage.iceberg_tables.namespace_id",
          "name": "namespace_id",
          "columnName": "namespace_id",
          "type": "uuid",
          "isRequired": true,
          "kind": "scalar",
          "isList": false,
          "isGenerated": false,
          "sequence": false,
          "hasDefaultValue": false,
          "isId": false,
          "maxLength": null
        },
        {
          "id": "storage.iceberg_tables.bucket_name",
          "name": "bucket_name",
          "columnName": "bucket_name",
          "type": "text",
          "isRequired": true,
          "kind": "scalar",
          "isList": false,
          "isGenerated": false,
          "sequence": false,
          "hasDefaultValue": false,
          "isId": false,
          "maxLength": null
        },
        {
          "id": "storage.iceberg_tables.name",
          "name": "name",
          "columnName": "name",
          "type": "text",
          "isRequired": true,
          "kind": "scalar",
          "isList": false,
          "isGenerated": false,
          "sequence": false,
          "hasDefaultValue": false,
          "isId": false,
          "maxLength": null
        },
        {
          "id": "storage.iceberg_tables.location",
          "name": "location",
          "columnName": "location",
          "type": "text",
          "isRequired": true,
          "kind": "scalar",
          "isList": false,
          "isGenerated": false,
          "sequence": false,
          "hasDefaultValue": false,
          "isId": false,
          "maxLength": null
        },
        {
          "id": "storage.iceberg_tables.created_at",
          "name": "created_at",
          "columnName": "created_at",
          "type": "timestamptz",
          "isRequired": true,
          "kind": "scalar",
          "isList": false,
          "isGenerated": false,
          "sequence": false,
          "hasDefaultValue": true,
          "isId": false,
          "maxLength": null
        },
        {
          "id": "storage.iceberg_tables.updated_at",
          "name": "updated_at",
          "columnName": "updated_at",
          "type": "timestamptz",
          "isRequired": true,
          "kind": "scalar",
          "isList": false,
          "isGenerated": false,
          "sequence": false,
          "hasDefaultValue": true,
          "isId": false,
          "maxLength": null
        },
        {
          "id": "storage.iceberg_tables.remote_table_id",
          "name": "remote_table_id",
          "columnName": "remote_table_id",
          "type": "text",
          "isRequired": false,
          "kind": "scalar",
          "isList": false,
          "isGenerated": false,
          "sequence": false,
          "hasDefaultValue": false,
          "isId": false,
          "maxLength": null
        },
        {
          "id": "storage.iceberg_tables.shard_key",
          "name": "shard_key",
          "columnName": "shard_key",
          "type": "text",
          "isRequired": false,
          "kind": "scalar",
          "isList": false,
          "isGenerated": false,
          "sequence": false,
          "hasDefaultValue": false,
          "isId": false,
          "maxLength": null
        },
        {
          "id": "storage.iceberg_tables.shard_id",
          "name": "shard_id",
          "columnName": "shard_id",
          "type": "text",
          "isRequired": false,
          "kind": "scalar",
          "isList": false,
          "isGenerated": false,
          "sequence": false,
          "hasDefaultValue": false,
          "isId": false,
          "maxLength": null
        },
        {
          "id": "storage.iceberg_tables.catalog_id",
          "name": "catalog_id",
          "columnName": "catalog_id",
          "type": "uuid",
          "isRequired": true,
          "kind": "scalar",
          "isList": false,
          "isGenerated": false,
          "sequence": false,
          "hasDefaultValue": false,
          "isId": false,
          "maxLength": null
        },
        {
          "name": "buckets_analytics",
          "type": "buckets_analytics",
          "isRequired": true,
          "kind": "object",
          "relationName": "iceberg_tablesTobuckets_analytics",
          "relationFromFields": ["catalog_id"],
          "relationToFields": ["id"],
          "isList": false,
          "isId": false,
          "isGenerated": false,
          "sequence": false,
          "hasDefaultValue": false
        },
        {
          "name": "iceberg_namespaces",
          "type": "iceberg_namespaces",
          "isRequired": true,
          "kind": "object",
          "relationName": "iceberg_tablesToiceberg_namespaces",
          "relationFromFields": ["namespace_id"],
          "relationToFields": ["id"],
          "isList": false,
          "isId": false,
          "isGenerated": false,
          "sequence": false,
          "hasDefaultValue": false
        }
      ],
      "uniqueConstraints": [
        {
          "name": "idx_iceberg_tables_location",
          "fields": ["location"],
          "nullNotDistinct": false
        },
        {
          "name": "idx_iceberg_tables_namespace_id",
          "fields": ["catalog_id", "name", "namespace_id"],
          "nullNotDistinct": false
        }
      ]
    },
    "identities": {
      "id": "auth.identities",
      "schemaName": "auth",
      "tableName": "identities",
      "fields": [
        {
          "id": "auth.identities.provider_id",
          "name": "provider_id",
          "columnName": "provider_id",
          "type": "text",
          "isRequired": true,
          "kind": "scalar",
          "isList": false,
          "isGenerated": false,
          "sequence": false,
          "hasDefaultValue": false,
          "isId": false,
          "maxLength": null
        },
        {
          "id": "auth.identities.user_id",
          "name": "user_id",
          "columnName": "user_id",
          "type": "uuid",
          "isRequired": true,
          "kind": "scalar",
          "isList": false,
          "isGenerated": false,
          "sequence": false,
          "hasDefaultValue": false,
          "isId": false,
          "maxLength": null
        },
        {
          "id": "auth.identities.identity_data",
          "name": "identity_data",
          "columnName": "identity_data",
          "type": "jsonb",
          "isRequired": true,
          "kind": "scalar",
          "isList": false,
          "isGenerated": false,
          "sequence": false,
          "hasDefaultValue": false,
          "isId": false,
          "maxLength": null
        },
        {
          "id": "auth.identities.provider",
          "name": "provider",
          "columnName": "provider",
          "type": "text",
          "isRequired": true,
          "kind": "scalar",
          "isList": false,
          "isGenerated": false,
          "sequence": false,
          "hasDefaultValue": false,
          "isId": false,
          "maxLength": null
        },
        {
          "id": "auth.identities.last_sign_in_at",
          "name": "last_sign_in_at",
          "columnName": "last_sign_in_at",
          "type": "timestamptz",
          "isRequired": false,
          "kind": "scalar",
          "isList": false,
          "isGenerated": false,
          "sequence": false,
          "hasDefaultValue": false,
          "isId": false,
          "maxLength": null
        },
        {
          "id": "auth.identities.created_at",
          "name": "created_at",
          "columnName": "created_at",
          "type": "timestamptz",
          "isRequired": false,
          "kind": "scalar",
          "isList": false,
          "isGenerated": false,
          "sequence": false,
          "hasDefaultValue": false,
          "isId": false,
          "maxLength": null
        },
        {
          "id": "auth.identities.updated_at",
          "name": "updated_at",
          "columnName": "updated_at",
          "type": "timestamptz",
          "isRequired": false,
          "kind": "scalar",
          "isList": false,
          "isGenerated": false,
          "sequence": false,
          "hasDefaultValue": false,
          "isId": false,
          "maxLength": null
        },
        {
          "id": "auth.identities.email",
          "name": "email",
          "columnName": "email",
          "type": "text",
          "isRequired": false,
          "kind": "scalar",
          "isList": false,
          "isGenerated": true,
          "sequence": false,
          "hasDefaultValue": false,
          "isId": false,
          "maxLength": null
        },
        {
          "id": "auth.identities.id",
          "name": "id",
          "columnName": "id",
          "type": "uuid",
          "isRequired": true,
          "kind": "scalar",
          "isList": false,
          "isGenerated": false,
          "sequence": false,
          "hasDefaultValue": true,
          "isId": true,
          "maxLength": null
        },
        {
          "name": "users",
          "type": "users",
          "isRequired": true,
          "kind": "object",
          "relationName": "identitiesTousers",
          "relationFromFields": ["user_id"],
          "relationToFields": ["id"],
          "isList": false,
          "isId": false,
          "isGenerated": false,
          "sequence": false,
          "hasDefaultValue": false
        }
      ],
      "uniqueConstraints": [
        {
          "name": "identities_provider_id_provider_unique",
          "fields": ["provider", "provider_id"],
          "nullNotDistinct": false
        }
      ]
    },
    "instances": {
      "id": "auth.instances",
      "schemaName": "auth",
      "tableName": "instances",
      "fields": [
        {
          "id": "auth.instances.id",
          "name": "id",
          "columnName": "id",
          "type": "uuid",
          "isRequired": true,
          "kind": "scalar",
          "isList": false,
          "isGenerated": false,
          "sequence": false,
          "hasDefaultValue": false,
          "isId": true,
          "maxLength": null
        },
        {
          "id": "auth.instances.uuid",
          "name": "uuid",
          "columnName": "uuid",
          "type": "uuid",
          "isRequired": false,
          "kind": "scalar",
          "isList": false,
          "isGenerated": false,
          "sequence": false,
          "hasDefaultValue": false,
          "isId": false,
          "maxLength": null
        },
        {
          "id": "auth.instances.raw_base_config",
          "name": "raw_base_config",
          "columnName": "raw_base_config",
          "type": "text",
          "isRequired": false,
          "kind": "scalar",
          "isList": false,
          "isGenerated": false,
          "sequence": false,
          "hasDefaultValue": false,
          "isId": false,
          "maxLength": null
        },
        {
          "id": "auth.instances.created_at",
          "name": "created_at",
          "columnName": "created_at",
          "type": "timestamptz",
          "isRequired": false,
          "kind": "scalar",
          "isList": false,
          "isGenerated": false,
          "sequence": false,
          "hasDefaultValue": false,
          "isId": false,
          "maxLength": null
        },
        {
          "id": "auth.instances.updated_at",
          "name": "updated_at",
          "columnName": "updated_at",
          "type": "timestamptz",
          "isRequired": false,
          "kind": "scalar",
          "isList": false,
          "isGenerated": false,
          "sequence": false,
          "hasDefaultValue": false,
          "isId": false,
          "maxLength": null
        }
      ],
      "uniqueConstraints": []
    },
    "map_pins": {
      "id": "public.map_pins",
      "schemaName": "public",
      "tableName": "map_pins",
      "fields": [
        {
          "id": "public.map_pins.id",
          "name": "id",
          "columnName": "id",
          "type": "int8",
          "isRequired": true,
          "kind": "scalar",
          "isList": false,
          "isGenerated": false,
          "sequence": {
            "identifier": "\"public\".\"map_pins_id_seq\"",
            "increment": 1,
            "start": 1
          },
          "hasDefaultValue": false,
          "isId": true,
          "maxLength": null
        },
        {
          "id": "public.map_pins.created_at",
          "name": "created_at",
          "columnName": "created_at",
          "type": "timestamptz",
          "isRequired": true,
          "kind": "scalar",
          "isList": false,
          "isGenerated": false,
          "sequence": false,
          "hasDefaultValue": true,
          "isId": false,
          "maxLength": null
        },
        {
          "id": "public.map_pins.profile_id",
          "name": "profile_id",
          "columnName": "profile_id",
          "type": "int8",
          "isRequired": true,
          "kind": "scalar",
          "isList": false,
          "isGenerated": false,
          "sequence": false,
          "hasDefaultValue": false,
          "isId": false,
          "maxLength": null
        },
        {
          "id": "public.map_pins.country",
          "name": "country",
          "columnName": "country",
          "type": "text",
          "isRequired": true,
          "kind": "scalar",
          "isList": false,
          "isGenerated": false,
          "sequence": false,
          "hasDefaultValue": false,
          "isId": false,
          "maxLength": null
        },
        {
          "id": "public.map_pins.country_code",
          "name": "country_code",
          "columnName": "country_code",
          "type": "text",
          "isRequired": true,
          "kind": "scalar",
          "isList": false,
          "isGenerated": false,
          "sequence": false,
          "hasDefaultValue": false,
          "isId": false,
          "maxLength": null
        },
        {
          "id": "public.map_pins.administrative",
          "name": "administrative",
          "columnName": "administrative",
          "type": "text",
          "isRequired": false,
          "kind": "scalar",
          "isList": false,
          "isGenerated": false,
          "sequence": false,
          "hasDefaultValue": false,
          "isId": false,
          "maxLength": null
        },
        {
          "id": "public.map_pins.post_code",
          "name": "post_code",
          "columnName": "post_code",
          "type": "text",
          "isRequired": false,
          "kind": "scalar",
          "isList": false,
          "isGenerated": false,
          "sequence": false,
          "hasDefaultValue": false,
          "isId": false,
          "maxLength": null
        },
        {
          "id": "public.map_pins.lat",
          "name": "lat",
          "columnName": "lat",
          "type": "text",
          "isRequired": true,
          "kind": "scalar",
          "isList": false,
          "isGenerated": false,
          "sequence": false,
          "hasDefaultValue": false,
          "isId": false,
          "maxLength": null
        },
        {
          "id": "public.map_pins.lng",
          "name": "lng",
          "columnName": "lng",
          "type": "text",
          "isRequired": true,
          "kind": "scalar",
          "isList": false,
          "isGenerated": false,
          "sequence": false,
          "hasDefaultValue": false,
          "isId": false,
          "maxLength": null
        },
        {
          "id": "public.map_pins.moderation",
          "name": "moderation",
          "columnName": "moderation",
          "type": "text",
          "isRequired": true,
          "kind": "scalar",
          "isList": false,
          "isGenerated": false,
          "sequence": false,
          "hasDefaultValue": false,
          "isId": false,
          "maxLength": null
        },
        {
          "id": "public.map_pins.tenant_id",
          "name": "tenant_id",
          "columnName": "tenant_id",
          "type": "text",
          "isRequired": true,
          "kind": "scalar",
          "isList": false,
          "isGenerated": false,
          "sequence": false,
          "hasDefaultValue": false,
          "isId": false,
          "maxLength": null
        },
        {
          "id": "public.map_pins.moderation_feedback",
          "name": "moderation_feedback",
          "columnName": "moderation_feedback",
          "type": "text",
          "isRequired": false,
          "kind": "scalar",
          "isList": false,
          "isGenerated": false,
          "sequence": false,
          "hasDefaultValue": false,
          "isId": false,
          "maxLength": null
        },
        {
          "id": "public.map_pins.name",
          "name": "name",
          "columnName": "name",
          "type": "text",
          "isRequired": false,
          "kind": "scalar",
          "isList": false,
          "isGenerated": false,
          "sequence": false,
          "hasDefaultValue": false,
          "isId": false,
          "maxLength": null
        },
        {
          "name": "profiles",
          "type": "profiles",
          "isRequired": true,
          "kind": "object",
          "relationName": "map_pinsToprofiles",
          "relationFromFields": ["profile_id"],
          "relationToFields": ["id"],
          "isList": false,
          "isId": false,
          "isGenerated": false,
          "sequence": false,
          "hasDefaultValue": false
        }
      ],
      "uniqueConstraints": [
        {
          "name": "map_pins_pkey",
          "fields": ["id"],
          "nullNotDistinct": false
        }
      ]
    },
    "map_settings": {
      "id": "public.map_settings",
      "schemaName": "public",
      "tableName": "map_settings",
      "fields": [
        {
          "id": "public.map_settings.id",
          "name": "id",
          "columnName": "id",
          "type": "int8",
          "isRequired": true,
          "kind": "scalar",
          "isList": false,
          "isGenerated": false,
          "sequence": {
            "identifier": "\"public\".\"map_settings_id_seq\"",
            "increment": 1,
            "start": 1
          },
          "hasDefaultValue": false,
          "isId": true,
          "maxLength": null
        },
        {
          "id": "public.map_settings.default_type_filters",
          "name": "default_type_filters",
          "columnName": "default_type_filters",
          "type": "text[]",
          "isRequired": false,
          "kind": "scalar",
          "isList": false,
          "isGenerated": false,
          "sequence": false,
          "hasDefaultValue": false,
          "isId": false,
          "maxLength": null
        },
        {
          "id": "public.map_settings.setting_filters",
          "name": "setting_filters",
          "columnName": "setting_filters",
          "type": "text[]",
          "isRequired": true,
          "kind": "scalar",
          "isList": false,
          "isGenerated": false,
          "sequence": false,
          "hasDefaultValue": false,
          "isId": false,
          "maxLength": null
        },
        {
          "id": "public.map_settings.tenant_id",
          "name": "tenant_id",
          "columnName": "tenant_id",
          "type": "text",
          "isRequired": true,
          "kind": "scalar",
          "isList": false,
          "isGenerated": false,
          "sequence": false,
          "hasDefaultValue": false,
          "isId": false,
          "maxLength": null
        }
      ],
      "uniqueConstraints": [
        {
          "name": "map_settings_pkey",
          "fields": ["id"],
          "nullNotDistinct": false
        }
      ]
    },
    "public_messages": {
      "id": "public.messages",
      "schemaName": "public",
      "tableName": "messages",
      "fields": [
        {
          "id": "public.messages.id",
          "name": "id",
          "columnName": "id",
          "type": "int8",
          "isRequired": true,
          "kind": "scalar",
          "isList": false,
          "isGenerated": false,
          "sequence": {
            "identifier": "\"public\".\"messages_id_seq\"",
            "increment": 1,
            "start": 1
          },
          "hasDefaultValue": false,
          "isId": true,
          "maxLength": null
        },
        {
          "id": "public.messages.created_at",
          "name": "created_at",
          "columnName": "created_at",
          "type": "timestamptz",
          "isRequired": true,
          "kind": "scalar",
          "isList": false,
          "isGenerated": false,
          "sequence": false,
          "hasDefaultValue": true,
          "isId": false,
          "maxLength": null
        },
        {
          "id": "public.messages.message",
          "name": "message",
          "columnName": "message",
          "type": "text",
          "isRequired": true,
          "kind": "scalar",
          "isList": false,
          "isGenerated": false,
          "sequence": false,
          "hasDefaultValue": false,
          "isId": false,
          "maxLength": null
        },
        {
          "id": "public.messages.sender_id",
          "name": "sender_id",
          "columnName": "sender_id",
          "type": "int8",
          "isRequired": true,
          "kind": "scalar",
          "isList": false,
          "isGenerated": false,
          "sequence": false,
          "hasDefaultValue": false,
          "isId": false,
          "maxLength": null
        },
        {
          "id": "public.messages.receiver_id",
          "name": "receiver_id",
          "columnName": "receiver_id",
          "type": "int8",
          "isRequired": false,
          "kind": "scalar",
          "isList": false,
          "isGenerated": false,
          "sequence": false,
          "hasDefaultValue": false,
          "isId": false,
          "maxLength": null
        },
        {
          "id": "public.messages.tenant_id",
          "name": "tenant_id",
          "columnName": "tenant_id",
          "type": "text",
          "isRequired": true,
          "kind": "scalar",
          "isList": false,
          "isGenerated": false,
          "sequence": false,
          "hasDefaultValue": false,
          "isId": false,
          "maxLength": null
        },
        {
          "name": "profiles_public_messages_receiver_idToprofiles",
          "type": "profiles",
          "isRequired": false,
          "kind": "object",
          "relationName": "public_messages_receiver_idToprofiles",
          "relationFromFields": ["receiver_id"],
          "relationToFields": ["id"],
          "isList": false,
          "isId": false,
          "isGenerated": false,
          "sequence": false,
          "hasDefaultValue": false
        },
        {
          "name": "profiles_public_messages_sender_idToprofiles",
          "type": "profiles",
          "isRequired": true,
          "kind": "object",
          "relationName": "public_messages_sender_idToprofiles",
          "relationFromFields": ["sender_id"],
          "relationToFields": ["id"],
          "isList": false,
          "isId": false,
          "isGenerated": false,
          "sequence": false,
          "hasDefaultValue": false
        }
      ],
      "uniqueConstraints": [
        {
          "name": "messages_pkey",
          "fields": ["id"],
          "nullNotDistinct": false
        }
      ]
    },
    "realtime_messages": {
      "id": "realtime.messages",
      "schemaName": "realtime",
      "tableName": "messages",
      "fields": [
        {
          "id": "realtime.messages.topic",
          "name": "topic",
          "columnName": "topic",
          "type": "text",
          "isRequired": true,
          "kind": "scalar",
          "isList": false,
          "isGenerated": false,
          "sequence": false,
          "hasDefaultValue": false,
          "isId": false,
          "maxLength": null
        },
        {
          "id": "realtime.messages.extension",
          "name": "extension",
          "columnName": "extension",
          "type": "text",
          "isRequired": true,
          "kind": "scalar",
          "isList": false,
          "isGenerated": false,
          "sequence": false,
          "hasDefaultValue": false,
          "isId": false,
          "maxLength": null
        },
        {
          "id": "realtime.messages.payload",
          "name": "payload",
          "columnName": "payload",
          "type": "jsonb",
          "isRequired": false,
          "kind": "scalar",
          "isList": false,
          "isGenerated": false,
          "sequence": false,
          "hasDefaultValue": false,
          "isId": false,
          "maxLength": null
        },
        {
          "id": "realtime.messages.event",
          "name": "event",
          "columnName": "event",
          "type": "text",
          "isRequired": false,
          "kind": "scalar",
          "isList": false,
          "isGenerated": false,
          "sequence": false,
          "hasDefaultValue": false,
          "isId": false,
          "maxLength": null
        },
        {
          "id": "realtime.messages.private",
          "name": "private",
          "columnName": "private",
          "type": "bool",
          "isRequired": false,
          "kind": "scalar",
          "isList": false,
          "isGenerated": false,
          "sequence": false,
          "hasDefaultValue": true,
          "isId": false,
          "maxLength": null
        },
        {
          "id": "realtime.messages.updated_at",
          "name": "updated_at",
          "columnName": "updated_at",
          "type": "timestamp",
          "isRequired": true,
          "kind": "scalar",
          "isList": false,
          "isGenerated": false,
          "sequence": false,
          "hasDefaultValue": true,
          "isId": false,
          "maxLength": null
        },
        {
          "id": "realtime.messages.inserted_at",
          "name": "inserted_at",
          "columnName": "inserted_at",
          "type": "timestamp",
          "isRequired": true,
          "kind": "scalar",
          "isList": false,
          "isGenerated": false,
          "sequence": false,
          "hasDefaultValue": true,
          "isId": true,
          "maxLength": null
        },
        {
          "id": "realtime.messages.id",
          "name": "id",
          "columnName": "id",
          "type": "uuid",
          "isRequired": true,
          "kind": "scalar",
          "isList": false,
          "isGenerated": false,
          "sequence": false,
          "hasDefaultValue": true,
          "isId": true,
          "maxLength": null
        }
      ],
      "uniqueConstraints": [
        {
          "name": "messages_pkey",
          "fields": ["id", "inserted_at"],
          "nullNotDistinct": false
        }
      ]
    },
    "mfa_amr_claims": {
      "id": "auth.mfa_amr_claims",
      "schemaName": "auth",
      "tableName": "mfa_amr_claims",
      "fields": [
        {
          "id": "auth.mfa_amr_claims.session_id",
          "name": "session_id",
          "columnName": "session_id",
          "type": "uuid",
          "isRequired": true,
          "kind": "scalar",
          "isList": false,
          "isGenerated": false,
          "sequence": false,
          "hasDefaultValue": false,
          "isId": false,
          "maxLength": null
        },
        {
          "id": "auth.mfa_amr_claims.created_at",
          "name": "created_at",
          "columnName": "created_at",
          "type": "timestamptz",
          "isRequired": true,
          "kind": "scalar",
          "isList": false,
          "isGenerated": false,
          "sequence": false,
          "hasDefaultValue": false,
          "isId": false,
          "maxLength": null
        },
        {
          "id": "auth.mfa_amr_claims.updated_at",
          "name": "updated_at",
          "columnName": "updated_at",
          "type": "timestamptz",
          "isRequired": true,
          "kind": "scalar",
          "isList": false,
          "isGenerated": false,
          "sequence": false,
          "hasDefaultValue": false,
          "isId": false,
          "maxLength": null
        },
        {
          "id": "auth.mfa_amr_claims.authentication_method",
          "name": "authentication_method",
          "columnName": "authentication_method",
          "type": "text",
          "isRequired": true,
          "kind": "scalar",
          "isList": false,
          "isGenerated": false,
          "sequence": false,
          "hasDefaultValue": false,
          "isId": false,
          "maxLength": null
        },
        {
          "id": "auth.mfa_amr_claims.id",
          "name": "id",
          "columnName": "id",
          "type": "uuid",
          "isRequired": true,
          "kind": "scalar",
          "isList": false,
          "isGenerated": false,
          "sequence": false,
          "hasDefaultValue": false,
          "isId": true,
          "maxLength": null
        },
        {
          "name": "sessions",
          "type": "sessions",
          "isRequired": true,
          "kind": "object",
          "relationName": "mfa_amr_claimsTosessions",
          "relationFromFields": ["session_id"],
          "relationToFields": ["id"],
          "isList": false,
          "isId": false,
          "isGenerated": false,
          "sequence": false,
          "hasDefaultValue": false
        }
      ],
      "uniqueConstraints": [
        {
          "name": "mfa_amr_claims_session_id_authentication_method_pkey",
          "fields": ["authentication_method", "session_id"],
          "nullNotDistinct": false
        }
      ]
    },
    "mfa_challenges": {
      "id": "auth.mfa_challenges",
      "schemaName": "auth",
      "tableName": "mfa_challenges",
      "fields": [
        {
          "id": "auth.mfa_challenges.id",
          "name": "id",
          "columnName": "id",
          "type": "uuid",
          "isRequired": true,
          "kind": "scalar",
          "isList": false,
          "isGenerated": false,
          "sequence": false,
          "hasDefaultValue": false,
          "isId": true,
          "maxLength": null
        },
        {
          "id": "auth.mfa_challenges.factor_id",
          "name": "factor_id",
          "columnName": "factor_id",
          "type": "uuid",
          "isRequired": true,
          "kind": "scalar",
          "isList": false,
          "isGenerated": false,
          "sequence": false,
          "hasDefaultValue": false,
          "isId": false,
          "maxLength": null
        },
        {
          "id": "auth.mfa_challenges.created_at",
          "name": "created_at",
          "columnName": "created_at",
          "type": "timestamptz",
          "isRequired": true,
          "kind": "scalar",
          "isList": false,
          "isGenerated": false,
          "sequence": false,
          "hasDefaultValue": false,
          "isId": false,
          "maxLength": null
        },
        {
          "id": "auth.mfa_challenges.verified_at",
          "name": "verified_at",
          "columnName": "verified_at",
          "type": "timestamptz",
          "isRequired": false,
          "kind": "scalar",
          "isList": false,
          "isGenerated": false,
          "sequence": false,
          "hasDefaultValue": false,
          "isId": false,
          "maxLength": null
        },
        {
          "id": "auth.mfa_challenges.ip_address",
          "name": "ip_address",
          "columnName": "ip_address",
          "type": "inet",
          "isRequired": true,
          "kind": "scalar",
          "isList": false,
          "isGenerated": false,
          "sequence": false,
          "hasDefaultValue": false,
          "isId": false,
          "maxLength": null
        },
        {
          "id": "auth.mfa_challenges.otp_code",
          "name": "otp_code",
          "columnName": "otp_code",
          "type": "text",
          "isRequired": false,
          "kind": "scalar",
          "isList": false,
          "isGenerated": false,
          "sequence": false,
          "hasDefaultValue": false,
          "isId": false,
          "maxLength": null
        },
        {
          "id": "auth.mfa_challenges.web_authn_session_data",
          "name": "web_authn_session_data",
          "columnName": "web_authn_session_data",
          "type": "jsonb",
          "isRequired": false,
          "kind": "scalar",
          "isList": false,
          "isGenerated": false,
          "sequence": false,
          "hasDefaultValue": false,
          "isId": false,
          "maxLength": null
        },
        {
          "name": "mfa_factors",
          "type": "mfa_factors",
          "isRequired": true,
          "kind": "object",
          "relationName": "mfa_challengesTomfa_factors",
          "relationFromFields": ["factor_id"],
          "relationToFields": ["id"],
          "isList": false,
          "isId": false,
          "isGenerated": false,
          "sequence": false,
          "hasDefaultValue": false
        }
      ],
      "uniqueConstraints": []
    },
    "mfa_factors": {
      "id": "auth.mfa_factors",
      "schemaName": "auth",
      "tableName": "mfa_factors",
      "fields": [
        {
          "id": "auth.mfa_factors.id",
          "name": "id",
          "columnName": "id",
          "type": "uuid",
          "isRequired": true,
          "kind": "scalar",
          "isList": false,
          "isGenerated": false,
          "sequence": false,
          "hasDefaultValue": false,
          "isId": true,
          "maxLength": null
        },
        {
          "id": "auth.mfa_factors.user_id",
          "name": "user_id",
          "columnName": "user_id",
          "type": "uuid",
          "isRequired": true,
          "kind": "scalar",
          "isList": false,
          "isGenerated": false,
          "sequence": false,
          "hasDefaultValue": false,
          "isId": false,
          "maxLength": null
        },
        {
          "id": "auth.mfa_factors.friendly_name",
          "name": "friendly_name",
          "columnName": "friendly_name",
          "type": "text",
          "isRequired": false,
          "kind": "scalar",
          "isList": false,
          "isGenerated": false,
          "sequence": false,
          "hasDefaultValue": false,
          "isId": false,
          "maxLength": null
        },
        {
          "id": "auth.mfa_factors.factor_type",
          "name": "factor_type",
          "columnName": "factor_type",
          "type": "factor_type",
          "isRequired": true,
          "kind": "scalar",
          "isList": false,
          "isGenerated": false,
          "sequence": false,
          "hasDefaultValue": false,
          "isId": false,
          "maxLength": null
        },
        {
          "id": "auth.mfa_factors.status",
          "name": "status",
          "columnName": "status",
          "type": "factor_status",
          "isRequired": true,
          "kind": "scalar",
          "isList": false,
          "isGenerated": false,
          "sequence": false,
          "hasDefaultValue": false,
          "isId": false,
          "maxLength": null
        },
        {
          "id": "auth.mfa_factors.created_at",
          "name": "created_at",
          "columnName": "created_at",
          "type": "timestamptz",
          "isRequired": true,
          "kind": "scalar",
          "isList": false,
          "isGenerated": false,
          "sequence": false,
          "hasDefaultValue": false,
          "isId": false,
          "maxLength": null
        },
        {
          "id": "auth.mfa_factors.updated_at",
          "name": "updated_at",
          "columnName": "updated_at",
          "type": "timestamptz",
          "isRequired": true,
          "kind": "scalar",
          "isList": false,
          "isGenerated": false,
          "sequence": false,
          "hasDefaultValue": false,
          "isId": false,
          "maxLength": null
        },
        {
          "id": "auth.mfa_factors.secret",
          "name": "secret",
          "columnName": "secret",
          "type": "text",
          "isRequired": false,
          "kind": "scalar",
          "isList": false,
          "isGenerated": false,
          "sequence": false,
          "hasDefaultValue": false,
          "isId": false,
          "maxLength": null
        },
        {
          "id": "auth.mfa_factors.phone",
          "name": "phone",
          "columnName": "phone",
          "type": "text",
          "isRequired": false,
          "kind": "scalar",
          "isList": false,
          "isGenerated": false,
          "sequence": false,
          "hasDefaultValue": false,
          "isId": false,
          "maxLength": null
        },
        {
          "id": "auth.mfa_factors.last_challenged_at",
          "name": "last_challenged_at",
          "columnName": "last_challenged_at",
          "type": "timestamptz",
          "isRequired": false,
          "kind": "scalar",
          "isList": false,
          "isGenerated": false,
          "sequence": false,
          "hasDefaultValue": false,
          "isId": false,
          "maxLength": null
        },
        {
          "id": "auth.mfa_factors.web_authn_credential",
          "name": "web_authn_credential",
          "columnName": "web_authn_credential",
          "type": "jsonb",
          "isRequired": false,
          "kind": "scalar",
          "isList": false,
          "isGenerated": false,
          "sequence": false,
          "hasDefaultValue": false,
          "isId": false,
          "maxLength": null
        },
        {
          "id": "auth.mfa_factors.web_authn_aaguid",
          "name": "web_authn_aaguid",
          "columnName": "web_authn_aaguid",
          "type": "uuid",
          "isRequired": false,
          "kind": "scalar",
          "isList": false,
          "isGenerated": false,
          "sequence": false,
          "hasDefaultValue": false,
          "isId": false,
          "maxLength": null
        },
        {
          "id": "auth.mfa_factors.last_webauthn_challenge_data",
          "name": "last_webauthn_challenge_data",
          "columnName": "last_webauthn_challenge_data",
          "type": "jsonb",
          "isRequired": false,
          "kind": "scalar",
          "isList": false,
          "isGenerated": false,
          "sequence": false,
          "hasDefaultValue": false,
          "isId": false,
          "maxLength": null
        },
        {
          "name": "users",
          "type": "users",
          "isRequired": true,
          "kind": "object",
          "relationName": "mfa_factorsTousers",
          "relationFromFields": ["user_id"],
          "relationToFields": ["id"],
          "isList": false,
          "isId": false,
          "isGenerated": false,
          "sequence": false,
          "hasDefaultValue": false
        },
        {
          "name": "mfa_challenges",
          "type": "mfa_challenges",
          "isRequired": false,
          "kind": "object",
          "relationName": "mfa_challengesTomfa_factors",
          "relationFromFields": [],
          "relationToFields": [],
          "isList": true,
          "isId": false,
          "isGenerated": false,
          "sequence": false,
          "hasDefaultValue": false
        }
      ],
      "uniqueConstraints": [
        {
          "name": "mfa_factors_last_challenged_at_key",
          "fields": ["last_challenged_at"],
          "nullNotDistinct": false
        },
        {
          "name": "mfa_factors_user_friendly_name_unique",
          "fields": ["friendly_name", "user_id"],
          "nullNotDistinct": false
        },
        {
          "name": "unique_phone_factor_per_user",
          "fields": ["phone", "user_id"],
          "nullNotDistinct": false
        }
      ]
    },
    "storage_migrations": {
      "id": "storage.migrations",
      "schemaName": "storage",
      "tableName": "migrations",
      "fields": [
        {
          "id": "storage.migrations.id",
          "name": "id",
          "columnName": "id",
          "type": "int4",
          "isRequired": true,
          "kind": "scalar",
          "isList": false,
          "isGenerated": false,
          "sequence": false,
          "hasDefaultValue": false,
          "isId": true,
          "maxLength": null
        },
        {
          "id": "storage.migrations.name",
          "name": "name",
          "columnName": "name",
          "type": "varchar",
          "isRequired": true,
          "kind": "scalar",
          "isList": false,
          "isGenerated": false,
          "sequence": false,
          "hasDefaultValue": false,
          "isId": false,
          "maxLength": 100
        },
        {
          "id": "storage.migrations.hash",
          "name": "hash",
          "columnName": "hash",
          "type": "varchar",
          "isRequired": true,
          "kind": "scalar",
          "isList": false,
          "isGenerated": false,
          "sequence": false,
          "hasDefaultValue": false,
          "isId": false,
          "maxLength": 40
        },
        {
          "id": "storage.migrations.executed_at",
          "name": "executed_at",
          "columnName": "executed_at",
          "type": "timestamp",
          "isRequired": false,
          "kind": "scalar",
          "isList": false,
          "isGenerated": false,
          "sequence": false,
          "hasDefaultValue": true,
          "isId": false,
          "maxLength": null
        }
      ],
      "uniqueConstraints": [
        {
          "name": "migrations_name_key",
          "fields": ["name"],
          "nullNotDistinct": false
        }
      ]
    },
    "supabase_functions_migrations": {
      "id": "supabase_functions.migrations",
      "schemaName": "supabase_functions",
      "tableName": "migrations",
      "fields": [
        {
          "id": "supabase_functions.migrations.version",
          "name": "version",
          "columnName": "version",
          "type": "text",
          "isRequired": true,
          "kind": "scalar",
          "isList": false,
          "isGenerated": false,
          "sequence": false,
          "hasDefaultValue": false,
          "isId": true,
          "maxLength": null
        },
        {
          "id": "supabase_functions.migrations.inserted_at",
          "name": "inserted_at",
          "columnName": "inserted_at",
          "type": "timestamptz",
          "isRequired": true,
          "kind": "scalar",
          "isList": false,
          "isGenerated": false,
          "sequence": false,
          "hasDefaultValue": true,
          "isId": false,
          "maxLength": null
        }
      ],
      "uniqueConstraints": [
        {
          "name": "migrations_pkey",
          "fields": ["version"],
          "nullNotDistinct": false
        }
      ]
    },
    "news": {
      "id": "public.news",
      "schemaName": "public",
      "tableName": "news",
      "fields": [
        {
          "id": "public.news.id",
          "name": "id",
          "columnName": "id",
          "type": "int8",
          "isRequired": true,
          "kind": "scalar",
          "isList": false,
          "isGenerated": false,
          "sequence": {
            "identifier": "\"public\".\"news_id_seq\"",
            "increment": 1,
            "start": 1
          },
          "hasDefaultValue": false,
          "isId": true,
          "maxLength": null
        },
        {
          "id": "public.news.created_at",
          "name": "created_at",
          "columnName": "created_at",
          "type": "timestamptz",
          "isRequired": true,
          "kind": "scalar",
          "isList": false,
          "isGenerated": false,
          "sequence": false,
          "hasDefaultValue": true,
          "isId": false,
          "maxLength": null
        },
        {
          "id": "public.news.created_by",
          "name": "created_by",
          "columnName": "created_by",
          "type": "int8",
          "isRequired": false,
          "kind": "scalar",
          "isList": false,
          "isGenerated": false,
          "sequence": false,
          "hasDefaultValue": false,
          "isId": false,
          "maxLength": null
        },
        {
          "id": "public.news.deleted",
          "name": "deleted",
          "columnName": "deleted",
          "type": "bool",
          "isRequired": false,
          "kind": "scalar",
          "isList": false,
          "isGenerated": false,
          "sequence": false,
          "hasDefaultValue": false,
          "isId": false,
          "maxLength": null
        },
        {
          "id": "public.news.modified_at",
          "name": "modified_at",
          "columnName": "modified_at",
          "type": "timestamptz",
          "isRequired": false,
          "kind": "scalar",
          "isList": false,
          "isGenerated": false,
          "sequence": false,
          "hasDefaultValue": true,
          "isId": false,
          "maxLength": null
        },
        {
          "id": "public.news.comment_count",
          "name": "comment_count",
          "columnName": "comment_count",
          "type": "int8",
          "isRequired": false,
          "kind": "scalar",
          "isList": false,
          "isGenerated": false,
          "sequence": false,
          "hasDefaultValue": true,
          "isId": false,
          "maxLength": null
        },
        {
          "id": "public.news.body",
          "name": "body",
          "columnName": "body",
          "type": "text",
          "isRequired": true,
          "kind": "scalar",
          "isList": false,
          "isGenerated": false,
          "sequence": false,
          "hasDefaultValue": false,
          "isId": false,
          "maxLength": null
        },
        {
          "id": "public.news.moderation",
          "name": "moderation",
          "columnName": "moderation",
          "type": "text",
          "isRequired": false,
          "kind": "scalar",
          "isList": false,
          "isGenerated": false,
          "sequence": false,
          "hasDefaultValue": false,
          "isId": false,
          "maxLength": null
        },
        {
          "id": "public.news.slug",
          "name": "slug",
          "columnName": "slug",
          "type": "text",
          "isRequired": true,
          "kind": "scalar",
          "isList": false,
          "isGenerated": false,
          "sequence": false,
          "hasDefaultValue": false,
          "isId": false,
          "maxLength": null
        },
        {
          "id": "public.news.previous_slugs",
          "name": "previous_slugs",
          "columnName": "previous_slugs",
          "type": "text[]",
          "isRequired": false,
          "kind": "scalar",
          "isList": false,
          "isGenerated": false,
          "sequence": false,
          "hasDefaultValue": false,
          "isId": false,
          "maxLength": null
        },
        {
          "id": "public.news.category",
          "name": "category",
          "columnName": "category",
          "type": "int8",
          "isRequired": false,
          "kind": "scalar",
          "isList": false,
          "isGenerated": false,
          "sequence": false,
          "hasDefaultValue": false,
          "isId": false,
          "maxLength": null
        },
        {
          "id": "public.news.tags",
          "name": "tags",
          "columnName": "tags",
          "type": "int8[]",
          "isRequired": false,
          "kind": "scalar",
          "isList": false,
          "isGenerated": false,
          "sequence": false,
          "hasDefaultValue": false,
          "isId": false,
          "maxLength": null
        },
        {
          "id": "public.news.title",
          "name": "title",
          "columnName": "title",
          "type": "text",
          "isRequired": true,
          "kind": "scalar",
          "isList": false,
          "isGenerated": false,
          "sequence": false,
          "hasDefaultValue": false,
          "isId": false,
          "maxLength": null
        },
        {
          "id": "public.news.total_views",
          "name": "total_views",
          "columnName": "total_views",
          "type": "int8",
          "isRequired": false,
          "kind": "scalar",
          "isList": false,
          "isGenerated": false,
          "sequence": false,
          "hasDefaultValue": false,
          "isId": false,
          "maxLength": null
        },
        {
          "id": "public.news.tenant_id",
          "name": "tenant_id",
          "columnName": "tenant_id",
          "type": "text",
          "isRequired": true,
          "kind": "scalar",
          "isList": false,
          "isGenerated": false,
          "sequence": false,
          "hasDefaultValue": false,
          "isId": false,
          "maxLength": null
        },
        {
          "id": "public.news.hero_image",
          "name": "hero_image",
          "columnName": "hero_image",
          "type": "json",
          "isRequired": false,
          "kind": "scalar",
          "isList": false,
          "isGenerated": false,
          "sequence": false,
          "hasDefaultValue": false,
          "isId": false,
          "maxLength": null
        },
        {
          "id": "public.news.summary",
          "name": "summary",
          "columnName": "summary",
          "type": "text",
          "isRequired": false,
          "kind": "scalar",
          "isList": false,
          "isGenerated": false,
          "sequence": false,
          "hasDefaultValue": false,
          "isId": false,
          "maxLength": null
        },
        {
          "id": "public.news.fts",
          "name": "fts",
          "columnName": "fts",
          "type": "tsvector",
          "isRequired": false,
          "kind": "scalar",
          "isList": false,
          "isGenerated": true,
          "sequence": false,
          "hasDefaultValue": false,
          "isId": false,
          "maxLength": null
        },
        {
          "id": "public.news.is_draft",
          "name": "is_draft",
          "columnName": "is_draft",
          "type": "bool",
          "isRequired": true,
          "kind": "scalar",
          "isList": false,
          "isGenerated": false,
          "sequence": false,
          "hasDefaultValue": true,
          "isId": false,
          "maxLength": null
        },
        {
          "id": "public.news.profile_badge",
          "name": "profile_badge",
          "columnName": "profile_badge",
          "type": "int8",
          "isRequired": false,
          "kind": "scalar",
          "isList": false,
          "isGenerated": false,
          "sequence": false,
          "hasDefaultValue": false,
          "isId": false,
          "maxLength": null
        },
        {
          "id": "public.news.published_at",
          "name": "published_at",
          "columnName": "published_at",
          "type": "timestamptz",
          "isRequired": false,
          "kind": "scalar",
          "isList": false,
          "isGenerated": false,
          "sequence": false,
          "hasDefaultValue": false,
          "isId": false,
          "maxLength": null
        },
        {
          "name": "categories",
          "type": "categories",
          "isRequired": false,
          "kind": "object",
          "relationName": "newsTocategories",
          "relationFromFields": ["category"],
          "relationToFields": ["id"],
          "isList": false,
          "isId": false,
          "isGenerated": false,
          "sequence": false,
          "hasDefaultValue": false
        },
        {
          "name": "profile_badges",
          "type": "profile_badges",
          "isRequired": false,
          "kind": "object",
          "relationName": "newsToprofile_badges",
          "relationFromFields": ["profile_badge"],
          "relationToFields": ["id"],
          "isList": false,
          "isId": false,
          "isGenerated": false,
          "sequence": false,
          "hasDefaultValue": false
        },
        {
          "name": "profiles",
          "type": "profiles",
          "isRequired": false,
          "kind": "object",
          "relationName": "newsToprofiles",
          "relationFromFields": ["created_by"],
          "relationToFields": ["id"],
          "isList": false,
          "isId": false,
          "isGenerated": false,
          "sequence": false,
          "hasDefaultValue": false
        }
      ],
      "uniqueConstraints": [
        {
          "name": "news_pkey",
          "fields": ["id"],
          "nullNotDistinct": false
        },
        {
          "name": "news_tenant_id_slug_key",
          "fields": ["slug", "tenant_id"],
          "nullNotDistinct": false
        }
      ]
    },
    "notifications": {
      "id": "public.notifications",
      "schemaName": "public",
      "tableName": "notifications",
      "fields": [
        {
          "id": "public.notifications.id",
          "name": "id",
          "columnName": "id",
          "type": "int8",
          "isRequired": true,
          "kind": "scalar",
          "isList": false,
          "isGenerated": false,
          "sequence": {
            "identifier": "\"public\".\"notifications_id_seq\"",
            "increment": 1,
            "start": 1
          },
          "hasDefaultValue": false,
          "isId": true,
          "maxLength": null
        },
        {
          "id": "public.notifications.created_at",
          "name": "created_at",
          "columnName": "created_at",
          "type": "timestamptz",
          "isRequired": true,
          "kind": "scalar",
          "isList": false,
          "isGenerated": false,
          "sequence": false,
          "hasDefaultValue": true,
          "isId": false,
          "maxLength": null
        },
        {
          "id": "public.notifications.modified_at",
          "name": "modified_at",
          "columnName": "modified_at",
          "type": "timestamptz",
          "isRequired": false,
          "kind": "scalar",
          "isList": false,
          "isGenerated": false,
          "sequence": false,
          "hasDefaultValue": true,
          "isId": false,
          "maxLength": null
        },
        {
          "id": "public.notifications.owned_by_id",
          "name": "owned_by_id",
          "columnName": "owned_by_id",
          "type": "int8",
          "isRequired": true,
          "kind": "scalar",
          "isList": false,
          "isGenerated": false,
          "sequence": false,
          "hasDefaultValue": false,
          "isId": false,
          "maxLength": null
        },
        {
          "id": "public.notifications.triggered_by_id",
          "name": "triggered_by_id",
          "columnName": "triggered_by_id",
          "type": "int8",
          "isRequired": true,
          "kind": "scalar",
          "isList": false,
          "isGenerated": false,
          "sequence": false,
          "hasDefaultValue": false,
          "isId": false,
          "maxLength": null
        },
        {
          "id": "public.notifications.content_type",
          "name": "content_type",
          "columnName": "content_type",
          "type": "notification_content_types",
          "isRequired": true,
          "kind": "scalar",
          "isList": false,
          "isGenerated": false,
          "sequence": false,
          "hasDefaultValue": false,
          "isId": false,
          "maxLength": null
        },
        {
          "id": "public.notifications.content_id",
          "name": "content_id",
          "columnName": "content_id",
          "type": "int8",
          "isRequired": true,
          "kind": "scalar",
          "isList": false,
          "isGenerated": false,
          "sequence": false,
          "hasDefaultValue": false,
          "isId": false,
          "maxLength": null
        },
        {
          "id": "public.notifications.is_read",
          "name": "is_read",
          "columnName": "is_read",
          "type": "bool",
          "isRequired": false,
          "kind": "scalar",
          "isList": false,
          "isGenerated": false,
          "sequence": false,
          "hasDefaultValue": true,
          "isId": false,
          "maxLength": null
        },
        {
          "id": "public.notifications.action_type",
          "name": "action_type",
          "columnName": "action_type",
          "type": "notification_action_types",
          "isRequired": true,
          "kind": "scalar",
          "isList": false,
          "isGenerated": false,
          "sequence": false,
          "hasDefaultValue": false,
          "isId": false,
          "maxLength": null
        },
        {
          "id": "public.notifications.tenant_id",
          "name": "tenant_id",
          "columnName": "tenant_id",
          "type": "text",
          "isRequired": true,
          "kind": "scalar",
          "isList": false,
          "isGenerated": false,
          "sequence": false,
          "hasDefaultValue": false,
          "isId": false,
          "maxLength": null
        },
        {
          "id": "public.notifications.source_content_type",
          "name": "source_content_type",
          "columnName": "source_content_type",
          "type": "text",
          "isRequired": false,
          "kind": "scalar",
          "isList": false,
          "isGenerated": false,
          "sequence": false,
          "hasDefaultValue": false,
          "isId": false,
          "maxLength": null
        },
        {
          "id": "public.notifications.source_content_id",
          "name": "source_content_id",
          "columnName": "source_content_id",
          "type": "int8",
          "isRequired": false,
          "kind": "scalar",
          "isList": false,
          "isGenerated": false,
          "sequence": false,
          "hasDefaultValue": false,
          "isId": false,
          "maxLength": null
        },
        {
          "id": "public.notifications.parent_comment_id",
          "name": "parent_comment_id",
          "columnName": "parent_comment_id",
          "type": "int8",
          "isRequired": false,
          "kind": "scalar",
          "isList": false,
          "isGenerated": false,
          "sequence": false,
          "hasDefaultValue": false,
          "isId": false,
          "maxLength": null
        },
        {
          "id": "public.notifications.parent_content_id",
          "name": "parent_content_id",
          "columnName": "parent_content_id",
          "type": "int8",
          "isRequired": false,
          "kind": "scalar",
          "isList": false,
          "isGenerated": false,
          "sequence": false,
          "hasDefaultValue": false,
          "isId": false,
          "maxLength": null
        },
        {
          "id": "public.notifications.should_email",
          "name": "should_email",
          "columnName": "should_email",
          "type": "bool",
          "isRequired": false,
          "kind": "scalar",
          "isList": false,
          "isGenerated": false,
          "sequence": false,
          "hasDefaultValue": false,
          "isId": false,
          "maxLength": null
        },
        {
          "id": "public.notifications.title",
          "name": "title",
          "columnName": "title",
          "type": "text",
          "isRequired": false,
          "kind": "scalar",
          "isList": false,
          "isGenerated": false,
          "sequence": false,
          "hasDefaultValue": false,
          "isId": false,
          "maxLength": null
        },
        {
          "name": "profiles_notifications_owned_by_idToprofiles",
          "type": "profiles",
          "isRequired": true,
          "kind": "object",
          "relationName": "notifications_owned_by_idToprofiles",
          "relationFromFields": ["owned_by_id"],
          "relationToFields": ["id"],
          "isList": false,
          "isId": false,
          "isGenerated": false,
          "sequence": false,
          "hasDefaultValue": false
        },
        {
          "name": "profiles_notifications_triggered_by_idToprofiles",
          "type": "profiles",
          "isRequired": true,
          "kind": "object",
          "relationName": "notifications_triggered_by_idToprofiles",
          "relationFromFields": ["triggered_by_id"],
          "relationToFields": ["id"],
          "isList": false,
          "isId": false,
          "isGenerated": false,
          "sequence": false,
          "hasDefaultValue": false
        }
      ],
      "uniqueConstraints": [
        {
          "name": "notifications_pkey",
          "fields": ["id"],
          "nullNotDistinct": false
        }
      ]
    },
    "notifications_preferences": {
      "id": "public.notifications_preferences",
      "schemaName": "public",
      "tableName": "notifications_preferences",
      "fields": [
        {
          "id": "public.notifications_preferences.id",
          "name": "id",
          "columnName": "id",
          "type": "int8",
          "isRequired": true,
          "kind": "scalar",
          "isList": false,
          "isGenerated": false,
          "sequence": {
            "identifier": "\"public\".\"notifications_preferences_id_seq\"",
            "increment": 1,
            "start": 1
          },
          "hasDefaultValue": false,
          "isId": true,
          "maxLength": null
        },
        {
          "id": "public.notifications_preferences.user_id",
          "name": "user_id",
          "columnName": "user_id",
          "type": "int8",
          "isRequired": true,
          "kind": "scalar",
          "isList": false,
          "isGenerated": false,
          "sequence": false,
          "hasDefaultValue": false,
          "isId": false,
          "maxLength": null
        },
        {
          "id": "public.notifications_preferences.comments",
          "name": "comments",
          "columnName": "comments",
          "type": "bool",
          "isRequired": true,
          "kind": "scalar",
          "isList": false,
          "isGenerated": false,
          "sequence": false,
          "hasDefaultValue": false,
          "isId": false,
          "maxLength": null
        },
        {
          "id": "public.notifications_preferences.replies",
          "name": "replies",
          "columnName": "replies",
          "type": "bool",
          "isRequired": true,
          "kind": "scalar",
          "isList": false,
          "isGenerated": false,
          "sequence": false,
          "hasDefaultValue": false,
          "isId": false,
          "maxLength": null
        },
        {
          "id": "public.notifications_preferences.tenant_id",
          "name": "tenant_id",
          "columnName": "tenant_id",
          "type": "text",
          "isRequired": true,
          "kind": "scalar",
          "isList": false,
          "isGenerated": false,
          "sequence": false,
          "hasDefaultValue": false,
          "isId": false,
          "maxLength": null
        },
        {
          "id": "public.notifications_preferences.research_updates",
          "name": "research_updates",
          "columnName": "research_updates",
          "type": "bool",
          "isRequired": true,
          "kind": "scalar",
          "isList": false,
          "isGenerated": false,
          "sequence": false,
          "hasDefaultValue": false,
          "isId": false,
          "maxLength": null
        },
        {
          "id": "public.notifications_preferences.is_unsubscribed",
          "name": "is_unsubscribed",
          "columnName": "is_unsubscribed",
          "type": "bool",
          "isRequired": true,
          "kind": "scalar",
          "isList": false,
          "isGenerated": false,
          "sequence": false,
          "hasDefaultValue": true,
          "isId": false,
          "maxLength": null
        },
        {
          "name": "profiles",
          "type": "profiles",
          "isRequired": true,
          "kind": "object",
          "relationName": "notifications_preferencesToprofiles",
          "relationFromFields": ["user_id"],
          "relationToFields": ["id"],
          "isList": false,
          "isId": false,
          "isGenerated": false,
          "sequence": false,
          "hasDefaultValue": false
        }
      ],
      "uniqueConstraints": [
        {
          "name": "notifications_preferences_pkey",
          "fields": ["id"],
          "nullNotDistinct": false
        }
      ]
    },
    "oauth_authorizations": {
      "id": "auth.oauth_authorizations",
      "schemaName": "auth",
      "tableName": "oauth_authorizations",
      "fields": [
        {
          "id": "auth.oauth_authorizations.id",
          "name": "id",
          "columnName": "id",
          "type": "uuid",
          "isRequired": true,
          "kind": "scalar",
          "isList": false,
          "isGenerated": false,
          "sequence": false,
          "hasDefaultValue": false,
          "isId": true,
          "maxLength": null
        },
        {
          "id": "auth.oauth_authorizations.authorization_id",
          "name": "authorization_id",
          "columnName": "authorization_id",
          "type": "text",
          "isRequired": true,
          "kind": "scalar",
          "isList": false,
          "isGenerated": false,
          "sequence": false,
          "hasDefaultValue": false,
          "isId": false,
          "maxLength": null
        },
        {
          "id": "auth.oauth_authorizations.client_id",
          "name": "client_id",
          "columnName": "client_id",
          "type": "uuid",
          "isRequired": true,
          "kind": "scalar",
          "isList": false,
          "isGenerated": false,
          "sequence": false,
          "hasDefaultValue": false,
          "isId": false,
          "maxLength": null
        },
        {
          "id": "auth.oauth_authorizations.user_id",
          "name": "user_id",
          "columnName": "user_id",
          "type": "uuid",
          "isRequired": false,
          "kind": "scalar",
          "isList": false,
          "isGenerated": false,
          "sequence": false,
          "hasDefaultValue": false,
          "isId": false,
          "maxLength": null
        },
        {
          "id": "auth.oauth_authorizations.redirect_uri",
          "name": "redirect_uri",
          "columnName": "redirect_uri",
          "type": "text",
          "isRequired": true,
          "kind": "scalar",
          "isList": false,
          "isGenerated": false,
          "sequence": false,
          "hasDefaultValue": false,
          "isId": false,
          "maxLength": null
        },
        {
          "id": "auth.oauth_authorizations.scope",
          "name": "scope",
          "columnName": "scope",
          "type": "text",
          "isRequired": true,
          "kind": "scalar",
          "isList": false,
          "isGenerated": false,
          "sequence": false,
          "hasDefaultValue": false,
          "isId": false,
          "maxLength": null
        },
        {
          "id": "auth.oauth_authorizations.state",
          "name": "state",
          "columnName": "state",
          "type": "text",
          "isRequired": false,
          "kind": "scalar",
          "isList": false,
          "isGenerated": false,
          "sequence": false,
          "hasDefaultValue": false,
          "isId": false,
          "maxLength": null
        },
        {
          "id": "auth.oauth_authorizations.resource",
          "name": "resource",
          "columnName": "resource",
          "type": "text",
          "isRequired": false,
          "kind": "scalar",
          "isList": false,
          "isGenerated": false,
          "sequence": false,
          "hasDefaultValue": false,
          "isId": false,
          "maxLength": null
        },
        {
          "id": "auth.oauth_authorizations.code_challenge",
          "name": "code_challenge",
          "columnName": "code_challenge",
          "type": "text",
          "isRequired": false,
          "kind": "scalar",
          "isList": false,
          "isGenerated": false,
          "sequence": false,
          "hasDefaultValue": false,
          "isId": false,
          "maxLength": null
        },
        {
          "id": "auth.oauth_authorizations.code_challenge_method",
          "name": "code_challenge_method",
          "columnName": "code_challenge_method",
          "type": "code_challenge_method",
          "isRequired": false,
          "kind": "scalar",
          "isList": false,
          "isGenerated": false,
          "sequence": false,
          "hasDefaultValue": false,
          "isId": false,
          "maxLength": null
        },
        {
          "id": "auth.oauth_authorizations.response_type",
          "name": "response_type",
          "columnName": "response_type",
          "type": "oauth_response_type",
          "isRequired": true,
          "kind": "scalar",
          "isList": false,
          "isGenerated": false,
          "sequence": false,
          "hasDefaultValue": true,
          "isId": false,
          "maxLength": null
        },
        {
          "id": "auth.oauth_authorizations.status",
          "name": "status",
          "columnName": "status",
          "type": "oauth_authorization_status",
          "isRequired": true,
          "kind": "scalar",
          "isList": false,
          "isGenerated": false,
          "sequence": false,
          "hasDefaultValue": true,
          "isId": false,
          "maxLength": null
        },
        {
          "id": "auth.oauth_authorizations.authorization_code",
          "name": "authorization_code",
          "columnName": "authorization_code",
          "type": "text",
          "isRequired": false,
          "kind": "scalar",
          "isList": false,
          "isGenerated": false,
          "sequence": false,
          "hasDefaultValue": false,
          "isId": false,
          "maxLength": null
        },
        {
          "id": "auth.oauth_authorizations.created_at",
          "name": "created_at",
          "columnName": "created_at",
          "type": "timestamptz",
          "isRequired": true,
          "kind": "scalar",
          "isList": false,
          "isGenerated": false,
          "sequence": false,
          "hasDefaultValue": true,
          "isId": false,
          "maxLength": null
        },
        {
          "id": "auth.oauth_authorizations.expires_at",
          "name": "expires_at",
          "columnName": "expires_at",
          "type": "timestamptz",
          "isRequired": true,
          "kind": "scalar",
          "isList": false,
          "isGenerated": false,
          "sequence": false,
          "hasDefaultValue": true,
          "isId": false,
          "maxLength": null
        },
        {
          "id": "auth.oauth_authorizations.approved_at",
          "name": "approved_at",
          "columnName": "approved_at",
          "type": "timestamptz",
          "isRequired": false,
          "kind": "scalar",
          "isList": false,
          "isGenerated": false,
          "sequence": false,
          "hasDefaultValue": false,
          "isId": false,
          "maxLength": null
        },
        {
          "id": "auth.oauth_authorizations.nonce",
          "name": "nonce",
          "columnName": "nonce",
          "type": "text",
          "isRequired": false,
          "kind": "scalar",
          "isList": false,
          "isGenerated": false,
          "sequence": false,
          "hasDefaultValue": false,
          "isId": false,
          "maxLength": null
        },
        {
          "name": "oauth_clients",
          "type": "oauth_clients",
          "isRequired": true,
          "kind": "object",
          "relationName": "oauth_authorizationsTooauth_clients",
          "relationFromFields": ["client_id"],
          "relationToFields": ["id"],
          "isList": false,
          "isId": false,
          "isGenerated": false,
          "sequence": false,
          "hasDefaultValue": false
        },
        {
          "name": "users",
          "type": "users",
          "isRequired": false,
          "kind": "object",
          "relationName": "oauth_authorizationsTousers",
          "relationFromFields": ["user_id"],
          "relationToFields": ["id"],
          "isList": false,
          "isId": false,
          "isGenerated": false,
          "sequence": false,
          "hasDefaultValue": false
        }
      ],
      "uniqueConstraints": [
        {
          "name": "oauth_authorizations_authorization_code_key",
          "fields": ["authorization_code"],
          "nullNotDistinct": false
        },
        {
          "name": "oauth_authorizations_authorization_id_key",
          "fields": ["authorization_id"],
          "nullNotDistinct": false
        }
      ]
    },
    "oauth_client_states": {
      "id": "auth.oauth_client_states",
      "schemaName": "auth",
      "tableName": "oauth_client_states",
      "fields": [
        {
          "id": "auth.oauth_client_states.id",
          "name": "id",
          "columnName": "id",
          "type": "uuid",
          "isRequired": true,
          "kind": "scalar",
          "isList": false,
          "isGenerated": false,
          "sequence": false,
          "hasDefaultValue": false,
          "isId": true,
          "maxLength": null
        },
        {
          "id": "auth.oauth_client_states.provider_type",
          "name": "provider_type",
          "columnName": "provider_type",
          "type": "text",
          "isRequired": true,
          "kind": "scalar",
          "isList": false,
          "isGenerated": false,
          "sequence": false,
          "hasDefaultValue": false,
          "isId": false,
          "maxLength": null
        },
        {
          "id": "auth.oauth_client_states.code_verifier",
          "name": "code_verifier",
          "columnName": "code_verifier",
          "type": "text",
          "isRequired": false,
          "kind": "scalar",
          "isList": false,
          "isGenerated": false,
          "sequence": false,
          "hasDefaultValue": false,
          "isId": false,
          "maxLength": null
        },
        {
          "id": "auth.oauth_client_states.created_at",
          "name": "created_at",
          "columnName": "created_at",
          "type": "timestamptz",
          "isRequired": true,
          "kind": "scalar",
          "isList": false,
          "isGenerated": false,
          "sequence": false,
          "hasDefaultValue": false,
          "isId": false,
          "maxLength": null
        }
      ],
      "uniqueConstraints": []
    },
    "oauth_clients": {
      "id": "auth.oauth_clients",
      "schemaName": "auth",
      "tableName": "oauth_clients",
      "fields": [
        {
          "id": "auth.oauth_clients.id",
          "name": "id",
          "columnName": "id",
          "type": "uuid",
          "isRequired": true,
          "kind": "scalar",
          "isList": false,
          "isGenerated": false,
          "sequence": false,
          "hasDefaultValue": false,
          "isId": true,
          "maxLength": null
        },
        {
          "id": "auth.oauth_clients.client_secret_hash",
          "name": "client_secret_hash",
          "columnName": "client_secret_hash",
          "type": "text",
          "isRequired": false,
          "kind": 
Download .txt
gitextract_7op3tyix/

├── .all-contributorsrc
├── .circleci/
│   └── config.yml
├── .dockerignore
├── .github/
│   ├── CODEOWNERS
│   ├── ISSUE_TEMPLATE/
│   │   ├── bug_report.md
│   │   ├── build-new-component.md
│   │   └── feature-request-or-suggestion.md
│   ├── actions/
│   │   └── destroy-fly-preview-app/
│   │       ├── Dockerfile
│   │       ├── action.yml
│   │       └── entrypoint.sh
│   ├── labels.yml
│   ├── pull_request_template.md
│   └── workflows/
│       ├── codeql-analysis.yml
│       ├── pr-preview-fly-deploy.yml
│       ├── pr-preview-fly-destroy.yml
│       ├── pr-preview-remove-label.yml
│       ├── pr-stale.yml
│       └── storybook-deploy.yml
├── .gitignore
├── .husky/
│   └── pre-commit
├── .node-version
├── .releaserc.json
├── .snaplet/
│   ├── config.json
│   ├── dataModel.json
│   ├── library.json
│   └── questions.json
├── .vscode/
│   └── launch.json
├── .yarnrc.yml
├── CNAME
├── CODE_OF_CONDUCT.md
├── CONTRIBUTING.md
├── Dockerfile
├── Dockerfile.preview
├── FUNDING.yml
├── LICENSE
├── README.md
├── SECURITY.md
├── biome.json
├── codecov.yml
├── docs/
│   ├── circle-ci.md
│   ├── db-seeding.md
│   ├── maintainers.md
│   ├── pwa-setup.md
│   ├── react-router-7.md
│   ├── supabase.md
│   ├── team-principles.md
│   └── technical-decisions.md
├── fly-ff.toml
├── fly-pk.toml
├── fly-pp.toml
├── fly-preview.toml
├── index.html
├── package.json
├── packages/
│   ├── components/
│   │   ├── .gitignore
│   │   ├── .storybook/
│   │   │   ├── main.ts
│   │   │   ├── manager.js
│   │   │   └── preview.tsx
│   │   ├── README.md
│   │   ├── package.json
│   │   ├── src/
│   │   │   ├── Accordion/
│   │   │   │   ├── Accordion.stories.tsx
│   │   │   │   ├── Accordion.test.tsx
│   │   │   │   └── Accordion.tsx
│   │   │   ├── ActionSet/
│   │   │   │   └── ActionSet.tsx
│   │   │   ├── Alert/
│   │   │   │   └── Alert.stories.tsx
│   │   │   ├── ArrowIcon/
│   │   │   │   ├── ArrowIcon.stories.tsx
│   │   │   │   ├── ArrowIcon.tsx
│   │   │   │   └── styles.css
│   │   │   ├── ArticleCallToActionSupabase/
│   │   │   │   ├── ArticleCallToActionSupabase.stories.tsx
│   │   │   │   └── ArticleCallToActionSupabase.tsx
│   │   │   ├── AuthorDisplay/
│   │   │   │   └── AuthorDisplay.tsx
│   │   │   ├── Banner/
│   │   │   │   ├── Banner.stories.tsx
│   │   │   │   ├── Banner.test.tsx
│   │   │   │   └── Banner.tsx
│   │   │   ├── BlockedRoute/
│   │   │   │   ├── BlockedRoute.stories.tsx
│   │   │   │   └── BlockedRoute.tsx
│   │   │   ├── Breadcrumbs/
│   │   │   │   ├── Breadcrumbs.stories.tsx
│   │   │   │   ├── Breadcrumbs.test.tsx
│   │   │   │   ├── Breadcrumbs.tsx
│   │   │   │   └── BreadcrumbsItem.tsx
│   │   │   ├── Button/
│   │   │   │   ├── Button.stories.tsx
│   │   │   │   └── Button.tsx
│   │   │   ├── ButtonIcon/
│   │   │   │   ├── ButtonIcon.stories.tsx
│   │   │   │   └── ButtonIcon.tsx
│   │   │   ├── ButtonShowReplies/
│   │   │   │   ├── ButtonShowReplies.stories.tsx
│   │   │   │   ├── ButtonShowReplies.test.tsx
│   │   │   │   └── ButtonShowReplies.tsx
│   │   │   ├── CardButton/
│   │   │   │   ├── CardButton.stories.tsx
│   │   │   │   └── CardButton.tsx
│   │   │   ├── CardListItem/
│   │   │   │   ├── CardListItem.stories.tsx
│   │   │   │   └── CardListItem.tsx
│   │   │   ├── CardProfile/
│   │   │   │   ├── CardDetailsMemberProfile.tsx
│   │   │   │   ├── CardDetailsSpaceProfile.tsx
│   │   │   │   ├── CardProfile.stories.tsx
│   │   │   │   ├── CardProfile.test.tsx
│   │   │   │   └── CardProfile.tsx
│   │   │   ├── Category/
│   │   │   │   ├── Category.stories.tsx
│   │   │   │   └── Category.tsx
│   │   │   ├── CategoryHorizonalList/
│   │   │   │   ├── CategoryHorizonalList.stories.tsx
│   │   │   │   ├── CategoryHorizonalList.test.tsx
│   │   │   │   └── CategoryHorizonalList.tsx
│   │   │   ├── CharacterCount/
│   │   │   │   ├── CharacterCount.stories.tsx
│   │   │   │   └── CharacterCount.tsx
│   │   │   ├── CommentAvatar/
│   │   │   │   └── CommentAvatar.tsx
│   │   │   ├── CommentBody/
│   │   │   │   └── CommentBody.tsx
│   │   │   ├── CommentDisplay/
│   │   │   │   ├── CommentDisplay.stories.tsx
│   │   │   │   ├── CommentDisplay.test.tsx
│   │   │   │   └── CommentDisplay.tsx
│   │   │   ├── CommentsTitle/
│   │   │   │   ├── CommentsTitle.stories.tsx
│   │   │   │   ├── CommentsTitle.test.tsx
│   │   │   │   └── CommentsTitle.tsx
│   │   │   ├── ConfirmModal/
│   │   │   │   ├── ConfirmModal.stories.tsx
│   │   │   │   └── ConfirmModal.tsx
│   │   │   ├── ContentStatistics/
│   │   │   │   ├── ContentStatistics.stories.tsx
│   │   │   │   ├── ContentStatistics.tsx
│   │   │   │   ├── ContentStatisticsList.tsx
│   │   │   │   └── types.ts
│   │   │   ├── CreateComment/
│   │   │   │   ├── CreateComment.css
│   │   │   │   ├── CreateComment.stories.tsx
│   │   │   │   ├── CreateComment.test.tsx
│   │   │   │   └── CreateComment.tsx
│   │   │   ├── CreateReply/
│   │   │   │   ├── CreateReply.stories.tsx
│   │   │   │   ├── CreateReply.test.tsx
│   │   │   │   └── CreateReply.tsx
│   │   │   ├── DisplayDate/
│   │   │   │   ├── DisplayDate.stories.tsx
│   │   │   │   ├── DisplayDate.test.tsx
│   │   │   │   ├── DisplayDate.tsx
│   │   │   │   └── display-date.css
│   │   │   ├── DonationRequestModal/
│   │   │   │   ├── DonationRequestModal.stories.tsx
│   │   │   │   ├── DonationRequestModal.test.tsx
│   │   │   │   └── DonationRequestModal.tsx
│   │   │   ├── DownloadButton/
│   │   │   │   ├── DownloadButton.stories.tsx
│   │   │   │   ├── DownloadButton.test.tsx
│   │   │   │   └── DownloadButton.tsx
│   │   │   ├── DownloadCounter/
│   │   │   │   ├── DownloadCounter.stories.tsx
│   │   │   │   ├── DownloadCounter.test.tsx
│   │   │   │   └── DownloadCounter.tsx
│   │   │   ├── DownloadStaticFile/
│   │   │   │   ├── DownloadStaticFile.stories.tsx
│   │   │   │   └── DownloadStaticFile.tsx
│   │   │   ├── EditComment/
│   │   │   │   ├── EditComment.stories.tsx
│   │   │   │   ├── EditComment.test.tsx
│   │   │   │   └── EditComment.tsx
│   │   │   ├── ElWithBeforeIcon/
│   │   │   │   ├── ElWithBeforeIcon.stories.tsx
│   │   │   │   └── ElWithBeforeIcon.tsx
│   │   │   ├── ExternalLink/
│   │   │   │   ├── ExternalLink.stories.tsx
│   │   │   │   └── ExternalLink.tsx
│   │   │   ├── FieldCheckbox/
│   │   │   │   └── FieldCheckbox.tsx
│   │   │   ├── FieldInput/
│   │   │   │   ├── FieldInput.stories.tsx
│   │   │   │   └── FieldInput.tsx
│   │   │   ├── FieldMarkdown/
│   │   │   │   ├── AddImage.tsx
│   │   │   │   ├── FieldMarkdown.stories.tsx
│   │   │   │   ├── FieldMarkdown.tsx
│   │   │   │   └── style.css
│   │   │   ├── FieldTextarea/
│   │   │   │   ├── FieldTextarea.stories.tsx
│   │   │   │   └── FieldTextarea.tsx
│   │   │   ├── FlagIcon/
│   │   │   │   └── FlagIcon.tsx
│   │   │   ├── FollowButton/
│   │   │   │   ├── FollowButton.stories.tsx
│   │   │   │   └── FollowButton.tsx
│   │   │   ├── FollowIcon/
│   │   │   │   ├── FollowIcon.stories.tsx
│   │   │   │   └── FollowIcon.tsx
│   │   │   ├── GlobalStyles/
│   │   │   │   └── GlobalStyles.tsx
│   │   │   ├── GridForm/
│   │   │   │   ├── GridForm.stories.tsx
│   │   │   │   └── GridForm.tsx
│   │   │   ├── Guidelines/
│   │   │   │   ├── Guidelines.stories.tsx
│   │   │   │   ├── Guidelines.test.tsx
│   │   │   │   └── Guidelines.tsx
│   │   │   ├── Heading/
│   │   │   │   └── Heading.stories.tsx
│   │   │   ├── HeroBanner/
│   │   │   │   ├── HeroBanner.stories.tsx
│   │   │   │   └── HeroBanner.tsx
│   │   │   ├── Icon/
│   │   │   │   ├── DonateIcon.tsx
│   │   │   │   ├── DownloadIcon.tsx
│   │   │   │   ├── ExternalUrl.tsx
│   │   │   │   ├── Icon.stories.tsx
│   │   │   │   ├── Icon.tsx
│   │   │   │   ├── svgs.tsx
│   │   │   │   └── types.ts
│   │   │   ├── IconCountWithTooltip/
│   │   │   │   ├── IconCountWithTooltip.stories.tsx
│   │   │   │   ├── IconCountWithTooltip.test.tsx
│   │   │   │   └── IconCountWithTooltip.tsx
│   │   │   ├── ImageGallery/
│   │   │   │   ├── ImageGallery.stories.tsx
│   │   │   │   ├── ImageGallery.test.tsx
│   │   │   │   └── ImageGallery.tsx
│   │   │   ├── ImageGalleryThumbnail/
│   │   │   │   ├── ImageGalleryThumbnail.stories.tsx
│   │   │   │   ├── ImageGalleryThumbnail.test.tsx
│   │   │   │   └── ImageGalleryThumbnail.tsx
│   │   │   ├── ImageInput/
│   │   │   │   ├── ImageInputDeleteOverlay.tsx
│   │   │   │   ├── ImageInputV2.tsx
│   │   │   │   ├── ImageInputWrapper.tsx
│   │   │   │   └── isImageValid.ts
│   │   │   ├── InformationTooltip/
│   │   │   │   ├── InformationTooltip.stories.tsx
│   │   │   │   └── InformationTooltip.tsx
│   │   │   ├── Input/
│   │   │   │   └── Input.stories.tsx
│   │   │   ├── InternalLink/
│   │   │   │   ├── InternalLink.stories.tsx
│   │   │   │   └── InternalLink.tsx
│   │   │   ├── LinkifyText/
│   │   │   │   ├── LinkifyText.stories.tsx
│   │   │   │   └── LinkifyText.tsx
│   │   │   ├── Loader/
│   │   │   │   ├── Loader.stories.tsx
│   │   │   │   └── Loader.tsx
│   │   │   ├── Map/
│   │   │   │   ├── Map.client.tsx
│   │   │   │   ├── Map.stories.tsx
│   │   │   │   └── index.css
│   │   │   ├── MapCardList/
│   │   │   │   ├── MapCardList.stories.tsx
│   │   │   │   ├── MapCardList.test.tsx
│   │   │   │   └── MapCardList.tsx
│   │   │   ├── MapFilterListItem/
│   │   │   │   └── MapFilterListItem.tsx
│   │   │   ├── MapWithPin/
│   │   │   │   ├── MapPin.client.tsx
│   │   │   │   ├── MapPin.stories.tsx
│   │   │   │   ├── MapWithPin.client.tsx
│   │   │   │   └── MapWithPin.stories.tsx
│   │   │   ├── MemberBadge/
│   │   │   │   ├── MemberBadge.stories.tsx
│   │   │   │   └── MemberBadge.tsx
│   │   │   ├── MemberHistory/
│   │   │   │   ├── MemberHistory.test.tsx
│   │   │   │   └── MemberHistory.tsx
│   │   │   ├── Modal/
│   │   │   │   ├── Modal.stories.tsx
│   │   │   │   └── Modal.tsx
│   │   │   ├── ModerationStatus/
│   │   │   │   ├── ModerationStatus.stories.tsx
│   │   │   │   └── ModerationStatus.tsx
│   │   │   ├── MoreContainer/
│   │   │   │   ├── MoreContainer.stories.tsx
│   │   │   │   └── MoreContainer.tsx
│   │   │   ├── NotificationItemSupabase/
│   │   │   │   ├── NotificationItemSupabase.stories.tsx
│   │   │   │   └── NotificationItemSupabase.tsx
│   │   │   ├── NotificationListSupabase/
│   │   │   │   ├── NotificationListSupabase.stories.tsx
│   │   │   │   ├── NotificationListSupabase.test.tsx
│   │   │   │   └── NotificationListSupabase.tsx
│   │   │   ├── NotificationsModal/
│   │   │   │   └── NotificationsModal.tsx
│   │   │   ├── OsmGeocoding/
│   │   │   │   ├── OsmGeocoding.stories.tsx
│   │   │   │   ├── OsmGeocoding.tsx
│   │   │   │   ├── OsmGeocodingLoader.tsx
│   │   │   │   ├── OsmGeocodingResultsList.tsx
│   │   │   │   └── types.tsx
│   │   │   ├── Pagination/
│   │   │   │   ├── Pagination.test.tsx
│   │   │   │   └── Pagination.tsx
│   │   │   ├── PaginationIcons/
│   │   │   │   ├── PaginationIcons.stories.tsx
│   │   │   │   ├── PaginationIcons.test.tsx
│   │   │   │   └── PaginationIcons.tsx
│   │   │   ├── PinProfile/
│   │   │   │   ├── PinProfile.stories.tsx
│   │   │   │   └── PinProfile.tsx
│   │   │   ├── ProfileBadgeContentLabel/
│   │   │   │   ├── ProfileBadgeContentLabel.stories.tsx
│   │   │   │   └── ProfileBadgeContentLabel.tsx
│   │   │   ├── ProfileLink/
│   │   │   │   ├── ProfileLink.stories.tsx
│   │   │   │   └── ProfileLink.tsx
│   │   │   ├── ProfileList/
│   │   │   │   ├── ProfileList.stories.tsx
│   │   │   │   ├── ProfileList.test.tsx
│   │   │   │   └── ProfileList.tsx
│   │   │   ├── ProfileTagsList/
│   │   │   │   ├── ProfileTagsList.stories.tsx
│   │   │   │   ├── ProfileTagsList.test.tsx
│   │   │   │   └── ProfileTagsList.tsx
│   │   │   ├── ResearchEditorOverview/
│   │   │   │   ├── ResearchEditorOverview.stories.tsx
│   │   │   │   ├── ResearchEditorOverview.test.tsx
│   │   │   │   ├── ResearchEditorOverview.tsx
│   │   │   │   └── __snapshots__/
│   │   │   │       └── ResearchEditorOverview.test.tsx.snap
│   │   │   ├── ReturnPathLink/
│   │   │   │   └── ReturnPathLink.tsx
│   │   │   ├── SearchField/
│   │   │   │   ├── SearchField.stories.tsx
│   │   │   │   └── SearchField.tsx
│   │   │   ├── Select/
│   │   │   │   ├── DropdownIndicator.tsx
│   │   │   │   ├── Option.tsx
│   │   │   │   ├── Select.stories.tsx
│   │   │   │   └── Select.tsx
│   │   │   ├── SiteFooter/
│   │   │   │   ├── SiteFooter.stories.tsx
│   │   │   │   └── SiteFooter.tsx
│   │   │   ├── TabbedContent/
│   │   │   │   ├── TabbedContent.stories.tsx
│   │   │   │   ├── TabbedContent.test.tsx
│   │   │   │   └── TabbedContent.tsx
│   │   │   ├── Tag/
│   │   │   │   ├── Tag.stories.tsx
│   │   │   │   └── Tag.tsx
│   │   │   ├── TagList/
│   │   │   │   ├── TagList.stories.tsx
│   │   │   │   ├── TagList.test.tsx
│   │   │   │   └── TagList.tsx
│   │   │   ├── Text/
│   │   │   │   └── Text.stories.tsx
│   │   │   ├── TextNotification/
│   │   │   │   ├── TextNotification.stories.tsx
│   │   │   │   └── TextNotification.tsx
│   │   │   ├── Textarea/
│   │   │   │   └── Textarea.stories.tsx
│   │   │   ├── Tooltip/
│   │   │   │   ├── Tooltip.stories.tsx
│   │   │   │   └── Tooltip.tsx
│   │   │   ├── UsefulStatsButton/
│   │   │   │   ├── UsefulButtonLite.test.tsx
│   │   │   │   ├── UsefulButtonLite.tsx
│   │   │   │   ├── UsefulStatsButton.stories.tsx
│   │   │   │   └── UsefulStatsButton.tsx
│   │   │   ├── UserEngagementWrapper/
│   │   │   │   ├── UserEngagementWrapper.stories.tsx
│   │   │   │   ├── UserEngagementWrapper.test.tsx
│   │   │   │   └── UserEngagementWrapper.tsx
│   │   │   ├── UserStatistics/
│   │   │   │   ├── UserStatistics.stories.tsx
│   │   │   │   ├── UserStatistics.test.tsx
│   │   │   │   └── UserStatistics.tsx
│   │   │   ├── Username/
│   │   │   │   ├── DisplayName.stories.tsx
│   │   │   │   ├── DisplayName.tsx
│   │   │   │   ├── UserBadge.tsx
│   │   │   │   ├── Username.stories.tsx
│   │   │   │   ├── Username.test.tsx
│   │   │   │   └── Username.tsx
│   │   │   ├── VerticalList/
│   │   │   │   ├── VerticalList.client.tsx
│   │   │   │   └── VerticalList.stories.tsx
│   │   │   ├── VideoPlayer/
│   │   │   │   ├── VideoPlayer.stories.tsx
│   │   │   │   ├── VideoPlayer.test.tsx
│   │   │   │   └── VideoPlayer.tsx
│   │   │   ├── VisitorModal/
│   │   │   │   ├── VisitorModal.tsx
│   │   │   │   ├── VisitorModalFooter.test.tsx
│   │   │   │   ├── VisitorModalFooter.tsx
│   │   │   │   ├── VisitorModalHeader.test.tsx
│   │   │   │   ├── VisitorModalHeader.tsx
│   │   │   │   └── props.ts
│   │   │   ├── __mocks__/
│   │   │   │   └── AuthWrapper.mock.tsx
│   │   │   ├── hooks/
│   │   │   │   ├── useImageLightbox.tsx
│   │   │   │   └── usePhotoSwipeLightbox.ts
│   │   │   ├── index.ts
│   │   │   ├── providers/
│   │   │   │   └── AuthorsContext.ts
│   │   │   ├── test/
│   │   │   │   ├── setup.ts
│   │   │   │   └── utils.tsx
│   │   │   ├── types/
│   │   │   │   └── common.ts
│   │   │   └── utils.ts
│   │   ├── tsconfig.json
│   │   ├── types/
│   │   │   ├── emotion.d.ts
│   │   │   ├── images.d.ts
│   │   │   └── photoswipe.d.ts
│   │   └── vite.config.ts
│   ├── cypress/
│   │   ├── .gitignore
│   │   ├── .npmrc
│   │   ├── README.md
│   │   ├── cypress.config.ts
│   │   ├── package.json
│   │   ├── scripts/
│   │   │   └── start.mts
│   │   ├── src/
│   │   │   ├── data/
│   │   │   │   └── index.ts
│   │   │   ├── fixtures/
│   │   │   │   ├── images/
│   │   │   │   │   └── file.random
│   │   │   │   └── searchResults.ts
│   │   │   ├── integration/
│   │   │   │   ├── SignIn.spec.ts
│   │   │   │   ├── SignUp.spec.ts
│   │   │   │   ├── academy.spec.ts
│   │   │   │   ├── common.spec.ts
│   │   │   │   ├── library/
│   │   │   │   │   ├── discussions.spec.ts
│   │   │   │   │   ├── read.spec.ts
│   │   │   │   │   ├── seo.spec.ts
│   │   │   │   │   └── write.spec.ts
│   │   │   │   ├── news/
│   │   │   │   │   ├── discussions.spec.ts
│   │   │   │   │   ├── read.spec.ts
│   │   │   │   │   ├── search.spec.ts
│   │   │   │   │   └── write.spec.ts
│   │   │   │   ├── notifications.spec.ts
│   │   │   │   ├── profile.spec.ts
│   │   │   │   ├── profileList.spec.ts
│   │   │   │   ├── questions/
│   │   │   │   │   ├── discussions.spec.ts
│   │   │   │   │   ├── read.spec.ts
│   │   │   │   │   ├── search.spec.ts
│   │   │   │   │   └── write.spec.ts
│   │   │   │   ├── research/
│   │   │   │   │   ├── discussions.spec.ts
│   │   │   │   │   ├── follow.spec.ts
│   │   │   │   │   ├── list.spec.ts
│   │   │   │   │   ├── read.spec.ts
│   │   │   │   │   └── write.spec.ts
│   │   │   │   └── settings.spec.ts
│   │   │   ├── support/
│   │   │   │   ├── commands.ts
│   │   │   │   ├── commandsUi.ts
│   │   │   │   ├── hooks.ts
│   │   │   │   ├── index.ts
│   │   │   │   └── rules.ts
│   │   │   └── utils/
│   │   │       ├── TestUtils.ts
│   │   │       └── supabaseTestsService.ts
│   │   └── tsconfig.json
│   └── themes/
│       ├── .gitignore
│       ├── assets/
│       │   └── fonts/
│       │       └── README.md
│       ├── package.json
│       ├── src/
│       │   ├── common/
│       │   │   ├── button.ts
│       │   │   ├── commonStyles.ts
│       │   │   └── index.ts
│       │   ├── fonts/
│       │   │   ├── fonts.d.ts
│       │   │   └── index.ts
│       │   ├── index.ts
│       │   └── types/
│       │       └── index.ts
│       └── tsconfig.json
├── react-router.config.ts
├── seed/
│   ├── profilesSeed.ts
│   └── usersSeed.ts
├── seed.config.ts
├── seed.sql
├── seed.ts
├── server.js
├── shared/
│   ├── .gitignore
│   ├── README.md
│   ├── index.ts
│   ├── messages.ts
│   ├── mocks/
│   │   ├── auth/
│   │   │   ├── index.ts
│   │   │   └── users.ts
│   │   ├── data/
│   │   │   ├── badges.ts
│   │   │   ├── categories.ts
│   │   │   ├── discussions.ts
│   │   │   ├── index.ts
│   │   │   ├── mappins.ts
│   │   │   ├── messages.ts
│   │   │   ├── news.ts
│   │   │   ├── profileTags.ts
│   │   │   ├── profileTypes.ts
│   │   │   ├── projects.ts
│   │   │   ├── questions.ts
│   │   │   ├── research.ts
│   │   │   ├── researchUpdates.ts
│   │   │   ├── tags.ts
│   │   │   └── users.ts
│   │   └── index.ts
│   ├── models/
│   │   ├── author.ts
│   │   ├── banner.ts
│   │   ├── category.ts
│   │   ├── comment.ts
│   │   ├── common.ts
│   │   ├── content.ts
│   │   ├── db.ts
│   │   ├── document.ts
│   │   ├── filesForm.ts
│   │   ├── index.ts
│   │   ├── library.ts
│   │   ├── maps.ts
│   │   ├── media.ts
│   │   ├── messages.ts
│   │   ├── moderation.ts
│   │   ├── news.ts
│   │   ├── notifications.ts
│   │   ├── notificationsPreferences.ts
│   │   ├── patreon.ts
│   │   ├── patreonSettings.ts
│   │   ├── profile.ts
│   │   ├── profileBadge.ts
│   │   ├── profileTag.ts
│   │   ├── profileType.ts
│   │   ├── question.ts
│   │   ├── research.ts
│   │   ├── selectValue.ts
│   │   ├── subscriber.ts
│   │   ├── tag.ts
│   │   ├── tags.ts
│   │   ├── tenantSettings.ts
│   │   ├── upgradeBadge.ts
│   │   ├── user.ts
│   │   ├── userCreatedDocs.ts
│   │   ├── userEmailData.ts
│   │   ├── voteUseful.ts
│   │   └── webmanifest.ts
│   ├── package.json
│   ├── tsconfig.json
│   └── utils/
│       ├── file.utils.ts
│       ├── index.ts
│       ├── markdown.test.ts
│       └── markdown.ts
├── src/
│   ├── .server/
│   │   ├── models/
│   │   │   └── messageSettings.ts
│   │   ├── resend.ts
│   │   └── templates/
│   │       ├── Layout.tsx
│   │       ├── ReceiverMessage.tsx
│   │       ├── components/
│   │       │   ├── box-text.tsx
│   │       │   ├── button.tsx
│   │       │   ├── footer.tsx
│   │       │   ├── header.tsx
│   │       │   └── heading.tsx
│   │       └── instant-notification-email.tsx
│   ├── common/
│   │   ├── Alerts/
│   │   │   ├── AlertBanner.test.tsx
│   │   │   ├── AlertBanner.tsx
│   │   │   ├── AlertIncompleteProfile.tsx
│   │   │   └── Alerts.tsx
│   │   ├── Analytics/
│   │   │   ├── GoogleAnalytics.tsx
│   │   │   └── index.tsx
│   │   ├── AuthWrapper.test.tsx
│   │   ├── AuthWrapper.tsx
│   │   ├── DonationRequestModalContainer.test.tsx
│   │   ├── DonationRequestModalContainer.tsx
│   │   ├── DownloadWrapper.test.tsx
│   │   ├── DownloadWrapper.tsx
│   │   ├── Form/
│   │   │   ├── Checkbox.tsx
│   │   │   ├── ErrorsContainer.test.tsx
│   │   │   ├── ErrorsContainer.tsx
│   │   │   ├── FieldContainer.ts
│   │   │   ├── FileInput/
│   │   │   │   ├── FileDisplay.tsx
│   │   │   │   └── FileInput.tsx
│   │   │   ├── FileInput.field.tsx
│   │   │   ├── FormWrapper.tsx
│   │   │   ├── PasswordField.tsx
│   │   │   ├── README.md
│   │   │   ├── Select.field.tsx
│   │   │   ├── TagsSelectField.tsx
│   │   │   ├── UnsavedChangesDialog.tsx
│   │   │   ├── labels.ts
│   │   │   └── types.ts
│   │   ├── HideDiscussionContainer.test.tsx
│   │   ├── HideDiscussionContainer.tsx
│   │   ├── Highlighter.tsx
│   │   ├── PageHeader.tsx
│   │   ├── PremiumTierWrapper.test.tsx
│   │   ├── PremiumTierWrapper.tsx
│   │   ├── Spinner.tsx
│   │   ├── Tags/
│   │   │   ├── ProfileTagsSelect.tsx
│   │   │   └── TagsSelect.tsx
│   │   ├── Toast/
│   │   │   ├── CustomToast.tsx
│   │   │   ├── index.tsx
│   │   │   └── useToast.tsx
│   │   ├── UserAction.test.tsx
│   │   ├── UserAction.tsx
│   │   └── hooks/
│   │       └── useClickOutside.ts
│   ├── config/
│   │   ├── config.ts
│   │   ├── constants.ts
│   │   ├── default.json
│   │   ├── imageTransforms.ts
│   │   └── types.ts
│   ├── constants.ts
│   ├── entry.client.tsx
│   ├── entry.server.tsx
│   ├── factories/
│   │   ├── commentFactory.server.ts
│   │   ├── mapPinFactory.server.ts
│   │   └── profileFactory.server.ts
│   ├── logger/
│   │   ├── index.test.ts
│   │   └── index.ts
│   ├── modules/
│   │   ├── index.test.ts
│   │   └── index.ts
│   ├── pages/
│   │   ├── Academy/
│   │   │   ├── Academy.test.tsx
│   │   │   ├── Academy.tsx
│   │   │   └── ExternalEmbed/
│   │   │       └── ExternalEmbed.tsx
│   │   ├── Library/
│   │   │   ├── Content/
│   │   │   │   ├── Common/
│   │   │   │   │   ├── DeleteProjectButton.tsx
│   │   │   │   │   ├── FormSettings.tsx
│   │   │   │   │   ├── Library.form.test.tsx
│   │   │   │   │   ├── LibraryCategory.field.tsx
│   │   │   │   │   ├── LibraryCategoryGuidance.test.tsx
│   │   │   │   │   ├── LibraryCategoryGuidance.tsx
│   │   │   │   │   ├── LibraryDescription.field.test.tsx
│   │   │   │   │   ├── LibraryDescription.field.tsx
│   │   │   │   │   ├── LibraryDifficulty.field.tsx
│   │   │   │   │   ├── LibraryFileLink.field.tsx
│   │   │   │   │   ├── LibraryFileUpload.field.tsx
│   │   │   │   │   ├── LibraryForm.tsx
│   │   │   │   │   ├── LibraryFormProvider.tsx
│   │   │   │   │   ├── LibraryPostingGuidelines.tsx
│   │   │   │   │   ├── LibraryStep.field.test.tsx
│   │   │   │   │   ├── LibraryStep.field.tsx
│   │   │   │   │   ├── LibraryStepsContainer.field.test.tsx
│   │   │   │   │   ├── LibraryStepsContainer.field.tsx
│   │   │   │   │   ├── LibraryTime.field.tsx
│   │   │   │   │   ├── LibraryTitle.field.test.tsx
│   │   │   │   │   └── LibraryTitle.field.tsx
│   │   │   │   ├── List/
│   │   │   │   │   ├── LibraryList.tsx
│   │   │   │   │   ├── LibraryListHeader.tsx
│   │   │   │   │   ├── LibrarySortOptions.ts
│   │   │   │   │   └── ProjectCard.tsx
│   │   │   │   ├── Page/
│   │   │   │   │   ├── LibraryDescription.tsx
│   │   │   │   │   ├── LibraryStep.tsx
│   │   │   │   │   └── ProjectPage.tsx
│   │   │   │   └── utils/
│   │   │   │       ├── downloadCooldown.ts
│   │   │   │       ├── index.ts
│   │   │   │       ├── transformLibraryErrors.test.ts
│   │   │   │       └── transformLibraryErrors.ts
│   │   │   ├── constants.ts
│   │   │   ├── labels.ts
│   │   │   └── library.service.ts
│   │   ├── Maps/
│   │   │   ├── Content/
│   │   │   │   ├── MapView/
│   │   │   │   │   ├── ButtonZoomIn.client.tsx
│   │   │   │   │   ├── Cluster.client.tsx
│   │   │   │   │   ├── MapList.tsx
│   │   │   │   │   ├── MapView.tsx
│   │   │   │   │   ├── MapWithListHeader.tsx
│   │   │   │   │   ├── Popup.client.tsx
│   │   │   │   │   ├── Sprites.tsx
│   │   │   │   │   ├── popup.css
│   │   │   │   │   └── sprites.css
│   │   │   │   └── MemberTypeVerticalList/
│   │   │   │       └── MemberTypeVerticalList.client.tsx
│   │   │   ├── MapContext.ts
│   │   │   ├── MapFilterList.tsx
│   │   │   ├── Maps.client.tsx
│   │   │   ├── map.service.ts
│   │   │   ├── styles.css
│   │   │   └── utils/
│   │   │       ├── geolocation.ts
│   │   │       ├── pinUtils.test.ts
│   │   │       └── pinUtils.ts
│   │   ├── News/
│   │   │   ├── Content/
│   │   │   │   └── Common/
│   │   │   │       ├── FormFields/
│   │   │   │       │   ├── NewsBodyField.tsx
│   │   │   │       │   ├── NewsImageField.tsx
│   │   │   │       │   └── index.ts
│   │   │   │       ├── NewsForm.test.tsx
│   │   │   │       ├── NewsForm.tsx
│   │   │   │       └── NewsPostingGuidelines.tsx
│   │   │   ├── NewsListHeader.tsx
│   │   │   ├── NewsListItem.tsx
│   │   │   ├── NewsListing.tsx
│   │   │   ├── NewsPage.test.tsx
│   │   │   ├── NewsPage.tsx
│   │   │   ├── NewsSortOptions.ts
│   │   │   ├── constants.ts
│   │   │   ├── labels.ts
│   │   │   └── newsContent.service.ts
│   │   ├── NotFound/
│   │   │   └── NotFound.tsx
│   │   ├── PageList.tsx
│   │   ├── Question/
│   │   │   ├── Content/
│   │   │   │   └── Common/
│   │   │   │       ├── FormFields/
│   │   │   │       │   ├── QuestionDescription.field.tsx
│   │   │   │       │   ├── QuestionImages.field.tsx
│   │   │   │       │   └── index.ts
│   │   │   │       ├── QuestionForm.tsx
│   │   │   │       ├── QuestionPostingGuidelines.tsx
│   │   │   │       └── index.ts
│   │   │   ├── QuestionListHeader.tsx
│   │   │   ├── QuestionListItem.tsx
│   │   │   ├── QuestionListing.tsx
│   │   │   ├── QuestionPage.test.tsx
│   │   │   ├── QuestionPage.tsx
│   │   │   ├── QuestionSortOptions.ts
│   │   │   ├── constants.ts
│   │   │   ├── labels.ts
│   │   │   └── question.service.ts
│   │   ├── Research/
│   │   │   ├── Content/
│   │   │   │   ├── Common/
│   │   │   │   │   ├── DeleteResearchButton.tsx
│   │   │   │   │   ├── FormFields/
│   │   │   │   │   │   ├── ResearchCollaboratorsField.tsx
│   │   │   │   │   │   ├── ResearchDescriptionField.tsx
│   │   │   │   │   │   └── ResearchTitleField.tsx
│   │   │   │   │   ├── ResearchCategorySelect.tsx
│   │   │   │   │   ├── ResearchForm.tsx
│   │   │   │   │   ├── ResearchPostingGuidelines.tsx
│   │   │   │   │   ├── ResearchUpdateForm.tsx
│   │   │   │   │   └── index.ts
│   │   │   │   ├── CreateResearch/
│   │   │   │   │   └── Form/
│   │   │   │   │       ├── DescriptionField.tsx
│   │   │   │   │       ├── ResearchImagesField.tsx
│   │   │   │   │       ├── TitleField.tsx
│   │   │   │   │       └── VideoUrlField.tsx
│   │   │   │   ├── ResearchArticle.test.tsx
│   │   │   │   ├── ResearchArticlePage.tsx
│   │   │   │   ├── ResearchDescription.tsx
│   │   │   │   ├── ResearchEngagementSection.tsx
│   │   │   │   ├── ResearchFooter.tsx
│   │   │   │   ├── ResearchLinkToUpdate.tsx
│   │   │   │   ├── ResearchList.tsx
│   │   │   │   ├── ResearchListHeader.tsx
│   │   │   │   ├── ResearchListItem.tsx
│   │   │   │   ├── ResearchSearchParams.ts
│   │   │   │   ├── ResearchUpdate.tsx
│   │   │   │   ├── helper.test.tsx
│   │   │   │   └── helper.ts
│   │   │   ├── ResearchSortOptions.ts
│   │   │   ├── constants.ts
│   │   │   ├── labels.ts
│   │   │   ├── research.service.test.ts
│   │   │   ├── research.service.ts
│   │   │   ├── researchHelpers.test.ts
│   │   │   └── researchHelpers.ts
│   │   ├── SignUp/
│   │   │   └── SignUpMessage.tsx
│   │   ├── User/
│   │   │   ├── constants.ts
│   │   │   ├── contact/
│   │   │   │   ├── UserContactFieldMessage.tsx
│   │   │   │   ├── UserContactFieldName.tsx
│   │   │   │   ├── UserContactForm.test.tsx
│   │   │   │   ├── UserContactForm.tsx
│   │   │   │   ├── UserContactFormAvailable.tsx
│   │   │   │   ├── UserContactFormNotLoggedIn.tsx
│   │   │   │   ├── UserContactNotLoggedIn.tsx
│   │   │   │   └── index.ts
│   │   │   ├── content/
│   │   │   │   ├── ProfileContact.tsx
│   │   │   │   ├── ProfileDetails.tsx
│   │   │   │   ├── ProfileHeader.tsx
│   │   │   │   ├── ProfileImage.tsx
│   │   │   │   ├── ProfilePage.tsx
│   │   │   │   ├── UserCreatedDocuments.test.tsx
│   │   │   │   ├── UserCreatedDocuments.tsx
│   │   │   │   ├── UserCreatedDocumentsItem.tsx
│   │   │   │   └── UserProfile.tsx
│   │   │   ├── impact/
│   │   │   │   ├── Impact.test.tsx
│   │   │   │   ├── Impact.tsx
│   │   │   │   ├── ImpactField.test.tsx
│   │   │   │   ├── ImpactField.tsx
│   │   │   │   ├── ImpactIcon.tsx
│   │   │   │   ├── ImpactItem.test.tsx
│   │   │   │   ├── ImpactItem.tsx
│   │   │   │   ├── ImpactMissing.test.tsx
│   │   │   │   ├── ImpactMissing.tsx
│   │   │   │   ├── constants.ts
│   │   │   │   └── labels.ts
│   │   │   └── labels.ts
│   │   ├── UserSettings/
│   │   │   ├── SettingsFormTab.tsx
│   │   │   ├── SettingsFormTabList.tsx
│   │   │   ├── SettingsPage.client.tsx
│   │   │   ├── SettingsPageAccount.tsx
│   │   │   ├── SettingsPageImpact.test.tsx
│   │   │   ├── SettingsPageImpact.tsx
│   │   │   ├── SettingsPageMapPin.test.tsx
│   │   │   ├── SettingsPageMapPin.tsx
│   │   │   ├── SettingsPageNotifications.tsx
│   │   │   ├── SettingsPageUserProfile.test.tsx
│   │   │   ├── SettingsPageUserProfile.tsx
│   │   │   ├── SupabaseNotifications.tsx
│   │   │   ├── SupabaseNotificationsForm.tsx
│   │   │   ├── SupabaseNotificationsViaEmail.tsx
│   │   │   ├── __mocks__/
│   │   │   │   └── FormProvider.tsx
│   │   │   ├── constants.ts
│   │   │   ├── content/
│   │   │   │   ├── elements.tsx
│   │   │   │   ├── fields/
│   │   │   │   │   ├── ImpactQuestion.field.tsx
│   │   │   │   │   ├── ImpactYear.field.tsx
│   │   │   │   │   ├── ImpactYearDisplay.field.tsx
│   │   │   │   │   ├── PatreonIntegration.test.tsx
│   │   │   │   │   ├── PatreonIntegration.tsx
│   │   │   │   │   └── ProfileTypeRadio.field.tsx
│   │   │   │   ├── impactQuestions.ts
│   │   │   │   └── sections/
│   │   │   │       ├── ChangeEmail.form.tsx
│   │   │   │       ├── ChangePassword.form.tsx
│   │   │   │       ├── EmailNotifications.section.tsx
│   │   │   │       ├── ImpactYear.section.tsx
│   │   │   │       ├── ProfileTags.section.tsx
│   │   │   │       ├── ProfileType.section.test.tsx
│   │   │   │       ├── ProfileType.section.tsx
│   │   │   │       ├── PublicContact.section.test.tsx
│   │   │   │       ├── PublicContact.section.tsx
│   │   │   │       ├── UserImages.section.tsx
│   │   │   │       ├── UserInfos.section.tsx
│   │   │   │       └── VisitorSection.tsx
│   │   │   ├── labels.ts
│   │   │   ├── services/
│   │   │   │   └── account.service.ts
│   │   │   ├── types.ts
│   │   │   ├── utils.test.ts
│   │   │   └── utils.ts
│   │   ├── common/
│   │   │   ├── Breadcrumbs/
│   │   │   │   └── Breadcrumbs.tsx
│   │   │   ├── Category/
│   │   │   │   └── CategoriesSelectV2.tsx
│   │   │   ├── CommentsSupabase/
│   │   │   │   ├── CollapsableCommentSection.tsx
│   │   │   │   ├── CommentItemSupabase.tsx
│   │   │   │   ├── CommentReplySupabase.tsx
│   │   │   │   ├── CommentSectionSupabase.tsx
│   │   │   │   ├── CommentSort.tsx
│   │   │   │   ├── CommentSortOptions.ts
│   │   │   │   ├── CreateCommentSupabase.css
│   │   │   │   ├── CreateCommentSupabase.tsx
│   │   │   │   └── useCopyCommentLink.ts
│   │   │   ├── Drafts/
│   │   │   │   ├── DraftButton.test.tsx
│   │   │   │   ├── DraftButton.tsx
│   │   │   │   ├── DraftTag.tsx
│   │   │   │   └── useDraftsSupabase.tsx
│   │   │   ├── FormFields/
│   │   │   │   ├── Category.field.tsx
│   │   │   │   ├── FilesFields.tsx
│   │   │   │   ├── FormFieldWrapper.test.tsx
│   │   │   │   ├── FormFieldWrapper.tsx
│   │   │   │   ├── ImageField.tsx
│   │   │   │   ├── ImageInputFieldWrapper.tsx
│   │   │   │   ├── ProfileBadgeField.tsx
│   │   │   │   ├── StepImagesField.tsx
│   │   │   │   ├── Tags.field.tsx
│   │   │   │   ├── Title.field.tsx
│   │   │   │   ├── index.ts
│   │   │   │   └── labels.ts
│   │   │   ├── GlobalSiteFooter/
│   │   │   │   └── GlobalSiteFooter.tsx
│   │   │   ├── Header/
│   │   │   │   ├── Header.tsx
│   │   │   │   ├── Menu/
│   │   │   │   │   ├── Logo/
│   │   │   │   │   │   └── Logo.tsx
│   │   │   │   │   ├── MenuDesktop.tsx
│   │   │   │   │   ├── MenuMobile/
│   │   │   │   │   │   ├── MenuMobileExternalLink.tsx
│   │   │   │   │   │   ├── MenuMobileLink.tsx
│   │   │   │   │   │   └── MenuMobilePanel.tsx
│   │   │   │   │   ├── Notifications/
│   │   │   │   │   │   └── NotificationsSupabase.tsx
│   │   │   │   │   ├── Profile/
│   │   │   │   │   │   ├── Profile.tsx
│   │   │   │   │   │   ├── ProfileButtonItem.tsx
│   │   │   │   │   │   ├── ProfileButtons.tsx
│   │   │   │   │   │   ├── UpgradeBadgeLink.tsx
│   │   │   │   │   │   └── profile.css
│   │   │   │   │   └── ProfileModal/
│   │   │   │   │       └── ProfileModal.tsx
│   │   │   │   └── MobileMenuContext.tsx
│   │   │   ├── Layout/
│   │   │   │   ├── ListHeader.tsx
│   │   │   │   ├── Main.tsx
│   │   │   │   └── MobileSortModal.tsx
│   │   │   ├── NotificationsContext.ts
│   │   │   ├── SessionContext.ts
│   │   │   ├── StickyButton.tsx
│   │   │   ├── TenantContext.ts
│   │   │   ├── UserNameSelect/
│   │   │   │   └── UserNameSelect.tsx
│   │   │   ├── UserNameTag/
│   │   │   │   └── UserNameTag.tsx
│   │   │   ├── banner.service.ts
│   │   │   └── labels.ts
│   │   ├── constants.ts
│   │   └── policy/
│   │       ├── PrivacyPolicy.tsx
│   │       └── TermsPolicy.tsx
│   ├── repository/
│   │   ├── supabase.server.ts
│   │   └── supabaseAdmin.server.ts
│   ├── root.tsx
│   ├── routes/
│   │   ├── [manifest.webmanifest].tsx
│   │   ├── [robots.txt].tsx
│   │   ├── _.$.tsx
│   │   ├── _.academy.$.tsx
│   │   ├── _.email-confirmation.tsx
│   │   ├── _.email-preferences.tsx
│   │   ├── _.feedback.tsx
│   │   ├── _.forbidden.tsx
│   │   ├── _.how-to.$slug._index.tsx
│   │   ├── _.how-to.$slug.edit.tsx
│   │   ├── _.how-to._index.tsx
│   │   ├── _.how-to.create.tsx
│   │   ├── _.how-to.tsx
│   │   ├── _.library.$slug._index.tsx
│   │   ├── _.library.$slug.edit.tsx
│   │   ├── _.library._index.tsx
│   │   ├── _.library.create.tsx
│   │   ├── _.library.tsx
│   │   ├── _.map.tsx
│   │   ├── _.news.$slug._index.tsx
│   │   ├── _.news.$slug.edit.tsx
│   │   ├── _.news._index.tsx
│   │   ├── _.news.create.tsx
│   │   ├── _.news.tsx
│   │   ├── _.patreon.tsx
│   │   ├── _.privacy.tsx
│   │   ├── _.questions.$slug._index.tsx
│   │   ├── _.questions.$slug.edit.tsx
│   │   ├── _.questions._index.tsx
│   │   ├── _.questions.create.tsx
│   │   ├── _.questions.tsx
│   │   ├── _.research.$slug._index.tsx
│   │   ├── _.research.$slug.edit-update.$updateId.tsx
│   │   ├── _.research.$slug.edit.tsx
│   │   ├── _.research.$slug.new-update.tsx
│   │   ├── _.research._index.tsx
│   │   ├── _.research.create.tsx
│   │   ├── _.research.tsx
│   │   ├── _.reset-password.tsx
│   │   ├── _.settings.$.tsx
│   │   ├── _.sign-in.tsx
│   │   ├── _.sign-up-message.tsx
│   │   ├── _.sign-up.tsx
│   │   ├── _.terms.tsx
│   │   ├── _.tsx
│   │   ├── _.u.$id._index.tsx
│   │   ├── _.u.tsx
│   │   ├── _.update-password.tsx
│   │   ├── _index.tsx
│   │   ├── api.account.change-email.tsx
│   │   ├── api.account.change-password.tsx
│   │   ├── api.banner.ts
│   │   ├── api.categories.$type.ts
│   │   ├── api.comments.$id.source.ts
│   │   ├── api.discussions.$sourceId.comments.$id.ts
│   │   ├── api.discussions.$sourceType.$sourceId.comments.ts
│   │   ├── api.documents.$type.$contentId.$docId.tsx
│   │   ├── api.documents.ts
│   │   ├── api.donation-settings.$profileId.ts
│   │   ├── api.favicon.ts
│   │   ├── api.images.ts
│   │   ├── api.map-filters.ts
│   │   ├── api.map-pin.ts
│   │   ├── api.map-pins.$userId.ts
│   │   ├── api.map-pins.ts
│   │   ├── api.messages.tsx
│   │   ├── api.news.$id.ts
│   │   ├── api.news.drafts.count.ts
│   │   ├── api.news.drafts.ts
│   │   ├── api.news.ts
│   │   ├── api.notifications-preferences-via-email.$userCode.ts
│   │   ├── api.notifications-preferences.ts
│   │   ├── api.notifications.$id.read.ts
│   │   ├── api.notifications.all.read.ts
│   │   ├── api.notifications.ts
│   │   ├── api.patreon.ts
│   │   ├── api.profile-badges.ts
│   │   ├── api.profile-tags.ts
│   │   ├── api.profile-types.ts
│   │   ├── api.profile.ts
│   │   ├── api.profile.username.ts
│   │   ├── api.profiles.ts
│   │   ├── api.projects.$id.ts
│   │   ├── api.projects.drafts.count.ts
│   │   ├── api.projects.drafts.ts
│   │   ├── api.projects.ts
│   │   ├── api.questions.$id.ts
│   │   ├── api.questions.drafts.count.ts
│   │   ├── api.questions.drafts.ts
│   │   ├── api.questions.ts
│   │   ├── api.research.$id.status.ts
│   │   ├── api.research.$id.ts
│   │   ├── api.research.$id.updates.$updateId.ts
│   │   ├── api.research.$id.updates.ts
│   │   ├── api.research.drafts.count.ts
│   │   ├── api.research.drafts.ts
│   │   ├── api.research.ts
│   │   ├── api.settings.impact.ts
│   │   ├── api.settings.map.ts
│   │   ├── api.subscribers.$contentType.$contentId.subscribed.ts
│   │   ├── api.subscribers.$contentType.$contentId.ts
│   │   ├── api.tags.ts
│   │   ├── api.upgrade-badges.ts
│   │   ├── api.useful.$contentType.$contentId.ts
│   │   ├── api.useful.$contentType.$contentId.users.ts
│   │   ├── api.useful.$contentType.$contentId.voted.ts
│   │   ├── api.useful.$contentType.$id.count.ts
│   │   ├── logout.ts
│   │   └── redirect.tsx
│   ├── routes.ts
│   ├── services/
│   │   ├── authService.server.ts
│   │   ├── broadcastCoordinationService.server.ts
│   │   ├── categoryService.ts
│   │   ├── commentService.ts
│   │   ├── contentRedirectService.server.ts
│   │   ├── contentService.server.ts
│   │   ├── discordService.server.ts
│   │   ├── formDataHelper.ts
│   │   ├── imageService.server.ts
│   │   ├── impactService.server.ts
│   │   ├── libraryService.server.ts
│   │   ├── mapPinsService.server.ts
│   │   ├── mapService.server.ts
│   │   ├── messageService.ts
│   │   ├── newsService.server.ts
│   │   ├── newsService.ts
│   │   ├── notificationEmailService.server.ts
│   │   ├── notificationMapperService.server.ts
│   │   ├── notificationsPreferencesService.ts
│   │   ├── notificationsPreferencesViaEmailService.ts
│   │   ├── notificationsSupabaseService.server.ts
│   │   ├── notificationsSupabaseService.ts
│   │   ├── patreonService.server.ts
│   │   ├── patreonService.ts
│   │   ├── profileBadgeService.ts
│   │   ├── profileService.server.ts
│   │   ├── profileService.ts
│   │   ├── profileTagsService.ts
│   │   ├── profileTypesService.server.ts
│   │   ├── profileTypesService.ts
│   │   ├── profilesService.ts
│   │   ├── questionService.server.test.ts
│   │   ├── questionService.server.ts
│   │   ├── questionService.ts
│   │   ├── redirectService.server.ts
│   │   ├── researchService.server.ts
│   │   ├── storageService.server.ts
│   │   ├── storageService.ts
│   │   ├── subscribersService.server.ts
│   │   ├── subscribersService.ts
│   │   ├── tagsService.server.ts
│   │   ├── tagsService.ts
│   │   ├── tenantSettingsService.server.ts
│   │   ├── upgradeBadgeService.ts
│   │   └── usefulService.ts
│   ├── stores/
│   │   ├── Profile/
│   │   │   ├── profile.store.test.ts
│   │   │   └── profile.store.tsx
│   │   ├── Subscription/
│   │   │   ├── subscription.store.test.ts
│   │   │   ├── subscription.store.tsx
│   │   │   └── useSubscription.tsx
│   │   └── UsefulVote/
│   │       ├── useUsefulVote.tsx
│   │       └── usefulVote.store.tsx
│   ├── styles/
│   │   ├── context.ts
│   │   ├── createEmotionCache.ts
│   │   └── leaflet.css
│   ├── test/
│   │   ├── components/
│   │   │   └── SettingsFormProvider.tsx
│   │   ├── factories/
│   │   │   ├── Category.ts
│   │   │   ├── Comment.ts
│   │   │   ├── Library.ts
│   │   │   ├── MapPin.ts
│   │   │   ├── News.ts
│   │   │   ├── Question.ts
│   │   │   ├── ResearchItem.ts
│   │   │   ├── User.ts
│   │   │   ├── dbNotification.ts
│   │   │   ├── notificationsPreferences.ts
│   │   │   ├── profile.ts
│   │   │   └── supabaseNotification.ts
│   │   ├── models/
│   │   │   └── profile.test.ts
│   │   ├── routes/
│   │   │   └── api.notifications-preferences.test.ts
│   │   ├── services/
│   │   │   ├── broadcastCoordinationService.server.ts
│   │   │   ├── notificationsPreferencesService.test.ts
│   │   │   ├── notificationsPreferencesViaEmailService.test.ts
│   │   │   └── subscribersService.server.test.ts
│   │   ├── setup.ts
│   │   └── utils/
│   │       └── supabaseClientMock.ts
│   ├── types/
│   │   └── emotion.d.ts
│   └── utils/
│       ├── comparisons.ts
│       ├── contentType.utils.ts
│       ├── filters.ts
│       ├── fireConfetti.ts
│       ├── formatImageListForGallery.ts
│       ├── getLocationData.ts
│       ├── getSummaryFromMarkdown.test.ts
│       ├── getSummaryFromMarkdown.ts
│       ├── helpers.test.ts
│       ├── helpers.ts
│       ├── httpException.ts
│       ├── mentions.utils.ts
│       ├── redirect.server.ts
│       ├── searchHelper.test.ts
│       ├── searchHelper.ts
│       ├── seo.utils.ts
│       ├── sessionStorage.ts
│       ├── slug.ts
│       ├── statistics.tsx
│       ├── stopwords.ts
│       ├── storage.ts
│       ├── tokens.server.ts
│       ├── urlHelper.ts
│       ├── urls.ts
│       ├── validators.test.ts
│       └── validators.ts
├── supabase/
│   ├── .gitignore
│   ├── README.md
│   ├── config.toml
│   ├── functions/
│   │   └── send-email/
│   │       ├── .npmrc
│   │       ├── _templates/
│   │       │   ├── components/
│   │       │   │   ├── box-text.tsx
│   │       │   │   ├── button.tsx
│   │       │   │   ├── footer.tsx
│   │       │   │   ├── header.tsx
│   │       │   │   ├── heading.tsx
│   │       │   │   ├── hero.tsx
│   │       │   │   ├── parent-box.tsx
│   │       │   │   └── plain-text.tsx
│   │       │   ├── email-change-new.tsx
│   │       │   ├── layout.tsx
│   │       │   ├── magic-link.tsx
│   │       │   ├── moderation-email.tsx
│   │       │   ├── reset-password.tsx
│   │       │   └── sign-up.tsx
│   │       ├── deno.json
│   │       ├── getTenantSettings.ts
│   │       ├── index.ts
│   │       └── signWebhookHeader.ts
│   ├── migrations/
│   │   ├── 20241125140428_profiles_and_comments.sql
│   │   ├── 20250111151556_questions.sql
│   │   ├── 20250113184950_profile_auth_columns.sql
│   │   ├── 20250208130256_auth_rpc.sql
│   │   ├── 20250209131232_profile_firebase.sql
│   │   ├── 20250214235014_messages.sql
│   │   ├── 20250225071100_unique_username.sql
│   │   ├── 20250307061534_messages_temp_fix.sql
│   │   ├── 20250312063008_patreon.sql
│   │   ├── 20250331134409_add_news.sql
│   │   ├── 20250416104948_research.sql
│   │   ├── 20250422092704_add_notifications.sql
│   │   ├── 20250512170000_research_sorting.sql
│   │   ├── 20250513090512_update_for_email_notifications.sql
│   │   ├── 20250514163118_update_notifications.sql
│   │   ├── 20250520134140_update_notifications_for_research_comments.sql
│   │   ├── 20250521044802_fix-research-sorting-useful.sql
│   │   ├── 20250523104253_20250523_add-get-user-questions.sql
│   │   ├── 20250603130017_add_notifications_preferences.sql
│   │   ├── 20250605115351_research-latest-updated.sql
│   │   ├── 20250609100159_research_query_ranking.sql
│   │   ├── 20250609101144_library.sql
│   │   ├── 20250617151457_update_notification_preferences.sql
│   │   ├── 20250621165139_user_research_filter_draft.sql
│   │   ├── 20250624101144_replace_get_projects_count.sql
│   │   ├── 20250624101145_replace_get_user_projects.sql
│   │   ├── 20250624101147_replace_get_user_projects_again.sql
│   │   ├── 20250625162400_update_questions_news_is_draft.sql
│   │   ├── 20250702155642_add_unsubscribe_to_preferences.sql
│   │   ├── 20250722145300_profile.sql
│   │   ├── 20250819103736_add_badge_id_to_news.sql
│   │   ├── 20250824222054_fix-author-vote-count-deleted.sql
│   │   ├── 20250830203011_banner.sql
│   │   ├── 20250902101059_map_pins-optimizations.sql
│   │   ├── 20250904101010_useful_comments.sql
│   │   ├── 20250912091153_fix-delete-comment-trigger.sql
│   │   ├── 20250912110000_optimize_get_comments_with_votes.sql
│   │   ├── 20250912210000_optimize_profile_indexes.sql
│   │   ├── 20250914104923_update_notifications.sql
│   │   ├── 20251011132910_fix_messages_receiver.sql
│   │   ├── 20251011233154_fix_policy_performance.sql
│   │   ├── 20251011234304_fix_function_security_warning.sql
│   │   ├── 20251012135652_fix_policy_performance_2.sql
│   │   ├── 20251024140004_fix_get_project_count.sql
│   │   ├── 20251025145021_add_most_views_sort.sql
│   │   ├── 20251031045802_add_favicon.sql
│   │   ├── 20251119072930_track_badges.sql
│   │   ├── 20251124054625_profile_donations.sql
│   │   ├── 20251130000401_create_upgrade_badge_table.sql
│   │   ├── 20251203151049_research_author_search_fix.sql
│   │   ├── 20251217132033_add_most_useful_last_week_feature.sql
│   │   ├── 20260103002808_add_premium_tier.sql
│   │   ├── 20260118140428_update_user_doc_gets.sql
│   │   ├── 20260118233300_batch_notifications.sql
│   │   ├── 20260216125228_more_tenant_settings.sql
│   │   ├── 20260227070309_site_description.sql
│   │   ├── 20260301000000_fix_partial_search.sql
│   │   ├── 20260309135320_questions_search_rpc.sql
│   │   ├── 20260317131051_add_published_at.sql
│   │   ├── 20260322000000_add_get_storage_object_path.sql
│   │   ├── 20260330124656_make_username_nullable.sql
│   │   ├── 20260401000000_tenant_settings_ga.sql
│   │   ├── 20260402103538_search_multiple_words.sql
│   │   ├── 20260402150623_search_stop_words.sql
│   │   └── 20260421051050_pwa_icons.sql
│   ├── schemas/
│   │   ├── banners.sql
│   │   ├── categories.sql
│   │   ├── comments.sql
│   │   ├── common.sql
│   │   ├── map.sql
│   │   ├── messages.sql
│   │   ├── news.sql
│   │   ├── notifications.sql
│   │   ├── patreon.sql
│   │   ├── profiles.sql
│   │   ├── projects.sql
│   │   ├── questions.sql
│   │   ├── research.sql
│   │   ├── subscribers.sql
│   │   ├── tags.sql
│   │   ├── tenant_settings.sql
│   │   └── useful.sql
│   └── seed.sql
├── tsconfig.json
├── tsconfig.prod.json
├── vite-env.d.ts
└── vite.config.ts
Download .txt
SYMBOL INDEX (1392 symbols across 560 files)

FILE: packages/components/.storybook/main.ts
  method viteFinal (line 18) | async viteFinal(config) {
  function getAbsolutePath (line 26) | function getAbsolutePath(value: string): any {

FILE: packages/components/.storybook/preview.tsx
  type ThemeName (line 30) | type ThemeName = keyof typeof themeColors;
  function getThemeCSSVariables (line 32) | function getThemeCSSVariables(themeName: ThemeName): string {
  function ThemeVariables (line 49) | function ThemeVariables({ themeName }: { themeName: ThemeName }) {

FILE: packages/components/src/Accordion/Accordion.tsx
  type IProps (line 6) | interface IProps {

FILE: packages/components/src/ActionSet/ActionSet.tsx
  type IProps (line 6) | interface IProps {

FILE: packages/components/src/ArrowIcon/ArrowIcon.tsx
  type IProps (line 8) | interface IProps {

FILE: packages/components/src/ArticleCallToActionSupabase/ArticleCallToActionSupabase.tsx
  type IProps (line 5) | interface IProps {

FILE: packages/components/src/AuthorDisplay/AuthorDisplay.tsx
  type IProps (line 5) | interface IProps {

FILE: packages/components/src/Banner/Banner.tsx
  type AlertVariants (line 5) | type AlertVariants = 'accent' | 'failure' | 'info' | 'success';
  type IProps (line 7) | interface IProps {

FILE: packages/components/src/BlockedRoute/BlockedRoute.tsx
  type BlockedRouteProps (line 6) | interface BlockedRouteProps {

FILE: packages/components/src/Breadcrumbs/Breadcrumbs.tsx
  type Step (line 6) | type Step = { text: string; link?: string };
  type BreadcrumbsProps (line 8) | interface BreadcrumbsProps {

FILE: packages/components/src/Breadcrumbs/BreadcrumbsItem.tsx
  type BreadcrumbButtonProps (line 6) | interface BreadcrumbButtonProps {
  type BreadcrumbItemProps (line 11) | interface BreadcrumbItemProps {

FILE: packages/components/src/Button/Button.tsx
  type IBtnProps (line 9) | interface IBtnProps extends React.ButtonHTMLAttributes<HTMLElement> {
  type ToArray (line 19) | type ToArray<Type> = [Type] extends [any] ? Type[] : never;
  type AvailableButtonProps (line 20) | type AvailableButtonProps = ToArray<keyof BtnProps>;
  type BtnProps (line 43) | type BtnProps = IBtnProps & ThemeUiButtonProps;
  function getSizeProps (line 45) | function getSizeProps(size: string, hasIcon: boolean) {
  function getScaleTransform (line 66) | function getScaleTransform(size: string) {
  function sanitizedProps (line 74) | function sanitizedProps(obj: BtnProps, keysToRemove: AvailableButtonProp...

FILE: packages/components/src/ButtonIcon/ButtonIcon.tsx
  type IProps (line 6) | interface IProps extends React.ButtonHTMLAttributes<HTMLElement> {

FILE: packages/components/src/ButtonShowReplies/ButtonShowReplies.tsx
  type Props (line 4) | interface Props {

FILE: packages/components/src/CardButton/CardButton.tsx
  type IProps (line 4) | interface IProps extends BoxProps {

FILE: packages/components/src/CardListItem/CardListItem.tsx
  type IProps (line 7) | interface IProps {

FILE: packages/components/src/CardProfile/CardDetailsMemberProfile.tsx
  type IProps (line 8) | interface IProps {

FILE: packages/components/src/CardProfile/CardDetailsSpaceProfile.tsx
  type IProps (line 7) | interface IProps {

FILE: packages/components/src/CardProfile/CardProfile.tsx
  type IProps (line 6) | interface IProps {

FILE: packages/components/src/Category/Category.tsx
  type Props (line 5) | interface Props {

FILE: packages/components/src/CategoryHorizonalList/CategoryHorizonalList.tsx
  type IProps (line 8) | interface IProps {

FILE: packages/components/src/CharacterCount/CharacterCount.tsx
  type ICharacterCountProps (line 3) | interface ICharacterCountProps {

FILE: packages/components/src/CommentAvatar/CommentAvatar.tsx
  type CommentAvatarProps (line 6) | type CommentAvatarProps = {

FILE: packages/components/src/CommentBody/CommentBody.tsx
  type IProps (line 6) | interface IProps {
  constant SHORT_COMMENT (line 9) | const SHORT_COMMENT = 129;

FILE: packages/components/src/CommentDisplay/CommentDisplay.tsx
  type IProps (line 11) | interface IProps {
  constant DELETED_COMMENT (line 19) | const DELETED_COMMENT = 'The original comment got deleted';

FILE: packages/components/src/CommentsTitle/CommentsTitle.tsx
  constant NO_COMMENTS (line 5) | const NO_COMMENTS = 'Start the discussion';
  constant ONE_COMMENT (line 6) | const ONE_COMMENT = '1 Comment';
  constant COMMENTS (line 7) | const COMMENTS = 'Comments';
  type IProps (line 9) | interface IProps {

FILE: packages/components/src/ConfirmModal/ConfirmModal.tsx
  type Props (line 6) | interface Props {

FILE: packages/components/src/ContentStatistics/ContentStatistics.tsx
  type IProps (line 9) | interface IProps {

FILE: packages/components/src/ContentStatistics/ContentStatisticsList.tsx
  type Props (line 8) | interface Props {

FILE: packages/components/src/ContentStatistics/types.ts
  type IStatistic (line 3) | type IStatistic = {

FILE: packages/components/src/CreateComment/CreateComment.tsx
  type Props (line 10) | interface Props {

FILE: packages/components/src/CreateReply/CreateReply.tsx
  type Props (line 6) | interface Props {

FILE: packages/components/src/DisplayDate/DisplayDate.tsx
  type DateType (line 6) | type DateType = string | number | Date;
  type PublishedAction (line 8) | type PublishedAction = 'Published' | 'Started' | 'Asked';
  type IProps (line 10) | interface IProps {
  function formatDistanceShort (line 72) | function formatDistanceShort(date: Date) {

FILE: packages/components/src/DonationRequestModal/DonationRequestModal.tsx
  type IProps (line 5) | interface IProps {
  constant FALLBACK_DONATION_WIDGET (line 15) | const FALLBACK_DONATION_WIDGET = 'https://donorbox.org/embed/onearmy?a=b...
  constant REQUEST_THANKYOU (line 16) | const REQUEST_THANKYOU = 'Thank you for helping to make this possible!';

FILE: packages/components/src/DownloadButton/DownloadButton.tsx
  type IProps (line 7) | interface IProps {

FILE: packages/components/src/DownloadCounter/DownloadCounter.tsx
  type IProps (line 3) | interface IProps {

FILE: packages/components/src/DownloadStaticFile/DownloadStaticFile.tsx
  type IProps (line 9) | interface IProps {
  type IPropFileDetails (line 19) | interface IPropFileDetails {

FILE: packages/components/src/EditComment/EditComment.tsx
  type IProps (line 9) | interface IProps {

FILE: packages/components/src/ElWithBeforeIcon/ElWithBeforeIcon.tsx
  type ElWithBeforeIconProps (line 6) | interface ElWithBeforeIconProps {
  constant DEFAULT_ICON_SIZE (line 14) | const DEFAULT_ICON_SIZE = 22;

FILE: packages/components/src/FieldCheckbox/FieldCheckbox.tsx
  type FieldProps (line 5) | type FieldProps = FieldRenderProps<boolean, any>;
  type Props (line 7) | interface Props extends FieldProps {

FILE: packages/components/src/FieldInput/FieldInput.tsx
  type FieldProps (line 5) | type FieldProps = FieldRenderProps<any, any> & { children?: React.ReactN...
  type Props (line 7) | interface Props extends FieldProps {
  type InputModifiers (line 17) | type InputModifiers = {

FILE: packages/components/src/FieldMarkdown/AddImage.tsx
  type IProps (line 10) | interface IProps {

FILE: packages/components/src/FieldMarkdown/FieldMarkdown.tsx
  type FieldProps (line 30) | type FieldProps = FieldRenderProps<any, any> & { children?: React.ReactN...
  type IProps (line 32) | interface IProps extends FieldProps {

FILE: packages/components/src/FieldTextarea/FieldTextarea.tsx
  type FieldProps (line 6) | type FieldProps = FieldRenderProps<any, any> & { children?: React.ReactN...
  type Props (line 7) | interface Props extends FieldProps {
  type InputModifiers (line 17) | type InputModifiers = {

FILE: packages/components/src/FlagIcon/FlagIcon.tsx
  type IProps (line 3) | interface IProps {

FILE: packages/components/src/FollowButton/FollowButton.tsx
  type FollowButtonProps (line 7) | interface FollowButtonProps {

FILE: packages/components/src/FollowIcon/FollowIcon.tsx
  type FollowIconProps (line 6) | interface FollowIconProps {

FILE: packages/components/src/GridForm/GridForm.tsx
  type GridFormFields (line 6) | interface GridFormFields {
  type IProps (line 13) | interface IProps {

FILE: packages/components/src/Guidelines/Guidelines.tsx
  type IProps (line 3) | interface IProps {

FILE: packages/components/src/HeroBanner/HeroBanner.tsx
  type IProps (line 6) | interface IProps {

FILE: packages/components/src/Icon/Icon.tsx
  type IProps (line 42) | interface IProps extends React.ButtonHTMLAttributes<HTMLElement> {
  type IconProps (line 165) | type IconProps = IProps & VerticalAlignProps & SpaceProps;

FILE: packages/components/src/Icon/svgs.tsx
  type IProps (line 93) | interface IProps {

FILE: packages/components/src/Icon/types.ts
  type availableGlyphs (line 3) | type availableGlyphs =
  type IGlyphs (line 114) | type IGlyphs = { [k in availableGlyphs]: JSX.Element };

FILE: packages/components/src/IconCountWithTooltip/IconCountWithTooltip.tsx
  type IconCountWithTooltipProps (line 8) | interface IconCountWithTooltipProps {
  function shortFormatNumber (line 15) | function shortFormatNumber(num: number): string {

FILE: packages/components/src/ImageGallery/ImageGallery.tsx
  type IImageGalleryItem (line 11) | interface IImageGalleryItem {
  type ImageGalleryProps (line 24) | interface ImageGalleryProps {
  type IState (line 32) | interface IState {

FILE: packages/components/src/ImageGalleryThumbnail/ImageGalleryThumbnail.tsx
  type ImageGalleryThumbnailProps (line 8) | interface ImageGalleryThumbnailProps {

FILE: packages/components/src/ImageInput/ImageInputDeleteOverlay.tsx
  type IProps (line 37) | interface IProps {

FILE: packages/components/src/ImageInput/ImageInputV2.tsx
  type IProps (line 8) | interface IProps {
  constant ACCEPTED_FORMATS (line 15) | const ACCEPTED_FORMATS = '.jpeg,.jpg,.png,.gif,.svg,.webp';
  constant DEFAULT_MAX_FILE_SIZE (line 16) | const DEFAULT_MAX_FILE_SIZE = 10 * 1024 * 1024;

FILE: packages/components/src/ImageInput/ImageInputWrapper.tsx
  type ITitleProps (line 6) | interface ITitleProps {

FILE: packages/components/src/InformationTooltip/InformationTooltip.tsx
  type IProps (line 6) | interface IProps extends IconProps {

FILE: packages/components/src/InternalLink/InternalLink.tsx
  type Props (line 7) | type Props = RouterLinkProps & ThemedUILinkProps;

FILE: packages/components/src/LinkifyText/LinkifyText.tsx
  type Props (line 10) | interface Props {

FILE: packages/components/src/Loader/Loader.tsx
  type LoaderProps (line 5) | interface LoaderProps {

FILE: packages/components/src/Map/Map.client.tsx
  type IProps (line 8) | interface IProps {
  function MapEventHandler (line 20) | function MapEventHandler({ setZoom }: { setZoom: (zoom: number) => void ...

FILE: packages/components/src/MapCardList/MapCardList.tsx
  type IProps (line 9) | interface IProps {
  constant EMPTY_LIST (line 16) | const EMPTY_LIST = 'Oh nos! Nothing to show!';
  constant ITEMS_PER_RENDER (line 17) | const ITEMS_PER_RENDER = 20;

FILE: packages/components/src/MapFilterListItem/MapFilterListItem.tsx
  type IProps (line 4) | interface IProps {

FILE: packages/components/src/MapWithPin/MapPin.client.tsx
  type IProps (line 13) | interface IProps {

FILE: packages/components/src/MapWithPin/MapWithPin.client.tsx
  type Props (line 13) | interface Props {
  function MapClickHandler (line 28) | function MapClickHandler({

FILE: packages/components/src/MemberBadge/MemberBadge.tsx
  type Props (line 6) | interface Props extends ImageProps {
  constant MINIMUM_SIZE (line 13) | const MINIMUM_SIZE = 40;

FILE: packages/components/src/MemberHistory/MemberHistory.tsx
  type IProps (line 5) | interface IProps {

FILE: packages/components/src/Modal/Modal.tsx
  type Props (line 5) | interface Props {

FILE: packages/components/src/ModerationStatus/ModerationStatus.tsx
  type Props (line 12) | interface Props {

FILE: packages/components/src/NotificationItemSupabase/NotificationItemSupabase.tsx
  type IProps (line 9) | interface IProps {

FILE: packages/components/src/NotificationListSupabase/NotificationListSupabase.tsx
  type IProps (line 10) | interface IProps {

FILE: packages/components/src/NotificationsModal/NotificationsModal.tsx
  type Props (line 4) | interface Props {

FILE: packages/components/src/OsmGeocoding/OsmGeocoding.tsx
  type Props (line 10) | interface Props {
  function getGeocoding (line 50) | function getGeocoding(address = '') {

FILE: packages/components/src/OsmGeocoding/OsmGeocodingResultsList.tsx
  type Props (line 6) | interface Props {

FILE: packages/components/src/OsmGeocoding/types.tsx
  type Result (line 1) | interface Result {

FILE: packages/components/src/Pagination/Pagination.tsx
  type Props (line 6) | interface Props {

FILE: packages/components/src/PaginationIcons/PaginationIcons.tsx
  type IProps (line 3) | interface IProps {

FILE: packages/components/src/PinProfile/PinProfile.tsx
  type IProps (line 9) | interface IProps {

FILE: packages/components/src/ProfileBadgeContentLabel/ProfileBadgeContentLabel.tsx
  type Props (line 5) | interface Props {

FILE: packages/components/src/ProfileLink/ProfileLink.tsx
  type Props (line 6) | interface Props {

FILE: packages/components/src/ProfileList/ProfileList.tsx
  type IProps (line 7) | interface IProps {

FILE: packages/components/src/ProfileTagsList/ProfileTagsList.tsx
  type IProps (line 7) | interface IProps {
  constant DEFAULT_COLOR (line 16) | const DEFAULT_COLOR = '#999999';
  type TagProps (line 18) | type TagProps = ComponentProps<typeof Text> & {

FILE: packages/components/src/ResearchEditorOverview/ResearchEditorOverview.stories.tsx
  type Story (line 10) | type Story = StoryObj<typeof ResearchEditorOverview>;

FILE: packages/components/src/ResearchEditorOverview/ResearchEditorOverview.tsx
  type ResearchEditorOverviewUpdate (line 5) | type ResearchEditorOverviewUpdate = {
  type ResearchEditorOverviewProps (line 12) | interface ResearchEditorOverviewProps {

FILE: packages/components/src/ReturnPathLink/ReturnPathLink.tsx
  type IProps (line 5) | type IProps = LinkProps & RefAttributes<HTMLAnchorElement>;

FILE: packages/components/src/SearchField/SearchField.tsx
  type Props (line 5) | type Props = {

FILE: packages/components/src/Select/Select.tsx
  type IOption (line 8) | type IOption = {
  type Props (line 13) | interface Props extends ReactSelectProps {

FILE: packages/components/src/SiteFooter/SiteFooter.tsx
  type SiteFooterProps (line 7) | type SiteFooterProps = {

FILE: packages/components/src/Tag/Tag.tsx
  type ITag (line 4) | interface ITag {
  type Props (line 8) | interface Props {

FILE: packages/components/src/TagList/TagList.tsx
  type TagListProps (line 5) | interface TagListProps {}
  type IProps (line 7) | interface IProps {

FILE: packages/components/src/TextNotification/TextNotification.tsx
  type TextNotificationProps (line 9) | interface TextNotificationProps {

FILE: packages/components/src/Tooltip/Tooltip.tsx
  type TooltipProps (line 11) | type TooltipProps = {

FILE: packages/components/src/UsefulStatsButton/UsefulButtonLite.tsx
  type UsefulConfig (line 8) | interface UsefulConfig {

FILE: packages/components/src/UsefulStatsButton/UsefulStatsButton.tsx
  type IProps (line 8) | interface IProps {

FILE: packages/components/src/UserEngagementWrapper/UserEngagementWrapper.tsx
  type Props (line 5) | interface Props {

FILE: packages/components/src/UserStatistics/UserStatistics.stories.tsx
  type Story (line 10) | type Story = StoryObj<typeof UserStatistics>;

FILE: packages/components/src/UserStatistics/UserStatistics.tsx
  type UserStatisticsProps (line 13) | interface UserStatisticsProps {

FILE: packages/components/src/Username/DisplayName.tsx
  type DisplayNameProps (line 10) | interface DisplayNameProps {

FILE: packages/components/src/Username/UserBadge.tsx
  type IProps (line 6) | interface IProps {

FILE: packages/components/src/Username/Username.tsx
  type IProps (line 11) | interface IProps {

FILE: packages/components/src/VerticalList/VerticalList.client.tsx
  type IProps (line 13) | interface IProps {
  function onWheel (line 69) | function onWheel(apiObj: publicApiType, ev: React.WheelEvent): void {

FILE: packages/components/src/VideoPlayer/VideoPlayer.stories.tsx
  type Story (line 10) | type Story = StoryObj<typeof VideoPlayer>;

FILE: packages/components/src/VideoPlayer/VideoPlayer.tsx
  type Props (line 4) | interface Props {

FILE: packages/components/src/VisitorModal/VisitorModal.tsx
  type VisitorModalProps (line 37) | type VisitorModalProps = HideProp & {

FILE: packages/components/src/VisitorModal/VisitorModalHeader.tsx
  type HeaderProps (line 8) | type HeaderProps = HideProp & { data: DisplayData };

FILE: packages/components/src/VisitorModal/props.ts
  type DisplayData (line 3) | interface DisplayData {
  type HideProp (line 9) | interface HideProp {

FILE: packages/components/src/hooks/useImageLightbox.tsx
  type Props (line 5) | interface Props {

FILE: packages/components/src/hooks/usePhotoSwipeLightbox.ts
  type UsePhotoSwipeLightboxProps (line 7) | interface UsePhotoSwipeLightboxProps {

FILE: packages/components/src/providers/AuthorsContext.ts
  type AuthorsContextType (line 3) | interface AuthorsContextType {

FILE: packages/components/src/test/utils.tsx
  method Component (line 14) | Component() {

FILE: packages/components/src/types/common.ts
  type User (line 1) | type User = {

FILE: packages/components/types/emotion.d.ts
  type Theme (line 6) | interface Theme extends PlatformTheme {}

FILE: packages/cypress/cypress.config.ts
  method log (line 33) | log(message) {
  method 'seed database' (line 38) | async 'seed database'() {
  method 'clear database' (line 68) | async 'clear database'() {

FILE: packages/cypress/src/data/index.ts
  constant MOCK_DATA (line 17) | const MOCK_DATA = {

FILE: packages/cypress/src/integration/library/write.spec.ts
  type Category (line 17) | type Category = 'brainstorm' | 'exhibition' | 'product';
  type Duration (line 18) | type Duration = '<1 week' | '1-2 weeks' | '3-4 weeks';

FILE: packages/cypress/src/support/commands.ts
  type ExpectedNewNotification (line 3) | interface ExpectedNewNotification {
  type Chainable (line 12) | interface Chainable {

FILE: packages/cypress/src/support/commandsUi.ts
  type UserMenuItem (line 6) | enum UserMenuItem {
  type IInfo (line 12) | interface IInfo {
  type IMapPin (line 19) | interface IMapPin {
  type Chainable (line 26) | interface Chainable {

FILE: packages/cypress/src/utils/TestUtils.ts
  type IUserSignUpDetails (line 1) | interface IUserSignUpDetails {
  type Page (line 7) | enum Page {
  type DbCollectionName (line 23) | enum DbCollectionName {

FILE: packages/cypress/src/utils/supabaseTestsService.ts
  type SeedData (line 8) | type SeedData = {
  class SupabaseTestsService (line 12) | class SupabaseTestsService {
    method constructor (line 17) | constructor(apiUrl: string, secretKey: string, tenantId: string) {
    method deleteAccounts (line 40) | async deleteAccounts() {
    method seedDatabase (line 65) | async seedDatabase(data: SeedData) {
    method clearDatabase (line 92) | async clearDatabase(tables: string[], tenantId: string) {
    method createStorage (line 99) | async createStorage(tenantId: string) {
    method clearStorage (line 107) | async clearStorage(tenantId: string) {
    method manuallyEmptyBucket (line 115) | async manuallyEmptyBucket (bucketName: string, path = '') {
    method getUserProfileByUsername (line 144) | async getUserProfileByUsername(username: string) {
    method seedResearch (line 154) | async seedResearch(profiles: DBProfile[], tagsData) {
    method seedCategories (line 214) | async seedCategories(type: string) {
    method seedProfileTags (line 224) | async seedProfileTags() {
    method seedProfileTypes (line 235) | async seedProfileTypes() {
    method seedTags (line 246) | async seedTags() {
    method seedTenantSettings (line 255) | async seedTenantSettings() {
    method seedQuestions (line 276) | async seedQuestions(profiles) {
    method seedUsefulVotes (line 294) | async seedUsefulVotes(profiles, sourceData, sourceType) {
    method seedComment (line 309) | async seedComment(profiles, sourceData, sourceType) {
    method seedReply (line 325) | async seedReply(profiles, comments, source) {
    method seedNews (line 341) | async seedNews(profiles, tagsData) {
    method seedMap (line 359) | async seedMap(profiles) {
    method seedLibrary (line 371) | async seedLibrary(profiles, tagsData) {
    method seedBadges (line 425) | async seedBadges() {
    method seedUpgradeBadges (line 436) | async seedUpgradeBadges(profileBadges: DBProfileBadge[]) {
    method seedProfileImages (line 458) | async seedProfileImages(): Promise<{ id: string; path: string; fullPat...
    method seedAccounts (line 466) | async seedAccounts(profileBadges, profileTags, profileTypes, profileIm...
    method createAuthAndProfile (line 492) | async createAuthAndProfile(user, profileBadgeId, profilTagIds, profile...
    method createProfile (line 530) | async createProfile(

FILE: packages/themes/src/common/button.ts
  constant BASE_BUTTON (line 3) | const BASE_BUTTON = {
  type ButtonVariants (line 163) | type ButtonVariants = 'primary' | 'secondary' | 'outline' | 'disabled' |...

FILE: packages/themes/src/common/index.ts
  type Colors (line 3) | type Colors = keyof typeof baseTheme.colors;

FILE: packages/themes/src/types/index.ts
  type PlatformTheme (line 1) | interface PlatformTheme {

FILE: shared/messages.ts
  constant FRIENDLY_MESSAGES (line 8) | const FRIENDLY_MESSAGES = {

FILE: shared/mocks/auth/users.ts
  type IMockAuthUser (line 3) | interface IMockAuthUser {
  type IMockUsers (line 11) | type IMockUsers = { [key in UserRole]: IMockAuthUser };
  constant MOCK_AUTH_USERS (line 14) | const MOCK_AUTH_USERS: IMockUsers = {

FILE: shared/mocks/data/research.ts
  type ResearchSeed (line 3) | type ResearchSeed = Partial<DBResearchItem> & {

FILE: shared/mocks/data/users.ts
  type Users (line 4) | type Users = {

FILE: shared/mocks/index.ts
  constant MOCKS (line 4) | const MOCKS = {

FILE: shared/models/author.ts
  type DBAuthor (line 8) | type DBAuthor = {
  class Author (line 19) | class Author {
    method constructor (line 29) | constructor(author: Author) {
    method fromDB (line 33) | static fromDB(dbAuthor: DBAuthor, photo?: Image) {

FILE: shared/models/banner.ts
  class DBBanner (line 3) | class DBBanner implements IDBDocSB {
    method constructor (line 11) | constructor(obj: any) {
  class Banner (line 16) | class Banner implements IDoc {
    method constructor (line 23) | constructor(obj: any) {
    method fromDB (line 27) | static fromDB(banner: DBBanner) {

FILE: shared/models/category.ts
  class DBCategory (line 4) | class DBCategory implements IDBDocSB {
    method constructor (line 12) | constructor(obj: any) {
    method toDB (line 16) | static toDB(category: Category) {
  class Category (line 28) | class Category implements IDoc {
    method constructor (line 35) | constructor(obj: any) {
    method fromDB (line 39) | static fromDB(category: DBCategory) {

FILE: shared/models/comment.ts
  class DBComment (line 6) | class DBComment implements IDBDocSB {
    method constructor (line 22) | constructor(comment: DBComment) {
  class Comment (line 27) | class Comment implements IDoc {
    method constructor (line 43) | constructor(comment: Comment) {
    method fromDB (line 47) | static fromDB(obj: DBComment, replies?: Reply[]) {
  type Reply (line 65) | type Reply = Omit<Comment, 'replies'>;

FILE: shared/models/common.ts
  type ISODateString (line 4) | type ISODateString = string;
  type FetchState (line 6) | type FetchState = 'idle' | 'fetching' | 'completed';
  type ILatLng (line 8) | interface ILatLng {
  type Collaborator (line 13) | type Collaborator = {
  type ContentType (line 19) | type ContentType = 'questions' | 'projects' | 'research' | 'news';
  type UsefulContentType (line 21) | type UsefulContentType = 'questions' | 'projects' | 'research' | 'news' ...
  type ContentFormType (line 23) | type ContentFormType = 'questions' | 'projects' | 'research' | 'research...
  type DiscussionContentType (line 31) | type DiscussionContentType = (typeof DiscussionContentTypes)[number];
  type SubscribableContentTypes (line 33) | type SubscribableContentTypes =

FILE: shared/models/content.ts
  type IDBContentDoc (line 6) | interface IDBContentDoc extends IDBDocSB {
  type IContentDoc (line 23) | interface IContentDoc extends IDoc {

FILE: shared/models/db.ts
  constant DB_ENDPOINTS (line 45) | const DB_ENDPOINTS = generateDBEndpoints();
  type DBEndpoint (line 47) | type DBEndpoint = keyof typeof DB_ENDPOINTS;

FILE: shared/models/document.ts
  type IDBDocSB (line 2) | interface IDBDocSB {
  type IDoc (line 8) | interface IDoc {
  type IDBDownloadable (line 14) | interface IDBDownloadable {
  type IDownloadable (line 20) | interface IDownloadable {

FILE: shared/models/filesForm.ts
  type IFilesForm (line 3) | interface IFilesForm {

FILE: shared/models/library.ts
  type DifficultyLevel (line 13) | type DifficultyLevel = 'easy' | 'medium' | 'hard' | 'very-hard';
  class DBProject (line 21) | class DBProject implements IDBContentDoc, IDBDownloadable, IDBModeration {
    method constructor (line 53) | constructor(obj: Omit<DBProject, 'id'>) {
    method toFormData (line 57) | static toFormData(obj: DBProject, images: Image[]) {
  class Project (line 82) | class Project implements IContentDoc, IDownloadable, IModeration {
    method constructor (line 112) | constructor(obj: Project) {
    method fromDB (line 116) | static fromDB(obj: DBProject, tags: Tag[], images: Image[] = []) {
  class DBProjectStep (line 153) | class DBProjectStep {
    method constructor (line 162) | constructor(obj: Omit<DBProjectStep, 'id'>) {
    method toFormData (line 166) | static toFormData(obj: DBProjectStep, images: Image[]) {
  class ProjectStep (line 184) | class ProjectStep {
    method constructor (line 193) | constructor(obj: ProjectStep) {
    method fromDB (line 197) | static fromDB(obj: DBProjectStep, images?: Image[]) {
  type ProjectFormData (line 216) | interface ProjectFormData extends IFilesForm {
  type ProjectStepFormData (line 227) | type ProjectStepFormData = {
  type ProjectDTO (line 235) | type ProjectDTO = {
  type ProjectStepDTO (line 249) | type ProjectStepDTO = {

FILE: shared/models/maps.ts
  type IMapGrouping (line 7) | interface IMapGrouping {
  type IBoundingBox (line 17) | interface IBoundingBox {
  type IPinGrouping (line 22) | enum IPinGrouping {
  type MapFilters (line 27) | type MapFilters = {
  type DBMapSettings (line 34) | type DBMapSettings = {
  type DefaultMapFilters (line 39) | type DefaultMapFilters = {
  type FilterResponse (line 43) | type FilterResponse = {

FILE: shared/models/media.ts
  class DBMedia (line 1) | class DBMedia {
    method constructor (line 6) | constructor(obj: DBMedia) {
    method fromPublicMedia (line 12) | static fromPublicMedia(obj: MediaWithPublicUrl) {
  type IMedia (line 21) | interface IMedia {
  type IMediaFile (line 26) | interface IMediaFile {
  class Image (line 32) | class Image implements IMedia {
    method constructor (line 36) | constructor(obj: Image) {
  class MediaFile (line 41) | class MediaFile implements IMediaFile {
    method constructor (line 47) | constructor(obj: MediaFile) {
  type MediaWithPublicUrl (line 52) | type MediaWithPublicUrl = DBMedia & Image;

FILE: shared/models/messages.ts
  type SendMessage (line 1) | type SendMessage = {

FILE: shared/models/moderation.ts
  type IModeration (line 1) | interface IModeration {
  type IDBModeration (line 6) | interface IDBModeration {
  type Moderation (line 11) | type Moderation = 'awaiting-moderation' | 'improvements-needed' | 'rejec...

FILE: shared/models/news.ts
  class DBNews (line 14) | class DBNews implements IDBContentDoc {
    method toFormData (line 38) | static toFormData(news: DBNews, publicHeroImage: Image | null) {
  type EditNews (line 64) | type EditNews = Omit<News, 'heroImage'> & {
  class News (line 68) | class News implements IContentDoc {
    method constructor (line 92) | constructor(news: Partial<News>) {
    method fromDB (line 96) | static fromDB(news: DBNews, tags: Tag[], heroImage?: Image | null) {
  type NewsFormData (line 132) | type NewsFormData = {
  type NewsDTO (line 142) | type NewsDTO = {

FILE: shared/models/notifications.ts
  type EmailNotificationFrequency (line 4) | enum EmailNotificationFrequency {
  type NotificationType (line 28) | type NotificationType = (typeof NotificationTypes)[number];
  type UserNotificationItem (line 30) | type UserNotificationItem = {
  type INotification (line 35) | interface INotification {
  type INotificationSettings (line 53) | type INotificationSettings = {
  type IPendingEmails (line 60) | interface IPendingEmails {

FILE: shared/models/notificationsPreferences.ts
  class NotificationsPreferences (line 1) | class NotificationsPreferences {
  class DBNotificationsPreferencesFields (line 10) | class DBNotificationsPreferencesFields {
  class DBNotificationsPreferences (line 17) | class DBNotificationsPreferences extends DBNotificationsPreferencesFields {
  type DBPreferencesWithProfileContact (line 22) | interface DBPreferencesWithProfileContact {
  type NotificationsPreferenceTypes (line 27) | type NotificationsPreferenceTypes = 'comments' | 'replies' | 'research_u...
  type NotificationsPreferencesFormData (line 29) | interface NotificationsPreferencesFormData {
  type NotificationsPreferencesViaEmailFormData (line 36) | interface NotificationsPreferencesViaEmailFormData {

FILE: shared/models/patreon.ts
  type IPatreonUserAttributes (line 1) | interface IPatreonUserAttributes {
  type IPatreonMembershipAttributes (line 13) | interface IPatreonMembershipAttributes {
  type IPatreonTierAttributes (line 28) | interface IPatreonTierAttributes {
  type IPatreonTier (line 41) | interface IPatreonTier {
  type IPatreonMembership (line 46) | interface IPatreonMembership {
  type IPatreonUser (line 52) | interface IPatreonUser {

FILE: shared/models/patreonSettings.ts
  type PatreonTier (line 1) | type PatreonTier = {
  type PatreonSettings (line 7) | type PatreonSettings = {

FILE: shared/models/profile.ts
  class DBProfile (line 18) | class DBProfile {
    method constructor (line 44) | constructor(obj: DBProfile) {
  class Profile (line 49) | class Profile {
    method constructor (line 73) | constructor(obj: Profile) {
    method fromDB (line 77) | static fromDB(
  type NotificationActionType (line 122) | type NotificationActionType = 'newContent' | 'newComment' | 'newReply';
  type NotificationContentType (line 124) | type NotificationContentType = (typeof NotificationContentTypes)[number];
  type BasicAuthorDetails (line 125) | type BasicAuthorDetails = Pick<Profile, 'id' | 'username' | 'photo'>;
  type ProfileListItem (line 126) | type ProfileListItem = Pick<
  type NotificationContent (line 131) | type NotificationContent = News | Comment | Question | ResearchUpdate;
  type NotificationSourceContentType (line 132) | type NotificationSourceContentType = SubscribableContentTypes;
  class DBNotification (line 134) | class DBNotification implements IDBDocSB {
    method constructor (line 151) | constructor(obj: Partial<DBNotification>) {
  class Notification (line 156) | class Notification implements IDoc {
    method constructor (line 173) | constructor(obj: Notification) {
    method fromDB (line 177) | static fromDB(dbNotification: DBNotification) {
  class NotificationDisplay (line 198) | class NotificationDisplay {
    method constructor (line 218) | constructor(obj: NotificationDisplay) {
    method setEmailBody (line 222) | static setEmailBody(notification: Notification): string {
    method setEmailButtonLabel (line 233) | static setEmailButtonLabel(notification: Notification) {
    method setEmailPreview (line 247) | static setEmailPreview(notification: Notification) {
    method setEmailSubject (line 270) | static setEmailSubject(notification: Notification) {
    method setBody (line 287) | static setBody(notification: Notification): string | undefined {
    method setDate (line 301) | static setDate(notification: Notification) {
    method setTitle (line 307) | static setTitle(notification: Notification) {
    method setSidebarIcon (line 324) | static setSidebarIcon(contentType: NotificationContentType): string {
    method setSidebarImage (line 338) | static setSidebarImage(author: BasicAuthorDetails | undefined): string {
    method setLink (line 342) | static setLink(notification: Notification) {
    method fromNotification (line 346) | static fromNotification(notification: Notification): NotificationDispl...
  type ProfileFormData (line 370) | type ProfileFormData = {
  type ProfileDTO (line 386) | type ProfileDTO = {
  class DBMapPin (line 401) | class DBMapPin implements IDBModeration {
  class MapPin (line 416) | class MapPin implements IModeration {
    method constructor (line 430) | constructor(obj: MapPin) {
  type MapPinFormData (line 435) | type MapPinFormData = {
  type DBAuthorVotes (line 445) | interface DBAuthorVotes {
  class AuthorVotes (line 450) | class AuthorVotes {
    method constructor (line 454) | constructor(obj: AuthorVotes) {
    method fromDB (line 458) | static fromDB(dbVotes: DBAuthorVotes) {
  type DBPinProfile (line 466) | type DBPinProfile = Pick<
  type PinProfile (line 482) | type PinProfile = Pick<
  type UpsertPin (line 498) | type UpsertPin = Omit<DBMapPin, 'id' | 'profile' | 'moderation' | 'moder...
  type SubscribedUser (line 500) | type SubscribedUser = {

FILE: shared/models/profileBadge.ts
  type PremiumTier (line 1) | enum PremiumTier {
  class DBProfileBadge (line 5) | class DBProfileBadge {
    method constructor (line 13) | constructor(obj: Partial<DBProfileBadge>) {
  class DBProfileBadgeJoin (line 18) | class DBProfileBadgeJoin {
  class ProfileBadge (line 22) | class ProfileBadge {
    method constructor (line 30) | constructor(obj: Partial<ProfileBadge>) {
    method fromDBJoin (line 34) | static fromDBJoin(value: DBProfileBadgeJoin): ProfileBadge {
    method fromDB (line 46) | static fromDB(value: DBProfileBadge) {

FILE: shared/models/profileTag.ts
  type ProfileCategory (line 1) | type ProfileCategory = 'member' | 'space';
  class DBProfileTag (line 3) | class DBProfileTag {
    method constructor (line 9) | constructor(obj: Partial<DBProfileTag>) {
  class DBProfileTagJoin (line 14) | class DBProfileTagJoin {
  class ProfileTag (line 18) | class ProfileTag {
    method constructor (line 24) | constructor(obj: Partial<ProfileTag>) {
    method fromDBJoin (line 28) | static fromDBJoin(value: DBProfileTagJoin) {
    method fromDB (line 38) | static fromDB(tag: DBProfileTag) {

FILE: shared/models/profileType.ts
  class DBProfileType (line 1) | class DBProfileType {
    method constructor (line 12) | constructor(obj: Partial<DBProfileType>) {
  class ProfileType (line 17) | class ProfileType {
    method constructor (line 28) | constructor(obj: Partial<ProfileType>) {
    method fromDB (line 32) | static fromDB(value: DBProfileType) {

FILE: shared/models/question.ts
  class DBQuestion (line 10) | class DBQuestion implements IDBContentDoc {
    method constructor (line 33) | constructor(question: DBQuestion) {
    method toFormData (line 37) | static toFormData(obj: DBQuestion, images: Image[]) {
  class Question (line 58) | class Question implements IContentDoc {
    method constructor (line 80) | constructor(question: Question) {
    method fromDB (line 84) | static fromDB(obj: DBQuestion, tags: Tag[], images?: Image[]) {
  type QuestionFormData (line 109) | type QuestionFormData = {
  type QuestionDTO (line 118) | type QuestionDTO = {

FILE: shared/models/research.ts
  type ResearchStatus (line 12) | type ResearchStatus = 'in-progress' | 'complete';
  class DBResearchItem (line 18) | class DBResearchItem implements IDBContentDoc {
    method constructor (line 45) | constructor(obj: Omit<DBResearchItem, 'id'>) {
    method toFormData (line 49) | static toFormData(obj: DBResearchItem, publicImage: Image | null) {
  class ResearchItem (line 63) | class ResearchItem implements IContentDoc {
    method constructor (line 90) | constructor(obj: ResearchItem) {
    method fromDB (line 94) | static fromDB(
  class DBResearchUpdate (line 158) | class DBResearchUpdate implements IDBDocSB, IDBDownloadable {
    method constructor (line 177) | constructor(obj: Omit<DBResearchUpdate, 'id'>) {
    method toFormData (line 181) | static toFormData(obj: DBResearchUpdate, images: Image[]) {
  class ResearchUpdate (line 200) | class ResearchUpdate implements IDoc, IDownloadable {
    method constructor (line 219) | constructor(obj: ResearchUpdate) {
    method fromDB (line 223) | static fromDB(obj: DBResearchUpdate, images?: Image[]) {
  function calculateUpdateCommentCount (line 246) | function calculateUpdateCommentCount(research: DBResearchItem): number {
  type ResearchFormData (line 256) | type ResearchFormData = {
  type ResearchUpdateFormData (line 265) | interface ResearchUpdateFormData extends IFilesForm {
  type ResearchDTO (line 272) | type ResearchDTO = {
  type ResearchUpdateDTO (line 282) | type ResearchUpdateDTO = {

FILE: shared/models/selectValue.ts
  type SelectValue (line 1) | type SelectValue = { label: string; value: string };

FILE: shared/models/subscriber.ts
  class DBSubscriber (line 3) | class DBSubscriber {

FILE: shared/models/tag.ts
  class DBTag (line 3) | class DBTag implements IDBDocSB {
    method constructor (line 10) | constructor(obj: any) {
    method toDB (line 14) | static toDB(tag: Tag) {
  class Tag (line 25) | class Tag implements IDoc {
    method constructor (line 32) | constructor(obj: any) {
    method fromDB (line 36) | static fromDB(tag: DBTag) {

FILE: shared/models/tags.ts
  type ISelectedTags (line 1) | interface ISelectedTags {

FILE: shared/models/tenantSettings.ts
  class TenantSettings (line 3) | class TenantSettings {
    method constructor (line 26) | constructor(obj: Partial<TenantSettings>) {
  type PWAIcons (line 31) | interface PWAIcons {

FILE: shared/models/upgradeBadge.ts
  class DBUpgradeBadge (line 4) | class DBUpgradeBadge {
    method constructor (line 13) | constructor(obj: Partial<DBUpgradeBadge>) {
  class UpgradeBadge (line 18) | class UpgradeBadge {
    method constructor (line 26) | constructor(obj: Partial<UpgradeBadge>) {
    method fromDB (line 30) | static fromDB(value: DBUpgradeBadge) {

FILE: shared/models/user.ts
  type UserRole (line 3) | enum UserRole {
  type WorkspaceType (line 12) | type WorkspaceType = 'shredder' | 'sheetpress' | 'extrusion' | 'injectio...
  type IWorkspaceType (line 14) | interface IWorkspaceType {
  type UserMention (line 21) | type UserMention = {
  type UserVisitorPreferencePolicy (line 28) | type UserVisitorPreferencePolicy = (typeof userVisitorPreferencePolicies...
  type UserVisitorPreference (line 30) | type UserVisitorPreference = {
  type IUserBadges (line 35) | interface IUserBadges {
  type IImpactDataField (line 40) | interface IImpactDataField {
  type IUserImpact (line 46) | interface IUserImpact {
  type IImpactYear (line 50) | type IImpactYear = 2019 | 2020 | 2021 | 2022 | 2023 | 2024 | 2025;
  type INotificationUpdate (line 52) | type INotificationUpdate = {

FILE: shared/models/userCreatedDocs.ts
  type UserCreatedDocs (line 5) | interface UserCreatedDocs {

FILE: shared/models/userEmailData.ts
  type UserEmailData (line 1) | type UserEmailData = {

FILE: shared/models/voteUseful.ts
  type IVotedUseful (line 1) | interface IVotedUseful {
  type ISharedFeatures (line 5) | interface ISharedFeatures extends IVotedUseful {
  type IVotedUsefulUpdate (line 10) | type IVotedUsefulUpdate = {

FILE: shared/models/webmanifest.ts
  type WebAppManifest (line 1) | interface WebAppManifest {
  type ManifestIcon (line 34) | interface ManifestIcon {

FILE: src/.server/models/messageSettings.ts
  type MessageSettings (line 1) | type MessageSettings = {

FILE: src/.server/resend.ts
  type SendEmailArgs (line 4) | type SendEmailArgs = {
  function sendEmail (line 11) | async function sendEmail({ from, to, subject, emailTemplate }: SendEmail...
  type SendEmailsArgs (line 29) | type SendEmailsArgs = {
  function sendBatchEmails (line 35) | async function sendBatchEmails({ from, subject, emails }: SendEmailsArgs) {

FILE: src/.server/templates/Layout.tsx
  type EmailType (line 14) | type EmailType = 'service' | 'moderation' | 'notification';
  type LayoutArgs (line 16) | type LayoutArgs = {

FILE: src/.server/templates/ReceiverMessage.tsx
  type ReceiverMessageArgs (line 4) | type ReceiverMessageArgs = {
  function ReceiverMessage (line 13) | function ReceiverMessage({

FILE: src/.server/templates/components/box-text.tsx
  type IProps (line 12) | interface IProps {

FILE: src/.server/templates/components/button.tsx
  type IProps (line 4) | interface IProps {

FILE: src/.server/templates/components/footer.tsx
  type IProps (line 4) | interface IProps {

FILE: src/.server/templates/components/header.tsx
  type IProps (line 4) | interface IProps {

FILE: src/.server/templates/components/heading.tsx
  type IProps (line 4) | interface IProps {

FILE: src/.server/templates/instant-notification-email.tsx
  type IProps (line 15) | interface IProps {

FILE: src/common/Analytics/index.tsx
  type EventAction (line 6) | type EventAction =
  type EventCategory (line 15) | type EventCategory = 'profiles' | SubscribableContentTypes;
  type TrackEventOptions (line 17) | type TrackEventOptions = Omit<UaEventOptions, 'action' | 'category'> & {

FILE: src/common/AuthWrapper.tsx
  type IProps (line 10) | interface IProps {

FILE: src/common/DonationRequestModalContainer.tsx
  type DonationRequestModalContainerProps (line 5) | type DonationRequestModalContainerProps = {
  type DonationSettings (line 12) | type DonationSettings = {

FILE: src/common/DownloadWrapper.tsx
  type IProps (line 10) | interface IProps {

FILE: src/common/Form/ErrorsContainer.tsx
  type IProps (line 7) | interface IProps {

FILE: src/common/Form/FieldContainer.ts
  type IFormElement (line 4) | interface IFormElement {

FILE: src/common/Form/FileInput/FileDisplay.tsx
  type FileDisplayProps (line 7) | type FileDisplayProps = {

FILE: src/common/Form/FileInput/FileInput.tsx
  type IProps (line 11) | interface IProps {
  type FileWithId (line 17) | type FileWithId = File & { id: string };

FILE: src/common/Form/FormWrapper.tsx
  type IProps (line 9) | interface IProps {
  constant DRAFT_LABEL (line 27) | const DRAFT_LABEL = 'Save as draft';

FILE: src/common/Form/Select.field.tsx
  type ISelectOption (line 9) | interface ISelectOption {
  type ISelectFieldProps (line 13) | interface ISelectFieldProps extends FieldProps {

FILE: src/common/Form/UnsavedChangesDialog.tsx
  constant CONFIRM_DIALOG_MSG (line 4) | const CONFIRM_DIALOG_MSG = 'You have unsaved changes. Are you sure you w...
  type IProps (line 10) | type IProps = {

FILE: src/common/Form/types.ts
  type FieldProps (line 7) | type FieldProps = FieldRenderProps<any, any> & {
  type EmptyObj (line 14) | type EmptyObj = Record<never, never>;
  type IStepErrorsList (line 16) | type IStepErrorsList = (INestedErrorList | EmptyObj)[];
  type INestedErrorList (line 18) | interface INestedErrorList {
  type ITopLevelErrorsList (line 22) | interface ITopLevelErrorsList {
  type Label (line 26) | interface Label {
  type ILabels (line 33) | interface ILabels {
  type IErrorsListSet (line 37) | interface IErrorsListSet {
  type MainFormAction (line 44) | type MainFormAction = 'create' | 'edit';

FILE: src/common/HideDiscussionContainer.tsx
  type IProps (line 5) | interface IProps {

FILE: src/common/Highlighter.tsx
  type IProps (line 12) | interface IProps {

FILE: src/common/PageHeader.tsx
  type PageHeaderProps (line 3) | type PageHeaderProps = {

FILE: src/common/PremiumTierWrapper.tsx
  type IProps (line 7) | interface IProps {

FILE: src/common/Tags/ProfileTagsSelect.tsx
  type IProps (line 8) | interface IProps extends Partial<FieldRenderProps<any, any>> {

FILE: src/common/Tags/TagsSelect.tsx
  type IProps (line 9) | interface IProps extends Partial<FieldRenderProps<any, any>> {

FILE: src/common/Toast/CustomToast.tsx
  type CustomToastProps (line 9) | interface CustomToastProps {

FILE: src/common/Toast/useToast.tsx
  type ToastOptions (line 4) | interface ToastOptions
  type PromiseOptions (line 9) | interface PromiseOptions<T>

FILE: src/common/UserAction.tsx
  type IProps (line 4) | interface IProps {

FILE: src/config/config.ts
  constant SITE (line 61) | const SITE = siteVariant;
  constant SENTRY_CONFIG (line 62) | const SENTRY_CONFIG: ISentryConfig = {

FILE: src/config/constants.ts
  type ConfigurationOption (line 13) | type ConfigurationOption = (typeof _supportedConfigurationOptions)[number];

FILE: src/config/imageTransforms.ts
  constant IMAGE_SIZES (line 3) | const IMAGE_SIZES: { [key: string]: TransformOptions } = {

FILE: src/config/types.ts
  type ISentryConfig (line 1) | interface ISentryConfig {
  type siteVariants (line 6) | type siteVariants = 'dev_site' | 'test-ci' | 'staging' | 'production' | ...

FILE: src/constants.ts
  constant MAX_COMMENT_LENGTH (line 1) | const MAX_COMMENT_LENGTH = 3000;
  constant DISCORD_INVITE_URL (line 2) | const DISCORD_INVITE_URL = 'https://discord.gg/gJ7Yyk4';

FILE: src/entry.client.tsx
  method reset (line 17) | reset() {

FILE: src/entry.server.tsx
  constant ABORT_DELAY (line 11) | const ABORT_DELAY = 5_000;
  function handleRequest (line 15) | function handleRequest(
  function handleBotRequest (line 26) | async function handleBotRequest(
  function handleBrowserRequest (line 62) | async function handleBrowserRequest(

FILE: src/factories/commentFactory.server.ts
  class CommentFactory (line 5) | class CommentFactory {
    method constructor (line 6) | constructor(private imageService: ImageServiceServer) {}
    method fromDBWithAuthor (line 8) | async fromDBWithAuthor(dbComment: DBComment, replies?: Reply[]): Promi...
    method fromDBCommentsToThreads (line 27) | async fromDBCommentsToThreads(dbComments: DBComment[]): Promise<Commen...
    method groupCommentsByParentId (line 53) | private groupCommentsByParentId(dbComments: DBComment[]): Record<numbe...
    method createAuthor (line 64) | async createAuthor(dbAuthor: DBAuthor): Promise<Author> {

FILE: src/factories/mapPinFactory.server.ts
  class MapPinFactory (line 6) | class MapPinFactory {
    method constructor (line 8) | constructor(client: SupabaseClient) {
    method fromDBWithProfile (line 12) | fromDBWithProfile(pin: DBMapPin): MapPin {
    method getProfilePin (line 31) | private getProfilePin(profile: DBPinProfile): PinProfile {

FILE: src/factories/profileFactory.server.ts
  class ProfileFactory (line 6) | class ProfileFactory {
    method constructor (line 8) | constructor(client: SupabaseClient) {
    method fromDB (line 12) | fromDB(dbProfile: DBProfile, authorVotes?: AuthorVotes[]): Profile {

FILE: src/modules/index.ts
  type MODULE (line 1) | enum MODULE {

FILE: src/pages/Academy/ExternalEmbed/ExternalEmbed.tsx
  type IProps (line 13) | interface IProps {

FILE: src/pages/Library/Content/Common/DeleteProjectButton.tsx
  type DeleteProjectButtonProps (line 9) | type DeleteProjectButtonProps = {

FILE: src/pages/Library/Content/Common/FormSettings.tsx
  constant TIME_OPTIONS (line 7) | const TIME_OPTIONS = [
  constant DIFFICULTY_OPTIONS (line 17) | const DIFFICULTY_OPTIONS = [

FILE: src/pages/Library/Content/Common/LibraryCategoryGuidance.tsx
  type IProps (line 5) | interface IProps {

FILE: src/pages/Library/Content/Common/LibraryForm.tsx
  type LibraryFormProps (line 24) | interface LibraryFormProps {

FILE: src/pages/Library/Content/Common/LibraryStep.field.tsx
  type IProps (line 23) | interface IProps {

FILE: src/pages/Library/Content/Common/LibraryStepsContainer.field.tsx
  type IPropsAnimation (line 10) | interface IPropsAnimation {

FILE: src/pages/Library/Content/List/LibraryListHeader.tsx
  type IProps (line 28) | interface IProps {
  constant DEFAULT_SORT (line 35) | const DEFAULT_SORT: LibrarySortOption = 'MostUsefulLastWeek';

FILE: src/pages/Library/Content/List/LibrarySortOptions.ts
  type LibrarySortOption (line 1) | type LibrarySortOption =

FILE: src/pages/Library/Content/List/ProjectCard.tsx
  type ProjectCardProps (line 9) | type ProjectCardProps = {

FILE: src/pages/Library/Content/Page/LibraryDescription.tsx
  type IProps (line 23) | interface IProps {

FILE: src/pages/Library/Content/Page/LibraryStep.tsx
  type IProps (line 7) | interface IProps {

FILE: src/pages/Library/Content/Page/ProjectPage.tsx
  type ProjectPageProps (line 24) | interface ProjectPageProps {

FILE: src/pages/Library/Content/utils/downloadCooldown.ts
  type localStorageExpiry (line 1) | interface localStorageExpiry {

FILE: src/pages/Library/constants.ts
  constant STEP_DESCRIPTION_MIN_LENGTH (line 1) | const STEP_DESCRIPTION_MIN_LENGTH = 100;
  constant STEP_DESCRIPTION_MAX_LENGTH (line 2) | const STEP_DESCRIPTION_MAX_LENGTH = 1000;
  constant LIBRARY_DESCRIPTION_MAX_LENGTH (line 3) | const LIBRARY_DESCRIPTION_MAX_LENGTH = 1000;
  constant LIBRARY_MIN_REQUIRED_STEPS (line 4) | const LIBRARY_MIN_REQUIRED_STEPS = 3;
  constant LIBRARY_TITLE_MIN_LENGTH (line 5) | const LIBRARY_TITLE_MIN_LENGTH = 5;
  constant LIBRARY_TITLE_MAX_LENGTH (line 6) | const LIBRARY_TITLE_MAX_LENGTH = 50;
  constant ITEMS_PER_PAGE (line 7) | const ITEMS_PER_PAGE = 12;

FILE: src/pages/Library/library.service.ts
  type LibrarySearchParams (line 6) | enum LibrarySearchParams {

FILE: src/pages/Maps/Content/MapView/ButtonZoomIn.client.tsx
  type IProps (line 8) | interface IProps {
  constant ZOOM_IN_TOOLTIP (line 13) | const ZOOM_IN_TOOLTIP = 'Zoom in to your location';
  constant DENIED_TOOLTIP (line 14) | const DENIED_TOOLTIP = 'Request to get your location already denied';

FILE: src/pages/Maps/Content/MapView/Cluster.client.tsx
  type IProps (line 8) | interface IProps {

FILE: src/pages/Maps/Content/MapView/MapView.tsx
  function MapEventsHandler (line 13) | function MapEventsHandler({

FILE: src/pages/Maps/Content/MapView/MapWithListHeader.tsx
  type IProps (line 9) | interface IProps {

FILE: src/pages/Maps/Content/MapView/Popup.client.tsx
  type IProps (line 10) | interface IProps {

FILE: src/pages/Maps/MapFilterList.tsx
  type MapFilterListProps (line 7) | type MapFilterListProps = {

FILE: src/pages/Maps/map.service.ts
  type IMapPinService (line 5) | interface IMapPinService {

FILE: src/pages/News/Content/Common/FormFields/NewsBodyField.tsx
  type IProps (line 8) | interface IProps {

FILE: src/pages/News/Content/Common/FormFields/NewsImageField.tsx
  type IProps (line 17) | interface IProps {

FILE: src/pages/News/Content/Common/NewsForm.tsx
  type IProps (line 22) | interface IProps {

FILE: src/pages/News/NewsListHeader.tsx
  type IProps (line 9) | interface IProps {

FILE: src/pages/News/NewsListItem.tsx
  type IProps (line 15) | interface IProps {

FILE: src/pages/News/NewsPage.tsx
  type IProps (line 22) | interface IProps {

FILE: src/pages/News/NewsSortOptions.ts
  type NewsSortOption (line 1) | type NewsSortOption =

FILE: src/pages/News/constants.ts
  constant NEWS_MIN_TITLE_LENGTH (line 1) | const NEWS_MIN_TITLE_LENGTH = 5;
  constant NEWS_MAX_TITLE_LENGTH (line 2) | const NEWS_MAX_TITLE_LENGTH = 60;
  constant NEWS_MAX_DESCRIPTION_LENGTH (line 3) | const NEWS_MAX_DESCRIPTION_LENGTH = 10000;
  constant ITEMS_PER_PAGE (line 4) | const ITEMS_PER_PAGE = 10;

FILE: src/pages/News/newsContent.service.ts
  type NewsSearchParams (line 5) | enum NewsSearchParams {

FILE: src/pages/PageList.tsx
  type IPageNavigation (line 3) | interface IPageNavigation {
  constant COMMUNITY_PAGES (line 48) | const COMMUNITY_PAGES: IPageNavigation[] = [

FILE: src/pages/Question/Content/Common/FormFields/QuestionImages.field.tsx
  type IProps (line 12) | interface IProps {

FILE: src/pages/Question/Content/Common/QuestionForm.tsx
  type IProps (line 20) | interface IProps {

FILE: src/pages/Question/QuestionListHeader.tsx
  type IProps (line 27) | interface IProps {
  constant DEFAULT_SORT (line 34) | const DEFAULT_SORT: QuestionSortOption = 'Newest';

FILE: src/pages/Question/QuestionListItem.tsx
  type IProps (line 13) | interface IProps {

FILE: src/pages/Question/QuestionPage.tsx
  type IProps (line 29) | interface IProps {

FILE: src/pages/Question/QuestionSortOptions.ts
  type QuestionSortOption (line 1) | type QuestionSortOption =

FILE: src/pages/Question/constants.ts
  constant QUESTION_MIN_TITLE_LENGTH (line 1) | const QUESTION_MIN_TITLE_LENGTH = 10;
  constant QUESTION_MAX_TITLE_LENGTH (line 2) | const QUESTION_MAX_TITLE_LENGTH = 60;
  constant QUESTION_MAX_DESCRIPTION_LENGTH (line 3) | const QUESTION_MAX_DESCRIPTION_LENGTH = 1000;
  constant QUESTION_MAX_IMAGES (line 4) | const QUESTION_MAX_IMAGES = 4;
  constant ITEMS_PER_PAGE (line 5) | const ITEMS_PER_PAGE = 20;

FILE: src/pages/Question/question.service.ts
  type QuestionSearchParams (line 5) | enum QuestionSearchParams {

FILE: src/pages/Research/Content/Common/DeleteResearchButton.tsx
  type DeleteResearchButtonProps (line 12) | type DeleteResearchButtonProps = {

FILE: src/pages/Research/Content/Common/ResearchForm.tsx
  type IProps (line 26) | interface IProps {

FILE: src/pages/Research/Content/Common/ResearchUpdateForm.tsx
  type IProps (line 17) | interface IProps {

FILE: src/pages/Research/Content/CreateResearch/Form/ResearchImagesField.tsx
  type IProps (line 11) | interface IProps {

FILE: src/pages/Research/Content/ResearchArticlePage.tsx
  type IProps (line 17) | interface IProps {

FILE: src/pages/Research/Content/ResearchDescription.tsx
  type IProps (line 17) | interface IProps {

FILE: src/pages/Research/Content/ResearchEngagementSection.tsx
  type ResearchEngagementSectionProps (line 18) | type ResearchEngagementSectionProps = {

FILE: src/pages/Research/Content/ResearchFooter.tsx
  type ResearchFooterProps (line 13) | type ResearchFooterProps = {

FILE: src/pages/Research/Content/ResearchLinkToUpdate.tsx
  type IProps (line 6) | interface IProps {
  constant COPY_TO_CLIPBOARD (line 11) | const COPY_TO_CLIPBOARD = 'Share this update';
  constant SUCCESS (line 12) | const SUCCESS = 'Link copied to clipboard!';

FILE: src/pages/Research/Content/ResearchListHeader.tsx
  type IProps (line 30) | interface IProps {
  constant DEFAULT_SORT (line 43) | const DEFAULT_SORT: ResearchSortOption = 'LatestUpdated';

FILE: src/pages/Research/Content/ResearchListItem.tsx
  type IProps (line 18) | interface IProps {

FILE: src/pages/Research/Content/ResearchSearchParams.ts
  type ResearchSearchParams (line 1) | enum ResearchSearchParams {

FILE: src/pages/Research/Content/ResearchUpdate.tsx
  type IProps (line 20) | interface IProps {

FILE: src/pages/Research/ResearchSortOptions.ts
  type ResearchSortOption (line 1) | type ResearchSortOption =

FILE: src/pages/Research/constants.ts
  constant RESEARCH_TITLE_MAX_LENGTH (line 1) | const RESEARCH_TITLE_MAX_LENGTH = 60;
  constant RESEARCH_TITLE_MIN_LENGTH (line 2) | const RESEARCH_TITLE_MIN_LENGTH = 5;
  constant RESEARCH_MAX_LENGTH (line 3) | const RESEARCH_MAX_LENGTH = 3000;
  constant ITEMS_PER_PAGE (line 4) | const ITEMS_PER_PAGE = 10;

FILE: src/pages/User/constants.ts
  constant MESSAGE_MIN_CHARACTERS (line 1) | const MESSAGE_MIN_CHARACTERS = 20;
  constant MESSAGE_MAX_CHARACTERS (line 2) | const MESSAGE_MAX_CHARACTERS = 500;

FILE: src/pages/User/contact/UserContactForm.tsx
  type Props (line 12) | interface Props {

FILE: src/pages/User/contact/UserContactFormAvailable.tsx
  type IProps (line 3) | interface IProps {

FILE: src/pages/User/contact/UserContactFormNotLoggedIn.tsx
  type Props (line 11) | interface Props {

FILE: src/pages/User/contact/UserContactNotLoggedIn.tsx
  type Props (line 4) | interface Props {

FILE: src/pages/User/content/ProfileContact.tsx
  type IProps (line 13) | interface IProps {

FILE: src/pages/User/content/ProfileDetails.tsx
  type IProps (line 11) | interface IProps {

FILE: src/pages/User/content/ProfileHeader.tsx
  type IProps (line 6) | interface IProps {

FILE: src/pages/User/content/ProfileImage.tsx
  type IProps (line 6) | interface IProps {

FILE: src/pages/User/content/ProfilePage.tsx
  type IProps (line 11) | interface IProps {

FILE: src/pages/User/content/UserCreatedDocuments.tsx
  type IProps (line 5) | interface IProps {

FILE: src/pages/User/content/UserCreatedDocumentsItem.tsx
  type IProps (line 6) | interface IProps {

FILE: src/pages/User/content/UserProfile.tsx
  type IProps (line 19) | interface IProps {

FILE: src/pages/User/impact/Impact.tsx
  type Props (line 6) | interface Props {

FILE: src/pages/User/impact/ImpactField.tsx
  type Props (line 7) | interface Props {

FILE: src/pages/User/impact/ImpactIcon.tsx
  type Props (line 5) | interface Props {

FILE: src/pages/User/impact/ImpactItem.tsx
  type Props (line 7) | interface Props {

FILE: src/pages/User/impact/ImpactMissing.tsx
  type Props (line 10) | interface Props {

FILE: src/pages/User/impact/constants.ts
  constant IMPACT_REPORT_LINKS (line 3) | const IMPACT_REPORT_LINKS = {
  constant IMPACT_YEARS (line 10) | const IMPACT_YEARS: IImpactYear[] = [2025, 2024, 2023, 2022, 2021, 2020,...

FILE: src/pages/UserSettings/SettingsFormTab.tsx
  type IProps (line 6) | interface IProps {

FILE: src/pages/UserSettings/SettingsFormTabList.tsx
  type IProps (line 54) | interface IProps {

FILE: src/pages/UserSettings/SupabaseNotificationsForm.tsx
  type IProps (line 62) | interface IProps {

FILE: src/pages/UserSettings/SupabaseNotificationsViaEmail.tsx
  type IProps (line 8) | interface IProps {

FILE: src/pages/UserSettings/constants.ts
  constant MAX_PIN_LENGTH (line 1) | const MAX_PIN_LENGTH = 70;
  constant MEMBER_PROFILE_DESCRIPTION_MAX_LENGTH (line 2) | const MEMBER_PROFILE_DESCRIPTION_MAX_LENGTH = 500;
  constant GROUP_PROFILE_DESCRIPTION_MAX_LENGTH (line 3) | const GROUP_PROFILE_DESCRIPTION_MAX_LENGTH = 2000;
  constant DEFAULT_PUBLIC_CONTACT_PREFERENCE (line 4) | const DEFAULT_PUBLIC_CONTACT_PREFERENCE = true;

FILE: src/pages/UserSettings/content/fields/ImpactQuestion.field.tsx
  type Props (line 7) | interface Props {

FILE: src/pages/UserSettings/content/fields/ImpactYear.field.tsx
  type Props (line 7) | interface Props {

FILE: src/pages/UserSettings/content/fields/ImpactYearDisplay.field.tsx
  type Props (line 8) | interface Props {

FILE: src/pages/UserSettings/content/fields/PatreonIntegration.test.tsx
  constant MOCK_PATREON_TIER_TITLE (line 61) | const MOCK_PATREON_TIER_TITLE = 'Patreon Tier Title';
  constant WRONG_PATREON_TIER_TITLE (line 82) | const WRONG_PATREON_TIER_TITLE = 'Wrong Patreon Tier Title';

FILE: src/pages/UserSettings/content/fields/PatreonIntegration.tsx
  constant HEADING (line 8) | const HEADING = 'Patreon';
  constant SUCCESS_MESSAGE (line 9) | const SUCCESS_MESSAGE = 'Successfully linked Patreon account!';
  constant SUPPORTER_MESSAGE (line 10) | const SUPPORTER_MESSAGE =
  constant CONNECT_BUTTON_TEXT (line 13) | const CONNECT_BUTTON_TEXT = 'Connect';
  constant UPDATE_BUTTON_TEXT (line 14) | const UPDATE_BUTTON_TEXT = 'Update';
  constant REMOVE_BUTTON_TEXT (line 15) | const REMOVE_BUTTON_TEXT = 'Disconnect';

FILE: src/pages/UserSettings/content/fields/ProfileTypeRadio.field.tsx
  type IProps (line 9) | interface IProps {
  type FieldProps (line 22) | type FieldProps = FieldRenderProps<any, any> & {

FILE: src/pages/UserSettings/content/impactQuestions.ts
  type IImpactQuestion (line 1) | interface IImpactQuestion {

FILE: src/pages/UserSettings/content/sections/ChangeEmail.form.tsx
  type IFormValues (line 13) | interface IFormValues {

FILE: src/pages/UserSettings/content/sections/ChangePassword.form.tsx
  type IFormValues (line 11) | interface IFormValues {

FILE: src/pages/UserSettings/content/sections/EmailNotifications.section.tsx
  type IProps (line 9) | interface IProps {

FILE: src/pages/UserSettings/content/sections/ImpactYear.section.tsx
  type Props (line 19) | interface Props {

FILE: src/pages/UserSettings/content/sections/ProfileTags.section.tsx
  type IProps (line 10) | interface IProps {

FILE: src/pages/UserSettings/content/sections/ProfileType.section.tsx
  type ProfileTypeSectionProps (line 11) | type ProfileTypeSectionProps = {

FILE: src/pages/UserSettings/content/sections/PublicContact.section.tsx
  type PublicContactSectionProps (line 5) | type PublicContactSectionProps = {

FILE: src/pages/UserSettings/content/sections/UserImages.section.tsx
  type IProps (line 13) | interface IProps {

FILE: src/pages/UserSettings/content/sections/UserInfos.section.tsx
  type IProps (line 29) | interface IProps {

FILE: src/pages/UserSettings/content/sections/VisitorSection.tsx
  type Props (line 10) | interface Props {
  function findPolicy (line 19) | function findPolicy(policyValue: UserVisitorPreferencePolicy) {

FILE: src/pages/UserSettings/types.ts
  type ISettingsTab (line 4) | interface ISettingsTab {

FILE: src/pages/UserSettings/utils.ts
  type ImpactDataFieldInputs (line 5) | interface ImpactDataFieldInputs {
  type IInputs (line 9) | interface IInputs {

FILE: src/pages/common/Breadcrumbs/Breadcrumbs.tsx
  type BreadcrumbStep (line 4) | type BreadcrumbStep = { text: string; link?: string };
  type BreadcrumbsProps (line 6) | interface BreadcrumbsProps {

FILE: src/pages/common/Category/CategoriesSelectV2.tsx
  type CategoriesSelectProps (line 5) | type CategoriesSelectProps = {

FILE: src/pages/common/CommentsSupabase/CollapsableCommentSection.tsx
  type Props (line 7) | type Props = {

FILE: src/pages/common/CommentsSupabase/CommentItemSupabase.tsx
  type ICommentItemProps (line 24) | interface ICommentItemProps {

FILE: src/pages/common/CommentsSupabase/CommentReplySupabase.tsx
  constant DELETED_COMMENT (line 19) | const DELETED_COMMENT = 'The original comment got deleted';
  type ICommentItemProps (line 21) | interface ICommentItemProps {

FILE: src/pages/common/CommentsSupabase/CommentSectionSupabase.tsx
  type IProps (line 18) | interface IProps {

FILE: src/pages/common/CommentsSupabase/CommentSort.tsx
  type IProps (line 7) | interface IProps {

FILE: src/pages/common/CommentsSupabase/CommentSortOptions.ts
  type CommentSortOption (line 3) | enum CommentSortOption {
  type SortConfig (line 9) | type SortConfig = {

FILE: src/pages/common/CommentsSupabase/CreateCommentSupabase.tsx
  type IProps (line 14) | interface IProps {

FILE: src/pages/common/Drafts/DraftButton.tsx
  type DraftButtonProps (line 4) | type DraftButtonProps = {

FILE: src/pages/common/Drafts/useDraftsSupabase.tsx
  type Props (line 5) | type Props<T> = {

FILE: src/pages/common/FormFields/Category.field.tsx
  type IProps (line 9) | interface IProps {

FILE: src/pages/common/FormFields/FilesFields.tsx
  type FilesFieldsProps (line 17) | interface FilesFieldsProps {
  type UploadNewFilesProps (line 98) | interface UploadNewFilesProps {

FILE: src/pages/common/FormFields/FormFieldWrapper.tsx
  type IProps (line 9) | interface IProps {

FILE: src/pages/common/FormFields/ImageField.tsx
  type ImageFieldProps (line 12) | type ImageFieldProps = {

FILE: src/pages/common/FormFields/ProfileBadgeField.tsx
  type IProps (line 9) | interface IProps {

FILE: src/pages/common/FormFields/StepImagesField.tsx
  constant MAX_IMAGES (line 12) | const MAX_IMAGES = 10;
  type StepImagesFieldProps (line 14) | interface StepImagesFieldProps {

FILE: src/pages/common/FormFields/Tags.field.tsx
  type IProps (line 6) | interface IProps {

FILE: src/pages/common/FormFields/Title.field.tsx
  type IProps (line 7) | interface IProps {

FILE: src/pages/common/Header/Menu/MenuMobile/MenuMobileExternalLink.tsx
  type IProps (line 7) | interface IProps {

FILE: src/pages/common/Header/Menu/MenuMobile/MenuMobileLink.tsx
  type IProps (line 9) | interface IProps {

FILE: src/pages/common/Header/Menu/Notifications/NotificationsSupabase.tsx
  type IProps (line 6) | interface IProps {

FILE: src/pages/common/Header/Menu/Profile/Profile.tsx
  type IProps (line 14) | interface IProps {

FILE: src/pages/common/Header/Menu/Profile/ProfileButtonItem.tsx
  type IProps (line 6) | interface IProps {

FILE: src/pages/common/Header/Menu/Profile/ProfileButtons.tsx
  type IProps (line 6) | interface IProps {

FILE: src/pages/common/Header/Menu/Profile/UpgradeBadgeLink.tsx
  type Props (line 6) | interface Props {

FILE: src/pages/common/Header/MobileMenuContext.tsx
  type MobileMenuContextType (line 3) | interface MobileMenuContextType {

FILE: src/pages/common/Layout/ListHeader.tsx
  type IProps (line 3) | interface IProps {

FILE: src/pages/common/Layout/Main.tsx
  type ILayoutProps (line 4) | interface ILayoutProps {
  type IProps (line 8) | type IProps = FlexProps & ILayoutProps;

FILE: src/pages/common/Layout/MobileSortModal.tsx
  type FilterSection (line 4) | interface FilterSection {
  type Props (line 11) | interface Props {

FILE: src/pages/common/NotificationsContext.ts
  type INotificationsContext (line 4) | type INotificationsContext = {

FILE: src/pages/common/TenantContext.ts
  type TenantSettingsContext (line 6) | type TenantSettingsContext =
  type EnvVariables (line 25) | type EnvVariables = {

FILE: src/pages/common/UserNameSelect/UserNameSelect.tsx
  type IOption (line 7) | interface IOption {
  type IProps (line 12) | interface IProps {

FILE: src/pages/common/UserNameTag/UserNameTag.tsx
  type IProps (line 6) | interface IProps {

FILE: src/pages/constants.ts
  constant MAX_LINK_LENGTH (line 1) | const MAX_LINK_LENGTH = 2000;

FILE: src/repository/supabase.server.ts
  function createSupabaseServerClient (line 4) | function createSupabaseServerClient(request: Request) {

FILE: src/repository/supabaseAdmin.server.ts
  function createSupabaseAdminServerClient (line 3) | function createSupabaseAdminServerClient() {

FILE: src/root.tsx
  type DocumentProps (line 13) | interface DocumentProps {
  function loader (line 17) | async function loader({ request }: LoaderFunctionArgs) {
  function Root (line 144) | function Root() {

FILE: src/routes/[manifest.webmanifest].tsx
  function loader (line 6) | async function loader({ request }: LoaderFunctionArgs) {

FILE: src/routes/_.$.tsx
  function loader (line 3) | async function loader() {
  function Index (line 7) | function Index() {

FILE: src/routes/_.academy.$.tsx
  function loader (line 9) | async function loader({ request }: LoaderFunctionArgs) {
  function Index (line 21) | function Index() {

FILE: src/routes/_.email-confirmation.tsx
  function Index (line 53) | function Index() {

FILE: src/routes/_.email-preferences.tsx
  function Index (line 28) | function Index() {

FILE: src/routes/_.feedback.tsx
  function loader (line 3) | function loader() {

FILE: src/routes/_.forbidden.tsx
  function loader (line 9) | async function loader({ request }: LoaderFunctionArgs) {
  function Index (line 21) | function Index() {

FILE: src/routes/_.how-to.$slug._index.tsx
  function loader (line 7) | function loader({ params }: LoaderFunctionArgs) {

FILE: src/routes/_.how-to.$slug.edit.tsx
  function loader (line 7) | function loader({ params }: LoaderFunctionArgs) {

FILE: src/routes/_.how-to._index.tsx
  function loader (line 6) | function loader() {

FILE: src/routes/_.how-to.create.tsx
  function loader (line 6) | function loader() {

FILE: src/routes/_.how-to.tsx
  function loader (line 7) | function loader({ params }: LoaderFunctionArgs) {

FILE: src/routes/_.library.$slug._index.tsx
  function loader (line 15) | async function loader({ request, params }: LoaderFunctionArgs) {
  function Index (line 67) | function Index() {

FILE: src/routes/_.library.$slug.edit.tsx
  function loader (line 11) | async function loader({ request, params }: LoaderFunctionArgs) {
  function Index (line 43) | function Index() {

FILE: src/routes/_.library._index.tsx
  function loader (line 7) | async function loader({ request }: LoaderFunctionArgs) {
  function Index (line 19) | function Index() {

FILE: src/routes/_.library.create.tsx
  function loader (line 10) | async function loader({ request }) {
  function Index (line 22) | function Index() {

FILE: src/routes/_.library.tsx
  function loader (line 4) | async function loader() {
  function Index (line 9) | function Index() {

FILE: src/routes/_.map.tsx
  function loader (line 11) | async function loader({ request }: LoaderFunctionArgs) {
  function Index (line 23) | function Index() {

FILE: src/routes/_.news.$slug._index.tsx
  function loader (line 17) | async function loader({ request, params }: LoaderFunctionArgs) {
  function loadNews (line 56) | async function loadNews(client: SupabaseClient, dbNews: DBNews) {
  function Index (line 88) | function Index() {

FILE: src/routes/_.news.$slug.edit.tsx
  function loader (line 11) | async function loader({ request, params }: LoaderFunctionArgs) {
  function isAllowedToEdit (line 45) | async function isAllowedToEdit(userAuthId: string, client: SupabaseClien...
  function Index (line 55) | function Index() {

FILE: src/routes/_.news._index.tsx
  function loader (line 7) | async function loader({ request }: LoaderFunctionArgs) {
  function Index (line 19) | function Index() {

FILE: src/routes/_.news.create.tsx
  function loader (line 11) | async function loader({ request }: LoaderFunctionArgs) {
  function Index (line 32) | function Index() {

FILE: src/routes/_.news.tsx
  function loader (line 10) | async function loader({ request }: LoaderFunctionArgs) {
  function Index (line 24) | function Index() {

FILE: src/routes/_.patreon.tsx
  function loader (line 9) | async function loader({ request }: LoaderFunctionArgs) {
  function Index (line 47) | function Index() {

FILE: src/routes/_.privacy.tsx
  function Index (line 7) | function Index() {

FILE: src/routes/_.questions.$slug._index.tsx
  function loader (line 17) | async function loader({ request, params }: LoaderFunctionArgs) {
  function Index (line 72) | function Index() {

FILE: src/routes/_.questions.$slug.edit.tsx
  function loader (line 11) | async function loader({ request, params }: LoaderFunctionArgs) {
  function isUserAllowedToEdit (line 45) | async function isUserAllowedToEdit(
  function Index (line 62) | function Index() {

FILE: src/routes/_.questions._index.tsx
  function loader (line 7) | async function loader({ request }: LoaderFunctionArgs) {
  function Index (line 19) | function Index() {

FILE: src/routes/_.questions.create.tsx
  function loader (line 9) | async function loader({ request }: LoaderFunctionArgs) {
  function Index (line 20) | function Index() {

FILE: src/routes/_.questions.tsx
  function loader (line 10) | async function loader({ request }: LoaderFunctionArgs) {
  function Index (line 22) | function Index() {

FILE: src/routes/_.research.$slug._index.tsx
  function loader (line 15) | async function loader({ request, params }: LoaderFunctionArgs) {
  function Index (line 85) | function Index() {

FILE: src/routes/_.research.$slug.edit-update.$updateId.tsx
  function loader (line 11) | async function loader({ request, params }: LoaderFunctionArgs) {
  function Index (line 56) | function Index() {

FILE: src/routes/_.research.$slug.edit.tsx
  function loader (line 11) | async function loader({ request, params }: LoaderFunctionArgs) {
  function Index (line 45) | function Index() {

FILE: src/routes/_.research.$slug.new-update.tsx
  function loader (line 10) | async function loader({ request, params }: LoaderFunctionArgs) {
  function Index (line 38) | function Index() {

FILE: src/routes/_.research._index.tsx
  function loader (line 7) | async function loader({ request }: LoaderFunctionArgs) {
  function Index (line 19) | function Index() {

FILE: src/routes/_.research.create.tsx
  function loader (line 8) | async function loader({ request }) {
  function Index (line 33) | function Index() {

FILE: src/routes/_.research.tsx
  function loader (line 4) | async function loader() {
  function Index (line 9) | function Index() {

FILE: src/routes/_.reset-password.tsx
  function Index (line 48) | function Index() {

FILE: src/routes/_.settings.$.tsx
  function loader (line 9) | async function loader({ request }: LoaderFunctionArgs) {
  function Index (line 25) | function Index() {

FILE: src/routes/_.sign-in.tsx
  function Index (line 93) | function Index() {

FILE: src/routes/_.sign-up-message.tsx
  function loader (line 6) | async function loader({ request }: LoaderFunctionArgs) {
  function Index (line 16) | function Index() {

FILE: src/routes/_.sign-up.tsx
  function Index (line 76) | function Index() {

FILE: src/routes/_.terms.tsx
  function Index (line 7) | function Index() {

FILE: src/routes/_.tsx
  function loader (line 24) | async function loader({ request }: LoaderFunctionArgs) {
  function Index (line 47) | function Index() {

FILE: src/routes/_.u.$id._index.tsx
  function loader (line 16) | async function loader({ request, params }: LoaderFunctionArgs) {
  function Index (line 79) | function Index() {

FILE: src/routes/_.u.tsx
  function Index (line 4) | function Index() {

FILE: src/routes/_.update-password.tsx
  function Index (line 74) | function Index() {

FILE: src/routes/_index.tsx
  function loader (line 3) | async function loader() {
  function Index (line 7) | function Index() {

FILE: src/routes/api.banner.ts
  function loader (line 10) | async function loader({ request }: LoaderFunctionArgs) {

FILE: src/routes/api.categories.$type.ts
  function loader (line 17) | async function loader({ request, params }: LoaderFunctionArgs) {

FILE: src/routes/api.comments.$id.source.ts
  function loader (line 4) | async function loader({ request, params }: LoaderFunctionArgs) {

FILE: src/routes/api.discussions.$sourceId.comments.$id.ts
  type Supabase (line 8) | type Supabase = {
  function action (line 13) | async function action({ params, request }: LoaderFunctionArgs) {
  function updateComment (line 55) | async function updateComment(
  function deleteComment (line 91) | async function deleteComment({ client, headers }: Supabase, id: string, ...
  function getProfileByAuthId (line 116) | async function getProfileByAuthId(request: Request, authId: string) {
  function isUserAdmin (line 128) | function isUserAdmin(user: DBProfile) {
  function validateRequest (line 132) | async function validateRequest(params: Params<string>, request: Request) {

FILE: src/routes/api.discussions.$sourceType.$sourceId.comments.ts
  function loader (line 12) | async function loader({ params, request }: LoaderFunctionArgs) {
  function action (line 53) | async function action({ params, request }: LoaderFunctionArgs) {
  function addSubscriptions (line 162) | function addSubscriptions(comment: DBComment, profile: DBProfile, client...
  function validateRequest (line 177) | async function validateRequest(

FILE: src/routes/api.documents.$type.$contentId.$docId.tsx
  function loader (line 9) | async function loader({ params, request }: LoaderFunctionArgs) {
  function resolveUrl (line 28) | async function resolveUrl(params: Params<string>, client: SupabaseClient...
  function resolveFileLink (line 62) | async function resolveFileLink(
  function resolveFileFromStorage (line 78) | async function resolveFileFromStorage(
  function incrementDownloadCount (line 102) | async function incrementDownloadCount(type: string, contentId: number, c...

FILE: src/routes/api.documents.ts
  function validateRequest (line 51) | async function validateRequest(request: Request) {

FILE: src/routes/api.donation-settings.$profileId.ts
  function loader (line 5) | async function loader({ request, params }: LoaderFunctionArgs) {

FILE: src/routes/api.favicon.ts
  function loader (line 10) | async function loader({ request }: LoaderFunctionArgs) {

FILE: src/routes/api.images.ts
  function validateRequest (line 52) | async function validateRequest(request: Request, imageFile: File) {

FILE: src/routes/api.messages.tsx
  function validateRequest (line 134) | async function validateRequest(request: Request, userEmail: string | nul...

FILE: src/routes/api.news.$id.ts
  function validateRequest (line 93) | async function validateRequest(

FILE: src/routes/api.news.drafts.ts
  function loader (line 9) | async function loader({ request }: LoaderFunctionArgs) {

FILE: src/routes/api.news.ts
  function notifyDiscord (line 212) | function notifyDiscord(news: News, profile: DBProfile, siteUrl: string) {
  function validateRequest (line 225) | async function validateRequest(request: Request, data: NewsDTO): Promise...

FILE: src/routes/api.notifications-preferences-via-email.$userCode.ts
  type DecodedToken (line 6) | interface DecodedToken {
  function validateRequest (line 123) | async function validateRequest(request: Request, userId: number) {

FILE: src/routes/api.notifications-preferences.ts
  constant DEFAULT_NOTIFICATION_PREFERENCES (line 6) | const DEFAULT_NOTIFICATION_PREFERENCES: DBNotificationsPreferencesFields...
  function validateRequest (line 100) | async function validateRequest(request: Request) {

FILE: src/routes/api.notifications.$id.read.ts
  function validateRequest (line 39) | async function validateRequest(params: Params<string>, request: Request) {

FILE: src/routes/api.notifications.all.read.ts
  function validateRequest (line 48) | async function validateRequest(request: Request) {

FILE: src/routes/api.profile-badges.ts
  function loader (line 10) | async function loader({ request }: LoaderFunctionArgs) {

FILE: src/routes/api.profile-tags.ts
  function loader (line 6) | async function loader({ request }: LoaderFunctionArgs) {

FILE: src/routes/api.profile-types.ts
  function loader (line 5) | async function loader({ request }: LoaderFunctionArgs) {

FILE: src/routes/api.profile.ts
  function validateRequest (line 142) | async function validateRequest(

FILE: src/routes/api.projects.$id.ts
  function validateRequest (line 140) | async function validateRequest(
  function updateProject (line 182) | async function updateProject(
  function deleteProject (line 230) | async function deleteProject(request: Request, id: number) {

FILE: src/routes/api.projects.drafts.ts
  function loader (line 9) | async function loader({ request }: LoaderFunctionArgs) {

FILE: src/routes/api.projects.ts
  function uploadSteps (line 173) | async function uploadSteps(data, formData: FormData, projectDb: DBProjec...
  function validateRequest (line 203) | async function validateRequest(
  function createProject (line 234) | async function createProject(
  function createStep (line 269) | async function createStep(

FILE: src/routes/api.questions.$id.ts
  function validateRequest (line 99) | async function validateRequest(

FILE: src/routes/api.questions.drafts.ts
  function loader (line 9) | async function loader({ request }: LoaderFunctionArgs) {

FILE: src/routes/api.questions.ts
  function notifyDiscord (line 167) | function notifyDiscord(question: Question, profile: DBProfile, siteUrl: ...
  function validateRequest (line 181) | async function validateRequest(request: Request, data: QuestionDTO) {

FILE: src/routes/api.research.$id.status.ts
  function validateRequest (line 61) | async function validateRequest(request: Request, data: { status: Researc...

FILE: src/routes/api.research.$id.ts
  function deleteResearch (line 98) | async function deleteResearch(request, id: number) {
  function validateRequest (line 137) | async function validateRequest(

FILE: src/routes/api.research.$id.updates.$updateId.ts
  function deleteResearchUpdate (line 104) | async function deleteResearchUpdate(request: Request, id: number, update...
  function validateRequest (line 131) | function validateRequest(request: Request, data: ResearchUpdateDTO) {

FILE: src/routes/api.research.$id.updates.ts
  function validateRequest (line 105) | function validateRequest(

FILE: src/routes/api.research.drafts.ts
  function loader (line 9) | async function loader({ request }: LoaderFunctionArgs) {

FILE: src/routes/api.research.ts
  function validateRequest (line 174) | function validateRequest(request: Request, data: ResearchDTO) {

FILE: src/routes/api.settings.impact.ts
  function validateRequest (line 64) | async function validateRequest(request: Request, data: any) {

FILE: src/routes/api.settings.map.ts
  function validateRequest (line 78) | async function validateRequest(request: Request, data: UpsertPin) {
  function deletePin (line 96) | async function deletePin(request: Request, profile: DBProfile) {

FILE: src/routes/api.subscribers.$contentType.$contentId.subscribed.ts
  function loader (line 4) | async function loader({ request, params }: LoaderFunctionArgs) {

FILE: src/routes/api.subscribers.$contentType.$contentId.ts
  function action (line 5) | async function action({ request, params }: LoaderFunctionArgs) {

FILE: src/routes/api.tags.ts
  function loader (line 4) | async function loader({ request }: LoaderFunctionArgs) {

FILE: src/routes/api.upgrade-badges.ts
  function loader (line 10) | async function loader({ request }: LoaderFunctionArgs) {

FILE: src/routes/api.useful.$contentType.$contentId.ts
  function action (line 5) | async function action({ request, params }: LoaderFunctionArgs) {

FILE: src/routes/api.useful.$contentType.$contentId.users.ts
  function loader (line 6) | async function loader({ request, params }: LoaderFunctionArgs) {

FILE: src/routes/api.useful.$contentType.$contentId.voted.ts
  function loader (line 4) | async function loader({ request, params }: LoaderFunctionArgs) {

FILE: src/routes/api.useful.$contentType.$id.count.ts
  function loader (line 5) | async function loader({ request, params }: LoaderFunctionArgs) {

FILE: src/routes/redirect.tsx
  function loader (line 6) | async function loader({ request }: LoaderFunctionArgs) {

FILE: src/services/authService.server.ts
  type CreateProfileArgs (line 3) | type CreateProfileArgs = {
  class AuthServiceServer (line 7) | class AuthServiceServer {
    method constructor (line 8) | constructor(private client: SupabaseClient) {}
    method createUserProfile (line 10) | async createUserProfile(args: CreateProfileArgs) {

FILE: src/services/broadcastCoordinationService.server.ts
  class BroadcastCoordinationServiceServer (line 6) | class BroadcastCoordinationServiceServer {
    method constructor (line 7) | constructor(private client: SupabaseClient) {}
    method researchUpdate (line 9) | researchUpdate(

FILE: src/services/contentRedirectService.server.ts
  class ContentRedirectServiceServer (line 5) | class ContentRedirectServiceServer {
    method constructor (line 6) | constructor(private client: SupabaseClient) {}
    method getUrl (line 8) | async getUrl(id: number, contentType: NotificationContentType): Promis...
    method resolveResearchUpdateUrl (line 17) | private async resolveResearchUpdateUrl(updateId: number) {
    method resolveCommentUrl (line 33) | private async resolveCommentUrl(commentId: number) {
    method resolveResearchUpdateCommentUrl (line 60) | private async resolveResearchUpdateCommentUrl(updateId: number, commen...
    method resolveGenericContentCommentUrl (line 76) | private async resolveGenericContentCommentUrl(

FILE: src/services/contentService.server.ts
  type Slug (line 5) | type Slug = string;
  type Id (line 6) | type Id = number;
  class ContentServiceServer (line 8) | class ContentServiceServer {
    method constructor (line 9) | constructor(private client: SupabaseClient) {}
    method getDraftCount (line 11) | async getDraftCount(profileId: number, table: ContentType) {
    method getMetaFields (line 22) | async getMetaFields(id: Id, table: ContentType, tagIds: number[]) {
    method incrementViewCount (line 38) | async incrementViewCount(table: ContentType, totalViews: number | unde...
    method isDuplicateExistingSlug (line 45) | async isDuplicateExistingSlug(slug: Slug, id: Id, table: ContentType) {
    method isDuplicateNewSlug (line 55) | async isDuplicateNewSlug(slug: Slug, table: ContentType) {
    method updatePreviousSlugs (line 65) | static updatePreviousSlugs(content: IDBContentDoc, newSlug: Slug) {

FILE: src/services/formDataHelper.ts
  function createFormData (line 1) | function createFormData<T extends Record<string, unknown>>(data: T): For...

FILE: src/services/imageService.server.ts
  class ImageServiceServer (line 6) | class ImageServiceServer {
    method constructor (line 7) | constructor(private client: SupabaseClient) {}
    method getPublicUrl (line 9) | getPublicUrl(image: DBMedia | null, size?: TransformOptions): Image | ...
    method getPublicUrls (line 34) | getPublicUrls(images: DBMedia[], size?: TransformOptions): Image[] {
    method uploadImage (line 47) | async uploadImage(files: File[], path: string) {
    method uploadFile (line 72) | async uploadFile(files: File[], path: string) {
    method removeFiles (line 100) | async removeFiles(paths: string[]) {
    method removeImages (line 104) | async removeImages(paths: string[]) {
    method getPathDocuments (line 108) | async getPathDocuments(path: string, mapUrlPrefix: string) {

FILE: src/services/impactService.server.ts
  class ImpactServiceServer (line 4) | class ImpactServiceServer {
    method constructor (line 5) | constructor(private client: SupabaseClient) {}
    method update (line 7) | async update(profileId: number, year: number, fields: IImpactDataField...

FILE: src/services/libraryService.server.ts
  class LibraryServiceServer (line 14) | class LibraryServiceServer {
    method constructor (line 15) | constructor(private client: SupabaseClient) {}
    method getBySlug (line 17) | getBySlug(slug: string) {
    method getUserProjects (line 71) | async getUserProjects(username: string): Promise<Partial<Project>[]> {
    method getProjectPublicMedia (line 96) | getProjectPublicMedia(projectDb: DBProject) {
    method isAllowedToEditProject (line 119) | async isAllowedToEditProject(
    method isAllowedToEditProjectById (line 130) | async isAllowedToEditProjectById(
    method getById (line 145) | async getById(id: number) {
    method getProjectStepIds (line 150) | async getProjectStepIds(id: number): Promise<number[]> {
    method upsertStep (line 156) | async upsertStep(
    method deleteStepsById (line 199) | async deleteStepsById(ids: number[]) {

FILE: src/services/mapPinsService.server.ts
  class MapPinsServiceServer (line 9) | class MapPinsServiceServer {
    method constructor (line 10) | constructor(private client: SupabaseClient) {}
    method get (line 12) | async get() {
    method delete (line 94) | async delete(profileId: number) {
    method clearCache (line 104) | clearCache() {

FILE: src/services/mapService.server.ts
  class MapServiceServer (line 4) | class MapServiceServer {
    method constructor (line 5) | constructor(private client: SupabaseClient) {}
    method upsert (line 7) | async upsert(pin: UpsertPin, profile: Profile) {

FILE: src/services/newsService.server.ts
  class NewsServiceServer (line 6) | class NewsServiceServer {
    method constructor (line 7) | constructor(private client: SupabaseClient) {}
    method getById (line 9) | async getById(id: number) {
    method getBySlug (line 14) | getBySlug(slug: string) {
    method getHeroImage (line 53) | async getHeroImage(dbImage: DBMedia | null) {

FILE: src/services/notificationEmailService.server.ts
  class NotificationEmailServiceServer (line 10) | class NotificationEmailServiceServer {
    method constructor (line 11) | constructor(private client: SupabaseClient) {}
    method sendInstantNotificationEmails (line 13) | async sendInstantNotificationEmails(

FILE: src/services/notificationMapperService.server.ts
  class NotificationMapperServiceServer (line 4) | class NotificationMapperServiceServer {
    method constructor (line 5) | constructor(private client: SupabaseClient) {}
    method transformNotification (line 7) | async transformNotification(dbNotification: DBNotification) {

FILE: src/services/notificationsSupabaseService.server.ts
  class NotificationsSupabaseServiceServer (line 13) | class NotificationsSupabaseServiceServer {
    method constructor (line 14) | constructor(private client: SupabaseClient) {}
    method getSubscribedUsers (line 16) | async getSubscribedUsers(
    method createNotifications (line 37) | async createNotifications(
    method createNotificationsNewComment (line 70) | async createNotificationsNewComment(comment: DBComment) {
    method createNotificationsResearchUpdate (line 118) | async createNotificationsResearchUpdate(

FILE: src/services/patreonService.server.ts
  class PatreonServiceServer (line 11) | class PatreonServiceServer {
    method constructor (line 12) | constructor(private client: SupabaseClient) {}
    method verifyAndUpdatePatreonUser (line 14) | async verifyAndUpdatePatreonUser(code: string, userAuthId: string, ori...
    method disconnectUser (line 54) | async disconnectUser(userAuthId: string) {
    method isSupporter (line 61) | private async isSupporter(patreonUser: IPatreonUser) {
    method parsePatreonUser (line 74) | private parsePatreonUser(patreonUser: any): IPatreonUser {

FILE: src/services/profileService.server.ts
  class ProfileServiceServer (line 6) | class ProfileServiceServer {
    method constructor (line 7) | constructor(private client: SupabaseClient) {}
    method getByAuthId (line 9) | async getByAuthId(id: string): Promise<DBProfile | null> {
    method getById (line 45) | async getById(id: number): Promise<DBProfile | null> {
    method getUsersByUsername (line 75) | async getUsersByUsername(usernames: string[]): Promise<DBProfile[] | n...
    method getByUsername (line 121) | async getByUsername(username: string): Promise<DBProfile | null> {
    method incrementViewCount (line 163) | async incrementViewCount(id: number, totalViews: number) {
    method getAuthorUsefulVotes (line 170) | async getAuthorUsefulVotes(id: number) {
    method updateUsername (line 183) | async updateUsername(id: number, username: string) {
    method updateProfile (line 216) | async updateProfile(id: number, values: ProfileDTO) {
    method updateTags (line 274) | async updateTags(profileId: number, tagIds: number[]) {
    method ensureProfile (line 314) | async ensureProfile(user: User) {
    method updateUserActivity (line 344) | async updateUserActivity(userId: string) {
    method determinePinModeration (line 356) | private determinePinModeration(types: ProfileType[], profile: DBProfil...

FILE: src/services/profileTypesService.server.ts
  class ProfileTypesServiceServer (line 8) | class ProfileTypesServiceServer {
    method constructor (line 9) | constructor(private client: SupabaseClient) {}
    method get (line 11) | async get(cached = true) {

FILE: src/services/questionService.server.ts
  class QuestionServiceServer (line 5) | class QuestionServiceServer {
    method constructor (line 6) | constructor(private client: SupabaseClient) {}
    method getById (line 8) | async getById(id: number): Promise<DBQuestion> {
    method getBySlug (line 13) | async getBySlug(slug: string) {
    method getQuestionsByUser (line 49) | async getQuestionsByUser(username: string): Promise<Partial<Question>[...

FILE: src/services/researchService.server.ts
  class ResearchServiceServer (line 16) | class ResearchServiceServer {
    method constructor (line 17) | constructor(private client: SupabaseClient) {}
    method getBySlug (line 19) | async getBySlug(slug: string) {
    method getCollaborators (line 96) | private async getCollaborators(collaboratorIds: string[] | null) {
    method getUpdate (line 107) | async getUpdate(researchId: number, updateId: number) {
    method getUserResearch (line 118) | async getUserResearch(username: string): Promise<Partial<ResearchItem>...
    method getResearchPublicMedia (line 142) | getResearchPublicMedia(researchDb: DBResearchItem) {
    method isAllowedToEditResearch (line 153) | async isAllowedToEditResearch(research: DBResearchItem, profile: DBPro...
    method isAllowedToEditResearchById (line 169) | async isAllowedToEditResearchById(id: number, profile: DBProfile) {
    method getById (line 181) | async getById(id: number) {
    method getUpdateById (line 186) | async getUpdateById(id: number) {
    method isAllowedToEditUpdate (line 191) | async isAllowedToEditUpdate(profile: DBProfile | null, researchId: num...

FILE: src/services/storageService.server.ts
  class StorageServiceServer (line 7) | class StorageServiceServer {
    method constructor (line 8) | constructor(private client: SupabaseClient) {}
    method getPublicUrl (line 10) | getPublicUrl(image: DBMedia, size?: TransformOptions): Image | null {
    method getPublicUrls (line 31) | getPublicUrls(images: DBMedia[], size?: TransformOptions): Image[] {
    method uploadImage (line 59) | async uploadImage(
    method uploadFile (line 203) | async uploadFile(
    method removeFiles (line 260) | async removeFiles(paths: string[]): Promise<void> {
    method removeImages (line 264) | async removeImages(paths: string[]): Promise<void> {
    method getPathDocuments (line 268) | async getPathDocuments(path: string, mapUrlPrefix: string): Promise<Me...
    method moveImage (line 288) | async moveImage(

FILE: src/services/storageService.ts
  type ImageFolder (line 3) | type ImageFolder = ContentType | 'profiles';

FILE: src/services/subscribersService.server.ts
  class SubscribersServiceServer (line 9) | class SubscribersServiceServer {
    method constructor (line 10) | constructor(private client: SupabaseClient) {}
    method combineSubscribers (line 12) | async combineSubscribers(
    method addResearchSubscribers (line 34) | async addResearchSubscribers(research: ResearchItem, profileId: number) {
    method addResearchUpdateSubscribers (line 46) | async addResearchUpdateSubscribers(update: ResearchUpdate, profileId: ...
    method add (line 58) | async add(contentType: SubscribableContentTypes, contentId: number, pr...
    method updateResearchSubscribers (line 84) | async updateResearchSubscribers(oldResearch: DBResearchItem, newResear...

FILE: src/services/tagsService.server.ts
  class TagsServiceServer (line 4) | class TagsServiceServer {
    method constructor (line 5) | constructor(private client: SupabaseClient) {}
    method getTags (line 7) | async getTags(tagIds: number[]) {

FILE: src/services/tenantSettingsService.server.ts
  class TenantSettingsService (line 8) | class TenantSettingsService {
    method constructor (line 9) | constructor(private client: SupabaseClient) {}
    method get (line 11) | async get(cacheBypass = false): Promise<TenantSettings> {
    method validateRoles (line 77) | private validateRoles(

FILE: src/stores/Profile/profile.store.tsx
  class ProfileStore (line 9) | class ProfileStore {
    method constructor (line 73) | constructor() {
    method upgradeBadgeForCurrentUser (line 90) | get upgradeBadgeForCurrentUser() {
    method isComplete (line 104) | get isComplete() {
    method missingFields (line 112) | get missingFields() {
    method getMissingFields (line 120) | getMissingFields(profile: Partial<Profile>) {
    method isProfileComplete (line 147) | isProfileComplete(profile: Partial<Profile>) {

FILE: src/stores/Subscription/subscription.store.tsx
  type SubscriptionKey (line 8) | type SubscriptionKey = `${SubscribableContentTypes}-${number}`;
  type SubscriptionState (line 10) | interface SubscriptionState {
  class SubscriptionStore (line 15) | class SubscriptionStore {
    method constructor (line 18) | constructor() {
    method getCacheKey (line 28) | private getCacheKey(contentType: SubscribableContentTypes, itemId: num...
    method isSubscribed (line 32) | isSubscribed(contentType: SubscribableContentTypes, itemId: number): b...
    method isLoading (line 38) | isLoading(contentType: SubscribableContentTypes, itemId: number): bool...
    method checkAndCacheSubscription (line 43) | async checkAndCacheSubscription(
    method subscribe (line 86) | async subscribe(contentType: SubscribableContentTypes, itemId: number)...
    method unsubscribe (line 128) | async unsubscribe(contentType: SubscribableContentTypes, itemId: numbe...
    method toggleSubscription (line 170) | async toggleSubscription(
    method clearCache (line 189) | clearCache() {
    method preloadSubscriptions (line 194) | async preloadSubscriptions(

FILE: src/stores/UsefulVote/useUsefulVote.tsx
  function useUsefulVote (line 6) | function useUsefulVote(

FILE: src/stores/UsefulVote/usefulVote.store.tsx
  type UsefulVoteKey (line 8) | type UsefulVoteKey = `${UsefulContentType}-${number}`;
  type UsefulVoteState (line 10) | interface UsefulVoteState {
  class UsefulVoteStore (line 16) | class UsefulVoteStore {
    method constructor (line 19) | constructor() {
    method getCacheKey (line 28) | private getCacheKey(contentType: UsefulContentType, contentId: number)...
    method getVoteState (line 32) | getVoteState(contentType: UsefulContentType, contentId: number): Usefu...
    method hasVoted (line 37) | hasVoted(contentType: UsefulContentType, contentId: number): boolean {
    method getUsefulCount (line 42) | getUsefulCount(contentType: UsefulContentType, contentId: number): num...
    method isLoading (line 47) | isLoading(contentType: UsefulContentType, contentId: number): boolean {
    method initializeVote (line 52) | async initializeVote(
    method toggleVote (line 114) | async toggleVote(contentType: UsefulContentType, contentId: number): P...
    method clearCache (line 172) | clearCache() {

FILE: src/styles/context.ts
  type ServerStyleContextData (line 3) | type ServerStyleContextData = {
  type ClientStyleContextData (line 11) | type ClientStyleContextData = {

FILE: src/types/emotion.d.ts
  type Theme (line 6) | interface Theme extends PlatformTheme {}
  type Theme (line 10) | interface Theme extends PlatformTheme {}

FILE: src/utils/comparisons.ts
  constant COMPARISONS (line 8) | const COMPARISONS = {

FILE: src/utils/contentType.utils.ts
  function resolveType (line 1) | function resolveType(type: string) {

FILE: src/utils/filters.ts
  type dateType (line 72) | type dateType = ISODateString | RelativeDateString;
  type RelativeDateString (line 74) | type RelativeDateString = 'yesterday' | 'tomorrow' | 'thisweek' | 'today';

FILE: src/utils/httpException.ts
  function createHTTPException (line 8) | function createHTTPException(
  function validationError (line 26) | function validationError(message: string, field?: string) {
  function unauthorizedError (line 30) | function unauthorizedError() {
  function methodNotAllowedError (line 34) | function methodNotAllowedError() {
  function notFoundError (line 38) | function notFoundError(resource: string) {
  function forbiddenError (line 42) | function forbiddenError(message = 'Forbidden') {
  function conflictError (line 46) | function conflictError(message: string) {
  function tooManyRequestsError (line 50) | function tooManyRequestsError(message: string) {

FILE: src/utils/seo.utils.ts
  type GenerateTagsOptions (line 30) | interface GenerateTagsOptions {

FILE: src/utils/statistics.tsx
  function createUsefulStatistic (line 7) | function createUsefulStatistic(

FILE: src/utils/storage.ts
  constant SUPPORTED_IMAGE_TYPES (line 1) | const SUPPORTED_IMAGE_TYPES = [
  function validateImage (line 10) | function validateImage(image: File | null) {
  function validateImages (line 20) | function validateImages(images: File[]) {

FILE: src/utils/urls.ts
  constant BAZAR_URL (line 1) | const BAZAR_URL = 'https://bazar.preciousplastic.com/';
  constant GLOBAL_SITE_URL (line 2) | const GLOBAL_SITE_URL = 'https://preciousplastic.com/';

FILE: supabase/functions/send-email/_templates/components/box-text.tsx
  type IProps (line 12) | interface IProps {

FILE: supabase/functions/send-email/_templates/components/button.tsx
  type IProps (line 14) | interface IProps {

FILE: supabase/functions/send-email/_templates/components/footer.tsx
  type IProps (line 10) | interface IProps {

FILE: supabase/functions/send-email/_templates/components/header.tsx
  type IProps (line 8) | interface IProps {

FILE: supabase/functions/send-email/_templates/components/heading.tsx
  type IProps (line 13) | interface IProps {

FILE: supabase/functions/send-email/_templates/components/hero.tsx
  type IProps (line 11) | interface IProps {

FILE: supabase/functions/send-email/_templates/components/parent-box.tsx
  type IProps (line 26) | interface IProps {

FILE: supabase/functions/send-email/_templates/components/plain-text.tsx
  type IProps (line 10) | interface IProps {

FILE: supabase/functions/send-email/_templates/email-change-new.tsx
  type SignUpEmailProps (line 19) | interface SignUpEmailProps {

FILE: supabase/functions/send-email/_templates/layout.tsx
  type EmailType (line 37) | type EmailType = 'service' | 'moderation' | 'notification';
  type LayoutArgs (line 39) | type LayoutArgs = {

FILE: supabase/functions/send-email/_templates/magic-link.tsx
  type SignUpEmailProps (line 20) | interface SignUpEmailProps {

FILE: supabase/functions/send-email/_templates/moderation-email.tsx
  type IProps (line 19) | interface IProps {

FILE: supabase/functions/send-email/_templates/reset-password.tsx
  type ResetPasswordProps (line 20) | interface ResetPasswordProps {

FILE: supabase/functions/send-email/_templates/sign-up.tsx
  type SignUpEmailProps (line 20) | interface SignUpEmailProps {

FILE: supabase/functions/send-email/getTenantSettings.ts
  function getTenantSettings (line 3) | async function getTenantSettings(req, redirect_to) {

FILE: supabase/functions/send-email/index.ts
  type EmailData (line 22) | type EmailData = {
  function getUsername (line 143) | async function getUsername(req: Request, authId: string): Promise<string> {

FILE: supabase/functions/send-email/signWebhookHeader.ts
  function signWebhookHeader (line 14) | function signWebhookHeader(

FILE: supabase/migrations/20241125140428_profiles_and_comments.sql
  type "public" (line 1) | create table "public"."categories" (
  type "public" (line 11) | create table "public"."comments" (
  type "public" (line 29) | create table "public"."profiles" (
  type "public" (line 46) | create table "public"."questions" (
  type categories_pkey (line 68) | CREATE UNIQUE INDEX categories_pkey ON public.categories USING btree (id)
  type comments_created_at_source_type_source_id_tenant_id_idx (line 70) | CREATE INDEX comments_created_at_source_type_source_id_tenant_id_idx ON ...
  type comments_pkey (line 72) | CREATE UNIQUE INDEX comments_pkey ON public.comments USING btree (id)
  type profiles_firebase_auth_id_idx (line 74) | CREATE INDEX profiles_firebase_auth_id_idx ON public.profiles USING btre...
  type profiles_pkey (line 76) | CREATE UNIQUE INDEX profiles_pkey ON public.profiles USING btree (id)
  type profiles_tenant_id_is_verified_created_at_idx (line 78) | CREATE INDEX profiles_tenant_id_is_verified_created_at_idx ON public.pro...
  type question_pkey (line 80) | CREATE UNIQUE INDEX question_pkey ON public.questions USING btree (id)
  type questions_deleted_moderation_category_total_views_tags_crea_idx (line 82) | CREATE INDEX questions_deleted_moderation_category_total_views_tags_crea...
  type questions_tags_idx (line 84) | CREATE INDEX questions_tags_idx ON public.questions USING gin (tags)
  function public (line 108) | CREATE OR REPLACE FUNCTION public.comment_authors_by_source_id_legacy(so...
  function public (line 120) | CREATE OR REPLACE FUNCTION public.update_comment_count()

FILE: supabase/migrations/20250111151556_questions.sql
  type "public" (line 3) | create table "public"."subscribers" (
  type "public" (line 15) | create table "public"."tags" (
  type "public" (line 26) | create table "public"."useful_votes" (
  type comments_created_by_idx (line 70) | CREATE INDEX comments_created_by_idx ON public.comments USING btree (cre...
  type questions_category_idx (line 72) | CREATE INDEX questions_category_idx ON public.questions USING btree (cat...
  type questions_created_by_idx (line 74) | CREATE INDEX questions_created_by_idx ON public.questions USING btree (c...
  type subscribers_pkey (line 76) | CREATE UNIQUE INDEX subscribers_pkey ON public.subscribers USING btree (id)
  type tags_pkey (line 78) | CREATE UNIQUE INDEX tags_pkey ON public.tags USING btree (id)
  type unique_tenant_slug (line 80) | CREATE UNIQUE INDEX unique_tenant_slug ON public.questions USING btree (...
  type useful_votes_pkey (line 82) | CREATE UNIQUE INDEX useful_votes_pkey ON public.useful_votes USING btree...
  function public (line 102) | CREATE OR REPLACE FUNCTION public.comment_authors_by_source_id(source_id...
  function public (line 114) | CREATE OR REPLACE FUNCTION public.get_useful_votes_count_by_content_id(p...
  function public (line 129) | CREATE OR REPLACE FUNCTION public.questions_search_fields(questions)

FILE: supabase/migrations/20250113184950_profile_auth_columns.sql
  type profiles_auth_id_tenant_id_key (line 5) | CREATE UNIQUE INDEX profiles_auth_id_tenant_id_key ON public.profiles US...

FILE: supabase/migrations/20250208130256_auth_rpc.sql
  function public (line 3) | CREATE OR REPLACE FUNCTION public.get_user_id_by_email(email text)

FILE: supabase/migrations/20250214235014_messages.sql
  type "public" (line 1) | create table "public"."messages" (
  type "public" (line 13) | create table "public"."tenant_settings" (
  type messages_pkey (line 27) | CREATE UNIQUE INDEX messages_pkey ON public.messages USING btree (id)
  type tenant_settings_pkey (line 29) | CREATE UNIQUE INDEX tenant_settings_pkey ON public.tenant_settings USING...
  function public (line 45) | CREATE OR REPLACE FUNCTION public.get_user_email_by_id(id uuid)
  function public (line 56) | CREATE OR REPLACE FUNCTION public.comment_authors_by_source_id(source_id...
  function public (line 68) | CREATE OR REPLACE FUNCTION public.get_useful_votes_count_by_content_id(p...
  function public (line 83) | CREATE OR REPLACE FUNCTION public.get_user_id_by_email(email text)
  function public (line 92) | CREATE OR REPLACE FUNCTION public.questions_search_fields(questions)

FILE: supabase/migrations/20250225071100_unique_username.sql
  function public (line 3) | CREATE OR REPLACE FUNCTION public.is_username_available(username text)

FILE: supabase/migrations/20250307061534_messages_temp_fix.sql
  function public (line 1) | CREATE OR REPLACE FUNCTION public.get_user_email_by_username(username text)

FILE: supabase/migrations/20250312063008_patreon.sql
  type "public" (line 1) | create table "public"."patreon_settings" (
  type patreon_settings_pkey (line 10) | CREATE UNIQUE INDEX patreon_settings_pkey ON public.patreon_settings USI...

FILE: supabase/migrations/20250331134409_add_news.sql
  type "public" (line 3) | create table "public"."news" (
  type news_category_idx (line 26) | CREATE INDEX news_category_idx ON public.news USING btree (category)
  type news_created_by_idx (line 28) | CREATE INDEX news_created_by_idx ON public.news USING btree (created_by)
  type news_deleted_moderation_category_total_views_tags_created_a_idx (line 30) | CREATE INDEX news_deleted_moderation_category_total_views_tags_created_a...
  type news_pkey (line 32) | CREATE UNIQUE INDEX news_pkey ON public.news USING btree (id)
  type news_tags_idx (line 34) | CREATE INDEX news_tags_idx ON public.news USING gin (tags)
  type news_tenant_id_slug_key (line 36) | CREATE UNIQUE INDEX news_tenant_id_slug_key ON public.news USING btree (...
  function public (line 100) | CREATE OR REPLACE FUNCTION public.news_search_fields(news)
  function public (line 110) | CREATE OR REPLACE FUNCTION public.update_comment_count()

FILE: supabase/migrations/20250416104948_research.sql
  type "public" (line 3) | create table "public"."research" (
  type "public" (line 29) | create table "public"."research_updates" (
  type research_fts_idx (line 52) | CREATE INDEX research_fts_idx ON public.research USING gin (fts)
  type research_pkey (line 54) | CREATE UNIQUE INDEX research_pkey ON public.research USING btree (id)
  type research_update_pkey (line 56) | CREATE UNIQUE INDEX research_update_pkey ON public.research_updates USIN...
  function public (line 80) | CREATE OR REPLACE FUNCTION public.combined_research_search_fields(resear...
  function public (line 92) | CREATE OR REPLACE FUNCTION public.get_research(search_query text DEFAULT...
  function public (line 140) | CREATE OR REPLACE FUNCTION public.update_research_tsvector()
  function public (line 159) | CREATE OR REPLACE FUNCTION public.comment_authors_by_source_id(source_id...
  function public (line 171) | CREATE OR REPLACE FUNCTION public.get_useful_votes_count_by_content_id(p...
  function public (line 186) | CREATE OR REPLACE FUNCTION public.get_user_email_by_id(id uuid)
  function public (line 197) | CREATE OR REPLACE FUNCTION public.get_user_email_by_username(username text)
  function public (line 208) | CREATE OR REPLACE FUNCTION public.get_user_id_by_email(email text)
  function public (line 217) | CREATE OR REPLACE FUNCTION public.is_username_available(username text)
  function public (line 226) | CREATE OR REPLACE FUNCTION public.news_search_fields(news)
  function public (line 234) | CREATE OR REPLACE FUNCTION public.questions_search_fields(questions)
  function public (line 242) | CREATE OR REPLACE FUNCTION public.update_comment_count()
  function public (line 288) | CREATE OR REPLACE FUNCTION public.get_research_count(search_query text D...

FILE: supabase/migrations/20250422092704_add_notifications.sql
  type "public" (line 8) | create table "public"."notifications" (
  type notifications_pkey (line 28) | CREATE UNIQUE INDEX notifications_pkey ON public.notifications USING btr...

FILE: supabase/migrations/20250512170000_research_sorting.sql
  function public (line 2) | CREATE OR REPLACE FUNCTION public.get_research(

FILE: supabase/migrations/20250513090512_update_for_email_notifications.sql
  function public (line 1) | CREATE OR REPLACE FUNCTION public.get_user_email_by_profile_id(id int8)

FILE: supabase/migrations/20250521044802_fix-research-sorting-useful.sql
  function public (line 1) | CREATE OR REPLACE FUNCTION public.get_user_research(username_param text)
  function public (line 22) | CREATE OR REPLACE FUNCTION public.get_research(search_query text DEFAULT...

FILE: supabase/migrations/20250523104253_20250523_add-get-user-questions.sql
  function public (line 1) | CREATE OR REPLACE FUNCTION public.get_user_questions(username_param text)

FILE: supabase/migrations/20250603130017_add_notifications_preferences.sql
  type "public" (line 1) | create table "public"."notifications_preferences" (
  type notifications_preferences_pkey (line 12) | CREATE UNIQUE INDEX notifications_preferences_pkey ON public.notificatio...

FILE: supabase/migrations/20250605115351_research-latest-updated.sql
  function public (line 1) | CREATE OR REPLACE FUNCTION public.get_research(search_query text DEFAULT...

FILE: supabase/migrations/20250609100159_research_query_ranking.sql
  function public (line 1) | CREATE OR REPLACE FUNCTION public.get_research(search_query text DEFAULT...

FILE: supabase/migrations/20250609101144_library.sql
  type "public" (line 1) | create table "public"."project_steps" (
  type "public" (line 16) | create table "public"."projects" (
  type project_steps_pkey (line 47) | CREATE UNIQUE INDEX project_steps_pkey ON public.project_steps USING btr...
  type projects_pkey (line 49) | CREATE UNIQUE INDEX projects_pkey ON public.projects USING btree (id)
  type projects_slug_key (line 51) | CREATE UNIQUE INDEX projects_slug_key ON public.projects USING btree (sl...
  type projects_title_key (line 53) | CREATE UNIQUE INDEX projects_title_key ON public.projects USING btree (t...
  function public (line 89) | CREATE OR REPLACE FUNCTION public.get_projects(search_query text DEFAULT...
  function public (line 158) | CREATE OR REPLACE FUNCTION public.get_projects_count(search_query text D...
  function public (line 182) | CREATE OR REPLACE FUNCTION public.update_project_tsvector()
  function public (line 201) | CREATE OR REPLACE FUNCTION public.get_user_projects(username_param text)

FILE: supabase/migrations/20250621165139_user_research_filter_draft.sql
  function public (line 1) | CREATE OR REPLACE FUNCTION public.get_user_research(username_param text)

FILE: supabase/migrations/20250624101144_replace_get_projects_count.sql
  function public (line 1) | CREATE OR REPLACE FUNCTION public.get_projects_count(search_query text D...

FILE: supabase/migrations/20250624101145_replace_get_user_projects.sql
  function public (line 1) | CREATE OR REPLACE FUNCTION public.get_user_projects(username_param text)

FILE: supabase/migrations/20250624101147_replace_get_user_projects_again.sql
  function public (line 1) | CREATE OR REPLACE FUNCTION public.get_user_projects(username_param text)

FILE: supabase/migrations/20250722145300_profile.sql
  type "public" (line 1) | create table "public"."map_pins" (
  type "public" (line 20) | create table "public"."profile_tags" (
  type "public" (line 30) | create table "public"."profile_tags_relations" (
  type "public" (line 38) | create table "public"."profile_badges" (
  type "public" (line 49) | create table "public"."profile_badges_relations" (
  type "public" (line 58) | create table "public"."profile_types" (
  type "public" (line 73) | create table "public"."map_settings" (
  type map_pins_lat_lng_idx (line 108) | CREATE INDEX map_pins_lat_lng_idx ON public.map_pins USING btree (lat, lng)
  type map_pins_pkey (line 110) | CREATE UNIQUE INDEX map_pins_pkey ON public.map_pins USING btree (id)
  type map_pins_user_id_idx (line 112) | CREATE INDEX map_pins_user_id_idx ON public.map_pins USING btree (profil...
  type profile_tags_pkey (line 114) | CREATE UNIQUE INDEX profile_tags_pkey ON public.profile_tags USING btree...
  type profile_tags_relations_pkey (line 116) | CREATE UNIQUE INDEX profile_tags_relations_pkey ON public.profile_tags_r...
  type profile_badges_pkey (line 118) | CREATE UNIQUE INDEX profile_badges_pkey ON public.profile_badges USING b...
  type profile_badges_relations_pkey (line 120) | CREATE UNIQUE INDEX profile_badges_relations_pkey ON public.profile_badg...
  type profile_types_pkey (line 122) | CREATE UNIQUE INDEX profile_types_pkey ON public.profile_types USING btr...
  function public (line 167) | CREATE OR REPLACE FUNCTION public.get_author_vote_counts(author_id bigint)
  function public (line 545) | CREATE OR REPLACE FUNCTION public.get_projects(search_query text DEFAULT...
  function public (line 627) | CREATE OR REPLACE FUNCTION public.get_research(search_query text DEFAULT...

FILE: supabase/migrations/20250824222054_fix-author-vote-count-deleted.sql
  function public (line 3) | CREATE OR REPLACE FUNCTION public.get_author_vote_counts(author_id bigint)

FILE: supabase/migrations/20250830203011_banner.sql
  type "public" (line 1) | create table "public"."banners" (
  type banner_pkey (line 13) | CREATE UNIQUE INDEX banner_pkey ON public.banners USING btree (id)

FILE: supabase/migrations/20250902101059_map_pins-optimizations.sql
  type idx_map_pins_moderation (line 1) | CREATE INDEX idx_map_pins_moderation ON public.map_pins USING btree (mod...
  type idx_map_pins_moderation_tenant (line 3) | CREATE INDEX idx_map_pins_moderation_tenant ON public.map_pins USING btr...
  type idx_map_pins_tenant_id (line 5) | CREATE INDEX idx_map_pins_tenant_id ON public.map_pins USING btree (tena...
  type idx_profile_badges_relations_badge_id (line 7) | CREATE INDEX idx_profile_badges_relations_badge_id ON public.profile_bad...
  type idx_profile_badges_relations_profile_id (line 9) | CREATE INDEX idx_profile_badges_relations_profile_id ON public.profile_b...
  type idx_profile_badges_relations_tenant_id (line 11) | CREATE INDEX idx_profile_badges_relations_tenant_id ON public.profile_ba...
  type idx_profile_badges_tenant_id (line 13) | CREATE INDEX idx_profile_badges_tenant_id ON public.profile_badges USING...
  type idx_profile_tags_relations_profile_id (line 15) | CREATE INDEX idx_profile_tags_relations_profile_id ON public.profile_tag...
  type idx_profile_tags_relations_tag_id (line 17) | CREATE INDEX idx_profile_tags_relations_tag_id ON public.profile_tags_re...
  type idx_profile_tags_relations_tenant_id (line 19) | CREATE INDEX idx_profile_tags_relations_tenant_id ON public.profile_tags...
  type idx_profile_tags_tenant_id (line 21) | CREATE INDEX idx_profile_tags_tenant_id ON public.profile_tags USING btr...
  type idx_profile_types_tenant_id (line 23) | CREATE INDEX idx_profile_types_tenant_id ON public.profile_types USING b...
  type idx_profiles_profile_type (line 25) | CREATE INDEX idx_profiles_profile_type ON public.profiles USING btree (p...

FILE: supabase/migrations/20250904101010_useful_comments.sql
  function public (line 11) | CREATE OR REPLACE FUNCTION public.get_useful_votes_count_by_content_id(
  function public (line 28) | CREATE OR REPLACE FUNCTION public.get_comments_with_votes(p_source_type ...

FILE: supabase/migrations/20250912091153_fix-delete-comment-trigger.sql
  function public (line 5) | CREATE OR REPLACE FUNCTION public.update_comment_count()

FILE: supabase/migrations/20250912110000_optimize_get_comments_with_votes.sql
  type comments_source_type_source_id_created_at_idx (line 3) | CREATE INDEX IF NOT EXISTS comments_source_type_source_id_created_at_idx...
  type useful_votes_comments_content_id_idx (line 5) | CREATE INDEX IF NOT EXISTS useful_votes_comments_content_id_idx ON publi...
  type useful_votes_comments_user_id_content_id_idx (line 9) | CREATE INDEX IF NOT EXISTS useful_votes_comments_user_id_content_id_idx ...

FILE: supabase/migrations/20250912210000_optimize_profile_indexes.sql
  type profiles_tenant_created_at_idx (line 1) | CREATE INDEX IF NOT EXISTS profiles_tenant_created_at_idx ON public.prof...
  type projects_created_by_idx (line 3) | CREATE INDEX IF NOT EXISTS projects_created_by_idx ON public.projects (c...
  type research_created_by_idx (line 5) | CREATE INDEX IF NOT EXISTS research_created_by_idx ON public.research (c...
  type research_updates_created_by_idx (line 7) | CREATE INDEX IF NOT EXISTS research_updates_created_by_idx ON public.res...
  type questions_created_by_idx (line 9) | CREATE INDEX IF NOT EXISTS questions_created_by_idx ON public.questions ...
  type useful_votes_content_type_content_id_idx (line 11) | CREATE INDEX IF NOT EXISTS useful_votes_content_type_content_id_idx ON p...
  type profile_tags_relations_profile_tenant_idx (line 13) | CREATE INDEX IF NOT EXISTS profile_tags_relations_profile_tenant_idx ON ...
  type profile_badges_relations_profile_tenant_idx (line 15) | CREATE INDEX IF NOT EXISTS profile_badges_relations_profile_tenant_idx O...

FILE: supabase/migrations/20251011132910_fix_messages_receiver.sql
  type banners_pkey (line 25) | CREATE UNIQUE INDEX banners_pkey ON public.banners USING btree (id)
  type questions_pkey (line 27) | CREATE UNIQUE INDEX questions_pkey ON public.questions USING btree (id)
  type research_updates_pkey (line 29) | CREATE UNIQUE INDEX research_updates_pkey ON public.research_updates USI...

FILE: supabase/migrations/20251011234304_fix_function_security_warning.sql
  function "public" (line 3) | CREATE OR REPLACE FUNCTION "public"."comment_authors_by_source_id"("sour...
  function "public" (line 14) | CREATE OR REPLACE FUNCTION "public"."get_comments_with_votes"("p_source_...
  function "public" (line 93) | CREATE OR REPLACE FUNCTION "public"."update_comment_count"() RETURNS "tr...
  function "public" (line 176) | CREATE OR REPLACE FUNCTION "public"."get_user_email_by_id"("id" "uuid") ...
  function "public" (line 185) | CREATE OR REPLACE FUNCTION "public"."get_user_email_by_profile_id"("id" ...
  function "public" (line 194) | CREATE OR REPLACE FUNCTION "public"."get_user_email_by_username"("userna...
  function "public" (line 203) | CREATE OR REPLACE FUNCTION "public"."get_user_id_by_email"("email" "text...
  function "public" (line 211) | CREATE OR REPLACE FUNCTION "public"."news_search_fields"("public"."news"...
  function "public" (line 218) | CREATE OR REPLACE FUNCTION "public"."is_username_available"("username" "...
  function "public" (line 226) | CREATE OR REPLACE FUNCTION "public"."combined_project_search_fields"("pr...
  function "public" (line 237) | CREATE OR REPLACE FUNCTION "public"."get_projects"("search_query" "text"...
  function "public" (line 318) | CREATE OR REPLACE FUNCTION "public"."get_projects_count"("search_query" ...
  function "public" (line 342) | CREATE OR REPLACE FUNCTION "public"."get_user_projects"("username_param"...
  function "public" (line 364) | CREATE OR REPLACE FUNCTION "public"."update_project_tsvector"() RETURNS ...
  function "public" (line 383) | CREATE OR REPLACE FUNCTION "public"."get_user_questions"("username_param...
  function "public" (line 403) | CREATE OR REPLACE FUNCTION "public"."questions_search_fields"("public"."...
  function "public" (line 411) | CREATE OR REPLACE FUNCTION "public"."combined_research_search_fields"("r...
  function "public" (line 422) | CREATE OR REPLACE FUNCTION "public"."get_research"("search_query" "text"...
  function "public" (line 526) | CREATE OR REPLACE FUNCTION "public"."get_research_count"("search_query" ...
  function "public" (line 544) | CREATE OR REPLACE FUNCTION "public"."get_user_research"("username_param"...
  function "public" (line 565) | CREATE OR REPLACE FUNCTION "public"."update_research_tsvector"() RETURNS...
  function "public" (line 584) | CREATE OR REPLACE FUNCTION "public"."get_author_vote_counts"("author_id"...
  function "public" (line 608) | CREATE OR REPLACE FUNCTION "public"."get_useful_votes_count_by_content_i...

FILE: supabase/migrations/20251012135652_fix_policy_performance_2.sql
  function public (line 53) | CREATE OR REPLACE FUNCTION public.combined_project_search_fields(project...
  function public (line 66) | CREATE OR REPLACE FUNCTION public.combined_research_search_fields(resear...
  function public (line 79) | CREATE OR REPLACE FUNCTION public.comment_authors_by_source_id(source_id...
  function public (line 92) | CREATE OR REPLACE FUNCTION public.get_author_vote_counts(author_id bigint)
  function public (line 119) | CREATE OR REPLACE FUNCTION public.get_comments_with_votes(p_source_type ...
  function public (line 200) | CREATE OR REPLACE FUNCTION public.get_projects(search_query text DEFAULT...
  function public (line 283) | CREATE OR REPLACE FUNCTION public.get_projects_count(search_query text D...
  function public (line 309) | CREATE OR REPLACE FUNCTION public.get_research(search_query text DEFAULT...
  function public (line 415) | CREATE OR REPLACE FUNCTION public.get_research_count(search_query text D...
  function public (line 435) | CREATE OR REPLACE FUNCTION public.get_useful_votes_count_by_content_id(p...
  function public (line 451) | CREATE OR REPLACE FUNCTION public.get_user_email_by_id(id uuid)
  function public (line 463) | CREATE OR REPLACE FUNCTION public.get_user_email_by_profile_id(id bigint)
  function public (line 475) | CREATE OR REPLACE FUNCTION public.get_user_email_by_username(username text)
  function public (line 487) | CREATE OR REPLACE FUNCTION public.get_user_id_by_email(email text)
  function public (line 497) | CREATE OR REPLACE FUNCTION public.get_user_projects(username_param text)
  function public (line 521) | CREATE OR REPLACE FUNCTION public.get_user_questions(username_param text)
  function public (line 543) | CREATE OR REPLACE FUNCTION public.get_user_research(username_param text)
  function public (line 566) | CREATE OR REPLACE FUNCTION public.is_username_available(username text)
  function public (line 576) | CREATE OR REPLACE FUNCTION public.news_search_fields(news)
  function public (line 585) | CREATE OR REPLACE FUNCTION public.questions_search_fields(questions)
  function public (line 594) | CREATE OR REPLACE FUNCTION public.update_comment_count()
  function public (line 679) | CREATE OR REPLACE FUNCTION public.update_project_tsvector()
  function public (line 699) | CREATE OR REPLACE FUNCTION public.update_research_tsvector()

FILE: supabase/migrations/20251024140004_fix_get_project_count.sql
  function public (line 3) | CREATE OR REPLACE FUNCTION public.get_projects_count(search_query text D...

FILE: supabase/migrations/20251025145021_add_most_views_sort.sql
  function public (line 3) | CREATE OR REPLACE FUNCTION public.get_projects(search_query text DEFAULT...

FILE: supabase/migrations/20251130000401_create_upgrade_badge_table.sql
  type "public" (line 1) | create table "public"."upgrade_badge" (
  type idx_upgrade_badge_is_space (line 13) | CREATE INDEX idx_upgrade_badge_is_space ON public.upgrade_badge USING bt...
  type idx_upgrade_badge_tenant_id (line 15) | CREATE INDEX idx_upgrade_badge_tenant_id ON public.upgrade_badge USING b...
  type upgrade_badge_pkey (line 17) | CREATE UNIQUE INDEX upgrade_badge_pkey ON public.upgrade_badge USING btr...

FILE: supabase/migrations/20251203151049_research_author_search_fix.sql
  function public (line 3) | CREATE OR REPLACE FUNCTION public.get_projects_count(search_query text D...
  function public (line 33) | CREATE OR REPLACE FUNCTION public.get_research(search_query text DEFAULT...
  function public (line 143) | CREATE OR REPLACE FUNCTION public.get_research_count(search_query text D...

FILE: supabase/migrations/20251217132033_add_most_useful_last_week_feature.sql
  function public (line 7) | CREATE OR REPLACE FUNCTION public.get_projects(search_query text DEFAULT...
  function public (line 102) | CREATE OR REPLACE FUNCTION public.get_research(search_query text DEFAULT...

FILE: supabase/migrations/20260103002808_add_premium_tier.sql
  function public (line 5) | CREATE OR REPLACE FUNCTION public.get_projects(search_query text DEFAULT...
  function public (line 100) | CREATE OR REPLACE FUNCTION public.get_research(search_query text DEFAULT...

FILE: supabase/migrations/20260118140428_update_user_doc_gets.sql
  function public (line 2) | CREATE OR REPLACE FUNCTION public.get_user_projects(username_param text)
  function public (line 29) | CREATE OR REPLACE FUNCTION public.get_user_questions(username_param text)
  function "public" (line 54) | CREATE OR REPLACE FUNCTION "public"."get_user_research"(username_param t...

FILE: supabase/migrations/20260118233300_batch_notifications.sql
  function public (line 3) | CREATE OR REPLACE FUNCTION public.get_subscribed_users_emails_to_notify(...

FILE: supabase/migrations/20260301000000_fix_partial_search.sql
  function public (line 3) | CREATE OR REPLACE FUNCTION public.get_research(search_query text DEFAULT...
  function public (line 123) | CREATE OR REPLACE FUNCTION public.get_research_count(search_query text D...
  function public (line 153) | CREATE OR REPLACE FUNCTION public.get_projects(search_query text DEFAULT...
  function public (line 248) | CREATE OR REPLACE FUNCTION public.get_projects_count(search_query text D...

FILE: supabase/migrations/20260309135320_questions_search_rpc.sql
  function public (line 3) | CREATE OR REPLACE FUNCTION public.get_questions(search_query text DEFAUL...
  function public (line 78) | CREATE OR REPLACE FUNCTION public.get_questions_count(search_query text ...

FILE: supabase/migrations/20260317131051_add_published_at.sql
  function public (line 22) | CREATE OR REPLACE FUNCTION public.get_projects(search_query text DEFAULT...
  function public (line 117) | CREATE OR REPLACE FUNCTION public.get_questions(search_query text DEFAUL...
  function public (line 193) | CREATE OR REPLACE FUNCTION public.get_research(search_query text DEFAULT...

FILE: supabase/migrations/20260322000000_add_get_storage_object_path.sql
  function public (line 1) | CREATE OR REPLACE FUNCTION public.get_storage_object_path(

FILE: supabase/migrations/20260330124656_make_username_nullable.sql
  type profiles_username_tenant_id_key (line 11) | CREATE UNIQUE INDEX profiles_username_tenant_id_key ON public.profiles U...
  function public (line 15) | CREATE OR REPLACE FUNCTION public.is_username_available(username text, e...

FILE: supabase/migrations/20260402103538_search_multiple_words.sql
  function public (line 3) | CREATE OR REPLACE FUNCTION public.get_projects(search_query text DEFAULT...
  function public (line 113) | CREATE OR REPLACE FUNCTION public.get_projects_count(search_query text D...

FILE: supabase/migrations/20260402150623_search_stop_words.sql
  function public (line 3) | CREATE OR REPLACE FUNCTION public.get_projects(search_query text DEFAULT...

FILE: supabase/schemas/banners.sql
  type "public" (line 1) | CREATE TABLE IF NOT EXISTS "public"."banners" (

FILE: supabase/schemas/categories.sql
  type "public" (line 1) | CREATE TABLE IF NOT EXISTS "public"."categories" (

FILE: supabase/schemas/comments.sql
  type "public" (line 1) | CREATE TABLE IF NOT EXISTS "public"."comments" (
  type "public" (line 16) | CREATE INDEX "comments_created_by_idx" ON "public"."comments" USING "btr...
  type "public" (line 17) | CREATE INDEX "comments_source_type_source_id_created_at_idx" ON "public"...
  function "public" (line 26) | CREATE OR REPLACE FUNCTION "public"."comment_authors_by_source_id"("sour...
  function "public" (line 37) | CREATE OR REPLACE FUNCTION "public"."get_comments_with_votes"("p_source_...
  function "public" (line 116) | CREATE OR REPLACE FUNCTION "public"."update_comment_count"() RETURNS "tr...

FILE: supabase/schemas/common.sql
  function "public" (line 9) | CREATE OR REPLACE FUNCTION "public"."get_user_email_by_id"("id" "uuid") ...
  function "public" (line 18) | CREATE OR REPLACE FUNCTION "public"."get_user_email_by_profile_id"("id" ...
  function "public" (line 27) | CREATE OR REPLACE FUNCTION "public"."get_user_email_by_username"("userna...
  function "public" (line 36) | CREATE OR REPLACE FUNCTION "public"."get_user_id_by_email"("email" "text...
  function public (line 43) | CREATE OR REPLACE FUNCTION public.get_storage_object_path(

FILE: supabase/schemas/map.sql
  type "public" (line 1) | CREATE TABLE IF NOT EXISTS "public"."map_pins" (
  type "public" (line 17) | CREATE TABLE IF NOT EXISTS "public"."map_settings" (
  type "public" (line 24) | CREATE INDEX "idx_map_pins_moderation" ON "public"."map_pins" USING "btr...
  type "public" (line 25) | CREATE INDEX "idx_map_pins_moderation_tenant" ON "public"."map_pins" USI...
  type "public" (line 26) | CREATE INDEX "idx_map_pins_tenant_id" ON "public"."map_pins" USING "btre...
  type "public" (line 27) | CREATE INDEX "map_pins_lat_lng_idx" ON "public"."map_pins" USING "btree"...
  type "public" (line 28) | CREATE INDEX "map_pins_user_id_idx" ON "public"."map_pins" USING "btree"...

FILE: supabase/schemas/messages.sql
  type "public" (line 1) | CREATE TABLE IF NOT EXISTS "public"."messages" (

FILE: supabase/schemas/news.sql
  type "public" (line 1) | CREATE TABLE IF NOT EXISTS "public"."news" (
  function "public" (line 25) | CREATE OR REPLACE FUNCTION "public"."news_search_fields"("public"."news"...
  type "public" (line 35) | CREATE INDEX "news_category_idx" ON "public"."news" USING "btree" ("cate...
  type "public" (line 36) | CREATE INDEX "news_created_by_idx" ON "public"."news" USING "btree" ("cr...
  type "public" (line 37) | CREATE INDEX "news_deleted_moderation_category_total_views_tags_created_...
  type "public" (line 38) | CREATE INDEX "news_tags_idx" ON "public"."news" USING "gin" ("tags")

FILE: supabase/schemas/notifications.sql
  type "public" (line 27) | CREATE TABLE IF NOT EXISTS "public"."notifications" (
  type "public" (line 46) | CREATE TABLE IF NOT EXISTS "public"."notifications_preferences" (

FILE: supabase/schemas/patreon.sql
  type "public" (line 1) | CREATE TABLE IF NOT EXISTS "public"."patreon_settings" (

FILE: supabase/schemas/profiles.sql
  type "public" (line 1) | CREATE TABLE IF NOT EXISTS "public"."profile_badges" (
  type "public" (line 11) | CREATE TABLE IF NOT EXISTS "public"."profile_badges_relations" (
  type "public" (line 19) | CREATE TABLE IF NOT EXISTS "public"."profile_tags" (
  type "public" (line 27) | CREATE TABLE IF NOT EXISTS "public"."upgrade_badge" (
  type "public" (line 36) | CREATE TABLE IF NOT EXISTS "public"."profile_tags_relations" (
  type "public" (line 44) | CREATE TABLE IF NOT EXISTS "public"."profile_types" (
  type "public" (line 57) | CREATE TABLE IF NOT EXISTS "public"."profiles" (
  type "public" (line 88) | CREATE INDEX "idx_profile_badges_relations_badge_id" ON "public"."profil...
  type "public" (line 89) | CREATE INDEX "idx_profile_badges_relations_profile_id" ON "public"."prof...
  type "public" (line 90) | CREATE INDEX "idx_profile_badges_relations_tenant_id" ON "public"."profi...
  type "public" (line 91) | CREATE INDEX "idx_profile_badges_tenant_id" ON "public"."profile_badges"...
  type "public" (line 92) | CREATE INDEX "idx_profile_tags_relations_profile_id" ON "public"."profil...
  type "public" (line 93) | CREATE INDEX "idx_profile_tags_relations_tag_id" ON "public"."profile_ta...
  type "public" (line 94) | CREATE INDEX "idx_profile_tags_relations_tenant_id" ON "public"."profile...
  type "public" (line 95) | CREATE INDEX "idx_profile_tags_tenant_id" ON "public"."profile_tags" USI...
  type "public" (line 96) | CREATE INDEX "idx_profile_types_tenant_id" ON "public"."profile_types" U...
  type "public" (line 97) | CREATE INDEX "idx_profiles_profile_type" ON "public"."profiles" USING "b...
  type "public" (line 98) | CREATE INDEX "idx_upgrade_badge_tenant_id" ON "public"."upgrade_badge" U...
  type "public" (line 99) | CREATE INDEX "idx_upgrade_badge_is_space" ON "public"."upgrade_badge" US...
  type "public" (line 101) | CREATE INDEX "profile_badges_relations_profile_tenant_idx" ON "public"."...
  type "public" (line 102) | CREATE INDEX "profile_tags_relations_profile_tenant_idx" ON "public"."pr...
  type "public" (line 103) | CREATE INDEX "profiles_firebase_auth_id_idx" ON "public"."profiles" USIN...
  type "public" (line 104) | CREATE INDEX "profiles_tenant_created_at_idx" ON "public"."profiles" USI...
  type "public" (line 105) | CREATE UNIQUE INDEX "profiles_username_tenant_id_key" ON "public"."profi...
  function "public" (line 144) | CREATE OR REPLACE FUNCTION "public"."is_username_available"("username" "...

FILE: supabase/schemas/projects.sql
  type "public" (line 1) | CREATE TABLE IF NOT EXISTS "public"."project_steps" (
  type "public" (line 13) | CREATE TABLE IF NOT EXISTS "public"."projects" (
  type "public" (line 48) | CREATE INDEX "projects_created_by_idx" ON "public"."projects" USING "btr...
  function "public" (line 67) | CREATE OR REPLACE FUNCTION "public"."combined_project_search_fields"("pr...
  function "public" (line 78) | CREATE OR REPLACE FUNCTION "public"."get_projects"("search_query" "text"...
  function "public" (line 249) | CREATE OR REPLACE FUNCTION "public"."update_project_tsvector"() RETURNS ...

FILE: supabase/schemas/questions.sql
  function public (line 1) | CREATE OR REPLACE FUNCTION public.get_user_questions(username_param text)
  type "public" (line 25) | CREATE TABLE IF NOT EXISTS "public"."questions" (
  function "public" (line 48) | CREATE OR REPLACE FUNCTION "public"."questions_search_fields"("public"."...

FILE: supabase/schemas/research.sql
  type "public" (line 7) | CREATE TABLE IF NOT EXISTS "public"."research" (
  type "public" (line 31) | CREATE TABLE IF NOT EXISTS "public"."research_updates" (
  type "public" (line 52) | CREATE INDEX "research_created_by_idx" ON "public"."research" USING "btr...
  type "public" (line 53) | CREATE INDEX "research_fts_idx" ON "public"."research" USING "gin" ("fts")
  type "public" (line 54) | CREATE INDEX "research_updates_created_by_idx" ON "public"."research_upd...
  function "public" (line 75) | CREATE OR REPLACE FUNCTION "public"."combined_research_search_fields"("r...
  function "public" (line 86) | CREATE OR REPLACE FUNCTION "public"."get_research"("search_query" "text"...
  function "public" (line 216) | CREATE OR REPLACE FUNCTION "public"."get_research_count"("search_query" ...
  function "public" (line 280) | CREATE OR REPLACE FUNCTION "public"."update_research_tsvector"() RETURNS...

FILE: supabase/schemas/subscribers.sql
  type "public" (line 1) | CREATE TABLE IF NOT EXISTS "public"."subscribers" (

FILE: supabase/schemas/tags.sql
  type "public" (line 1) | CREATE TABLE IF NOT EXISTS "public"."tags" (

FILE: supabase/schemas/tenant_settings.sql
  type "public" (line 1) | CREATE TABLE IF NOT EXISTS "public"."tenant_settings" (

FILE: supabase/schemas/useful.sql
  type "public" (line 9) | CREATE TABLE IF NOT EXISTS "public"."useful_votes" (
  type "public" (line 18) | CREATE INDEX "useful_votes_comments_content_id_idx" ON "public"."useful_...
  type "public" (line 19) | CREATE INDEX "useful_votes_comments_user_id_content_id_idx" ON "public"....
  type "public" (line 20) | CREATE INDEX "useful_votes_content_type_content_id_idx" ON "public"."use...
  function "public" (line 29) | CREATE OR REPLACE FUNCTION "public"."get_author_vote_counts"("author_id"...
  function "public" (line 53) | CREATE OR REPLACE FUNCTION "public"."get_useful_votes_count_by_content_i...

FILE: vite.config.ts
  method manualChunks (line 48) | manualChunks(id) {
Condensed preview — 1080 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (3,114K chars).
[
  {
    "path": ".all-contributorsrc",
    "chars": 30976,
    "preview": "{\n  \"files\": [\n    \"README.md\"\n  ],\n  \"imageSize\": 60,\n  \"contributorsPerLine\": 7,\n  \"contributorsSortAlphabetically\": f"
  },
  {
    "path": ".circleci/config.yml",
    "chars": 13043,
    "preview": "version: 2.1\n######################################################################################################\n# Pr"
  },
  {
    "path": ".dockerignore",
    "chars": 335,
    "preview": "*node_modules*\ndump\nbuild\n.circleci\n.github\n.nxs\n.yarn\n.yarnrc.yml\nyarn.lock\ndocs\npackages/cypress\npackages/documentatio"
  },
  {
    "path": ".github/CODEOWNERS",
    "chars": 22,
    "preview": "* @ONEARMY/maintainers"
  },
  {
    "path": ".github/ISSUE_TEMPLATE/bug_report.md",
    "chars": 560,
    "preview": "---\nname: Bug report\nabout: Create a report to help us improve\ntitle: '[bug]'\nlabels: \"Type:Bug\\U0001F41B\"\nassignees: ''"
  },
  {
    "path": ".github/ISSUE_TEMPLATE/build-new-component.md",
    "chars": 848,
    "preview": "---\nname: Build new component\nabout: Describe the new component you want to build\ntitle: ''\nlabels: ''\nassignees: ''\n---"
  },
  {
    "path": ".github/ISSUE_TEMPLATE/feature-request-or-suggestion.md",
    "chars": 643,
    "preview": "---\nname: Feature request or suggestion\nabout: Suggest an idea for this project\ntitle: '[feature request]'\nlabels: 'Feed"
  },
  {
    "path": ".github/actions/destroy-fly-preview-app/Dockerfile",
    "chars": 208,
    "preview": "FROM alpine\n\nRUN apk add --no-cache curl jq\n\nRUN curl -L https://fly.io/install.sh | FLYCTL_INSTALL=/usr/local sh\n\nCOPY "
  },
  {
    "path": ".github/actions/destroy-fly-preview-app/action.yml",
    "chars": 235,
    "preview": "name: \"Destroy fly.io app\"\ndescription: \"Destroy fly.io app if matching app name found\"\nauthor: iSCJT\nbranding:\n  icon: "
  },
  {
    "path": ".github/actions/destroy-fly-preview-app/entrypoint.sh",
    "chars": 237,
    "preview": "#!/bin/sh -l\n\nset -ex\n\n# Change underscores to hyphens.\napp=\"${INPUT_NAME//_/-}\"\n\n\nif ! flyctl status --app \"$app\"; then"
  },
  {
    "path": ".github/labels.yml",
    "chars": 2597,
    "preview": "# This is currently just an export of labels used in the project\n# In the future we could also use to add more and keep "
  },
  {
    "path": ".github/pull_request_template.md",
    "chars": 1164,
    "preview": "## PR Checklist\n\n- [ ] - Unit and/or e2e tests for the changes that have been added (for bug fixes / features)\n\n## What "
  },
  {
    "path": ".github/workflows/codeql-analysis.yml",
    "chars": 815,
    "preview": "name: 'CodeQL'\n\non:\n  push:\n    branches: [master]\n  pull_request:\n    branches: [master]\n  schedule:\n    - cron: '35 21"
  },
  {
    "path": ".github/workflows/pr-preview-fly-deploy.yml",
    "chars": 1695,
    "preview": "name: Deploy Fly PR Preview\non:\n  pull_request_target:\n    types: [labeled, synchronize]\n\nenv:\n  FLY_API_TOKEN: ${{ secr"
  },
  {
    "path": ".github/workflows/pr-preview-fly-destroy.yml",
    "chars": 787,
    "preview": "name: Destroy Fly PR Preview\n\non:\n  pull_request_target:\n    types:\n      - unlabeled\n      - closed\n\nenv:\n  FLY_API_TOK"
  },
  {
    "path": ".github/workflows/pr-preview-remove-label.yml",
    "chars": 1175,
    "preview": "name: Remove PR Preview Label\non:\n  # Run this workflow on every PR event. Existing review apps will be updated when the"
  },
  {
    "path": ".github/workflows/pr-stale.yml",
    "chars": 539,
    "preview": "name: 'Close stale issues and PRs'\non:\n  schedule:\n    - cron: '30 1 * * *'\n\njobs:\n  stale:\n    runs-on: ubuntu-latest\n "
  },
  {
    "path": ".github/workflows/storybook-deploy.yml",
    "chars": 2024,
    "preview": "# Build and deploy Storybook to GitHub Pages\nname: Storybook Deploy\non:\n  push:\n    branches:\n      - master\n    # Only "
  },
  {
    "path": ".gitignore",
    "chars": 610,
    "preview": "# See https://help.github.com/ignore-files/ for more about ignoring files.\n\n# dependencies\nnode_modules\n\n# testing\n/cove"
  },
  {
    "path": ".husky/pre-commit",
    "chars": 22,
    "preview": "  bun run lint-staged\n"
  },
  {
    "path": ".node-version",
    "chars": 8,
    "preview": "22.18.0\n"
  },
  {
    "path": ".releaserc.json",
    "chars": 586,
    "preview": "{\n  \"branches\": [\"master\"],\n  \"ci\": false,\n  \"plugins\": [\n    [\n      \"@semantic-release/commit-analyzer\",\n      {\n     "
  },
  {
    "path": ".snaplet/config.json",
    "chars": 22,
    "preview": "{\n  \"adapter\": \"pg\"\n}\n"
  },
  {
    "path": ".snaplet/dataModel.json",
    "chars": 351092,
    "preview": "{\n  \"models\": {\n    \"_http_response\": {\n      \"id\": \"net._http_response\",\n      \"schemaName\": \"net\",\n      \"tableName\": "
  },
  {
    "path": ".snaplet/library.json",
    "chars": 5749,
    "preview": "[\n  {\n    \"title\": \"Basic Shredder Machine\",\n    \"description\": \"Learn how to build a basic plastic shredder machine for"
  },
  {
    "path": ".snaplet/questions.json",
    "chars": 5244,
    "preview": "{\n  \"jereerickson92\": [\n    {\n      \"title\": \"What is Precious Plastic?\",\n      \"description\": \"Explain the mission and "
  },
  {
    "path": ".vscode/launch.json",
    "chars": 800,
    "preview": "{\n  // Use IntelliSense to learn about possible attributes.\n  // Hover to view descriptions of existing attributes.\n  //"
  },
  {
    "path": ".yarnrc.yml",
    "chars": 276,
    "preview": "checksumBehavior: update\n\ncompressionLevel: mixed\n\nenableGlobalCache: false\n\nenableScripts: false\n\nlogFilters:\n  - code:"
  },
  {
    "path": "CNAME",
    "chars": 23,
    "preview": "storybook.onearmy.earth"
  },
  {
    "path": "CODE_OF_CONDUCT.md",
    "chars": 3437,
    "preview": "# Contributor Covenant Code of Conduct\n\n## Our Pledge\n\nIn the interest of fostering an open and welcoming environment, w"
  },
  {
    "path": "CONTRIBUTING.md",
    "chars": 7365,
    "preview": "# Contribution Guidelines\n\nThanks for being here already! You'll find all the information you need to start contributing"
  },
  {
    "path": "Dockerfile",
    "chars": 1275,
    "preview": "# syntax = docker/dockerfile:1\n\nFROM oven/bun:1.3.10 AS base\n\nLABEL fly_launch_runtime=\"React Router\"\n\n# App lives here\n"
  },
  {
    "path": "Dockerfile.preview",
    "chars": 991,
    "preview": "# syntax = docker/dockerfile:1\n\nFROM oven/bun:1.3.10 AS base\n\nLABEL fly_launch_runtime=\"React Router\"\n\n# App lives here\n"
  },
  {
    "path": "FUNDING.yml",
    "chars": 90,
    "preview": "# These are supported funding model platforms\n\npatreon: one_army\nopen_collective: onearmy\n"
  },
  {
    "path": "LICENSE",
    "chars": 1069,
    "preview": "MIT License\n\nCopyright (c) 2026 OneArmyWorld\n\nPermission is hereby granted, free of charge, to any person obtaining a co"
  },
  {
    "path": "README.md",
    "chars": 48527,
    "preview": "[![Gitpod Ready-to-Code](https://img.shields.io/badge/Gitpod-Ready--to--Code-blue?logo=gitpod)](https://gitpod.io/from-r"
  },
  {
    "path": "SECURITY.md",
    "chars": 1202,
    "preview": "# Security Policy\n\n# Reporting Security Issues\n\nIf you believe you have found a security vulnerability on our platform, "
  },
  {
    "path": "biome.json",
    "chars": 4973,
    "preview": "{\n  \"$schema\": \"https://biomejs.dev/schemas/2.4.4/schema.json\",\n  \"vcs\": { \"enabled\": true, \"clientKind\": \"git\", \"useIgn"
  },
  {
    "path": "codecov.yml",
    "chars": 177,
    "preview": "ignore:\n  - \"packages/documentation\"\ncoverage: \n  status: \n    project:\n      default:\n        target: auto\n        thre"
  },
  {
    "path": "docs/circle-ci.md",
    "chars": 277,
    "preview": "# Deployment via CircleCI\n\nWe use CircleCI to handle automated build-test-deploy cycles when PRs and releases are create"
  },
  {
    "path": "docs/db-seeding.md",
    "chars": 676,
    "preview": "# Supabase seeding\n\nThis file describes how supabase seeding works.\n\n## Snaplet\n\nSnaplet is a tool used to seed mostly P"
  },
  {
    "path": "docs/maintainers.md",
    "chars": 1521,
    "preview": "### ⚡️ Things that Maintainers do:\n\n#### Review incoming code from Contributors\n\n1. Validate code quality and give feedb"
  },
  {
    "path": "docs/pwa-setup.md",
    "chars": 1560,
    "preview": "# PWA Setup Documentation\n\n## Overview\n\nThis project has Progressive Web App (PWA) capabilities configured for React Rou"
  },
  {
    "path": "docs/react-router-7.md",
    "chars": 878,
    "preview": "### What is React Router 7?\nA React Fullstack Framework that provides server-side rendering and an API Layer.\nhttps://re"
  },
  {
    "path": "docs/supabase.md",
    "chars": 3636,
    "preview": "# What is Supabase?\n\nSupabase is an open source Firebase alternative, based on Postgres.\n\n## Getting Started\n\n### Local "
  },
  {
    "path": "docs/team-principles.md",
    "chars": 660,
    "preview": "---\nid: team-principles\ntitle: Team Principles\n---\n\nThe principles we hold close to guide the work we prioritise, the wa"
  },
  {
    "path": "docs/technical-decisions.md",
    "chars": 5352,
    "preview": "# Technical Decisions\n\n## Multi-tenant\n\nMulti-tenancy is a requirement because:\n\n- Single login for all websites.\n- Easi"
  },
  {
    "path": "fly-ff.toml",
    "chars": 304,
    "preview": "app = 'community-platform-ff'\nprimary_region = 'ams'\n\n[build]\n\n[http_service]\ninternal_port = 3000\nforce_https = true\nau"
  },
  {
    "path": "fly-pk.toml",
    "chars": 275,
    "preview": "app = 'community-platform-pk'\nprimary_region = 'ams'\n\n[build]\n\n[http_service]\ninternal_port = 3000\nforce_https = true\nau"
  },
  {
    "path": "fly-pp.toml",
    "chars": 275,
    "preview": "app = 'community-platform-pp'\nprimary_region = 'ams'\n\n[build]\n\n[http_service]\ninternal_port = 3000\nforce_https = true\nau"
  },
  {
    "path": "fly-preview.toml",
    "chars": 253,
    "preview": "primary_region = 'ams'\n\n[build]\ndockerfile = \"Dockerfile.preview\"\n\n[http_service]\ninternal_port = 3000\nforce_https = tru"
  },
  {
    "path": "index.html",
    "chars": 2465,
    "preview": "<!doctype html>\n<html lang=\"en\">\n  <head>\n    <meta charset=\"utf-8\" />\n    <meta\n      name=\"viewport\"\n      content=\"wi"
  },
  {
    "path": "package.json",
    "chars": 5738,
    "preview": "{\n  \"name\": \"one-army-community-platform\",\n  \"repository\": {\n    \"type\": \"git\",\n    \"url\": \"https://github.com/ONEARMY/c"
  },
  {
    "path": "packages/components/.gitignore",
    "chars": 51,
    "preview": "node_modules\nstorybook-static\ndist\ncoverage\nreports"
  },
  {
    "path": "packages/components/.storybook/main.ts",
    "chars": 749,
    "preview": "import type { StorybookConfig } from '@storybook/react-vite';\nimport { createRequire } from 'module';\nimport { dirname, "
  },
  {
    "path": "packages/components/.storybook/manager.js",
    "chars": 636,
    "preview": "import { addons } from 'storybook/manager-api';\nimport { create } from 'storybook/theming';\n\naddons.setConfig({\n  isFull"
  },
  {
    "path": "packages/components/.storybook/preview.tsx",
    "chars": 3045,
    "preview": "import { Global } from '@emotion/react';\nimport type { Preview } from '@storybook/react-vite';\nimport { ThemeProvider } "
  },
  {
    "path": "packages/components/README.md",
    "chars": 1936,
    "preview": "# Platform Components\n\nA collection of react components for reuse across the platform. Built with [Theme UI](https://the"
  },
  {
    "path": "packages/components/package.json",
    "chars": 2577,
    "preview": "{\n  \"name\": \"oa-components\",\n  \"version\": \"1.0.0\",\n  \"private\": true,\n  \"type\": \"module\",\n  \"exports\": {\n    \".\": {\n    "
  },
  {
    "path": "packages/components/src/Accordion/Accordion.stories.tsx",
    "chars": 388,
    "preview": "import { Text } from 'theme-ui';\n\nimport { Accordion } from './Accordion';\n\nimport type { Meta, StoryFn } from '@storybo"
  },
  {
    "path": "packages/components/src/Accordion/Accordion.test.tsx",
    "chars": 744,
    "preview": "import '@testing-library/jest-dom/vitest';\n\nimport { act, screen } from '@testing-library/react';\nimport { Text } from '"
  },
  {
    "path": "packages/components/src/Accordion/Accordion.tsx",
    "chars": 1216,
    "preview": "import { useState } from 'react';\nimport type { ThemeUIStyleObject } from 'theme-ui';\nimport { Flex, Heading, Text } fro"
  },
  {
    "path": "packages/components/src/ActionSet/ActionSet.tsx",
    "chars": 1913,
    "preview": "import type { ReactNode } from 'react';\nimport { useEffect, useRef, useState } from 'react';\nimport { Card, Flex } from "
  },
  {
    "path": "packages/components/src/Alert/Alert.stories.tsx",
    "chars": 1121,
    "preview": "import { Alert } from 'theme-ui';\n\nimport type { Meta, StoryFn } from '@storybook/react-vite';\n\nexport default {\n  title"
  },
  {
    "path": "packages/components/src/ArrowIcon/ArrowIcon.stories.tsx",
    "chars": 528,
    "preview": "import { Arrow } from './ArrowIcon';\n\nimport type { Meta, StoryFn } from '@storybook/react-vite';\n\nexport default {\n  /*"
  },
  {
    "path": "packages/components/src/ArrowIcon/ArrowIcon.tsx",
    "chars": 1349,
    "preview": "import type { ThemeUIStyleObject } from 'theme-ui';\nimport { Flex } from 'theme-ui';\nimport { Icon } from '../Icon/Icon'"
  },
  {
    "path": "packages/components/src/ArrowIcon/styles.css",
    "chars": 302,
    "preview": ".react-horizontal-scrolling-menu--inner-wrapper {\n  position: relative;\n}\n\n.react-horizontal-scrolling-menu--arrow-left "
  },
  {
    "path": "packages/components/src/ArticleCallToActionSupabase/ArticleCallToActionSupabase.stories.tsx",
    "chars": 3067,
    "preview": "import { faker } from '@faker-js/faker';\n\nimport { Button } from '../Button/Button';\nimport { UsefulStatsButton } from '"
  },
  {
    "path": "packages/components/src/ArticleCallToActionSupabase/ArticleCallToActionSupabase.tsx",
    "chars": 1395,
    "preview": "import type { Author } from 'oa-shared';\nimport { Flex, Heading, Text } from 'theme-ui';\nimport { Username } from '../Us"
  },
  {
    "path": "packages/components/src/AuthorDisplay/AuthorDisplay.tsx",
    "chars": 703,
    "preview": "import type { Author } from 'oa-shared';\nimport { Avatar, Flex } from 'theme-ui';\nimport { Username } from '../Username/"
  },
  {
    "path": "packages/components/src/Banner/Banner.stories.tsx",
    "chars": 816,
    "preview": "import { Banner } from './Banner';\n\nimport type { Meta, StoryFn } from '@storybook/react-vite';\n\nexport default {\n  titl"
  },
  {
    "path": "packages/components/src/Banner/Banner.test.tsx",
    "chars": 476,
    "preview": "import { fireEvent } from '@testing-library/react';\nimport { describe, expect, it, vi } from 'vitest';\n\nimport { render "
  },
  {
    "path": "packages/components/src/Banner/Banner.tsx",
    "chars": 881,
    "preview": "import type { ThemeUIStyleObject } from 'theme-ui';\nimport { Alert } from 'theme-ui';\n\n// Types of alert currently speci"
  },
  {
    "path": "packages/components/src/BlockedRoute/BlockedRoute.stories.tsx",
    "chars": 587,
    "preview": "import { faker } from '@faker-js/faker';\n\nimport { BlockedRoute } from './BlockedRoute';\n\nimport type { Meta, StoryFn } "
  },
  {
    "path": "packages/components/src/BlockedRoute/BlockedRoute.tsx",
    "chars": 880,
    "preview": "import { Box, Flex, Text } from 'theme-ui';\n\nimport { Button } from '../Button/Button';\nimport { InternalLink } from '.."
  },
  {
    "path": "packages/components/src/Breadcrumbs/Breadcrumbs.stories.tsx",
    "chars": 748,
    "preview": "import { Breadcrumbs } from './Breadcrumbs';\n\nimport type { Meta, StoryFn } from '@storybook/react-vite';\n\nexport defaul"
  },
  {
    "path": "packages/components/src/Breadcrumbs/Breadcrumbs.test.tsx",
    "chars": 1422,
    "preview": "import '@testing-library/jest-dom/vitest';\n\nimport { describe, expect, it } from 'vitest';\n\nimport { render } from '../t"
  },
  {
    "path": "packages/components/src/Breadcrumbs/Breadcrumbs.tsx",
    "chars": 1104,
    "preview": "import { Flex } from 'theme-ui';\n\nimport { Icon } from '../Icon/Icon';\nimport { BreadcrumbItem } from './BreadcrumbsItem"
  },
  {
    "path": "packages/components/src/Breadcrumbs/BreadcrumbsItem.tsx",
    "chars": 1275,
    "preview": "import { Link } from 'react-router';\nimport { Box, Text } from 'theme-ui';\n\nimport { Button } from '../Button/Button';\n\n"
  },
  {
    "path": "packages/components/src/Button/Button.stories.tsx",
    "chars": 3708,
    "preview": "import { glyphs } from '../Icon/Icon';\nimport { Button } from './Button';\n\nimport type { Meta, StoryFn } from '@storyboo"
  },
  {
    "path": "packages/components/src/Button/Button.tsx",
    "chars": 3363,
    "preview": "import type { Colors } from 'oa-themes';\nimport React from 'react';\nimport type { ButtonProps as ThemeUiButtonProps } fr"
  },
  {
    "path": "packages/components/src/ButtonIcon/ButtonIcon.stories.tsx",
    "chars": 293,
    "preview": "import { ButtonIcon } from './ButtonIcon';\n\nimport type { Meta, StoryFn } from '@storybook/react-vite';\n\nexport default "
  },
  {
    "path": "packages/components/src/ButtonIcon/ButtonIcon.tsx",
    "chars": 530,
    "preview": "import type { ThemeUIStyleObject } from 'theme-ui';\nimport { Button } from 'theme-ui';\nimport { Icon } from '../Icon/Ico"
  },
  {
    "path": "packages/components/src/ButtonShowReplies/ButtonShowReplies.stories.tsx",
    "chars": 1610,
    "preview": "import { useState } from 'react';\n\nimport { createFakeCommentsSB } from '../utils';\nimport { ButtonShowReplies } from '."
  },
  {
    "path": "packages/components/src/ButtonShowReplies/ButtonShowReplies.test.tsx",
    "chars": 1531,
    "preview": "import '@testing-library/jest-dom/vitest';\n\nimport { describe, expect, it } from 'vitest';\n\nimport { render } from '../t"
  },
  {
    "path": "packages/components/src/ButtonShowReplies/ButtonShowReplies.tsx",
    "chars": 934,
    "preview": "import type { Comment } from 'oa-shared';\nimport { Button } from '../Button/Button';\n\nexport interface Props {\n  isShowR"
  },
  {
    "path": "packages/components/src/CardButton/CardButton.stories.tsx",
    "chars": 436,
    "preview": "import { CardButton } from './CardButton';\n\nimport type { Meta, StoryFn } from '@storybook/react-vite';\n\nexport default "
  },
  {
    "path": "packages/components/src/CardButton/CardButton.tsx",
    "chars": 1418,
    "preview": "import type { BoxProps, ThemeUIStyleObject } from 'theme-ui';\nimport { Card } from 'theme-ui';\n\nexport interface IProps "
  },
  {
    "path": "packages/components/src/CardListItem/CardListItem.stories.tsx",
    "chars": 2252,
    "preview": "import { faker } from '@faker-js/faker';\n\nimport { CardListItem } from './CardListItem';\n\nimport type { Meta, StoryFn } "
  },
  {
    "path": "packages/components/src/CardListItem/CardListItem.tsx",
    "chars": 1299,
    "preview": "import type { MapPin } from 'oa-shared';\nimport { Box } from 'theme-ui';\nimport { CardButton } from '../CardButton/CardB"
  },
  {
    "path": "packages/components/src/CardProfile/CardDetailsMemberProfile.tsx",
    "chars": 1697,
    "preview": "import type { PinProfile } from 'oa-shared';\nimport { Avatar, Box, Flex } from 'theme-ui';\nimport defaultProfileImage fr"
  },
  {
    "path": "packages/components/src/CardProfile/CardDetailsSpaceProfile.tsx",
    "chars": 2452,
    "preview": "import type { PinProfile } from 'oa-shared';\nimport { Box, Flex, Image, Text } from 'theme-ui';\nimport { MemberBadge } f"
  },
  {
    "path": "packages/components/src/CardProfile/CardProfile.stories.tsx",
    "chars": 701,
    "preview": "import { fakePinProfile, fakeProfileType } from '../utils';\nimport { CardProfile } from './CardProfile';\n\nimport type { "
  },
  {
    "path": "packages/components/src/CardProfile/CardProfile.test.tsx",
    "chars": 903,
    "preview": "import '@testing-library/jest-dom/vitest';\n\nimport { describe, expect, it } from 'vitest';\n\nimport { render } from '../t"
  },
  {
    "path": "packages/components/src/CardProfile/CardProfile.tsx",
    "chars": 722,
    "preview": "import type { MapPin } from 'oa-shared';\nimport { Flex } from 'theme-ui';\nimport { CardDetailsMemberProfile } from './Ca"
  },
  {
    "path": "packages/components/src/Category/Category.stories.tsx",
    "chars": 414,
    "preview": "import { Category } from './Category';\n\nimport type { Meta, StoryFn } from '@storybook/react-vite';\nimport type { Catego"
  },
  {
    "path": "packages/components/src/Category/Category.tsx",
    "chars": 657,
    "preview": "import type { Category as CategoryType } from 'oa-shared';\nimport type { ThemeUIStyleObject } from 'theme-ui';\nimport { "
  },
  {
    "path": "packages/components/src/CategoryHorizonalList/CategoryHorizonalList.stories.tsx",
    "chars": 4277,
    "preview": "import { useState } from 'react';\n\nimport { CategoryHorizonalList } from './CategoryHorizonalList';\n\nimport type { Meta,"
  },
  {
    "path": "packages/components/src/CategoryHorizonalList/CategoryHorizonalList.test.tsx",
    "chars": 4930,
    "preview": "import '@testing-library/jest-dom/vitest';\n\nimport { beforeEach, describe, expect, it, vi } from 'vitest';\n\nimport { ren"
  },
  {
    "path": "packages/components/src/CategoryHorizonalList/CategoryHorizonalList.tsx",
    "chars": 2495,
    "preview": "import type { Category } from 'oa-shared';\nimport { Text } from 'theme-ui';\nimport { CardButton } from '../CardButton/Ca"
  },
  {
    "path": "packages/components/src/CharacterCount/CharacterCount.stories.tsx",
    "chars": 975,
    "preview": "import { CharacterCount } from './CharacterCount';\n\nimport type { Meta, StoryFn } from '@storybook/react-vite';\n\nexport "
  },
  {
    "path": "packages/components/src/CharacterCount/CharacterCount.tsx",
    "chars": 1172,
    "preview": "import { Text } from 'theme-ui';\n\nexport interface ICharacterCountProps {\n  currentSize: number;\n  minSize: number;\n  ma"
  },
  {
    "path": "packages/components/src/CommentAvatar/CommentAvatar.tsx",
    "chars": 1320,
    "preview": "import { Avatar, Image } from 'theme-ui';\n\nimport defaultBaloonUrl from '../../assets/images/author.svg';\nimport default"
  },
  {
    "path": "packages/components/src/CommentBody/CommentBody.tsx",
    "chars": 1349,
    "preview": "import { useEffect, useRef, useState } from 'react';\nimport { Text } from 'theme-ui';\n\nimport { LinkifyText } from '../L"
  },
  {
    "path": "packages/components/src/CommentDisplay/CommentDisplay.stories.tsx",
    "chars": 4924,
    "preview": "import { fakeCommentSB } from '../utils';\nimport { CommentDisplay } from './CommentDisplay';\n\nimport type { Meta, StoryF"
  },
  {
    "path": "packages/components/src/CommentDisplay/CommentDisplay.test.tsx",
    "chars": 4079,
    "preview": "import '@testing-library/jest-dom/vitest';\n\nimport { fireEvent } from '@testing-library/react';\nimport { beforeEach, des"
  },
  {
    "path": "packages/components/src/CommentDisplay/CommentDisplay.tsx",
    "chars": 3569,
    "preview": "import type { Comment } from 'oa-shared';\nimport { useContext } from 'react';\nimport { Box, Flex, Text } from 'theme-ui'"
  },
  {
    "path": "packages/components/src/CommentsTitle/CommentsTitle.stories.tsx",
    "chars": 692,
    "preview": "import { CommentsTitle } from './CommentsTitle';\n\nimport type { Meta, StoryFn } from '@storybook/react-vite';\nimport typ"
  },
  {
    "path": "packages/components/src/CommentsTitle/CommentsTitle.test.tsx",
    "chars": 987,
    "preview": "import '@testing-library/jest-dom/vitest';\n\nimport { describe, expect, it } from 'vitest';\n\nimport { render } from '../t"
  },
  {
    "path": "packages/components/src/CommentsTitle/CommentsTitle.tsx",
    "chars": 850,
    "preview": "import type { Comment } from 'oa-shared';\nimport { useMemo } from 'react';\nimport { Heading } from 'theme-ui';\n\nexport c"
  },
  {
    "path": "packages/components/src/ConfirmModal/ConfirmModal.stories.tsx",
    "chars": 470,
    "preview": "import { ConfirmModal } from './ConfirmModal';\n\nimport type { Meta, StoryFn } from '@storybook/react-vite';\n\nexport defa"
  },
  {
    "path": "packages/components/src/ConfirmModal/ConfirmModal.tsx",
    "chars": 1640,
    "preview": "import { Flex, Text } from 'theme-ui';\n\nimport { Button } from '../Button/Button';\nimport { Modal } from '../Modal/Modal"
  },
  {
    "path": "packages/components/src/ContentStatistics/ContentStatistics.stories.tsx",
    "chars": 1349,
    "preview": "import { faker } from '@faker-js/faker';\n\nimport { ContentStatistics } from './ContentStatistics';\n\nimport type { Meta, "
  },
  {
    "path": "packages/components/src/ContentStatistics/ContentStatistics.tsx",
    "chars": 2471,
    "preview": "import React, { cloneElement, isValidElement, useCallback, useState } from 'react';\nimport { Flex, Text } from 'theme-ui"
  },
  {
    "path": "packages/components/src/ContentStatistics/ContentStatisticsList.tsx",
    "chars": 1786,
    "preview": "import { Flex, Text } from 'theme-ui';\n\nimport { Icon } from '../Icon/Icon';\nimport { Tooltip } from '../Tooltip/Tooltip"
  },
  {
    "path": "packages/components/src/ContentStatistics/types.ts",
    "chars": 255,
    "preview": "import type { availableGlyphs } from '../Icon/types';\n\nexport type IStatistic = {\n  icon: availableGlyphs;\n  label: stri"
  },
  {
    "path": "packages/components/src/CreateComment/CreateComment.css",
    "chars": 1184,
    "preview": "/* https://css-tricks.com/the-cleanest-trick-for-autogrowing-textareas/ */\n.grow-wrap {\n  /* easy way to plop the elemen"
  },
  {
    "path": "packages/components/src/CreateComment/CreateComment.stories.tsx",
    "chars": 3931,
    "preview": "import { useState } from 'react';\nimport { faker } from '@faker-js/faker';\n\nimport { CreateComment } from './CreateComme"
  },
  {
    "path": "packages/components/src/CreateComment/CreateComment.test.tsx",
    "chars": 3583,
    "preview": "import '@testing-library/jest-dom/vitest';\n\nimport { faker } from '@faker-js/faker';\nimport { fireEvent } from '@testing"
  },
  {
    "path": "packages/components/src/CreateComment/CreateComment.tsx",
    "chars": 4647,
    "preview": "import type { ProfileType } from 'oa-shared';\nimport { useState } from 'react';\nimport { Box, Button, Flex, Image, Text,"
  },
  {
    "path": "packages/components/src/CreateReply/CreateReply.stories.tsx",
    "chars": 936,
    "preview": "import { CreateReply } from './CreateReply';\n\nimport type { Meta, StoryFn } from '@storybook/react-vite';\n\nexport defaul"
  },
  {
    "path": "packages/components/src/CreateReply/CreateReply.test.tsx",
    "chars": 2474,
    "preview": "import '@testing-library/jest-dom/vitest';\n\nimport { fireEvent, waitFor } from '@testing-library/react';\nimport { descri"
  },
  {
    "path": "packages/components/src/CreateReply/CreateReply.tsx",
    "chars": 1464,
    "preview": "import { useState } from 'react';\nimport { Alert, Box } from 'theme-ui';\n\nimport { CreateComment } from '../CreateCommen"
  },
  {
    "path": "packages/components/src/DisplayDate/DisplayDate.stories.tsx",
    "chars": 737,
    "preview": "import { subMonths } from 'date-fns';\n\nimport { DisplayDate } from './DisplayDate';\n\nimport type { Meta, StoryFn } from "
  },
  {
    "path": "packages/components/src/DisplayDate/DisplayDate.test.tsx",
    "chars": 4073,
    "preview": "import '@testing-library/jest-dom/vitest';\n\nimport { subDays, subMonths } from 'date-fns';\nimport { describe, expect, it"
  },
  {
    "path": "packages/components/src/DisplayDate/DisplayDate.tsx",
    "chars": 2789,
    "preview": "import { differenceInSeconds, format, formatDistanceToNow } from 'date-fns';\nimport { Text } from 'theme-ui';\n\nimport '."
  },
  {
    "path": "packages/components/src/DisplayDate/display-date.css",
    "chars": 266,
    "preview": ".date-mobile {\n  display: inline;\n}\n\n.date-desktop {\n  display: none;\n}\n\n/* Show desktop version and hide mobile version"
  },
  {
    "path": "packages/components/src/DonationRequestModal/DonationRequestModal.stories.tsx",
    "chars": 1058,
    "preview": "import { useState } from 'react';\n\nimport { DonationRequestModal } from './DonationRequestModal';\n\nimport type { Meta, S"
  },
  {
    "path": "packages/components/src/DonationRequestModal/DonationRequestModal.test.tsx",
    "chars": 1413,
    "preview": "import '@testing-library/jest-dom/vitest';\n\nimport { describe, expect, it, vi } from 'vitest';\n\nimport { render } from '"
  },
  {
    "path": "packages/components/src/DonationRequestModal/DonationRequestModal.tsx",
    "chars": 2816,
    "preview": "import { AspectImage, Card, Flex, Text } from 'theme-ui';\n\nimport { Modal } from '../Modal/Modal';\n\nexport interface IPr"
  },
  {
    "path": "packages/components/src/DownloadButton/DownloadButton.stories.tsx",
    "chars": 488,
    "preview": "import { DownloadButton } from './DownloadButton';\n\nimport type { Meta, StoryFn } from '@storybook/react-vite';\n\nexport "
  },
  {
    "path": "packages/components/src/DownloadButton/DownloadButton.test.tsx",
    "chars": 644,
    "preview": "import '@testing-library/jest-dom/vitest';\n\nimport { describe, expect, it } from 'vitest';\n\nimport { render } from '../t"
  },
  {
    "path": "packages/components/src/DownloadButton/DownloadButton.tsx",
    "chars": 1303,
    "preview": "import { Flex, Text } from 'theme-ui';\n\nimport { Icon } from '../Icon/Icon';\nimport type { IGlyphs } from '../Icon/types"
  },
  {
    "path": "packages/components/src/DownloadCounter/DownloadCounter.stories.tsx",
    "chars": 525,
    "preview": "import { DownloadCounter } from './DownloadCounter';\n\nimport type { Meta, StoryFn } from '@storybook/react-vite';\n\nexpor"
  },
  {
    "path": "packages/components/src/DownloadCounter/DownloadCounter.test.tsx",
    "chars": 792,
    "preview": "import '@testing-library/jest-dom/vitest';\n\nimport { describe, expect, it } from 'vitest';\n\nimport { render } from '../t"
  },
  {
    "path": "packages/components/src/DownloadCounter/DownloadCounter.tsx",
    "chars": 599,
    "preview": "import { Text } from 'theme-ui';\n\nexport interface IProps {\n  total: number | undefined;\n}\n\n// Duplicated util from main"
  },
  {
    "path": "packages/components/src/DownloadStaticFile/DownloadStaticFile.stories.tsx",
    "chars": 803,
    "preview": "import { DownloadStaticFile } from './DownloadStaticFile';\n\nimport type { Meta, StoryFn } from '@storybook/react-vite';\n"
  },
  {
    "path": "packages/components/src/DownloadStaticFile/DownloadStaticFile.tsx",
    "chars": 3013,
    "preview": "import type { MediaFile } from 'oa-shared';\nimport { Flex, Text } from 'theme-ui';\nimport { DownloadButton } from '../Do"
  },
  {
    "path": "packages/components/src/EditComment/EditComment.stories.tsx",
    "chars": 739,
    "preview": "import { EditComment } from './EditComment';\n\nimport type { Meta, StoryFn } from '@storybook/react-vite';\n\nexport defaul"
  },
  {
    "path": "packages/components/src/EditComment/EditComment.test.tsx",
    "chars": 2842,
    "preview": "import '@testing-library/jest-dom/vitest';\n\nimport { act, fireEvent } from '@testing-library/react';\nimport { describe, "
  },
  {
    "path": "packages/components/src/EditComment/EditComment.tsx",
    "chars": 3133,
    "preview": "import { useState } from 'react';\nimport { Field, Form } from 'react-final-form';\nimport { Flex, Label } from 'theme-ui'"
  },
  {
    "path": "packages/components/src/ElWithBeforeIcon/ElWithBeforeIcon.stories.tsx",
    "chars": 693,
    "preview": "import HeaderHowtoIcon from '../../../../src/assets/images/header-section/howto-header-icon.svg';\nimport { ElWithBeforeI"
  },
  {
    "path": "packages/components/src/ElWithBeforeIcon/ElWithBeforeIcon.tsx",
    "chars": 1483,
    "preview": "import type { JSX } from 'react';\nimport type { ThemeUIStyleObject } from 'theme-ui';\nimport { Box } from 'theme-ui';\nim"
  },
  {
    "path": "packages/components/src/ExternalLink/ExternalLink.stories.tsx",
    "chars": 929,
    "preview": "import { Text } from 'theme-ui';\n\nimport { Icon } from '..';\nimport { ExternalLink } from './ExternalLink';\n\nimport type"
  },
  {
    "path": "packages/components/src/ExternalLink/ExternalLink.tsx",
    "chars": 508,
    "preview": "import type { LinkProps } from 'theme-ui';\nimport { Link } from 'theme-ui';\n\n/**\n * Provides a styled `a` tag. Opens in "
  },
  {
    "path": "packages/components/src/FieldCheckbox/FieldCheckbox.tsx",
    "chars": 831,
    "preview": "import styled from '@emotion/styled';\nimport type { FieldRenderProps } from 'react-final-form';\nimport { Flex, Text } fr"
  },
  {
    "path": "packages/components/src/FieldInput/FieldInput.stories.tsx",
    "chars": 539,
    "preview": "import { FieldInput } from './FieldInput';\n\nimport type { Meta, StoryFn } from '@storybook/react-vite';\n\nexport default "
  },
  {
    "path": "packages/components/src/FieldInput/FieldInput.tsx",
    "chars": 2552,
    "preview": "import type { FieldRenderProps } from 'react-final-form';\nimport { Box, Flex, Input, Text } from 'theme-ui';\nimport { Ch"
  },
  {
    "path": "packages/components/src/FieldMarkdown/AddImage.tsx",
    "chars": 2279,
    "preview": "import { insertImage$, usePublisher } from '@mdxeditor/editor';\nimport { MediaWithPublicUrl } from 'oa-shared';\nimport {"
  },
  {
    "path": "packages/components/src/FieldMarkdown/FieldMarkdown.stories.tsx",
    "chars": 770,
    "preview": "import { MediaWithPublicUrl } from 'oa-shared';\nimport { FieldMarkdown } from './FieldMarkdown';\n\nimport type { Meta, St"
  },
  {
    "path": "packages/components/src/FieldMarkdown/FieldMarkdown.tsx",
    "chars": 3284,
    "preview": "import type { MDXEditorMethods } from '@mdxeditor/editor';\nimport {\n  BlockTypeSelect,\n  BoldItalicUnderlineToggles,\n  C"
  },
  {
    "path": "packages/components/src/FieldMarkdown/style.css",
    "chars": 369,
    "preview": ".mdxeditor {\n  border-radius: 8px;\n  border: 2px solid #f0f0f3;\n  position: relative;\n  z-index: 0;\n\n  &.mdxeditor-error"
  },
  {
    "path": "packages/components/src/FieldTextarea/FieldTextarea.stories.tsx",
    "chars": 1847,
    "preview": "import { FieldTextarea } from './FieldTextarea';\n\nimport type { Meta, StoryFn } from '@storybook/react-vite';\n\nexport de"
  },
  {
    "path": "packages/components/src/FieldTextarea/FieldTextarea.tsx",
    "chars": 2480,
    "preview": "import { useMemo } from 'react';\nimport type { FieldRenderProps } from 'react-final-form';\nimport { Flex, Text, Textarea"
  },
  {
    "path": "packages/components/src/FlagIcon/FlagIcon.tsx",
    "chars": 453,
    "preview": "import { ReactCountryFlag } from 'react-country-flag';\n\ninterface IProps {\n  countryCode: string;\n}\n\nexport const FlagIc"
  },
  {
    "path": "packages/components/src/FollowButton/FollowButton.stories.tsx",
    "chars": 685,
    "preview": "import { FollowButton } from './FollowButton';\n\nimport type { Meta, StoryFn } from '@storybook/react-vite';\n\nexport defa"
  },
  {
    "path": "packages/components/src/FollowButton/FollowButton.tsx",
    "chars": 1550,
    "preview": "import { useId } from 'react';\nimport { useNavigate } from 'react-router';\nimport type { ThemeUIStyleObject } from 'them"
  },
  {
    "path": "packages/components/src/FollowIcon/FollowIcon.stories.tsx",
    "chars": 432,
    "preview": "import { FollowIcon } from './FollowIcon';\n\nimport type { Meta, StoryFn } from '@storybook/react-vite';\n\nexport default "
  },
  {
    "path": "packages/components/src/FollowIcon/FollowIcon.tsx",
    "chars": 671,
    "preview": "import { useId } from 'react';\nimport { Box, ThemeUIStyleObject } from 'theme-ui';\nimport { Icon } from '../Icon/Icon';\n"
  },
  {
    "path": "packages/components/src/GlobalStyles/GlobalStyles.tsx",
    "chars": 1063,
    "preview": "import { css } from '@emotion/react';\nimport { commonStyles, GlobalFonts } from 'oa-themes';\n\nexport const GlobalStyles "
  },
  {
    "path": "packages/components/src/GridForm/GridForm.stories.tsx",
    "chars": 787,
    "preview": "import { Card, Checkbox, Text } from 'theme-ui';\n\nimport { GridForm } from './GridForm';\n\nimport type { Meta, StoryFn } "
  },
  {
    "path": "packages/components/src/GridForm/GridForm.tsx",
    "chars": 1259,
    "preview": "import type { ReactNode } from 'react';\nimport { Box, Flex, Grid, Text } from 'theme-ui';\nimport { Icon } from '../Icon/"
  },
  {
    "path": "packages/components/src/Guidelines/Guidelines.stories.tsx",
    "chars": 998,
    "preview": "import { ExternalLink } from '../ExternalLink/ExternalLink';\nimport { Guidelines } from './Guidelines';\n\nimport type { M"
  },
  {
    "path": "packages/components/src/Guidelines/Guidelines.test.tsx",
    "chars": 502,
    "preview": "import '@testing-library/jest-dom/vitest';\n\nimport { describe, expect, it } from 'vitest';\n\nimport { render } from '../t"
  },
  {
    "path": "packages/components/src/Guidelines/Guidelines.tsx",
    "chars": 611,
    "preview": "import { Card, Flex, Heading, Text } from 'theme-ui';\n\nexport interface IProps {\n  title: string;\n  steps: React.ReactEl"
  },
  {
    "path": "packages/components/src/Heading/Heading.stories.tsx",
    "chars": 405,
    "preview": "import { Heading } from 'theme-ui';\n\nimport type { Meta, StoryFn } from '@storybook/react-vite';\n\nexport default {\n  tit"
  },
  {
    "path": "packages/components/src/HeroBanner/HeroBanner.stories.tsx",
    "chars": 389,
    "preview": "import { HeroBanner } from './HeroBanner';\n\nimport type { Meta, StoryFn } from '@storybook/react-vite';\n\nexport default "
  },
  {
    "path": "packages/components/src/HeroBanner/HeroBanner.tsx",
    "chars": 386,
    "preview": "import { Image } from 'theme-ui';\n\nimport Celebration from '../../assets/images/celebration.svg';\nimport Email from '../"
  },
  {
    "path": "packages/components/src/Icon/DonateIcon.tsx",
    "chars": 4772,
    "preview": "export const DonateIcon = () => (\n  <svg width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" fill=\"none\" xmlns=\"http://www.w3.org"
  },
  {
    "path": "packages/components/src/Icon/DownloadIcon.tsx",
    "chars": 187,
    "preview": "import SvgDownloadIcon from '../../assets/icons/icon-download.svg';\n\nexport const DownloadIcon = () => (\n  <img alt=\"dow"
  },
  {
    "path": "packages/components/src/Icon/ExternalUrl.tsx",
    "chars": 196,
    "preview": "import ImageTargetBlank from '../../assets/icons/link-target-blank.svg';\n\nexport const ExternalUrl = () => (\n  <img alt="
  },
  {
    "path": "packages/components/src/Icon/Icon.stories.tsx",
    "chars": 1057,
    "preview": "import { Flex } from 'theme-ui';\nimport { glyphs, Icon } from './Icon';\nimport type { Meta, StoryFn } from '@storybook/r"
  },
  {
    "path": "packages/components/src/Icon/Icon.tsx",
    "chars": 6550,
    "preview": "/** @jsxImportSource theme-ui */\n\nimport styled from '@emotion/styled';\nimport type { Colors } from 'oa-themes';\nimport "
  },
  {
    "path": "packages/components/src/Icon/svgs.tsx",
    "chars": 10150,
    "preview": "import React from 'react';\nimport accountSVG from '../../assets/icons/account.svg';\nimport approvedSVG from '../../asset"
  },
  {
    "path": "packages/components/src/Icon/types.ts",
    "chars": 1851,
    "preview": "import type { JSX } from 'react';\n\nexport type availableGlyphs =\n  | 'account-circle'\n  | 'account'\n  | 'add'\n  | 'appro"
  },
  {
    "path": "packages/components/src/IconCountWithTooltip/IconCountWithTooltip.stories.tsx",
    "chars": 717,
    "preview": "import { IconCountWithTooltip } from './IconCountWithTooltip';\n\nimport type { Meta, StoryFn } from '@storybook/react-vit"
  },
  {
    "path": "packages/components/src/IconCountWithTooltip/IconCountWithTooltip.test.tsx",
    "chars": 852,
    "preview": "import '@testing-library/jest-dom/vitest';\n\nimport { describe, expect, it } from 'vitest';\n\nimport { render } from '../t"
  },
  {
    "path": "packages/components/src/IconCountWithTooltip/IconCountWithTooltip.tsx",
    "chars": 1249,
    "preview": "import { useId } from 'react';\nimport { Text } from 'theme-ui';\n\nimport { Icon } from '../Icon/Icon';\nimport type { avai"
  },
  {
    "path": "packages/components/src/ImageGallery/ImageGallery.stories.tsx",
    "chars": 2172,
    "preview": "import { ImageGallery } from './ImageGallery';\n\nimport type { Meta, StoryFn } from '@storybook/react-vite';\nimport type "
  },
  {
    "path": "packages/components/src/ImageGallery/ImageGallery.test.tsx",
    "chars": 6957,
    "preview": "import '@testing-library/jest-dom/vitest';\n\nimport { act, waitFor } from '@testing-library/react';\nimport { beforeAll, b"
  },
  {
    "path": "packages/components/src/ImageGallery/ImageGallery.tsx",
    "chars": 7091,
    "preview": "import styled from '@emotion/styled';\nimport type { PhotoSwipeOptions } from 'photoswipe/lightbox';\nimport { useLayoutEf"
  },
  {
    "path": "packages/components/src/ImageGalleryThumbnail/ImageGalleryThumbnail.stories.tsx",
    "chars": 3007,
    "preview": "import { ImageGalleryThumbnail } from './ImageGalleryThumbnail';\n\nimport type { Meta, StoryFn } from '@storybook/react-v"
  },
  {
    "path": "packages/components/src/ImageGalleryThumbnail/ImageGalleryThumbnail.test.tsx",
    "chars": 704,
    "preview": "import '@testing-library/jest-dom/vitest';\n\nimport { describe, expect, it, vi } from 'vitest';\n\nimport { render } from '"
  },
  {
    "path": "packages/components/src/ImageGalleryThumbnail/ImageGalleryThumbnail.tsx",
    "chars": 1315,
    "preview": "import styled from '@emotion/styled';\nimport React from 'react';\nimport type { CardProps } from 'theme-ui';\nimport { Box"
  },
  {
    "path": "packages/components/src/ImageInput/ImageInputDeleteOverlay.tsx",
    "chars": 1292,
    "preview": "import type { JSX } from 'react';\nimport type { BoxProps, ThemeUIStyleObject } from 'theme-ui';\nimport { Flex } from 'th"
  },
  {
    "path": "packages/components/src/ImageInput/ImageInputV2.tsx",
    "chars": 3498,
    "preview": "import { MediaWithPublicUrl } from 'oa-shared';\nimport { useEffect, useMemo, useRef, useState } from 'react';\nimport { F"
  },
  {
    "path": "packages/components/src/ImageInput/ImageInputWrapper.tsx",
    "chars": 1031,
    "preview": "import type { JSX } from 'react';\nimport { forwardRef } from 'react';\nimport type { BoxProps } from 'theme-ui';\nimport {"
  },
  {
    "path": "packages/components/src/ImageInput/isImageValid.ts",
    "chars": 892,
    "preview": "// Basic check using the filereader api to see whether we can create a displayable image\n// If this fails then there is "
  },
  {
    "path": "packages/components/src/InformationTooltip/InformationTooltip.stories.tsx",
    "chars": 436,
    "preview": "import { InformationTooltip } from './InformationTooltip';\n\nimport type { Meta, StoryFn } from '@storybook/react-vite';\n"
  },
  {
    "path": "packages/components/src/InformationTooltip/InformationTooltip.tsx",
    "chars": 561,
    "preview": "import { useId } from 'react';\nimport { Tooltip } from 'react-tooltip';\nimport type { IconProps } from '../Icon/Icon';\ni"
  },
  {
    "path": "packages/components/src/Input/Input.stories.tsx",
    "chars": 492,
    "preview": "import { Input } from 'theme-ui';\n\nimport type { Meta, StoryFn } from '@storybook/react-vite';\n\nexport default {\n  title"
  },
  {
    "path": "packages/components/src/InternalLink/InternalLink.stories.tsx",
    "chars": 335,
    "preview": "import { InternalLink } from './InternalLink';\n\nimport type { Meta, StoryFn } from '@storybook/react-vite';\n\nexport defa"
  },
  {
    "path": "packages/components/src/InternalLink/InternalLink.tsx",
    "chars": 531,
    "preview": "import { forwardRef } from 'react';\nimport type { LinkProps as RouterLinkProps } from 'react-router';\nimport { Link as R"
  },
  {
    "path": "packages/components/src/LinkifyText/LinkifyText.stories.tsx",
    "chars": 678,
    "preview": "import { LinkifyText } from './LinkifyText';\n\nimport type { Meta, StoryFn } from '@storybook/react-vite';\n\nexport defaul"
  },
  {
    "path": "packages/components/src/LinkifyText/LinkifyText.tsx",
    "chars": 1355,
    "preview": "import 'linkify-plugin-mention';\n\nimport styled from '@emotion/styled';\nimport Linkify from 'linkify-react';\nimport { us"
  },
  {
    "path": "packages/components/src/Loader/Loader.stories.tsx",
    "chars": 370,
    "preview": "import { Loader } from './Loader';\n\nimport type { Meta, StoryFn } from '@storybook/react-vite';\n\nexport default {\n  titl"
  },
  {
    "path": "packages/components/src/Loader/Loader.tsx",
    "chars": 560,
    "preview": "import { commonStyles } from 'oa-themes';\nimport type { ThemeUIStyleObject } from 'theme-ui';\nimport { Flex, Spinner, Te"
  },
  {
    "path": "packages/components/src/Map/Map.client.tsx",
    "chars": 1457,
    "preview": "import { forwardRef } from 'react';\nimport type { MapContainerProps } from 'react-leaflet';\nimport { MapContainer, TileL"
  },
  {
    "path": "packages/components/src/Map/Map.stories.tsx",
    "chars": 483,
    "preview": "import { useState } from 'react';\n\nimport { Map } from './Map.client';\n\nimport type { Meta, StoryFn } from '@storybook/r"
  },
  {
    "path": "packages/components/src/Map/index.css",
    "chars": 48,
    "preview": ".markercluster-map .closed {\n  display: none;\n}\n"
  }
]

// ... and 880 more files (download for full content)

About this extraction

This page contains the full source code of the OneArmyWorld/onearmy GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 1080 files (2.8 MB), approximately 781.5k tokens, and a symbol index with 1392 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.

Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.

Copied to clipboard!