From c00d1fe0d0254450640626c06fc4232a4128671d Mon Sep 17 00:00:00 2001 From: Nikita Mashchenko <52038455+nmashchenko@users.noreply.github.com> Date: Sat, 9 Dec 2023 00:16:42 -0600 Subject: [PATCH] feature: transfer user card functionality (#110) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * feat(user-card): move user-card component from previuos branch * fix(docs): change .MD to .md * feat(and-more): add new component * feat(and-more): add counter * feat(and-more): {finaly} add counting of languages * fix(user-card): names of files * fix(user-card & and-more): delete comments * fix(user-card): move inline styles to separate file * fix(user-card): change props using + minor changes * feat(user-card): move 'and-more' feature to badge-framework component * feat(user-card): move 'and-more' feature to badge-languages component * fix(user-card): and-more button size in badge-framework component * fix(user-card): displaying of 2 languages * fix(and-more): delete unused component * fix(user-card): use css variables * fix(user-card): delete inline styles and move to scss file * fix(badge-framework): replace img tag with Image * refactor(user-card): new polymorphic function to use render badges * fix(user-card): all problems * fix(user-card): delete unused part of code * fix(user-card): linter * fix(user-card): fix placement of elements * feat(user-card): crown for leaders * feat: add new logic for render langs and frameworks * refactor: refactor * refactor: refactor * refactor: refactor * refactor: refactor * refactor: refactor scss * refactor: refactor * refactor: refactor * feat: :sparkles: add animation for crown * feat: :sparkles: add animation for card * feat: :sparkles: add types * feat: :sparkles: add types * feat: :sparkles: add @teameights/types * Delete node_modules directory * fix: save changes * fix: fix css * refactor: refactor * refactor: refactor * fix(user-card): crown * feat(user-card): hover effect * feat(user-card): use entities instead of widgets * feat(user-card): add controller for storybook * feat(user-card): storybook params * feat(user-card): add onClick param for useCallback hooks * save changes * feat(user-card): adjust badgeFrameworkLayoutConfig and Image component in card module * feat(user-card): add hover effect and cursor pointer to user card component * feat(user-card): add hover effect and cursor pointer to user card component * feat(user-card): update UserCard component to display user's date of birth and role name * feat(user-card): use generateMockUser function for default user in UserCardPreview story * feat(user-card): update generateMockFileEntity to include random query parameter for image path 🚀 * feat(user-card): calculate and display user's age in UserCard component 🎂 * feat(user-card): add new mock data generation functions and update Home component to use them 🚀 * feat(user-card): update file paths and import styles to use consistent naming convention 🔄📦 * feat(user-card): add new logic for render langs and frameworks 🌐✨ * fix * fix * feat(user-card): restyle badge-language * fix: adjust code to changes from merge * fix(user-card): update user for storybook to match user type * feat(user-card): add country flag icon --------- Co-authored-by: Berezhnev Vladimir Co-authored-by: Sivritkin Dmitriy Co-authored-by: Romas Bitinas <93491714+pupixipup@users.noreply.github.com> --- .github/workflows/client.yml | 16 +- client/.gitignore | 2 +- client/next.config.js | 5 +- client/src/app/styles/variables.scss | 6 + client/src/entities/user/index.ts | 1 + .../frameworks-layout-config.tsx | 16 ++ .../frameworks-layout/frameworks-layout.tsx | 28 +++ .../language-layout-config.tsx | 15 ++ .../ui/language-layout/language-layout.tsx | 20 ++ .../user/ui/user-card/user-card.module.scss | 121 +++++++++++ .../user/ui/user-card/user-card.stories.tsx | 91 ++++++++ .../entities/user/ui/user-card/user-card.tsx | 50 +++++ client/src/shared/lib/index.ts | 1 + client/src/shared/lib/mock/user.ts | 7 +- .../get-elapsed-time/get-elapsed-time.test.ts | 7 - .../badge/badge-icon/badge-icon.module.scss | 4 + .../shared/ui/badge/badge-icon/badge-icon.tsx | 2 +- .../badge/badge-text/badge-text.module.scss | 7 + .../shared/ui/badge/badge-text/badge-text.tsx | 2 +- client/src/widgets/{README.MD => README.md} | 0 package.json | 5 + yarn.lock | 201 ++++++++++++++++++ 22 files changed, 576 insertions(+), 31 deletions(-) create mode 100644 client/src/entities/user/index.ts create mode 100644 client/src/entities/user/ui/frameworks-layout/frameworks-layout-config.tsx create mode 100644 client/src/entities/user/ui/frameworks-layout/frameworks-layout.tsx create mode 100644 client/src/entities/user/ui/language-layout/language-layout-config.tsx create mode 100644 client/src/entities/user/ui/language-layout/language-layout.tsx create mode 100644 client/src/entities/user/ui/user-card/user-card.module.scss create mode 100644 client/src/entities/user/ui/user-card/user-card.stories.tsx create mode 100644 client/src/entities/user/ui/user-card/user-card.tsx rename client/src/widgets/{README.MD => README.md} (100%) create mode 100644 package.json create mode 100644 yarn.lock diff --git a/.github/workflows/client.yml b/.github/workflows/client.yml index b7905b68f..326d94936 100644 --- a/.github/workflows/client.yml +++ b/.github/workflows/client.yml @@ -17,7 +17,6 @@ on: jobs: pipeline: - # Exclude renovate[bot] from triggering the workflow if: github.actor != 'renovate[bot]' runs-on: ubuntu-latest strategy: @@ -29,20 +28,14 @@ jobs: uses: actions/setup-node@v3 with: node-version: ${{matrix.node-version}} - - - name: Cache Yarn dependencies - uses: actions/cache@v3.2.2 - with: - path: ./client/node_modules - key: ${{ runner.os }}-yarn-${{ hashFiles('./client/yarn.lock') }} - restore-keys: | - ${{ runner.os }}-yarn- + cache: 'yarn' + cache-dependency-path: ./client/yarn.lock - name: Install yarn and dependencies working-directory: ./client run: | npm install --global yarn - yarn install --frozen-lockfile + yarn install --immutable - name: Lint and Format working-directory: ./client @@ -52,8 +45,7 @@ jobs: - name: Unit testing 💀💀 working-directory: ./client - run: | - yarn test:unit + run: yarn test:unit - name: Build project working-directory: ./client diff --git a/client/.gitignore b/client/.gitignore index e0f3b5d0f..4171e5a5f 100644 --- a/client/.gitignore +++ b/client/.gitignore @@ -1,5 +1,5 @@ # See https://help.github.com/articles/ignoring-files/ for more about ignoring files. - +node_modules .idea .vscode /storybook-static diff --git a/client/next.config.js b/client/next.config.js index e8d2b2b16..49efab5b2 100644 --- a/client/next.config.js +++ b/client/next.config.js @@ -3,6 +3,7 @@ const path = require('path'); module.exports = { images: { + domains: ['picsum.photos', 'source.unsplash.com'], remotePatterns: [ { protocol: 'https', @@ -10,10 +11,6 @@ module.exports = { port: '', pathname: '/my-bucket/**', }, - { - protocol: 'https', - hostname: 'picsum.photos', - }, { protocol: 'https', hostname: 'flagcdn.com', diff --git a/client/src/app/styles/variables.scss b/client/src/app/styles/variables.scss index d4d874209..d5f198d27 100644 --- a/client/src/app/styles/variables.scss +++ b/client/src/app/styles/variables.scss @@ -108,16 +108,22 @@ --font-body-size-s: 14px; --font-body-line-s: 120%; --font-body-weight-s: 400; + --font-body-s: var(--font-body-weight-s) var(--font-body-size-s) / var(--font-body-line-s) + var(--font-rubik); /* Body 2 -> Body M */ --font-body-size-m: 16px; --font-body-line-m: 140%; --font-body-weight-m: 400; + --font-body-m: var(--font-body-weight-s) var(--font-body-size-m) / var(--font-body-line-m) + var(--font-rubik); /* Body 1 -> Body XL */ --font-body-size-l: 20px; --font-body-line-l: 140%; --font-body-weight-l: 400; + --font-body-l: var(--font-body-weight-l) var(--font-body-size-l) / var(--font-body-line-l) + var(--font-rubik); /* Caption font */ --font-caption-size: 12px; diff --git a/client/src/entities/user/index.ts b/client/src/entities/user/index.ts new file mode 100644 index 000000000..07faba283 --- /dev/null +++ b/client/src/entities/user/index.ts @@ -0,0 +1 @@ +export { UserCard } from './ui/user-card/user-card'; diff --git a/client/src/entities/user/ui/frameworks-layout/frameworks-layout-config.tsx b/client/src/entities/user/ui/frameworks-layout/frameworks-layout-config.tsx new file mode 100644 index 000000000..c137958a0 --- /dev/null +++ b/client/src/entities/user/ui/frameworks-layout/frameworks-layout-config.tsx @@ -0,0 +1,16 @@ +type BadgeFrameworkType = 'full' | 'half' | 'empty' | 'extra'; +type BadgeFrameworkLayout = BadgeFrameworkType[]; + +interface badgeFrameworkLayoutConfig { + readonly default: Readonly; + + readonly [badgeCount: number]: Readonly; +} + +export const badgeFrameworkLayoutConfig: badgeFrameworkLayoutConfig = { + 1: ['empty', 'full'], + 2: ['full', 'full'], + 3: ['half', 'half', 'full'], + 4: ['half', 'half', 'half', 'half'], + default: ['half', 'half', 'half', 'extra'], +} as const; diff --git a/client/src/entities/user/ui/frameworks-layout/frameworks-layout.tsx b/client/src/entities/user/ui/frameworks-layout/frameworks-layout.tsx new file mode 100644 index 000000000..5ab1331d6 --- /dev/null +++ b/client/src/entities/user/ui/frameworks-layout/frameworks-layout.tsx @@ -0,0 +1,28 @@ +import styles from '../user-card/user-card.module.scss'; +import { BadgeText } from '@/shared/ui'; +import { badgeFrameworkLayoutConfig } from './frameworks-layout-config'; + +type BadgeFrameworksProps = { + frameworks: string[]; +}; + +export const BadgeFrameworksLayout: React.FC = ({ frameworks }) => { + const layout = + badgeFrameworkLayoutConfig[frameworks.length] || badgeFrameworkLayoutConfig.default; + + const isOneFramework = frameworks.length === 1; + + return ( +
+ {layout.map((size, index) => ( + + ))} +
+ ); +}; diff --git a/client/src/entities/user/ui/language-layout/language-layout-config.tsx b/client/src/entities/user/ui/language-layout/language-layout-config.tsx new file mode 100644 index 000000000..c626d1d76 --- /dev/null +++ b/client/src/entities/user/ui/language-layout/language-layout-config.tsx @@ -0,0 +1,15 @@ +type LanguageType = 'single' | 'more' | 'empty'; +type LanguageLayout = LanguageType[]; + +interface LanguageLayoutConfig { + readonly default: Readonly; + + readonly [languageCount: number]: Readonly; +} + +export const languageLayoutConfig: LanguageLayoutConfig = { + 1: ['single', 'empty'], + 2: ['single', 'single'], + 3: ['single', 'more'], + default: ['single', 'more'], +} as const; diff --git a/client/src/entities/user/ui/language-layout/language-layout.tsx b/client/src/entities/user/ui/language-layout/language-layout.tsx new file mode 100644 index 000000000..21412549f --- /dev/null +++ b/client/src/entities/user/ui/language-layout/language-layout.tsx @@ -0,0 +1,20 @@ +import styles from '../user-card/user-card.module.scss'; +import { BadgeIcon } from '@/shared/ui'; +import { languageLayoutConfig } from './language-layout-config'; + +interface ProgrammingLanguagesProps { + languages: string[]; +} + +export const ProgrammingLanguagesLayout: React.FC = ({ languages }) => { + const layout = languageLayoutConfig[languages.length] || languageLayoutConfig.default; + + return ( +
+ {layout.map((type, index) => { + if (type === 'more') return ; + return languages[index] && ; + })} +
+ ); +}; diff --git a/client/src/entities/user/ui/user-card/user-card.module.scss b/client/src/entities/user/ui/user-card/user-card.module.scss new file mode 100644 index 000000000..f56004853 --- /dev/null +++ b/client/src/entities/user/ui/user-card/user-card.module.scss @@ -0,0 +1,121 @@ +@keyframes pulse { + 0% { + transform: rotate(30deg) scale(1); + } + 50% { + transform: rotate(30deg) scale(1.1); + } + 100% { + transform: rotate(30deg) scale(1); + } +} + +.card { + padding: 20px; + position: relative; + border-radius: 15px; + width: 100%; + max-width: 230px; + height: 280px; + background: var(--cards-color); + cursor: pointer; + box-sizing: border-box; + border: 1px solid transparent; + transition: all 0.25s ease; + transition-property: border, background, box-shadow; + + &:hover { + border: 1px solid rgba(188, 202, 235, 0.4); + background: linear-gradient( + 126deg, + rgba(184, 197, 229, 0.16) 10.31%, + rgba(188, 202, 235, 0.08) 91.99% + ); + box-shadow: var(--usercard-shadow); + } +} + +.header { + display: flex; + align-items: center; +} + +.avatar { + position: relative; + + .image { + border-radius: 5px; + } + + .crown { + position: absolute; + top: -15%; + right: -15%; + transform: rotate(30deg); + animation: pulse 2s infinite; + } +} + +.languagesContainer { + display: flex; + gap: 10px; + width: 100%; + justify-content: flex-end; + align-items: center; + align-self: stretch; +} + +.content { + padding-top: 16px; + padding-bottom: 20px; + display: flex; + flex-direction: column; + column-gap: 8px; + + .name { + font: var(--font-body-m); + display: flex; + align-items: center; + gap: 8px; + } + + .role { + font: var(--font-body-s); + color: var(--grey-normal-color); + flex-basis: 34px; + display: -webkit-box; + overflow: hidden; + -webkit-line-clamp: 2; + -webkit-box-orient: vertical; + } +} + +.badgeContainer { + display: flex; + flex-wrap: wrap; + align-self: stretch; + height: 74px; + gap: 10px; +} + +.empty { + visibility: hidden; +} + +.full, +.framework { + flex: 1 1 100%; +} + +.half { + flex: 1 1 calc(50% - 10px); +} + +.extra { + flex: 1 1 calc(50% - 10px); + background: var(--grey-dark-color); + display: flex; + justify-content: center; + align-items: center; + border-radius: 5px; +} diff --git a/client/src/entities/user/ui/user-card/user-card.stories.tsx b/client/src/entities/user/ui/user-card/user-card.stories.tsx new file mode 100644 index 000000000..6a9e64a0b --- /dev/null +++ b/client/src/entities/user/ui/user-card/user-card.stories.tsx @@ -0,0 +1,91 @@ +import type { Meta, StoryObj } from '@storybook/react'; +import { UserCard } from './user-card'; +import { IUserResponse } from '@teameights/types'; +import { generateMockUser } from '@/shared/lib/mock'; + +const defaultUser = generateMockUser(); + +// More on how to set up stories at: https://storybook.js.org/docs/react/writing-stories/introduction +const meta: Meta = { + title: 'entities/User/UserCard', + component: UserCard, + tags: ['autodocs'], + argTypes: { + user: { + photo: { control: 'text' }, + fullName: { control: 'text' }, + programmingLanguages: { control: 'array' }, + frameworks: { control: 'array' }, + isLeader: { control: 'boolean' }, + }, + }, +}; +export default meta; +type Story = StoryObj; + +export const UserCardPreview: Story = { + args: { + user: defaultUser, + }, +}; + +const user1 = { + ...defaultUser, + skills: { programmingLanguages: ['JavaScript'], frameworks: ['Node.js'] }, + isLeader: true, +} as unknown as IUserResponse; +export const UserCard_1variant = () => ; + +const user2 = { + ...defaultUser, + skills: { + programmingLanguages: ['JavaScript', 'TypeScript'], + frameworks: ['Node.js', 'React.js'], + }, + isLeader: true, +} as unknown as IUserResponse; +export const UserCard_2variant = () => ; + +const user3 = { + ...defaultUser, + skills: { + programmingLanguages: ['JavaScript', 'TypeScript', 'Rust'], + frameworks: ['Node.js', 'React.js', 'MUI'], + }, + isLeader: true, +} as unknown as IUserResponse; +export const UserCard_3variant = () => ; + +const user4 = { + ...defaultUser, + skills: { + programmingLanguages: ['JavaScript', 'TypeScript', 'Rust', 'Java'], + frameworks: ['Node.js', 'React.js', 'MUI', 'Vue.js'], + }, + isLeader: true, +} as unknown as IUserResponse; +export const UserCard_4variant = () => ; + +const user5 = { + ...defaultUser, + skills: { + programmingLanguages: ['JavaScript', 'TypeScript', 'Rust', 'Java', 'PHP'], + frameworks: ['Node.js', 'React.js', 'MUI', 'Vue.js', 'Angular'], + }, + isLeader: true, +} as unknown as IUserResponse; +export const UserCard_5variant = () => ; + +const userWithoutPhoto = { + ...defaultUser, + skills: { + programmingLanguages: ['JS', 'TS', 'Rust', 'Java', 'Php'], + frameworks: ['Node.js', 'React.js', 'MUI', 'Vue.js', 'Angular'], + }, + fullName: 'John Doe', + isLeader: true, +} as unknown as IUserResponse; + +userWithoutPhoto.photo = null; + +export const UserCardWithImageFallback = () => ; diff --git a/client/src/entities/user/ui/user-card/user-card.tsx b/client/src/entities/user/ui/user-card/user-card.tsx new file mode 100644 index 000000000..e57e6c433 --- /dev/null +++ b/client/src/entities/user/ui/user-card/user-card.tsx @@ -0,0 +1,50 @@ +import styles from './user-card.module.scss'; +import { ProgrammingLanguagesLayout } from '../language-layout/language-layout'; +import { BadgeFrameworksLayout } from '../frameworks-layout/frameworks-layout'; +import { IUserResponse } from '@teameights/types'; +import { calculateAge } from '@/shared/lib'; +import { ImageLoader } from '@/shared/ui'; +import { CrownIcon28 } from '@/shared/assets'; +import { countryFlags } from '@/shared/constant'; + +interface UserCardProps { + user: IUserResponse; + onClick?: () => void; +} + +export const UserCard: React.FC = ({ + user: { country, photo, skills, isLeader, fullName, role, dateOfBirth }, + onClick, +}) => { + const years = calculateAge(dateOfBirth); + + return ( +
+
+
+ {/* TODO: Починить это опсле фикса типов с фотками*/} + + {isLeader && } +
+ {skills?.programmingLanguages && ( + + )} +
+
+
+ {fullName}, {years} + +
+
{role.name}
+
+ {skills?.frameworks && } +
+ ); +}; diff --git a/client/src/shared/lib/index.ts b/client/src/shared/lib/index.ts index cb64b4baf..c70acf382 100644 --- a/client/src/shared/lib/index.ts +++ b/client/src/shared/lib/index.ts @@ -1,3 +1,4 @@ export * from './ts-particles'; export * from './hooks'; export * from './utils'; +export * from './mock'; diff --git a/client/src/shared/lib/mock/user.ts b/client/src/shared/lib/mock/user.ts index ed3a20742..68a04bede 100644 --- a/client/src/shared/lib/mock/user.ts +++ b/client/src/shared/lib/mock/user.ts @@ -12,7 +12,7 @@ import { IUserBase, NotificationType, } from '@teameights/types'; -import { getRandomItemFromArray, getRandomNumberBetween, shuffleArray } from './common'; +import { getRandomItemFromArray, shuffleArray } from './common'; import { designerTools, fields, @@ -70,10 +70,7 @@ export const getRandomBadgeIcon = ( export const generateMockFileEntity = (): IFileEntity => { return { id: faker.number.int(), - path: `https://picsum.photos/${getRandomNumberBetween(1000, 1500)}/${getRandomNumberBetween( - 1000, - 1500 - )}`, + path: `https://source.unsplash.com/random?${faker.lorem.word()}`, }; }; diff --git a/client/src/shared/lib/utils/get-elapsed-time/get-elapsed-time.test.ts b/client/src/shared/lib/utils/get-elapsed-time/get-elapsed-time.test.ts index 28e37fc9b..b7f01e7c6 100644 --- a/client/src/shared/lib/utils/get-elapsed-time/get-elapsed-time.test.ts +++ b/client/src/shared/lib/utils/get-elapsed-time/get-elapsed-time.test.ts @@ -25,13 +25,6 @@ describe('getElapsedTime', () => { expect(getElapsedTime(pastTime)).toBe('2h ago'); }); - // Returns "0s ago" for a time that is 1 millisecond ago - it('should return "1s ago" for a time that is 0 millisecond ago', () => { - const currentTime = new Date(); - const pastTime = new Date(currentTime.getTime() - 1); // 1 millisecond ago - expect(getElapsedTime(pastTime)).toBe('0s ago'); - }); - // Returns "1s ago" for a time that is 1 secons ago it('should return ""1s ago" for a time that is 1 secons ago', () => { const currentTime = new Date(); diff --git a/client/src/shared/ui/badge/badge-icon/badge-icon.module.scss b/client/src/shared/ui/badge/badge-icon/badge-icon.module.scss index 3cc44c3d6..befddf563 100644 --- a/client/src/shared/ui/badge/badge-icon/badge-icon.module.scss +++ b/client/src/shared/ui/badge/badge-icon/badge-icon.module.scss @@ -8,4 +8,8 @@ display: flex; justify-content: center; align-items: center; + + &:only-child { + width: 90px; + } } diff --git a/client/src/shared/ui/badge/badge-icon/badge-icon.tsx b/client/src/shared/ui/badge/badge-icon/badge-icon.tsx index 62fb97927..fc884b153 100644 --- a/client/src/shared/ui/badge/badge-icon/badge-icon.tsx +++ b/client/src/shared/ui/badge/badge-icon/badge-icon.tsx @@ -46,7 +46,7 @@ export const BadgeIcon: FC = props => { background: `${isActive ? badgeColors[data] : 'var(--grey-dark-color)'}`, }} > - {badgeIcons[data]} + {badgeIcons[data] || data} ); }; diff --git a/client/src/shared/ui/badge/badge-text/badge-text.module.scss b/client/src/shared/ui/badge/badge-text/badge-text.module.scss index 1223b70ce..41d9bd7d8 100644 --- a/client/src/shared/ui/badge/badge-text/badge-text.module.scss +++ b/client/src/shared/ui/badge/badge-text/badge-text.module.scss @@ -6,4 +6,11 @@ justify-content: center; align-items: center; position: relative; + overflow: hidden; + + span { + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; + } } diff --git a/client/src/shared/ui/badge/badge-text/badge-text.tsx b/client/src/shared/ui/badge/badge-text/badge-text.tsx index 264ced76b..7d46d8046 100644 --- a/client/src/shared/ui/badge/badge-text/badge-text.tsx +++ b/client/src/shared/ui/badge/badge-text/badge-text.tsx @@ -46,7 +46,7 @@ export const BadgeText: FC = props => { maxWidth: `${maxWidth ? maxWidth : '100%'}`, }} > - {data} + {data} ); }; diff --git a/client/src/widgets/README.MD b/client/src/widgets/README.md similarity index 100% rename from client/src/widgets/README.MD rename to client/src/widgets/README.md diff --git a/package.json b/package.json new file mode 100644 index 000000000..be31f53f3 --- /dev/null +++ b/package.json @@ -0,0 +1,5 @@ +{ + "dependencies": { + "@teameights/types": "^1.1.11" + } +} diff --git a/yarn.lock b/yarn.lock new file mode 100644 index 000000000..e98f05cd2 --- /dev/null +++ b/yarn.lock @@ -0,0 +1,201 @@ +# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. +# yarn lockfile v1 + + +"@esbuild/android-arm64@0.18.20": + version "0.18.20" + resolved "https://registry.yarnpkg.com/@esbuild/android-arm64/-/android-arm64-0.18.20.tgz#984b4f9c8d0377443cc2dfcef266d02244593622" + integrity sha512-Nz4rJcchGDtENV0eMKUNa6L12zz2zBDXuhj/Vjh18zGqB44Bi7MBMSXjgunJgjRhCmKOjnPuZp4Mb6OKqtMHLQ== + +"@esbuild/android-arm@0.18.20": + version "0.18.20" + resolved "https://registry.yarnpkg.com/@esbuild/android-arm/-/android-arm-0.18.20.tgz#fedb265bc3a589c84cc11f810804f234947c3682" + integrity sha512-fyi7TDI/ijKKNZTUJAQqiG5T7YjJXgnzkURqmGj13C6dCqckZBLdl4h7bkhHt/t0WP+zO9/zwroDvANaOqO5Sw== + +"@esbuild/android-x64@0.18.20": + version "0.18.20" + resolved "https://registry.yarnpkg.com/@esbuild/android-x64/-/android-x64-0.18.20.tgz#35cf419c4cfc8babe8893d296cd990e9e9f756f2" + integrity sha512-8GDdlePJA8D6zlZYJV/jnrRAi6rOiNaCC/JclcXpB+KIuvfBN4owLtgzY2bsxnx666XjJx2kDPUmnTtR8qKQUg== + +"@esbuild/darwin-arm64@0.18.20": + version "0.18.20" + resolved "https://registry.yarnpkg.com/@esbuild/darwin-arm64/-/darwin-arm64-0.18.20.tgz#08172cbeccf95fbc383399a7f39cfbddaeb0d7c1" + integrity sha512-bxRHW5kHU38zS2lPTPOyuyTm+S+eobPUnTNkdJEfAddYgEcll4xkT8DB9d2008DtTbl7uJag2HuE5NZAZgnNEA== + +"@esbuild/darwin-x64@0.18.20": + version "0.18.20" + resolved "https://registry.yarnpkg.com/@esbuild/darwin-x64/-/darwin-x64-0.18.20.tgz#d70d5790d8bf475556b67d0f8b7c5bdff053d85d" + integrity sha512-pc5gxlMDxzm513qPGbCbDukOdsGtKhfxD1zJKXjCCcU7ju50O7MeAZ8c4krSJcOIJGFR+qx21yMMVYwiQvyTyQ== + +"@esbuild/freebsd-arm64@0.18.20": + version "0.18.20" + resolved "https://registry.yarnpkg.com/@esbuild/freebsd-arm64/-/freebsd-arm64-0.18.20.tgz#98755cd12707f93f210e2494d6a4b51b96977f54" + integrity sha512-yqDQHy4QHevpMAaxhhIwYPMv1NECwOvIpGCZkECn8w2WFHXjEwrBn3CeNIYsibZ/iZEUemj++M26W3cNR5h+Tw== + +"@esbuild/freebsd-x64@0.18.20": + version "0.18.20" + resolved "https://registry.yarnpkg.com/@esbuild/freebsd-x64/-/freebsd-x64-0.18.20.tgz#c1eb2bff03915f87c29cece4c1a7fa1f423b066e" + integrity sha512-tgWRPPuQsd3RmBZwarGVHZQvtzfEBOreNuxEMKFcd5DaDn2PbBxfwLcj4+aenoh7ctXcbXmOQIn8HI6mCSw5MQ== + +"@esbuild/linux-arm64@0.18.20": + version "0.18.20" + resolved "https://registry.yarnpkg.com/@esbuild/linux-arm64/-/linux-arm64-0.18.20.tgz#bad4238bd8f4fc25b5a021280c770ab5fc3a02a0" + integrity sha512-2YbscF+UL7SQAVIpnWvYwM+3LskyDmPhe31pE7/aoTMFKKzIc9lLbyGUpmmb8a8AixOL61sQ/mFh3jEjHYFvdA== + +"@esbuild/linux-arm@0.18.20": + version "0.18.20" + resolved "https://registry.yarnpkg.com/@esbuild/linux-arm/-/linux-arm-0.18.20.tgz#3e617c61f33508a27150ee417543c8ab5acc73b0" + integrity sha512-/5bHkMWnq1EgKr1V+Ybz3s1hWXok7mDFUMQ4cG10AfW3wL02PSZi5kFpYKrptDsgb2WAJIvRcDm+qIvXf/apvg== + +"@esbuild/linux-ia32@0.18.20": + version "0.18.20" + resolved "https://registry.yarnpkg.com/@esbuild/linux-ia32/-/linux-ia32-0.18.20.tgz#699391cccba9aee6019b7f9892eb99219f1570a7" + integrity sha512-P4etWwq6IsReT0E1KHU40bOnzMHoH73aXp96Fs8TIT6z9Hu8G6+0SHSw9i2isWrD2nbx2qo5yUqACgdfVGx7TA== + +"@esbuild/linux-loong64@0.18.20": + version "0.18.20" + resolved "https://registry.yarnpkg.com/@esbuild/linux-loong64/-/linux-loong64-0.18.20.tgz#e6fccb7aac178dd2ffb9860465ac89d7f23b977d" + integrity sha512-nXW8nqBTrOpDLPgPY9uV+/1DjxoQ7DoB2N8eocyq8I9XuqJ7BiAMDMf9n1xZM9TgW0J8zrquIb/A7s3BJv7rjg== + +"@esbuild/linux-mips64el@0.18.20": + version "0.18.20" + resolved "https://registry.yarnpkg.com/@esbuild/linux-mips64el/-/linux-mips64el-0.18.20.tgz#eeff3a937de9c2310de30622a957ad1bd9183231" + integrity sha512-d5NeaXZcHp8PzYy5VnXV3VSd2D328Zb+9dEq5HE6bw6+N86JVPExrA6O68OPwobntbNJ0pzCpUFZTo3w0GyetQ== + +"@esbuild/linux-ppc64@0.18.20": + version "0.18.20" + resolved "https://registry.yarnpkg.com/@esbuild/linux-ppc64/-/linux-ppc64-0.18.20.tgz#2f7156bde20b01527993e6881435ad79ba9599fb" + integrity sha512-WHPyeScRNcmANnLQkq6AfyXRFr5D6N2sKgkFo2FqguP44Nw2eyDlbTdZwd9GYk98DZG9QItIiTlFLHJHjxP3FA== + +"@esbuild/linux-riscv64@0.18.20": + version "0.18.20" + resolved "https://registry.yarnpkg.com/@esbuild/linux-riscv64/-/linux-riscv64-0.18.20.tgz#6628389f210123d8b4743045af8caa7d4ddfc7a6" + integrity sha512-WSxo6h5ecI5XH34KC7w5veNnKkju3zBRLEQNY7mv5mtBmrP/MjNBCAlsM2u5hDBlS3NGcTQpoBvRzqBcRtpq1A== + +"@esbuild/linux-s390x@0.18.20": + version "0.18.20" + resolved "https://registry.yarnpkg.com/@esbuild/linux-s390x/-/linux-s390x-0.18.20.tgz#255e81fb289b101026131858ab99fba63dcf0071" + integrity sha512-+8231GMs3mAEth6Ja1iK0a1sQ3ohfcpzpRLH8uuc5/KVDFneH6jtAJLFGafpzpMRO6DzJ6AvXKze9LfFMrIHVQ== + +"@esbuild/linux-x64@0.18.20": + version "0.18.20" + resolved "https://registry.yarnpkg.com/@esbuild/linux-x64/-/linux-x64-0.18.20.tgz#c7690b3417af318a9b6f96df3031a8865176d338" + integrity sha512-UYqiqemphJcNsFEskc73jQ7B9jgwjWrSayxawS6UVFZGWrAAtkzjxSqnoclCXxWtfwLdzU+vTpcNYhpn43uP1w== + +"@esbuild/netbsd-x64@0.18.20": + version "0.18.20" + resolved "https://registry.yarnpkg.com/@esbuild/netbsd-x64/-/netbsd-x64-0.18.20.tgz#30e8cd8a3dded63975e2df2438ca109601ebe0d1" + integrity sha512-iO1c++VP6xUBUmltHZoMtCUdPlnPGdBom6IrO4gyKPFFVBKioIImVooR5I83nTew5UOYrk3gIJhbZh8X44y06A== + +"@esbuild/openbsd-x64@0.18.20": + version "0.18.20" + resolved "https://registry.yarnpkg.com/@esbuild/openbsd-x64/-/openbsd-x64-0.18.20.tgz#7812af31b205055874c8082ea9cf9ab0da6217ae" + integrity sha512-e5e4YSsuQfX4cxcygw/UCPIEP6wbIL+se3sxPdCiMbFLBWu0eiZOJ7WoD+ptCLrmjZBK1Wk7I6D/I3NglUGOxg== + +"@esbuild/sunos-x64@0.18.20": + version "0.18.20" + resolved "https://registry.yarnpkg.com/@esbuild/sunos-x64/-/sunos-x64-0.18.20.tgz#d5c275c3b4e73c9b0ecd38d1ca62c020f887ab9d" + integrity sha512-kDbFRFp0YpTQVVrqUd5FTYmWo45zGaXe0X8E1G/LKFC0v8x0vWrhOWSLITcCn63lmZIxfOMXtCfti/RxN/0wnQ== + +"@esbuild/win32-arm64@0.18.20": + version "0.18.20" + resolved "https://registry.yarnpkg.com/@esbuild/win32-arm64/-/win32-arm64-0.18.20.tgz#73bc7f5a9f8a77805f357fab97f290d0e4820ac9" + integrity sha512-ddYFR6ItYgoaq4v4JmQQaAI5s7npztfV4Ag6NrhiaW0RrnOXqBkgwZLofVTlq1daVTQNhtI5oieTvkRPfZrePg== + +"@esbuild/win32-ia32@0.18.20": + version "0.18.20" + resolved "https://registry.yarnpkg.com/@esbuild/win32-ia32/-/win32-ia32-0.18.20.tgz#ec93cbf0ef1085cc12e71e0d661d20569ff42102" + integrity sha512-Wv7QBi3ID/rROT08SABTS7eV4hX26sVduqDOTe1MvGMjNd3EjOz4b7zeexIR62GTIEKrfJXKL9LFxTYgkyeu7g== + +"@esbuild/win32-x64@0.18.20": + version "0.18.20" + resolved "https://registry.yarnpkg.com/@esbuild/win32-x64/-/win32-x64-0.18.20.tgz#786c5f41f043b07afb1af37683d7c33668858f6d" + integrity sha512-kTdfRcSiDfQca/y9QIkng02avJ+NCaQvrMejlsB3RRv5sE9rRoeBPISaZpKxHELzRxZyLvNts1P27W3wV+8geQ== + +"@teameights/types@^1.1.11": + version "1.1.11" + resolved "https://registry.yarnpkg.com/@teameights/types/-/types-1.1.11.tgz#8727efd568cb95f6349badcde53d8252fcebb29b" + integrity sha512-jClfm74nMMqx77JC82EtCUet1f+yYcqHpu9Zmw5dd5iRBUed4RvDeleOMOMVH/ZiPBxVAn7Z5FjXKBeV9Tdoag== + dependencies: + esno "^0.17.0" + +buffer-from@^1.0.0: + version "1.1.2" + resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.1.2.tgz#2b146a6fd72e80b4f55d255f35ed59a3a9a41bd5" + integrity sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ== + +esbuild@~0.18.20: + version "0.18.20" + resolved "https://registry.yarnpkg.com/esbuild/-/esbuild-0.18.20.tgz#4709f5a34801b43b799ab7d6d82f7284a9b7a7a6" + integrity sha512-ceqxoedUrcayh7Y7ZX6NdbbDzGROiyVBgC4PriJThBKSVPWnnFHZAkfI1lJT8QFkOwH4qOS2SJkS4wvpGl8BpA== + optionalDependencies: + "@esbuild/android-arm" "0.18.20" + "@esbuild/android-arm64" "0.18.20" + "@esbuild/android-x64" "0.18.20" + "@esbuild/darwin-arm64" "0.18.20" + "@esbuild/darwin-x64" "0.18.20" + "@esbuild/freebsd-arm64" "0.18.20" + "@esbuild/freebsd-x64" "0.18.20" + "@esbuild/linux-arm" "0.18.20" + "@esbuild/linux-arm64" "0.18.20" + "@esbuild/linux-ia32" "0.18.20" + "@esbuild/linux-loong64" "0.18.20" + "@esbuild/linux-mips64el" "0.18.20" + "@esbuild/linux-ppc64" "0.18.20" + "@esbuild/linux-riscv64" "0.18.20" + "@esbuild/linux-s390x" "0.18.20" + "@esbuild/linux-x64" "0.18.20" + "@esbuild/netbsd-x64" "0.18.20" + "@esbuild/openbsd-x64" "0.18.20" + "@esbuild/sunos-x64" "0.18.20" + "@esbuild/win32-arm64" "0.18.20" + "@esbuild/win32-ia32" "0.18.20" + "@esbuild/win32-x64" "0.18.20" + +esno@^0.17.0: + version "0.17.0" + resolved "https://registry.yarnpkg.com/esno/-/esno-0.17.0.tgz#8692f002c4fa54b995849350eae6b824537f334e" + integrity sha512-w78cQGlptQfsBYfootUCitsKS+MD74uR5L6kNsvwVkJsfzEepIafbvWsx2xK4rcFP4IUftt4F6J8EhagUxX+Bg== + dependencies: + tsx "^3.12.7" + +fsevents@~2.3.3: + version "2.3.3" + resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.3.3.tgz#cac6407785d03675a2a5e1a5305c697b347d90d6" + integrity sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw== + +get-tsconfig@^4.7.2: + version "4.7.2" + resolved "https://registry.yarnpkg.com/get-tsconfig/-/get-tsconfig-4.7.2.tgz#0dcd6fb330391d46332f4c6c1bf89a6514c2ddce" + integrity sha512-wuMsz4leaj5hbGgg4IvDU0bqJagpftG5l5cXIAvo8uZrqn0NJqwtfupTN00VnkQJPcIRrxYrm1Ue24btpCha2A== + dependencies: + resolve-pkg-maps "^1.0.0" + +resolve-pkg-maps@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/resolve-pkg-maps/-/resolve-pkg-maps-1.0.0.tgz#616b3dc2c57056b5588c31cdf4b3d64db133720f" + integrity sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw== + +source-map-support@^0.5.21: + version "0.5.21" + resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.21.tgz#04fe7c7f9e1ed2d662233c28cb2b35b9f63f6e4f" + integrity sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w== + dependencies: + buffer-from "^1.0.0" + source-map "^0.6.0" + +source-map@^0.6.0: + version "0.6.1" + resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263" + integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g== + +tsx@^3.12.7: + version "3.14.0" + resolved "https://registry.yarnpkg.com/tsx/-/tsx-3.14.0.tgz#be6e2176b6f210fe8f48124fb6e22e0f075e927b" + integrity sha512-xHtFaKtHxM9LOklMmJdI3BEnQq/D5F73Of2E1GDrITi9sgoVkvIsrQUTY1G8FlmGtA+awCI4EBlTRRYxkL2sRg== + dependencies: + esbuild "~0.18.20" + get-tsconfig "^4.7.2" + source-map-support "^0.5.21" + optionalDependencies: + fsevents "~2.3.3"