diff --git a/.github/delete-merged-branch-config.yml b/.github/delete-merged-branch-config.yml new file mode 100644 index 000000000..2a6d27bef --- /dev/null +++ b/.github/delete-merged-branch-config.yml @@ -0,0 +1,15 @@ +name: delete branch on close pr + +on: + pull_request: + types: [closed] + +permissions: + pull-requests: write + +jobs: + delete-branch: + runs-on: ubuntu-latest + steps: + - name: delete branch + uses: SvanBoxel/delete-merged-branch@main diff --git a/base.css b/base.css new file mode 100644 index 000000000..b03cf0605 --- /dev/null +++ b/base.css @@ -0,0 +1,5 @@ +*{ + box-sizing: border-box; + font-family: Pretendard; + margin: 0; +} \ No newline at end of file diff --git a/image/akar-icons_facebook-fill.svg b/image/akar-icons_facebook-fill.svg new file mode 100644 index 000000000..af5130815 --- /dev/null +++ b/image/akar-icons_facebook-fill.svg @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/image/akar-icons_twitter-fill.svg b/image/akar-icons_twitter-fill.svg new file mode 100644 index 000000000..4586b559d --- /dev/null +++ b/image/akar-icons_twitter-fill.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/image/akar-icons_youtube-fill.svg b/image/akar-icons_youtube-fill.svg new file mode 100644 index 000000000..426c2540f --- /dev/null +++ b/image/akar-icons_youtube-fill.svg @@ -0,0 +1,14 @@ + + + + + + + + + + + + + + diff --git a/image/ant-design_instagram-filled.svg b/image/ant-design_instagram-filled.svg new file mode 100644 index 000000000..acd5df20b --- /dev/null +++ b/image/ant-design_instagram-filled.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/image/folder/logo.svg b/image/folder/logo.svg new file mode 100644 index 000000000..70dcc424e --- /dev/null +++ b/image/folder/logo.svg @@ -0,0 +1,15 @@ + + + diff --git a/image/index/landing.png b/image/index/landing.png new file mode 100644 index 000000000..d4809f36a Binary files /dev/null and b/image/index/landing.png differ diff --git a/image/index/manage-folder.png b/image/index/manage-folder.png new file mode 100644 index 000000000..27b80aea1 Binary files /dev/null and b/image/index/manage-folder.png differ diff --git a/image/index/save-link.png b/image/index/save-link.png new file mode 100644 index 000000000..4397a64dc Binary files /dev/null and b/image/index/save-link.png differ diff --git a/image/index/search-link.png b/image/index/search-link.png new file mode 100644 index 000000000..a48851090 Binary files /dev/null and b/image/index/search-link.png differ diff --git a/image/index/share-link.png b/image/index/share-link.png new file mode 100644 index 000000000..653acd59c Binary files /dev/null and b/image/index/share-link.png differ diff --git a/image/logo.svg b/image/logo.svg new file mode 100644 index 000000000..ac750371b --- /dev/null +++ b/image/logo.svg @@ -0,0 +1,15 @@ + + + diff --git a/image/search/Search.svg b/image/search/Search.svg new file mode 100644 index 000000000..0406766fd --- /dev/null +++ b/image/search/Search.svg @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/image/signin/eye-off.svg b/image/signin/eye-off.svg new file mode 100644 index 000000000..bec50d66f --- /dev/null +++ b/image/signin/eye-off.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/image/signin/eye-on.svg b/image/signin/eye-on.svg new file mode 100644 index 000000000..61afee898 --- /dev/null +++ b/image/signin/eye-on.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/image/social/google.png b/image/social/google.png new file mode 100644 index 000000000..e6f5aff87 Binary files /dev/null and b/image/social/google.png differ diff --git a/image/social/kakao.svg b/image/social/kakao.svg new file mode 100644 index 000000000..7a6062bc6 --- /dev/null +++ b/image/social/kakao.svg @@ -0,0 +1,13 @@ + + + + + + + + + + + + + diff --git a/image/star/state=Default.svg b/image/star/state=Default.svg new file mode 100644 index 000000000..f7d90ed0b --- /dev/null +++ b/image/star/state=Default.svg @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/index.css b/index.css new file mode 100644 index 000000000..064931fc9 --- /dev/null +++ b/index.css @@ -0,0 +1,355 @@ +/* PC */ +html::-webkit-scrollbar{ + display: none; +} + +.action-button { + padding: 16px 20px; + + color: #F5F5F5; + border-radius: 8px; + + font-size: 18px; + font-weight: 600; + text-align: center; + text-decoration: none; +} + +.action-button_nav_add-link { + width: 350px; + +} + +.action-button_nav_signin { + width: 128px; +} + +.action-button_grad_blue-sky { + background: linear-gradient(91deg, #6D6AFE 0.12%, #6AE3FE 101.84%); +} + +.feature-description { + display: flex; + justify-content: space-between; + align-items: center; + gap: 157px; + + width: fit-content; + max-width: 998px; +} + +.feature-descriptions { + display: flex; + flex-direction: column; + gap: 100px; + + padding: 120px 0 170px; + + background-color: #FFFFFF; +} + +.feature-description__detail-text { + color: #6B6B6B; + font-size: 16px; + font-weight: 500; + line-height: 24px; +} + +.feature-description__embrace-text { + -webkit-background-clip: text; + color: transparent; +} + +.feature-description__embrace-text_grad_blue-gray { + background-image: linear-gradient(99deg, #6D7CCD 19.76%, rgba(82, 136, 133, 0.22) 52.69%); +} + +.feature-description__embrace-text_grad_blue-pink { + background-image: linear-gradient(271deg, #FE578F -9.84%, #68E8F9 107.18%); +} + +.feature-description__embrace-text_grad_pink-blue { + background-image: linear-gradient(96deg, #FE8A8A 1.72%, #A4CEFF 74.97%); +} + +.feature-description__embrace-text_grad_yellow_blue { + background-image: linear-gradient(277deg, #6FBAFF 59.22%, #FFD88B 93.66%); +} + +.feature-description__sample-image-background { + flex-shrink: 0; + + width: 550px; + height: 450px; + + overflow: hidden; + + background-position: center; + background-repeat: no-repeat; + background-size: cover; + border-radius: 15px; +} + +.feature-description__sample-image-background_img_manage-folder{ + background-image: url(./image/index/manage-folder.png); +} + +.feature-description__sample-image-background_img_save-link{ + background-image: url(./image/index/save-link.png); +} + +.feature-description__sample-image-background_img_search-link{ + background-image: url(./image/index/search-link.png); +} + +.feature-description__sample-image-background_img_share-link{ + background-image: url(./image/index/share-link.png); +} +.feature-description__text-box { + display: flex; + flex-direction: column; + justify-content: start; + gap: 10px; +} + +.feature-description__title { + font-size: 48px; + font-weight: 700; + letter-spacing: -0.3px; +} + +.feature-description_reverse { + flex-direction: row-reverse; +} + +.footer { + display: flex; + justify-content: space-between; + align-items: flex-start; + padding: 32px 104px 64px; + background-color: #111322; +} + +.footer__company-info { + font-family: Arial; + font-size: 16px; + font-weight: 400; + + color: #676767; + text-align: center; +} + +.footer__policy-faq { + display: flex; + align-items: center; + gap: 30px; + + font-family: Arial; + font-size: 16px; + font-weight: 400; +} + +.footer__policy { + color: #CFCFCF; + text-decoration: none; +} + +.footer__faq { + color: #CFCFCF; + text-decoration: none; +} + +.footer__sns-icons { + display: flex; + justify-content: center; + align-items: center; + gap: 12px; +} + +.footer__sns-icon { + width: 20px; + height: 20px; + display: block; +} + +.header { + display: flex; + justify-content: space-between; + align-items: center; + padding: 20px 200px; + position: sticky; + top: 0; + z-index: 9999; + background-color: #F0F6FF; +} + +.main { + background-color: #F0F6FF; +} + +.service-description { + display: flex; + flex-direction: column; + justify-content: center; + align-items: center; + position: relative; + padding-top: 70px; + gap: 40px; + overflow: hidden; +} + +.service-description__embrace-text { + -webkit-background-clip: text; + color: transparent; +} + +.service-description__embrace-text_grad_blue-red { + background-image: linear-gradient(91deg, #6D6AFE 17.28%, #FF9F9F 74.98%); +} + +.service-description__title { + font-size: 64px; + font-weight: 700; + line-height: 125%; + text-align: center; +} + +.service-description__sample-image-background_img_landing { + background-image: url(./image/index/landing.png); + +} + +.service-description__sample-image-background { + width: 1200px; + height: 590px; + + overflow: hidden; + + background-position: center; + background-repeat: no-repeat; + background-size: cover; +} + + +/* Tablet */ +@media all and (max-width:1199px) { + + .feature-description { + width: unset; + max-width: 698px; + gap: 51px; + } + + .feature-descriptions { + padding: 80px 0 170px; + } + + .feature-description__sample-image-background { + width: 385px; + height: 315px; + } + + + .header{ + padding: 20px max(calc(100% - 999px),32px); + } + + .service-description { + width: unset; + } + + .service-description__sample-image-background { + width: 698px; + height: 343px; + } + +} + +/* Mobile */ +@media all and (min-width:375px) and (max-width:767px) { + + .action-button { + padding: 10px 16px; + + font-size: 14px; + font-weight: 600; + } + + .action-button_nav_add-link { + width: 200px; + } + + .action-button_nav_signin { + width: 80px; + } + + .feature-description { + flex-direction: column; + gap: 24px; + + width: unset; + width: 100%; + } + + .feature-descriptions { + padding: 40px 0 80px; + gap: 80px; + } + + + .feature-description__detail-text { + font-size: 15px; + font-weight: 500; + line-height: 150%; + /* 22.5px */ + } + + .feature-description__sample-image-background { + width: calc(100% - 64px); /* 좌우 여백을 제외한 너비 설정 */ + height: unset; + padding-top: calc((100% - 64px)*265.909/325); /* 높이는 자동으로 설정하여 비율 유지 */ + } + + .feature-description__text-box{ + width: 325px; + } + .feature-description__title { + font-size: 24px; + font-weight: 700; + letter-spacing: -0.3px; + } + + .footer{ + position: relative; + + height: 160px; + padding: 32px 32px 64px; + } + + .footer__company-info{ + position:absolute; + top: 108px; + } + + .header{ + padding: 13px 32px; + } + + .service-description { + gap:24px; + + width: unset; + } + + .service-description__sample-image-background { + width: calc(100% - 64px); /* 좌우 여백을 제외한 너비 설정 */ + height: unset; + padding-top: calc((100% - 64px) * 590/1200); /* 높이는 자동으로 설정하여 비율 유지 */ + } + + .service-description__title { + font-size: 32px; + font-weight: 700; + line-height: 42px; + } +} \ No newline at end of file diff --git a/index.html b/index.html new file mode 100644 index 000000000..4c2f9650d --- /dev/null +++ b/index.html @@ -0,0 +1,146 @@ + + + + + + + + + + + + + + + + + + + + + + + + + Linkbrary + + + + + + + + + + +
+
+

+ + 세상의 모든 정보를 +
+ 쉽게 저장하고 관리해 보세요 +

+ 링크 추가하기 +
+
+ +
+ +
+
+

+ 원하는 링크를 + 저장하세요 +

+

+ 나중에 읽고 싶은 글, 다시 보고 싶은 영상, + 사고 싶은 옷, 기억하고 싶은 모든 것을 + 한 공간에 저장하세요. +

+
+ +
+ +
+
+

+ 링크를 폴더로 + 관리하세요 +

+

+ 나만의 폴더를 무제한으로 만들고 다양하게 활용할 수 있습니다. +

+
+
+
+ +
+
+

+ 저장한 링크를 + 공유해 보세요 +

+

+ 여러 링크를 폴더에 담고 공유할 수 있습니다. + 가족, 친구, 동료들에게 쉽고 빠르게 링크를 공유해 보세요. +

+
+ +
+ +
+
+

+ 저장한 링크를 + 검색해 보세요 +

+

중요한 정보들을 검색으로 쉽게 찾아보세요.

+
+ +
+ +
+ + + diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 000000000..eb97d5d55 --- /dev/null +++ b/package-lock.json @@ -0,0 +1,1406 @@ +{ + "name": "2-weekly-mission", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "dependencies": { + "@vitejs/plugin-react": "^4.2.0", + "classnames": "^2.3.2", + "react": "^18.2.0", + "react-dom": "^18.2.0" + }, + "devDependencies": { + "vite": "^5.0.2" + } + }, + "node_modules/@ampproject/remapping": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.2.1.tgz", + "integrity": "sha512-lFMjJTrFL3j7L9yBxwYfCq2k6qqwHyzuUl/XBnif78PWTJYyL/dfowQHWE3sp6U6ZzqWiiIZnpTMO96zhkjwtg==", + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.0", + "@jridgewell/trace-mapping": "^0.3.9" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@babel/code-frame": { + "version": "7.23.4", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.23.4.tgz", + "integrity": "sha512-r1IONyb6Ia+jYR2vvIDhdWdlTGhqbBoFqLTQidzZ4kepUFH15ejXvFHxCVbtl7BOXIudsIubf4E81xeA3h3IXA==", + "dependencies": { + "@babel/highlight": "^7.23.4", + "chalk": "^2.4.2" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/compat-data": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.23.3.tgz", + "integrity": "sha512-BmR4bWbDIoFJmJ9z2cZ8Gmm2MXgEDgjdWgpKmKWUt54UGFJdlj31ECtbaDvCG/qVdG3AQ1SfpZEs01lUFbzLOQ==", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/core": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.23.3.tgz", + "integrity": "sha512-Jg+msLuNuCJDyBvFv5+OKOUjWMZgd85bKjbICd3zWrKAo+bJ49HJufi7CQE0q0uR8NGyO6xkCACScNqyjHSZew==", + "dependencies": { + "@ampproject/remapping": "^2.2.0", + "@babel/code-frame": "^7.22.13", + "@babel/generator": "^7.23.3", + "@babel/helper-compilation-targets": "^7.22.15", + "@babel/helper-module-transforms": "^7.23.3", + "@babel/helpers": "^7.23.2", + "@babel/parser": "^7.23.3", + "@babel/template": "^7.22.15", + "@babel/traverse": "^7.23.3", + "@babel/types": "^7.23.3", + "convert-source-map": "^2.0.0", + "debug": "^4.1.0", + "gensync": "^1.0.0-beta.2", + "json5": "^2.2.3", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/babel" + } + }, + "node_modules/@babel/generator": { + "version": "7.23.4", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.23.4.tgz", + "integrity": "sha512-esuS49Cga3HcThFNebGhlgsrVLkvhqvYDTzgjfFFlHJcIfLe5jFmRRfCQ1KuBfc4Jrtn3ndLgKWAKjBE+IraYQ==", + "dependencies": { + "@babel/types": "^7.23.4", + "@jridgewell/gen-mapping": "^0.3.2", + "@jridgewell/trace-mapping": "^0.3.17", + "jsesc": "^2.5.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-compilation-targets": { + "version": "7.22.15", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.22.15.tgz", + "integrity": "sha512-y6EEzULok0Qvz8yyLkCvVX+02ic+By2UdOhylwUOvOn9dvYc9mKICJuuU1n1XBI02YWsNsnrY1kc6DVbjcXbtw==", + "dependencies": { + "@babel/compat-data": "^7.22.9", + "@babel/helper-validator-option": "^7.22.15", + "browserslist": "^4.21.9", + "lru-cache": "^5.1.1", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-environment-visitor": { + "version": "7.22.20", + "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.22.20.tgz", + "integrity": "sha512-zfedSIzFhat/gFhWfHtgWvlec0nqB9YEIVrpuwjruLlXfUSnA8cJB0miHKwqDnQ7d32aKo2xt88/xZptwxbfhA==", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-function-name": { + "version": "7.23.0", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.23.0.tgz", + "integrity": "sha512-OErEqsrxjZTJciZ4Oo+eoZqeW9UIiOcuYKRJA4ZAgV9myA+pOXhhmpfNCKjEH/auVfEYVFJ6y1Tc4r0eIApqiw==", + "dependencies": { + "@babel/template": "^7.22.15", + "@babel/types": "^7.23.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-hoist-variables": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.22.5.tgz", + "integrity": "sha512-wGjk9QZVzvknA6yKIUURb8zY3grXCcOZt+/7Wcy8O2uctxhplmUPkOdlgoNhmdVee2c92JXbf1xpMtVNbfoxRw==", + "dependencies": { + "@babel/types": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-module-imports": { + "version": "7.22.15", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.22.15.tgz", + "integrity": "sha512-0pYVBnDKZO2fnSPCrgM/6WMc7eS20Fbok+0r88fp+YtWVLZrp4CkafFGIp+W0VKw4a22sgebPT99y+FDNMdP4w==", + "dependencies": { + "@babel/types": "^7.22.15" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-module-transforms": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.23.3.tgz", + "integrity": "sha512-7bBs4ED9OmswdfDzpz4MpWgSrV7FXlc3zIagvLFjS5H+Mk7Snr21vQ6QwrsoCGMfNC4e4LQPdoULEt4ykz0SRQ==", + "dependencies": { + "@babel/helper-environment-visitor": "^7.22.20", + "@babel/helper-module-imports": "^7.22.15", + "@babel/helper-simple-access": "^7.22.5", + "@babel/helper-split-export-declaration": "^7.22.6", + "@babel/helper-validator-identifier": "^7.22.20" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-plugin-utils": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.22.5.tgz", + "integrity": "sha512-uLls06UVKgFG9QD4OeFYLEGteMIAa5kpTPcFL28yuCIIzsf6ZyKZMllKVOCZFhiZ5ptnwX4mtKdWCBE/uT4amg==", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-simple-access": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.22.5.tgz", + "integrity": "sha512-n0H99E/K+Bika3++WNL17POvo4rKWZ7lZEp1Q+fStVbUi8nxPQEBOlTmCOxW/0JsS56SKKQ+ojAe2pHKJHN35w==", + "dependencies": { + "@babel/types": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-split-export-declaration": { + "version": "7.22.6", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.22.6.tgz", + "integrity": "sha512-AsUnxuLhRYsisFiaJwvp1QF+I3KjD5FOxut14q/GzovUe6orHLesW2C7d754kRm53h5gqrz6sFl6sxc4BVtE/g==", + "dependencies": { + "@babel/types": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-string-parser": { + "version": "7.23.4", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.23.4.tgz", + "integrity": "sha512-803gmbQdqwdf4olxrX4AJyFBV/RTr3rSmOj0rKwesmzlfhYNDEs+/iOcznzpNWlJlIlTJC2QfPFcHB6DlzdVLQ==", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-identifier": { + "version": "7.22.20", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.20.tgz", + "integrity": "sha512-Y4OZ+ytlatR8AI+8KZfKuL5urKp7qey08ha31L8b3BwewJAoJamTzyvxPR/5D+KkdJCGPq/+8TukHBlY10FX9A==", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-option": { + "version": "7.22.15", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.22.15.tgz", + "integrity": "sha512-bMn7RmyFjY/mdECUbgn9eoSY4vqvacUnS9i9vGAGttgFWesO6B4CYWA7XlpbWgBt71iv/hfbPlynohStqnu5hA==", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helpers": { + "version": "7.23.4", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.23.4.tgz", + "integrity": "sha512-HfcMizYz10cr3h29VqyfGL6ZWIjTwWfvYBMsBVGwpcbhNGe3wQ1ZXZRPzZoAHhd9OqHadHqjQ89iVKINXnbzuw==", + "dependencies": { + "@babel/template": "^7.22.15", + "@babel/traverse": "^7.23.4", + "@babel/types": "^7.23.4" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/highlight": { + "version": "7.23.4", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.23.4.tgz", + "integrity": "sha512-acGdbYSfp2WheJoJm/EBBBLh/ID8KDc64ISZ9DYtBmC8/Q204PZJLHyzeB5qMzJ5trcOkybd78M4x2KWsUq++A==", + "dependencies": { + "@babel/helper-validator-identifier": "^7.22.20", + "chalk": "^2.4.2", + "js-tokens": "^4.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/parser": { + "version": "7.23.4", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.23.4.tgz", + "integrity": "sha512-vf3Xna6UEprW+7t6EtOmFpHNAuxw3xqPZghy+brsnusscJRW5BMUzzHZc5ICjULee81WeUV2jjakG09MDglJXQ==", + "bin": { + "parser": "bin/babel-parser.js" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@babel/plugin-transform-react-jsx-self": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-self/-/plugin-transform-react-jsx-self-7.23.3.tgz", + "integrity": "sha512-qXRvbeKDSfwnlJnanVRp0SfuWE5DQhwQr5xtLBzp56Wabyo+4CMosF6Kfp+eOD/4FYpql64XVJ2W0pVLlJZxOQ==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-react-jsx-source": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-source/-/plugin-transform-react-jsx-source-7.23.3.tgz", + "integrity": "sha512-91RS0MDnAWDNvGC6Wio5XYkyWI39FMFO+JK9+4AlgaTH+yWwVTsw7/sn6LK0lH7c5F+TFkpv/3LfCJ1Ydwof/g==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/template": { + "version": "7.22.15", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.22.15.tgz", + "integrity": "sha512-QPErUVm4uyJa60rkI73qneDacvdvzxshT3kksGqlGWYdOTIUOwJ7RDUL8sGqslY1uXWSL6xMFKEXDS3ox2uF0w==", + "dependencies": { + "@babel/code-frame": "^7.22.13", + "@babel/parser": "^7.22.15", + "@babel/types": "^7.22.15" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/traverse": { + "version": "7.23.4", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.23.4.tgz", + "integrity": "sha512-IYM8wSUwunWTB6tFC2dkKZhxbIjHoWemdK+3f8/wq8aKhbUscxD5MX72ubd90fxvFknaLPeGw5ycU84V1obHJg==", + "dependencies": { + "@babel/code-frame": "^7.23.4", + "@babel/generator": "^7.23.4", + "@babel/helper-environment-visitor": "^7.22.20", + "@babel/helper-function-name": "^7.23.0", + "@babel/helper-hoist-variables": "^7.22.5", + "@babel/helper-split-export-declaration": "^7.22.6", + "@babel/parser": "^7.23.4", + "@babel/types": "^7.23.4", + "debug": "^4.1.0", + "globals": "^11.1.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/types": { + "version": "7.23.4", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.23.4.tgz", + "integrity": "sha512-7uIFwVYpoplT5jp/kVv6EF93VaJ8H+Yn5IczYiaAi98ajzjfoZfslet/e0sLh+wVBjb2qqIut1b0S26VSafsSQ==", + "dependencies": { + "@babel/helper-string-parser": "^7.23.4", + "@babel/helper-validator-identifier": "^7.22.20", + "to-fast-properties": "^2.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@esbuild/android-arm": { + "version": "0.19.7", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.19.7.tgz", + "integrity": "sha512-YGSPnndkcLo4PmVl2tKatEn+0mlVMr3yEpOOT0BeMria87PhvoJb5dg5f5Ft9fbCVgtAz4pWMzZVgSEGpDAlww==", + "cpu": [ + "arm" + ], + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/android-arm64": { + "version": "0.19.7", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.19.7.tgz", + "integrity": "sha512-YEDcw5IT7hW3sFKZBkCAQaOCJQLONVcD4bOyTXMZz5fr66pTHnAet46XAtbXAkJRfIn2YVhdC6R9g4xa27jQ1w==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/android-x64": { + "version": "0.19.7", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.19.7.tgz", + "integrity": "sha512-jhINx8DEjz68cChFvM72YzrqfwJuFbfvSxZAk4bebpngGfNNRm+zRl4rtT9oAX6N9b6gBcFaJHFew5Blf6CvUw==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/darwin-arm64": { + "version": "0.19.7", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.19.7.tgz", + "integrity": "sha512-dr81gbmWN//3ZnBIm6YNCl4p3pjnabg1/ZVOgz2fJoUO1a3mq9WQ/1iuEluMs7mCL+Zwv7AY5e3g1hjXqQZ9Iw==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/darwin-x64": { + "version": "0.19.7", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.19.7.tgz", + "integrity": "sha512-Lc0q5HouGlzQEwLkgEKnWcSazqr9l9OdV2HhVasWJzLKeOt0PLhHaUHuzb8s/UIya38DJDoUm74GToZ6Wc7NGQ==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/freebsd-arm64": { + "version": "0.19.7", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.19.7.tgz", + "integrity": "sha512-+y2YsUr0CxDFF7GWiegWjGtTUF6gac2zFasfFkRJPkMAuMy9O7+2EH550VlqVdpEEchWMynkdhC9ZjtnMiHImQ==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/freebsd-x64": { + "version": "0.19.7", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.19.7.tgz", + "integrity": "sha512-CdXOxIbIzPJmJhrpmJTLx+o35NoiKBIgOvmvT+jeSadYiWJn0vFKsl+0bSG/5lwjNHoIDEyMYc/GAPR9jxusTA==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-arm": { + "version": "0.19.7", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.19.7.tgz", + "integrity": "sha512-Y+SCmWxsJOdQtjcBxoacn/pGW9HDZpwsoof0ttL+2vGcHokFlfqV666JpfLCSP2xLxFpF1lj7T3Ox3sr95YXww==", + "cpu": [ + "arm" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-arm64": { + "version": "0.19.7", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.19.7.tgz", + "integrity": "sha512-inHqdOVCkUhHNvuQPT1oCB7cWz9qQ/Cz46xmVe0b7UXcuIJU3166aqSunsqkgSGMtUCWOZw3+KMwI6otINuC9g==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-ia32": { + "version": "0.19.7", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.19.7.tgz", + "integrity": "sha512-2BbiL7nLS5ZO96bxTQkdO0euGZIUQEUXMTrqLxKUmk/Y5pmrWU84f+CMJpM8+EHaBPfFSPnomEaQiG/+Gmh61g==", + "cpu": [ + "ia32" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-loong64": { + "version": "0.19.7", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.19.7.tgz", + "integrity": "sha512-BVFQla72KXv3yyTFCQXF7MORvpTo4uTA8FVFgmwVrqbB/4DsBFWilUm1i2Oq6zN36DOZKSVUTb16jbjedhfSHw==", + "cpu": [ + "loong64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-mips64el": { + "version": "0.19.7", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.19.7.tgz", + "integrity": "sha512-DzAYckIaK+pS31Q/rGpvUKu7M+5/t+jI+cdleDgUwbU7KdG2eC3SUbZHlo6Q4P1CfVKZ1lUERRFP8+q0ob9i2w==", + "cpu": [ + "mips64el" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-ppc64": { + "version": "0.19.7", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.19.7.tgz", + "integrity": "sha512-JQ1p0SmUteNdUaaiRtyS59GkkfTW0Edo+e0O2sihnY4FoZLz5glpWUQEKMSzMhA430ctkylkS7+vn8ziuhUugQ==", + "cpu": [ + "ppc64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-riscv64": { + "version": "0.19.7", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.19.7.tgz", + "integrity": "sha512-xGwVJ7eGhkprY/nB7L7MXysHduqjpzUl40+XoYDGC4UPLbnG+gsyS1wQPJ9lFPcxYAaDXbdRXd1ACs9AE9lxuw==", + "cpu": [ + "riscv64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-s390x": { + "version": "0.19.7", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.19.7.tgz", + "integrity": "sha512-U8Rhki5PVU0L0nvk+E8FjkV8r4Lh4hVEb9duR6Zl21eIEYEwXz8RScj4LZWA2i3V70V4UHVgiqMpszXvG0Yqhg==", + "cpu": [ + "s390x" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-x64": { + "version": "0.19.7", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.19.7.tgz", + "integrity": "sha512-ZYZopyLhm4mcoZXjFt25itRlocKlcazDVkB4AhioiL9hOWhDldU9n38g62fhOI4Pth6vp+Mrd5rFKxD0/S+7aQ==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/netbsd-x64": { + "version": "0.19.7", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.19.7.tgz", + "integrity": "sha512-/yfjlsYmT1O3cum3J6cmGG16Fd5tqKMcg5D+sBYLaOQExheAJhqr8xOAEIuLo8JYkevmjM5zFD9rVs3VBcsjtQ==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/openbsd-x64": { + "version": "0.19.7", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.19.7.tgz", + "integrity": "sha512-MYDFyV0EW1cTP46IgUJ38OnEY5TaXxjoDmwiTXPjezahQgZd+j3T55Ht8/Q9YXBM0+T9HJygrSRGV5QNF/YVDQ==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/sunos-x64": { + "version": "0.19.7", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.19.7.tgz", + "integrity": "sha512-JcPvgzf2NN/y6X3UUSqP6jSS06V0DZAV/8q0PjsZyGSXsIGcG110XsdmuWiHM+pno7/mJF6fjH5/vhUz/vA9fw==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "sunos" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/win32-arm64": { + "version": "0.19.7", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.19.7.tgz", + "integrity": "sha512-ZA0KSYti5w5toax5FpmfcAgu3ZNJxYSRm0AW/Dao5up0YV1hDVof1NvwLomjEN+3/GMtaWDI+CIyJOMTRSTdMw==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/win32-ia32": { + "version": "0.19.7", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.19.7.tgz", + "integrity": "sha512-CTOnijBKc5Jpk6/W9hQMMvJnsSYRYgveN6O75DTACCY18RA2nqka8dTZR+x/JqXCRiKk84+5+bRKXUSbbwsS0A==", + "cpu": [ + "ia32" + ], + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/win32-x64": { + "version": "0.19.7", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.19.7.tgz", + "integrity": "sha512-gRaP2sk6hc98N734luX4VpF318l3w+ofrtTu9j5L8EQXF+FzQKV6alCOHMVoJJHvVK/mGbwBXfOL1HETQu9IGQ==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@jridgewell/gen-mapping": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.3.tgz", + "integrity": "sha512-HLhSWOLRi875zjjMG/r+Nv0oCW8umGb0BgEhyX3dDX3egwZtB8PqLnjz3yedt8R5StBrzcg4aBpnh8UA9D1BoQ==", + "dependencies": { + "@jridgewell/set-array": "^1.0.1", + "@jridgewell/sourcemap-codec": "^1.4.10", + "@jridgewell/trace-mapping": "^0.3.9" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/resolve-uri": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.1.tgz", + "integrity": "sha512-dSYZh7HhCDtCKm4QakX0xFpsRDqjjtZf/kjI/v3T3Nwt5r8/qz/M19F9ySyOqU94SXBmeG9ttTul+YnR4LOxFA==", + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/set-array": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.1.2.tgz", + "integrity": "sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==", + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.4.15", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz", + "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==" + }, + "node_modules/@jridgewell/trace-mapping": { + "version": "0.3.20", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.20.tgz", + "integrity": "sha512-R8LcPeWZol2zR8mmH3JeKQ6QRCFb7XgUhV9ZlGhHLGyg4wpPiPZNQOOWhFZhxKw8u//yTbNGI42Bx/3paXEQ+Q==", + "dependencies": { + "@jridgewell/resolve-uri": "^3.1.0", + "@jridgewell/sourcemap-codec": "^1.4.14" + } + }, + "node_modules/@rollup/rollup-android-arm-eabi": { + "version": "4.5.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.5.2.tgz", + "integrity": "sha512-ee7BudTwwrglFYSc3UnqInDDjCLWHKrFmGNi4aK7jlEyg4CyPa1DCMrZfsN1O13YT76UFEqXz2CoN7BCGpUlJw==", + "cpu": [ + "arm" + ], + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@rollup/rollup-android-arm64": { + "version": "4.5.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.5.2.tgz", + "integrity": "sha512-xOuhj9HHtn8128ir8veoQsBbAUBasDbHIBniYTEx02pAmu9EXL+ZjJqngnNEy6ZgZ4h1JwL33GMNu3yJL5Mzow==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@rollup/rollup-darwin-arm64": { + "version": "4.5.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.5.2.tgz", + "integrity": "sha512-NTGJWoL8bKyqyWFn9/RzSv4hQ4wTbaAv0lHHRwf4OnpiiP4P8W0jiXbm8Nc5BCXKmWAwuvJY82mcIU2TayC20g==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@rollup/rollup-darwin-x64": { + "version": "4.5.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.5.2.tgz", + "integrity": "sha512-hlKqj7bpPvU15sZo4za14u185lpMzdwWLMc9raMqPK4wywt0wR23y1CaVQ4oAFXat3b5/gmRntyfpwWTKl+vvA==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@rollup/rollup-linux-arm-gnueabihf": { + "version": "4.5.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.5.2.tgz", + "integrity": "sha512-7ZIZx8c3u+pfI0ohQsft/GywrXez0uR6dUP0JhBuCK3sFO5TfdLn/YApnVkvPxuTv3+YKPIZend9Mt7Cz6sS3Q==", + "cpu": [ + "arm" + ], + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm64-gnu": { + "version": "4.5.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.5.2.tgz", + "integrity": "sha512-7Pk/5mO11JW/cH+a8lL/i0ZxmRGrbpYqN0VwO2DHhU+SJWWOH2zE1RAcPaj8KqiwC8DCDIJOSxjV9+9lLb6aeA==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm64-musl": { + "version": "4.5.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.5.2.tgz", + "integrity": "sha512-KrRnuG5phJx756e62wxvWH2e+TK84MP2IVuPwfge+GBvWqIUfVzFRn09TKruuQBXzZp52Vyma7FjMDkwlA9xpg==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-x64-gnu": { + "version": "4.5.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.5.2.tgz", + "integrity": "sha512-My+53GasPa2D2tU5dXiyHYwrELAUouSfkNlZ3bUKpI7btaztO5vpALEs3mvFjM7aKTvEbc7GQckuXeXIDKQ0fg==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-x64-musl": { + "version": "4.5.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.5.2.tgz", + "integrity": "sha512-/f0Q6Sc+Vw54Ws6N8fxaEe4R7at3b8pFyv+O/F2VaQ4hODUJcRUcCBJh6zuqtgQQt7w845VTkGLFgWZkP3tUoQ==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-win32-arm64-msvc": { + "version": "4.5.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.5.2.tgz", + "integrity": "sha512-NCKuuZWLht6zj7s6EIFef4BxCRX1GMr83S2W4HPCA0RnJ4iHE4FS1695q6Ewoa6A9nFjJe1//yUu0kgBU07Edw==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-ia32-msvc": { + "version": "4.5.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.5.2.tgz", + "integrity": "sha512-J5zL3riR4AOyU/J3M/i4k/zZ8eP1yT+nTmAKztCXJtnI36jYH0eepvob22mAQ/kLwfsK2TB6dbyVY1F8c/0H5A==", + "cpu": [ + "ia32" + ], + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-x64-msvc": { + "version": "4.5.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.5.2.tgz", + "integrity": "sha512-pL0RXRHuuGLhvs7ayX/SAHph1hrDPXOM5anyYUQXWJEENxw3nfHkzv8FfVlEVcLyKPAEgDRkd6RKZq2SMqS/yg==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@types/babel__core": { + "version": "7.20.5", + "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.20.5.tgz", + "integrity": "sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA==", + "dependencies": { + "@babel/parser": "^7.20.7", + "@babel/types": "^7.20.7", + "@types/babel__generator": "*", + "@types/babel__template": "*", + "@types/babel__traverse": "*" + } + }, + "node_modules/@types/babel__generator": { + "version": "7.6.7", + "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.6.7.tgz", + "integrity": "sha512-6Sfsq+EaaLrw4RmdFWE9Onp63TOUue71AWb4Gpa6JxzgTYtimbM086WnYTy2U67AofR++QKCo08ZP6pwx8YFHQ==", + "dependencies": { + "@babel/types": "^7.0.0" + } + }, + "node_modules/@types/babel__template": { + "version": "7.4.4", + "resolved": "https://registry.npmjs.org/@types/babel__template/-/babel__template-7.4.4.tgz", + "integrity": "sha512-h/NUaSyG5EyxBIp8YRxo4RMe2/qQgvyowRwVMzhYhBCONbW8PUsg4lkFMrhgZhUe5z3L3MiLDuvyJ/CaPa2A8A==", + "dependencies": { + "@babel/parser": "^7.1.0", + "@babel/types": "^7.0.0" + } + }, + "node_modules/@types/babel__traverse": { + "version": "7.20.4", + "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.20.4.tgz", + "integrity": "sha512-mSM/iKUk5fDDrEV/e83qY+Cr3I1+Q3qqTuEn++HAWYjEa1+NxZr6CNrcJGf2ZTnq4HoFGC3zaTPZTobCzCFukA==", + "dependencies": { + "@babel/types": "^7.20.7" + } + }, + "node_modules/@vitejs/plugin-react": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/@vitejs/plugin-react/-/plugin-react-4.2.0.tgz", + "integrity": "sha512-+MHTH/e6H12kRp5HUkzOGqPMksezRMmW+TNzlh/QXfI8rRf6l2Z2yH/v12no1UvTwhZgEDMuQ7g7rrfMseU6FQ==", + "dependencies": { + "@babel/core": "^7.23.3", + "@babel/plugin-transform-react-jsx-self": "^7.23.3", + "@babel/plugin-transform-react-jsx-source": "^7.23.3", + "@types/babel__core": "^7.20.4", + "react-refresh": "^0.14.0" + }, + "engines": { + "node": "^14.18.0 || >=16.0.0" + }, + "peerDependencies": { + "vite": "^4.2.0 || ^5.0.0" + } + }, + "node_modules/ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dependencies": { + "color-convert": "^1.9.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/browserslist": { + "version": "4.22.1", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.22.1.tgz", + "integrity": "sha512-FEVc202+2iuClEhZhrWy6ZiAcRLvNMyYcxZ8raemul1DYVOVdFsbqckWLdsixQZCpJlwe77Z3UTalE7jsjnKfQ==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "dependencies": { + "caniuse-lite": "^1.0.30001541", + "electron-to-chromium": "^1.4.535", + "node-releases": "^2.0.13", + "update-browserslist-db": "^1.0.13" + }, + "bin": { + "browserslist": "cli.js" + }, + "engines": { + "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" + } + }, + "node_modules/caniuse-lite": { + "version": "1.0.30001564", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001564.tgz", + "integrity": "sha512-DqAOf+rhof+6GVx1y+xzbFPeOumfQnhYzVnZD6LAXijR77yPtm9mfOcqOnT3mpnJiZVT+kwLAFnRlZcIz+c6bg==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/caniuse-lite" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ] + }, + "node_modules/chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dependencies": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/classnames": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/classnames/-/classnames-2.3.2.tgz", + "integrity": "sha512-CSbhY4cFEJRe6/GQzIk5qXZ4Jeg5pcsP7b5peFSDpffpe1cqjASH/n9UTjBwOp6XpMSTwQ8Za2K5V02ueA7Tmw==" + }, + "node_modules/color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dependencies": { + "color-name": "1.1.3" + } + }, + "node_modules/color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==" + }, + "node_modules/convert-source-map": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", + "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==" + }, + "node_modules/debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/electron-to-chromium": { + "version": "1.4.594", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.594.tgz", + "integrity": "sha512-xT1HVAu5xFn7bDfkjGQi9dNpMqGchUkebwf1GL7cZN32NSwwlHRPMSDJ1KN6HkS0bWUtndbSQZqvpQftKG2uFQ==" + }, + "node_modules/esbuild": { + "version": "0.19.7", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.19.7.tgz", + "integrity": "sha512-6brbTZVqxhqgbpqBR5MzErImcpA0SQdoKOkcWK/U30HtQxnokIpG3TX2r0IJqbFUzqLjhU/zC1S5ndgakObVCQ==", + "hasInstallScript": true, + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=12" + }, + "optionalDependencies": { + "@esbuild/android-arm": "0.19.7", + "@esbuild/android-arm64": "0.19.7", + "@esbuild/android-x64": "0.19.7", + "@esbuild/darwin-arm64": "0.19.7", + "@esbuild/darwin-x64": "0.19.7", + "@esbuild/freebsd-arm64": "0.19.7", + "@esbuild/freebsd-x64": "0.19.7", + "@esbuild/linux-arm": "0.19.7", + "@esbuild/linux-arm64": "0.19.7", + "@esbuild/linux-ia32": "0.19.7", + "@esbuild/linux-loong64": "0.19.7", + "@esbuild/linux-mips64el": "0.19.7", + "@esbuild/linux-ppc64": "0.19.7", + "@esbuild/linux-riscv64": "0.19.7", + "@esbuild/linux-s390x": "0.19.7", + "@esbuild/linux-x64": "0.19.7", + "@esbuild/netbsd-x64": "0.19.7", + "@esbuild/openbsd-x64": "0.19.7", + "@esbuild/sunos-x64": "0.19.7", + "@esbuild/win32-arm64": "0.19.7", + "@esbuild/win32-ia32": "0.19.7", + "@esbuild/win32-x64": "0.19.7" + } + }, + "node_modules/escalade": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", + "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", + "engines": { + "node": ">=6" + } + }, + "node_modules/escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/fsevents": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "hasInstallScript": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/gensync": { + "version": "1.0.0-beta.2", + "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", + "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/globals": { + "version": "11.12.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", + "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", + "engines": { + "node": ">=4" + } + }, + "node_modules/has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "engines": { + "node": ">=4" + } + }, + "node_modules/js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==" + }, + "node_modules/jsesc": { + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", + "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", + "bin": { + "jsesc": "bin/jsesc" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/json5": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", + "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", + "bin": { + "json5": "lib/cli.js" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/loose-envify": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", + "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==", + "dependencies": { + "js-tokens": "^3.0.0 || ^4.0.0" + }, + "bin": { + "loose-envify": "cli.js" + } + }, + "node_modules/lru-cache": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", + "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", + "dependencies": { + "yallist": "^3.0.2" + } + }, + "node_modules/ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + }, + "node_modules/nanoid": { + "version": "3.3.7", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.7.tgz", + "integrity": "sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "bin": { + "nanoid": "bin/nanoid.cjs" + }, + "engines": { + "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" + } + }, + "node_modules/node-releases": { + "version": "2.0.13", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.13.tgz", + "integrity": "sha512-uYr7J37ae/ORWdZeQ1xxMJe3NtdmqMC/JZK+geofDrkLUApKRHPd18/TxtBOJ4A0/+uUIliorNrfYV6s1b02eQ==" + }, + "node_modules/picocolors": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", + "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==" + }, + "node_modules/postcss": { + "version": "8.4.31", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.31.tgz", + "integrity": "sha512-PS08Iboia9mts/2ygV3eLpY5ghnUcfLV/EXTOW1E2qYxJKGGBUtNjN76FYHnMs36RmARn41bC0AZmn+rR0OVpQ==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/postcss" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "dependencies": { + "nanoid": "^3.3.6", + "picocolors": "^1.0.0", + "source-map-js": "^1.0.2" + }, + "engines": { + "node": "^10 || ^12 || >=14" + } + }, + "node_modules/react": { + "version": "18.2.0", + "resolved": "https://registry.npmjs.org/react/-/react-18.2.0.tgz", + "integrity": "sha512-/3IjMdb2L9QbBdWiW5e3P2/npwMBaU9mHCSCUzNln0ZCYbcfTsGbTJrU/kGemdH2IWmB2ioZ+zkxtmq6g09fGQ==", + "dependencies": { + "loose-envify": "^1.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/react-dom": { + "version": "18.2.0", + "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-18.2.0.tgz", + "integrity": "sha512-6IMTriUmvsjHUjNtEDudZfuDQUoWXVxKHhlEGSk81n4YFS+r/Kl99wXiwlVXtPBtJenozv2P+hxDsw9eA7Xo6g==", + "dependencies": { + "loose-envify": "^1.1.0", + "scheduler": "^0.23.0" + }, + "peerDependencies": { + "react": "^18.2.0" + } + }, + "node_modules/react-refresh": { + "version": "0.14.0", + "resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.14.0.tgz", + "integrity": "sha512-wViHqhAd8OHeLS/IRMJjTSDHF3U9eWi62F/MledQGPdJGDhodXJ9PBLNGr6WWL7qlH12Mt3TyTpbS+hGXMjCzQ==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/rollup": { + "version": "4.5.2", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.5.2.tgz", + "integrity": "sha512-CRK1uoROBfkcqrZKyaFcqCcZWNsvJ6yVYZkqTlRocZhO2s5yER6Z3f/QaYtO8RGyloPnmhwgzuPQpNGeK210xQ==", + "bin": { + "rollup": "dist/bin/rollup" + }, + "engines": { + "node": ">=18.0.0", + "npm": ">=8.0.0" + }, + "optionalDependencies": { + "@rollup/rollup-android-arm-eabi": "4.5.2", + "@rollup/rollup-android-arm64": "4.5.2", + "@rollup/rollup-darwin-arm64": "4.5.2", + "@rollup/rollup-darwin-x64": "4.5.2", + "@rollup/rollup-linux-arm-gnueabihf": "4.5.2", + "@rollup/rollup-linux-arm64-gnu": "4.5.2", + "@rollup/rollup-linux-arm64-musl": "4.5.2", + "@rollup/rollup-linux-x64-gnu": "4.5.2", + "@rollup/rollup-linux-x64-musl": "4.5.2", + "@rollup/rollup-win32-arm64-msvc": "4.5.2", + "@rollup/rollup-win32-ia32-msvc": "4.5.2", + "@rollup/rollup-win32-x64-msvc": "4.5.2", + "fsevents": "~2.3.2" + } + }, + "node_modules/scheduler": { + "version": "0.23.0", + "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.23.0.tgz", + "integrity": "sha512-CtuThmgHNg7zIZWAXi3AsyIzA3n4xx7aNyjwC2VJldO2LMVDhFK+63xGqq6CsJH4rTAt6/M+N4GhZiDYPx9eUw==", + "dependencies": { + "loose-envify": "^1.1.0" + } + }, + "node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/source-map-js": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.2.tgz", + "integrity": "sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/to-fast-properties": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", + "integrity": "sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==", + "engines": { + "node": ">=4" + } + }, + "node_modules/update-browserslist-db": { + "version": "1.0.13", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.13.tgz", + "integrity": "sha512-xebP81SNcPuNpPP3uzeW1NYXxI3rxyJzF3pD6sH4jE7o/IX+WtSpwnVU+qIsDPyk0d3hmFQ7mjqc6AtV604hbg==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "dependencies": { + "escalade": "^3.1.1", + "picocolors": "^1.0.0" + }, + "bin": { + "update-browserslist-db": "cli.js" + }, + "peerDependencies": { + "browserslist": ">= 4.21.0" + } + }, + "node_modules/vite": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/vite/-/vite-5.0.2.tgz", + "integrity": "sha512-6CCq1CAJCNM1ya2ZZA7+jS2KgnhbzvxakmlIjN24cF/PXhRMzpM/z8QgsVJA/Dm5fWUWnVEsmtBoMhmerPxT0g==", + "dependencies": { + "esbuild": "^0.19.3", + "postcss": "^8.4.31", + "rollup": "^4.2.0" + }, + "bin": { + "vite": "bin/vite.js" + }, + "engines": { + "node": "^18.0.0 || >=20.0.0" + }, + "funding": { + "url": "https://github.com/vitejs/vite?sponsor=1" + }, + "optionalDependencies": { + "fsevents": "~2.3.3" + }, + "peerDependencies": { + "@types/node": "^18.0.0 || >=20.0.0", + "less": "*", + "lightningcss": "^1.21.0", + "sass": "*", + "stylus": "*", + "sugarss": "*", + "terser": "^5.4.0" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + }, + "less": { + "optional": true + }, + "lightningcss": { + "optional": true + }, + "sass": { + "optional": true + }, + "stylus": { + "optional": true + }, + "sugarss": { + "optional": true + }, + "terser": { + "optional": true + } + } + }, + "node_modules/yallist": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", + "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==" + } + } +} diff --git a/package.json b/package.json new file mode 100644 index 000000000..cdb8104bf --- /dev/null +++ b/package.json @@ -0,0 +1,16 @@ +{ + "dependencies": { + "@vitejs/plugin-react": "^4.2.0", + "classnames": "^2.3.2", + "react": "^18.2.0", + "react-dom": "^18.2.0" + }, + "devDependencies": { + "vite": "^5.0.2" + }, + "scripts": { + "dev": "vite", + "build": "vite build", + "serve": "vite preview" + } +} diff --git a/reset.css b/reset.css new file mode 100644 index 000000000..b211cb197 --- /dev/null +++ b/reset.css @@ -0,0 +1,349 @@ +/*! normalize.css v8.0.1 | MIT License | github.com/necolas/normalize.css */ + +/* Document + ========================================================================== */ + +/** + * 1. Correct the line height in all browsers. + * 2. Prevent adjustments of font size after orientation changes in iOS. + */ + + html { + line-height: 1.15; /* 1 */ + -webkit-text-size-adjust: 100%; /* 2 */ + } + + /* Sections + ========================================================================== */ + + /** + * Remove the margin in all browsers. + */ + + body { + margin: 0; + } + + /** + * Render the `main` element consistently in IE. + */ + + main { + display: block; + } + + /** + * Correct the font size and margin on `h1` elements within `section` and + * `article` contexts in Chrome, Firefox, and Safari. + */ + + h1 { + font-size: 2em; + margin: 0.67em 0; + } + + /* Grouping content + ========================================================================== */ + + /** + * 1. Add the correct box sizing in Firefox. + * 2. Show the overflow in Edge and IE. + */ + + hr { + box-sizing: content-box; /* 1 */ + height: 0; /* 1 */ + overflow: visible; /* 2 */ + } + + /** + * 1. Correct the inheritance and scaling of font size in all browsers. + * 2. Correct the odd `em` font sizing in all browsers. + */ + + pre { + font-family: monospace, monospace; /* 1 */ + font-size: 1em; /* 2 */ + } + + /* Text-level semantics + ========================================================================== */ + + /** + * Remove the gray background on active links in IE 10. + */ + + a { + background-color: transparent; + } + + /** + * 1. Remove the bottom border in Chrome 57- + * 2. Add the correct text decoration in Chrome, Edge, IE, Opera, and Safari. + */ + + abbr[title] { + border-bottom: none; /* 1 */ + text-decoration: underline; /* 2 */ + text-decoration: underline dotted; /* 2 */ + } + + /** + * Add the correct font weight in Chrome, Edge, and Safari. + */ + + b, + strong { + font-weight: bolder; + } + + /** + * 1. Correct the inheritance and scaling of font size in all browsers. + * 2. Correct the odd `em` font sizing in all browsers. + */ + + code, + kbd, + samp { + font-family: monospace, monospace; /* 1 */ + font-size: 1em; /* 2 */ + } + + /** + * Add the correct font size in all browsers. + */ + + small { + font-size: 80%; + } + + /** + * Prevent `sub` and `sup` elements from affecting the line height in + * all browsers. + */ + + sub, + sup { + font-size: 75%; + line-height: 0; + position: relative; + vertical-align: baseline; + } + + sub { + bottom: -0.25em; + } + + sup { + top: -0.5em; + } + + /* Embedded content + ========================================================================== */ + + /** + * Remove the border on images inside links in IE 10. + */ + + img { + border-style: none; + } + + /* Forms + ========================================================================== */ + + /** + * 1. Change the font styles in all browsers. + * 2. Remove the margin in Firefox and Safari. + */ + + button, + input, + optgroup, + select, + textarea { + font-family: inherit; /* 1 */ + font-size: 100%; /* 1 */ + line-height: 1.15; /* 1 */ + margin: 0; /* 2 */ + } + + /** + * Show the overflow in IE. + * 1. Show the overflow in Edge. + */ + + button, + input { /* 1 */ + overflow: visible; + } + + /** + * Remove the inheritance of text transform in Edge, Firefox, and IE. + * 1. Remove the inheritance of text transform in Firefox. + */ + + button, + select { /* 1 */ + text-transform: none; + } + + /** + * Correct the inability to style clickable types in iOS and Safari. + */ + + button, + [type="button"], + [type="reset"], + [type="submit"] { + -webkit-appearance: button; + } + + /** + * Remove the inner border and padding in Firefox. + */ + + button::-moz-focus-inner, + [type="button"]::-moz-focus-inner, + [type="reset"]::-moz-focus-inner, + [type="submit"]::-moz-focus-inner { + border-style: none; + padding: 0; + } + + /** + * Restore the focus styles unset by the previous rule. + */ + + button:-moz-focusring, + [type="button"]:-moz-focusring, + [type="reset"]:-moz-focusring, + [type="submit"]:-moz-focusring { + outline: 1px dotted ButtonText; + } + + /** + * Correct the padding in Firefox. + */ + + fieldset { + padding: 0.35em 0.75em 0.625em; + } + + /** + * 1. Correct the text wrapping in Edge and IE. + * 2. Correct the color inheritance from `fieldset` elements in IE. + * 3. Remove the padding so developers are not caught out when they zero out + * `fieldset` elements in all browsers. + */ + + legend { + box-sizing: border-box; /* 1 */ + color: inherit; /* 2 */ + display: table; /* 1 */ + max-width: 100%; /* 1 */ + padding: 0; /* 3 */ + white-space: normal; /* 1 */ + } + + /** + * Add the correct vertical alignment in Chrome, Firefox, and Opera. + */ + + progress { + vertical-align: baseline; + } + + /** + * Remove the default vertical scrollbar in IE 10+. + */ + + textarea { + overflow: auto; + } + + /** + * 1. Add the correct box sizing in IE 10. + * 2. Remove the padding in IE 10. + */ + + [type="checkbox"], + [type="radio"] { + box-sizing: border-box; /* 1 */ + padding: 0; /* 2 */ + } + + /** + * Correct the cursor style of increment and decrement buttons in Chrome. + */ + + [type="number"]::-webkit-inner-spin-button, + [type="number"]::-webkit-outer-spin-button { + height: auto; + } + + /** + * 1. Correct the odd appearance in Chrome and Safari. + * 2. Correct the outline style in Safari. + */ + + [type="search"] { + -webkit-appearance: textfield; /* 1 */ + outline-offset: -2px; /* 2 */ + } + + /** + * Remove the inner padding in Chrome and Safari on macOS. + */ + + [type="search"]::-webkit-search-decoration { + -webkit-appearance: none; + } + + /** + * 1. Correct the inability to style clickable types in iOS and Safari. + * 2. Change font properties to `inherit` in Safari. + */ + + ::-webkit-file-upload-button { + -webkit-appearance: button; /* 1 */ + font: inherit; /* 2 */ + } + + /* Interactive + ========================================================================== */ + + /* + * Add the correct display in Edge, IE 10+, and Firefox. + */ + + details { + display: block; + } + + /* + * Add the correct display in all browsers. + */ + + summary { + display: list-item; + } + + /* Misc + ========================================================================== */ + + /** + * Add the correct display in IE 10+. + */ + + template { + display: none; + } + + /** + * Add the correct display in IE 10. + */ + + [hidden] { + display: none; + } \ No newline at end of file diff --git a/script/SignIn.js b/script/SignIn.js new file mode 100644 index 000000000..5fb9bdf01 --- /dev/null +++ b/script/SignIn.js @@ -0,0 +1,14 @@ +import {signInInputFocusOutCheckHandler, testSignInButtonClickCheckHandler, showIconClickHandler} from './SignUtility.js'; + +const inputFormInputs = document.querySelectorAll(`.input-form__input`); +for(const inputFormInput of inputFormInputs){ + inputFormInput.addEventListener('focusout', signInInputFocusOutCheckHandler); +} + +const showIcons = document.querySelectorAll(`.input-form__show-icon`); +for(const showIcon of showIcons){ + showIcon.addEventListener('click', showIconClickHandler); +} + +const loginButton = document.querySelector(`.action-button_signin`); +loginButton.addEventListener('click', testSignInButtonClickCheckHandler); \ No newline at end of file diff --git a/script/SignUtility.js b/script/SignUtility.js new file mode 100644 index 000000000..48fdf06c5 --- /dev/null +++ b/script/SignUtility.js @@ -0,0 +1,306 @@ +const email = `email`; +const password = `password`; +const passwordCheck = `password-check`; + +const inputFormClass = `input-form` +const inputFormInputClass = `${inputFormClass}__input`; + +const showIconClass = `${inputFormClass}__show-icon`; +const showIconOffClass = `${showIconClass}_eye-off`; + +const errorClass = `${inputFormClass}__input_error`; + +const SignRegex = { + [email]: /^[a-zA-Z0-9.!#$%&'*+\/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$/, + // 갈이 8~20, 영문자, 숫자 1개 이상 + [password]: /^(?=.*[a-zA-Z])(?=.*[0-9]).{8,20}$/, +}; + +const SignErrorMessage = { + [email]: { + nothing: `이메일을 입력해주세요`, + invaild: `올바른 이메일 주소가 아닙니다`, + used: `이미 사용 중인 이메일입니다`, + other: `이메일을 확인해주세요`, + }, + [password]: { + nothing: `비밀번호을 입력해주세요`, + invaild: `비밀번호는 영문, 숫자 조합 8자 이상 입력해주세요`, + other: `비밀번호을 확인해주세요`, + }, + [passwordCheck]: { + different: `비밀번호가 일치하지 않아요`, + } +}; + +const TestLoginInfo = { + [email]: `test@codeit.kr`, + [password]: `codeit101`, +} + +function signInInputFocusOutCheckHandler(e) { + const { target } = e; + + const errorMessage = getSignInErrorMessageByTarget(target); + handleErrorMessageElement(target, errorMessage); +} + +function signUpInputFocusOutCheckHandler(e) { + const { target } = e; + + const errorMessage = getSignUpErrorMessageByTarget(target); + handleErrorMessageElement(target, errorMessage); +} + + +function getSignInErrorMessageByTarget(target) { + switch (target.name) { + case email: { + if (nothingErrorCheck(target)) { + return SignErrorMessage[email].nothing; + } + + if (invalidErrorCheck(target)) { + return SignErrorMessage[email].invaild; + } + + break; + } + + case password: { + if (nothingErrorCheck(target)) { + return SignErrorMessage[password].nothing; + } + + if (invalidErrorCheck(target)) { + return SignErrorMessage[password].invaild; + } + + break; + } + + default: + break; + } + + return undefined; +} + +function getSignUpErrorMessageByTarget(target) { + switch (target.name) { + case email: { + if (nothingErrorCheck(target)) { + return SignErrorMessage[email].nothing; + } + + if (invalidErrorCheck(target)) { + return SignErrorMessage[email].invaild; + } + + if (usedErrorCheck(target)) { + return SignErrorMessage[email].used; + } + + break; + } + + case password: { + if (nothingErrorCheck(target)) { + return SignErrorMessage[password].nothing; + } + + if (invalidErrorCheck(target)) { + return SignErrorMessage[password].invaild; + } + + break; + } + + case passwordCheck: { + if (differentErrorCheck(target)) { + return SignErrorMessage[passwordCheck].different; + } + + break; + } + + default: + break; + } + + return undefined; +} + +function getErrorMessageElement(elements) { + + for (const element of elements) { + if (element.classList.contains(errorClass)) { + return element; + } + } + + return null; +} + +function testSignInButtonClickCheckHandler(e) { + const inputFormInputList = findinputFormInputList(); + + let isError = false; + + for (const inputFormInput of inputFormInputList) { + if (!otherErrorCheck(inputFormInput)) { + isError = true; + break; + } + } + + console.log(isError) + if (isError) { + for (const inputFormInput of inputFormInputList) { + putErrorMessageParentsSibling(inputFormInput, SignErrorMessage[inputFormInput.name].other); + addErrorClassOnInputForm(inputFormInput); + } + } else { + goToFolderPage(); + } +} + +function testSignUpButtonClickCheckHandler(e) { + const inputFormInputList = findinputFormInputList(); + + let isError = false; + + for (const inputFormInput of inputFormInputList) { + const errorMessage = getSignUpErrorMessageByTarget(inputFormInput); + handleErrorMessageElement(inputFormInput, errorMessage); + + errorMessage? isError = true: null; + } + + if(!isError){ + goToFolderPage(); + } +} + +/** + * + * @param {KeyboardEvent} e + */ +function testSignUpInputCheckHandler(e){ + if(e.key === 'Enter'){ + testSignUpButtonClickCheckHandler(e); + } +} + +function findinputFormInputList() { + return document.querySelectorAll(`.${inputFormInputClass}`); +} + +function handleErrorMessageElement(target, errorMessage) { + if (errorMessage) { + putErrorMessageParentsSibling(target, errorMessage); + addErrorClassOnInputForm(target); + } else { + deleteErrorMessageParentsSibling(target); + deleteErrorClassOnInputForm(target); + } +} + +function nothingErrorCheck(element) { + const { value } = element; + + if (value === "") { + return true; + } + + return false; +} + +function invalidErrorCheck(element) { + const { name, value } = element; + + return !SignRegex[name].test(value); +} + +function usedErrorCheck(element) { + const { name, value } = element; + + return value === TestLoginInfo[name]; +} + +function differentErrorCheck(element) { + const { value } = document.querySelector('#signup-password'); + const passwordCheckValue = element.value; + + if (value !== passwordCheckValue) { + return true; + } + + return false; +} + +function otherErrorCheck(inputFormInput) { + const { value, name } = inputFormInput; + + switch (name) { + case email: { + return value === TestLoginInfo[email]; + } + + case password: { + return value === TestLoginInfo[password]; + } + } +} + +function goToFolderPage() { + location.replace('./folder.html'); +} + +function putErrorMessageParentsSibling(target, errorMessage) { + const grandParent = target.parentElement.parentElement; + const ParentSiblings = target.parentElement.parentElement.children; + + const ErrorMessageElement = getErrorMessageElement(ParentSiblings); + if (ErrorMessageElement) { + ErrorMessageElement.textContent = errorMessage; + } else { + const errorMessageElement = document.createElement('span'); + errorMessageElement.textContent = errorMessage; + errorMessageElement.classList.add(errorClass); + grandParent.append(errorMessageElement); + } +} + +function addErrorClassOnInputForm(target) { + target.classList.add(errorClass); +} + +function deleteErrorMessageParentsSibling(target) { + const ParentSiblings = target.parentElement.parentElement.children; + const ErrorMessageElement = getErrorMessageElement(ParentSiblings); + ErrorMessageElement?.remove(); +} + +function deleteErrorClassOnInputForm(target) { + target?.classList.remove(errorClass); +} + +function showIconClickHandler(e) { + const { target } = e; + + const showTarget = [...target.parentElement.children].find((element) => element.classList.contains(inputFormInputClass)); + changeShowType(target, showTarget); +} + +function changeShowType(iconElement, targetElement) { + if (targetElement.type === 'password') { + targetElement.type = 'text'; + iconElement.classList.remove(showIconOffClass); + } else { + targetElement.type = 'password'; + iconElement.classList.add(showIconOffClass); + } +} + +export { signInInputFocusOutCheckHandler, signUpInputFocusOutCheckHandler, testSignInButtonClickCheckHandler, testSignUpButtonClickCheckHandler, testSignUpInputCheckHandler, showIconClickHandler }; \ No newline at end of file diff --git a/script/Signup.js b/script/Signup.js new file mode 100644 index 000000000..faf79618d --- /dev/null +++ b/script/Signup.js @@ -0,0 +1,15 @@ +import {signUpInputFocusOutCheckHandler, testSignUpButtonClickCheckHandler, testSignUpInputCheckHandler, showIconClickHandler} from './SignUtility.js'; + +const inputFormInputs = document.querySelectorAll(`.input-form__input`); +for(const inputFormInput of inputFormInputs){ + inputFormInput.addEventListener('focusout', signUpInputFocusOutCheckHandler); + inputFormInput.addEventListener('keydown', testSignUpInputCheckHandler); +} + +const showIcons = document.querySelectorAll(`.input-form__show-icon`); +for(const showIcon of showIcons){ + showIcon.addEventListener('click', showIconClickHandler); +} + +const loginButton = document.querySelector(`.action-button_signup`); +loginButton.addEventListener('click', testSignUpButtonClickCheckHandler); \ No newline at end of file diff --git a/script/shared.js b/script/shared.js new file mode 100644 index 000000000..caf4e41a2 --- /dev/null +++ b/script/shared.js @@ -0,0 +1,41 @@ +import ENDPOINTS from "../src/config/api"; + +//TODO header을 react 컴포넌트로 재구성해야함 +fetch(ENDPOINTS.SAMPLE.USER) + .then((response) => response.json()) + .then((result) => { + console.log(result); + if (result) { + const headerButton = document.querySelector(".header .action-button"); + headerButton.outerHTML = ` +
+ 프로필 이미지 + ${result.email} +
+ `; + + const headerUserInfo = document.querySelector(".header__user-info"); + headerUserInfo.style.cssText = ` + display: flex; + align-items: center; + gap: 6px; + `; + + const headerUserProfile = document.querySelector(".header__user-profile"); + headerUserProfile.style.cssText = ` + width: 28px; + height: 28px; + border-radius: 100%; + `; + + const headerUserEmail = document.querySelector(".header__user-email"); + headerUserEmail.style.cssText = ` + color: #373740; + font-size: 14px; + font-weight: 400; + `; + } + }) + .catch((error) => { + console.error(`데이터 가져오는 중 오류 발생\n${error}`); + }); diff --git a/shared.css b/shared.css new file mode 100644 index 000000000..ebf40c74f --- /dev/null +++ b/shared.css @@ -0,0 +1,143 @@ +.action-button { + padding: 16px 20px; + + color: #F5F5F5; + border-radius: 8px; + + font-size: 18px; + font-weight: 600; + text-align: center; + text-decoration: none; +} + +.action-button_nav_signin { + width: 128px; +} + +.action-button_grad_blue-sky { + background: linear-gradient(91deg, #6D6AFE 0.12%, #6AE3FE 101.84%); +} + +.footer { + display: flex; + justify-content: space-between; + align-items: flex-start; + padding: 32px 104px 64px; + background-color: #111322; +} + +.footer__company-info { + font-family: Arial; + font-size: 16px; + font-weight: 400; + + color: #676767; + text-align: center; +} + +.footer__policy-faq { + display: flex; + align-items: center; + gap: 30px; + + font-family: Arial; + font-size: 16px; + font-weight: 400; +} + +.footer__policy { + color: #CFCFCF; + text-decoration: none; +} + +.footer__faq { + color: #CFCFCF; + text-decoration: none; +} + +.footer__sns-icons { + display: flex; + justify-content: center; + align-items: center; + gap: 12px; +} + +.footer__sns-icon { + width: 20px; + height: 20px; + display: block; +} + + +.header { + display: flex; + justify-content: space-between; + align-items: center; + padding: 20px 200px; + position: sticky; + top: 0; + z-index: 9999; + background-color: #F0F6FF; +} + +#main-root{ + width: 100%; + + display: flex; + flex-direction: column; + align-items: center; +} + +#main-root .folder-info{ + margin: 20px auto 60px; +} + +#main-root .folder-info::before{ + height:294px; + width: 100%; + + position:absolute; + top: 0; + z-index: -1; + + background-color :#F0F6FF; + + content: ""; +} + +#main-root .search-bar{ + width: min(1066px, calc(100% - 64px)); + + margin: 40px 0 0; +} + +#main-root .table-layout_card{ + margin: 40px 0 100px; +} + +/* Tablet */ +@media all and (max-width:1199px) { + .header{ + padding: 20px max(calc(100% - 999px),32px); + } +} + + +/* Mobile */ +@media all and (min-width:375px) and (max-width:767px) { + .footer{ + position: relative; + + height: 160px; + padding: 32px 32px 64px; + } + + .footer__company-info{ + position:absolute; + top: 108px; + } + + .header{ + padding: 13px 32px; + } +} \ No newline at end of file diff --git a/shared.html b/shared.html new file mode 100644 index 000000000..434ea7d14 --- /dev/null +++ b/shared.html @@ -0,0 +1,63 @@ + + + + + + + Linkbrary + + + + + + + + + + +
+
+ + + diff --git a/signin.css b/signin.css new file mode 100644 index 000000000..ae7a35c32 --- /dev/null +++ b/signin.css @@ -0,0 +1,179 @@ +.action-button{ + padding: 16px 20px; + + color: #F5F5F5; + border: 0; + border-radius: 8px; + + font-size: 18px; + font-weight: 600; + text-align: center; + text-decoration: none; +} + +.action-button_signin{ + width: 100%; +} + +.action-button_grad_blue-sky{ + background: linear-gradient(91deg, #6D6AFE 0.12%, #6AE3FE 101.84%); +} + +.body{ + display: flex; + flex-direction: column; + justify-content: center; + align-items: center; + + width: 400px; +} + +.header{ + display: flex; + flex-direction: column; + align-items: center; + + gap: 8px; +} + +.header__logo-image{ + height: 38px; +} + +.html{ + background-color: #F0F6FF; +} + +.input-form{ + display: flex; + flex-direction: column; + gap: 12px; +} +.input-form__label{ + font-size: 14px; + font-weight: 400; +} +.input-form__input{ + padding: 18px 15px; + + width: inherit; + height: 60px; + + border: 1px solid #373740; + border-radius: 8px; + + font-size: 16px; + font-weight: 400; + line-height: 24px; +} +.input-form__input_error{ + border-color: #FF5B56; + color: #FF5B56; +} +.input-form__input:focus{ + outline: 0; +} +.input-form__input:focus-visible{ + border: 1px solid #6D6AFE; +} +.input-form__input-wrapper{ + width: 100%; + position: relative; +} +.input-form__show-icon{ + width: 16px; + height: 16px; + position: absolute; + right: 10px; + top: 50%; + transform: translateY(-50%); + + background-image: url(./image/signin/eye-on.svg); + background-position: center; + background-repeat: no-repeat; +} + +.input-form__show-icon_eye-off{ + background-image: url(./image/signin/eye-off.svg); +} + +.main{ + width: 100%; +} + +.page_centered{ + display: flex; + justify-content: center; + align-items: center; + + height: 100%; +} + +.sign__move-page{ + color: #6D6AFE; + + font-size: 16px; + font-weight: 500; + line-height: 24px; + text-decoration: underline; +} + +.sign-form{ + display: flex; + flex-direction: column; + gap: 24px; +} + +.social-signin{ + display: flex; + justify-content: space-between; + align-items: center; + + padding: 12px 24px; + + background-color: #E7EFFB; + border-radius: 8px; + border: 1px solid #CCD5E3; +} + +.social-signin__sns-icons{ + display: flex; + justify-content: space-between; + align-items: center; + gap: 16px; +} + +.social-signin__sns-icon{ + display: inline-flex; + + width: 42px; + height: 42px; + + border-radius: 100%; +} + +.social-signin__sns-icon_img-google{ + padding: 10px; +} + +.social-signin__sns-icon_img-kakao{ + padding: 10px 8px 8px; + +} + +.social-signin__sns-icon_background_google{ + background-color: #FFFFFF; + border: 1px solid #D3D4DD; +} +.social-signin__sns-icon_background_kakao{ + background-color: #F5E14B; + } + + + +/* Mobile */ +@media all and (min-width:375px) and (max-width:767px) { + .body{ + width: min(400px, calc(100% - 64px)); + } +} \ No newline at end of file diff --git a/signin.html b/signin.html new file mode 100644 index 000000000..c5877bcce --- /dev/null +++ b/signin.html @@ -0,0 +1,70 @@ + + + + + + + + 로그인 + + + + + + + + + +
+ +
+

회원이 아니신가요? 회원 가입하기

+
+
+
+
+
+
+ +
+ +
+ +
+
+ +
+ +
+
+
+
+
+ +
+ + +
+
+ + + + + \ No newline at end of file diff --git a/signup.css b/signup.css new file mode 100644 index 000000000..eb3d1fa1f --- /dev/null +++ b/signup.css @@ -0,0 +1,177 @@ +.action-button{ + padding: 16px 20px; + + color: #F5F5F5; + border: 0; + border-radius: 8px; + + font-size: 18px; + font-weight: 600; + text-align: center; + text-decoration: none; +} + +.action-button_signup{ + width: 100%; +} + +.action-button_grad_blue-sky{ + background: linear-gradient(91deg, #6D6AFE 0.12%, #6AE3FE 101.84%); +} + +.body{ + display: flex; + flex-direction: column; + justify-content: center; + align-items: center; + + width: 400px; +} + +.header{ + display: flex; + flex-direction: column; + align-items: center; + gap: 8px; +} + +.header__logo-image{ + height: 38px; +} + +.html{ + background-color: #F0F6FF; +} + +.input-form{ + display: flex; + flex-direction: column; + gap: 12px; +} +.input-form__label{ + font-size: 14px; + font-weight: 400; +} +.input-form__input{ + padding: 18px 15px; + + width: inherit; + height: 60px; + + border: 1px solid #373740; + border-radius: 8px; + + font-size: 16px; + font-weight: 400; + line-height: 24px; +} +.input-form__input_error{ + border-color: #FF5B56; + color: #FF5B56; +} + +.input-form__input:focus{ + outline: 0; +} +.input-form__input:focus-visible{ + border: 1px solid #6D6AFE; +} +.input-form__input-wrapper{ + width: 100%; + position: relative; +} + +.input-form__show-icon{ + width: 16px; + height: 16px; + position: absolute; + right: 10px; + top: 50%; + transform: translateY(-50%); + + background-image: url(./image/signin/eye-on.svg); + background-position: center; + background-repeat: no-repeat; +} + +.input-form__show-icon_eye-off{ + background-image: url(./image/signin/eye-off.svg); +} + +.main{ + width: 100%; +} + +.page_centered{ + display: flex; + justify-content: center; + align-items: center; + + height: 100%; +} + +.sign__move-page{ + color: #6D6AFE; + + font-size: 16px; + font-weight: 500; + line-height: 24px; + text-decoration: underline; +} + +.sign-form{ + display: flex; + flex-direction: column; + gap: 24px; +} + +.social-signup{ + display: flex; + justify-content: space-between; + align-items: center; + + padding: 12px 24px; + + background-color: #E7EFFB; + border-radius: 8px; + border: 1px solid #CCD5E3; +} + +.social-signup__sns-icons{ + display: flex; + justify-content: space-between; + align-items: center; + gap: 16px; +} + +.social-signup__sns-icon{ + display: inline-flex; + + width: 42px; + height: 42px; + + border-radius: 100%; +} + +.social-signup__sns-icon_img-google{ + padding: 10px; +} + +.social-signup__sns-icon_img-kakao{ + padding: 10px 8px 8px; +} + +.social-signup__sns-icon_background_google{ + background-color: #FFFFFF; + border: 1px solid #D3D4DD; +} +.social-signup__sns-icon_background_kakao{ + background-color: #F5E14B; +} + +/* Mobile */ +@media all and (min-width:375px) and (max-width:767px) { + .body{ + width: min(400px, calc(100% - 64px)); + } +} \ No newline at end of file diff --git a/signup.html b/signup.html new file mode 100644 index 000000000..d6da0c0c4 --- /dev/null +++ b/signup.html @@ -0,0 +1,80 @@ + + + + + + + + 로그인 + + + + + + + + + +
+ +
+

이미 회원이신가요? 로그인 하기

+
+
+
+
+
+
+ +
+ +
+ +
+
+ +
+ +
+
+
+
+ +
+ +
+
+
+
+
+ +
+ + +
+
+ + + + + \ No newline at end of file diff --git a/src/components/commons/Card.css b/src/components/commons/Card.css new file mode 100644 index 000000000..cc94e1fff --- /dev/null +++ b/src/components/commons/Card.css @@ -0,0 +1,108 @@ +.card{ + width: 340px; + height: 334px; + + border-radius: 15px; + box-shadow: 0px 5px 25px 0px rgba(0, 0, 0, 0.08); + + overflow: hidden; + + cursor: pointer; + + box-sizing: content-box; +} + +.card:hover{ + border: 2px solid #6D6AFE; + box-shadow: 0px 5px 40px 0px rgba(0, 0, 0, 0.16); +} + +.card:hover .card__image{ + animation: bigger 0.5s forwards; +} + +.card__content{ + height: 49px; + + display: -webkit-box; + + color: #000; + + font-size: 16px; + font-weight: 400; + line-height: 24px; + + overflow: hidden; + text-overflow: ellipsis; + word-break: break-all; + + -webkit-line-clamp: 2; + -webkit-box-orient: vertical; +} + +.card__created-at{ + color: #333; + + font-size: 14px; + font-weight: 400; + + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; +} + +.card__created-before{ + color: #666; + + font-size: 13px; + font-weight: 400; +} + +.card__image{ + min-width: 100%; + min-height: 100%; + object-fit: cover; + overflow: hidden; +} + +.card__image_no-image{ + width: 133px; + + min-width: unset; + min-height: unset; +} + +.card__image-container{ + height: 199px; + + display: flex; + align-items: center; + justify-content: center; + + overflow: hidden; +} + +.card__image-container_no-image{ + background-color: #DDDFFF; +} + +.card__info{ + height: 135px; + padding: 15px; + + display: flex; + flex-direction: column; + gap: 10px; +} + + + + +@keyframes bigger { + from { + transform: scale(1); + } + to { + transform: scale(1.3); + } +} \ No newline at end of file diff --git a/src/components/commons/Card.jsx b/src/components/commons/Card.jsx new file mode 100644 index 000000000..18e4f7c6c --- /dev/null +++ b/src/components/commons/Card.jsx @@ -0,0 +1,88 @@ +import React from "react"; +import classNames from "classnames"; +import "./Card.css"; +import { openLinkOnNewTab } from "../../utility/linkUtil"; +import { toKRDateString } from "../../utility/timeUtil"; + +function Card({ classNameList = [], data }) { + const { id, createdAt, url, title, description, imageSource } = data; + + return ( +
openLinkOnNewTab(url)} + > + + +
+ ); +} + +function CardImage({ src, title }) { + return ( + <> + {src ? ( +
+ {title} +
+ ) : ( +
+ {title} +
+ )} + + ); +} + +function CardInfo({ content, createdAt }) { + return ( +
+

{formatCreatedBefore(createdAt)}

+

{content}

+

{formatCreatedAt(createdAt)}

+
+ ); +} + +function formatCreatedAt(createdAt) { + const date = new Date(createdAt); + + return toKRDateString(date); +} + +function formatCreatedBefore(createdAt) { + const date = new Date(createdAt); + const now = new Date(); + const diff = now - date; + + const minutes = Math.floor(diff / 60000); + const hours = Math.floor(diff / 3600000); + const days = Math.floor(diff / 86400000); + const months = Math.floor(diff / 2592000000); + const years = Math.floor(diff / 31536000000); + + if (years) { + if (years === 1) return `${years} year ago`; + else return `${years} years ago`; + } else if (months) { + if (months === 1) return `${months} month ago`; + else return `${months} months ago`; + } else if (days) { + if (days === 1) return `${days} day ago`; + else return `${days} days ago`; + } else if (hours) { + if (hours === 1) return `${hours} hour ago`; + else return `${hours} hours ago`; + } else if (minutes) { + if (minutes === 1) return `${minutes} minute ago`; + else return `${minutes} minutes ago`; + } else { + return `1 minute ago`; + } +} + +export default Card; diff --git a/src/components/commons/CardFactory.jsx b/src/components/commons/CardFactory.jsx new file mode 100644 index 000000000..c6671759b --- /dev/null +++ b/src/components/commons/CardFactory.jsx @@ -0,0 +1,16 @@ +import React from "react"; +import Card from "./Card"; + +const classNames = [`card`]; + +function CardFactory({ dataList }) { + return ( + <> + {dataList?.map((item) => ( + + ))} + + ); +} + +export default CardFactory; diff --git a/src/components/commons/SearchBar.css b/src/components/commons/SearchBar.css new file mode 100644 index 000000000..bb522ed14 --- /dev/null +++ b/src/components/commons/SearchBar.css @@ -0,0 +1,27 @@ +.search-bar{ + width: min(1066px, 100%); + + padding: 15px; + + display: flex; + align-items: center; + gap: 10px; + + background-color: #f5f5f5; + border-radius: 10px; +} + +.search-bar__input{ + width: 100%; + + background-color:unset; + border: none; + + color: #666; + font-size: 16px; + font-weight: 400; +} + +.search-bar__input:focus{ + outline: none; +} \ No newline at end of file diff --git a/src/components/commons/SearchBar.jsx b/src/components/commons/SearchBar.jsx new file mode 100644 index 000000000..f59441976 --- /dev/null +++ b/src/components/commons/SearchBar.jsx @@ -0,0 +1,16 @@ +import React from 'react'; + +import SearchIcon from '../../../image/search/Search.svg' + +import './SearchBar.css'; + +function SearchBar() { + return ( +
+ 검색 아이콘 + +
+ ); +} + +export default SearchBar; diff --git a/src/components/layouts/TableLayout.css b/src/components/layouts/TableLayout.css new file mode 100644 index 000000000..7b25a3759 --- /dev/null +++ b/src/components/layouts/TableLayout.css @@ -0,0 +1,24 @@ +.table-layout{ + display: grid; + grid-template-columns: 1fr 1fr 1fr; +} + +.table-layout_card{ + width: fit-content; + height: fit-content; + + gap: 25px 20px; +} + +@media screen and (max-width: 1123px){ + .table-layout{ + grid-template-columns: 1fr 1fr; + } +} + +@media screen and (max-width: 767px){ + .table-layout{ + grid-template-columns: 1fr; + } + +} \ No newline at end of file diff --git a/src/components/layouts/TableLayout.jsx b/src/components/layouts/TableLayout.jsx new file mode 100644 index 000000000..351987140 --- /dev/null +++ b/src/components/layouts/TableLayout.jsx @@ -0,0 +1,14 @@ +import React from 'react'; +import classNames from 'classnames'; + +import './TableLayout.css'; + +function TableLayout({ children, classNameList = [] }) { + return ( +
+ {children} +
+ ); +} + +export default TableLayout; diff --git a/src/components/shared-screen/FolderInfo.css b/src/components/shared-screen/FolderInfo.css new file mode 100644 index 000000000..469c2dfa6 --- /dev/null +++ b/src/components/shared-screen/FolderInfo.css @@ -0,0 +1,31 @@ +.folder-info { + display: flex; + flex-direction: column; + align-items: center; + gap: 20px; +} + +.folder-info__profile { + display: flex; + flex-direction: column; + align-items: center; +} + +.folder-info__profile-image { + width: 60px; + height: 60px; + + border-radius: 100%; +} + +.folder-info__profile-name{ + color: var(--text-color-light-mode, #000); + font-size: 16px; + font-weight: 400; + line-height: 24px; +} + +.folder-info__title{ + font-size: 40px; + font-weight: 600; +} \ No newline at end of file diff --git a/src/components/shared-screen/FolderInfo.jsx b/src/components/shared-screen/FolderInfo.jsx new file mode 100644 index 000000000..8a943cb95 --- /dev/null +++ b/src/components/shared-screen/FolderInfo.jsx @@ -0,0 +1,41 @@ +import React from "react"; + +import "./FolderInfo.css"; + +function FolderInfo({ dataList }) { + return ( + <> +
+ + +
+ + ); +} + +function FolderProfile({ profileImageSource, profileName }) { + return ( +
+ {profileName} +

+ {`@${profileName ?? ""}`} +

+
+ ); +} + +function FolderTitle({folderName}){ + return( +
{folderName}
+ ) +} +export default FolderInfo; diff --git a/src/components/shared-screen/SharedMainScreen.jsx b/src/components/shared-screen/SharedMainScreen.jsx new file mode 100644 index 000000000..0fcabd8a2 --- /dev/null +++ b/src/components/shared-screen/SharedMainScreen.jsx @@ -0,0 +1,49 @@ +import React, { useEffect, useState } from "react"; +import ReactDOM from "react-dom/client"; + +import ENDPOINTS from "../../config/api"; + +import CardFactory from "../commons/CardFactory"; +import FolderInfo from "./FolderInfo"; +import SearchBar from "../commons/SearchBar"; +import TableLayout from "../layouts/TableLayout"; + +const root = ReactDOM.createRoot(document.getElementById("main-root")); +root.render(); + +function SharedMainScreen() { + const [folderData, setFolderData] = useState({}); + const [linkData, setLinkData] = useState([]); + + useEffect(() => { + fetch(ENDPOINTS.SAMPLE.FOLDER) + .then((response) => response.json()) + .then((result) => { + return result.folder; + }) + .then((folder) => { + setFolderData({ + id: folder.id, + name: folder.name, + owner: folder.owner, + }); + return folder.links; + }) + .then((links) => { + setLinkData(links); + }) + .catch((error) => { + console.error(`데이터 가져오는 중 오류 발생\n${error}`); + }); + }, []); + + return ( + <> + + + + + + + ); +} diff --git a/src/config/api.js b/src/config/api.js new file mode 100644 index 000000000..898ab77ba --- /dev/null +++ b/src/config/api.js @@ -0,0 +1,10 @@ +const API_BASE_URL = "https://bootcamp-api.codeit.kr/api"; + +const ENDPOINTS = { + SAMPLE: { + FOLDER: `${API_BASE_URL}/sample/folder`, + USER: `${API_BASE_URL}/sample/user`, + } +}; + +export default ENDPOINTS; \ No newline at end of file diff --git a/src/utility/linkUtil.js b/src/utility/linkUtil.js new file mode 100644 index 000000000..ff3d83d2d --- /dev/null +++ b/src/utility/linkUtil.js @@ -0,0 +1,5 @@ +function openLinkOnNewTab(url) { + window.open(url, '_blank'); +} + +export { openLinkOnNewTab} \ No newline at end of file diff --git a/src/utility/timeUtil.js b/src/utility/timeUtil.js new file mode 100644 index 000000000..c03bd8c99 --- /dev/null +++ b/src/utility/timeUtil.js @@ -0,0 +1,3 @@ +export function toKRDateString(date){ + return date.toLocaleDateString("ko-KR").slice(0, -1); +} \ No newline at end of file diff --git a/utility.css b/utility.css new file mode 100644 index 000000000..ecb9729b6 --- /dev/null +++ b/utility.css @@ -0,0 +1,12 @@ +.centered{ + margin: 0 auto; +} + +.mh_30px{ + margin-top: 30px; + margin-bottom: 30px; +} + +.mt_32px{ + margin-top: 32px; +} \ No newline at end of file diff --git a/vite.config.js b/vite.config.js new file mode 100644 index 000000000..1a2b773ef --- /dev/null +++ b/vite.config.js @@ -0,0 +1,11 @@ +// vite.config.js +/** + * Vite의 구성 옵션을 정의하는 곳입니다. + * React를 사용하는 경우 JSX를 처리하기 위한 플러그인을 설정할 수 있습니다. + */ +import { defineConfig } from 'vite'; +import react from '@vitejs/plugin-react'; + +export default defineConfig({ + plugins: [react()] +});